diff --git a/packages/LICENSE b/packages/LICENSE deleted file mode 100644 index 9cecc1d..0000000 --- a/packages/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {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 . - -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 -. - - 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 -. diff --git a/packages/a-20180907.953.el b/packages/a-20180907.953.el new file mode 100644 index 0000000..b699160 --- /dev/null +++ b/packages/a-20180907.953.el @@ -0,0 +1,347 @@ +;;; a.el --- Associative data structure functions -*- lexical-binding: t; -*- + +;; Copyright (C) 2017 Arne Brasseur + +;; Author: Arne Brasseur +;; URL: https://github.com/plexus/a.el +;; Package-Version: 20180907.953 +;; Keywords: lisp +;; Version: 0.1.1 +;; Package-Requires: ((emacs "25")) + +;; This file is not 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 file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Library for dealing with associative data structures: alists, hash-maps, and +;; vectors (for vectors, the indices are treated as keys). +;; +;; This library is largely inspired by Clojure, it has many of the functions +;; found in clojure.core, prefixed with `a-'. All functions treat their +;; arguments as immutable, so e.g. `a-assoc' will clone the hash-table or alist +;; it is given. Keep this in mind when writing performance sensitive code. + +;;; Code: + +(eval-when-compile (require 'subr-x)) ;; for things like hash-table-keys + +(require 'cl-lib) +(require 'seq) + +(defun a-associative-p (obj) + (or (not obj) + (hash-table-p obj) + (and (consp obj) (consp (car obj))))) + +(defalias 'a-associative? 'a-associative-p) + +(defun a-get (map key &optional not-found) + "Return the value MAP mapped to KEY, NOT-FOUND or nil if key not present." + (cond + ;; own implementation instead of alist-get so keys are checked with equal + ;; instead of eq + ((listp map) + (a--alist-get map key not-found)) + + ((vectorp map) + (if (a-has-key? map key) + (aref map key) + not-found)) + + ((hash-table-p map) + (gethash key map not-found)) + (t (user-error "Not associative: %S" map)))) + +(defun a--alist-get (map key &optional not-found) + "Like alist-get, but uses equal instead of eq to look up in map MAP key KEY. +Returns NOT-FOUND if the key is not present, or `nil' if +NOT-FOUND is not specified." + (cl-block nil + (seq-doseq (pair map) + (when (equal (car pair) key) + (cl-return (cdr pair)))) + not-found)) + +(defun a-get-in (m ks &optional not-found) + "Look up a value in a nested associative structure. + +Given a data structure M, and a sequence of keys KS, find the +value found by using each key in turn to do a lookup in the next +\"layer\". Return `nil' if the key is not present, or the NOT-FOUND +value if supplied." + (let ((result m)) + (cl-block nil + (seq-doseq (k ks) + (if (a-has-key? result k) + (setq result (a-get result k)) + (cl-return not-found))) + result))) + +(defmacro a-get* (&rest keys) + "Look up a value in a nested associative structure. + +Like a-get-in, but takes the key sequence KEYS directly as vararg +arguments, rather than as a single sequence." + (cl-labels ((rec (keys) + `(a-get ,(if (and (consp (cdr keys)) + (cddr keys)) + (rec (cdr keys)) + (cadr keys)) + ,(car keys)))) + (rec (nreverse keys)))) + +(defun a-has-key (coll k) + "Check if the given associative collection COLL has a certain key K." + (cond + ((listp coll) (not (eq (a--alist-get coll k :not-found) :not-found))) + ((vectorp coll) (and (integerp k) (< -1 k (length coll)))) + ((hash-table-p coll) (not (eq (gethash k coll :not-found) :not-found))) + (t (user-error "Not associative: %S" coll)))) + +(defalias 'a-has-key? 'a-has-key) + +(defun a-assoc-1 (coll k v) + "Like `a-assoc', (in COLL assoc K with V) but only takes a single k-v pair. +Internal helper function." + (cond + ((listp coll) + (if (a-has-key? coll k) + (mapcar (lambda (entry) + (if (equal (car entry) k) + (cons k v) + entry)) + coll) + (cons (cons k v) coll))) + + ((vectorp coll) + (if (and (integerp k) (> k 0)) + (if (< k (length coll)) + (let ((copy (copy-sequence coll))) + (aset copy k v) + copy) + (vconcat coll (make-list (- k (length coll)) nil) (list v))))) + + ((hash-table-p coll) + (let ((copy (copy-hash-table coll))) + (puthash k v copy) + copy)))) + +(defun a-assoc (coll &rest kvs) + "Return an updated collection COLL, associating values with keys KVS." + (when (not (cl-evenp (a-count kvs))) + (user-error "a-assoc requires an even number of arguments!")) + (seq-reduce (lambda (coll kv) + (seq-let [k v] kv + (a-assoc-1 coll k v))) + (seq-partition kvs 2) + coll)) + +(defun a-keys (coll) + "Return the keys in the collection COLL." + (cond + ((listp coll) + (mapcar #'car coll)) + + ((hash-table-p coll) + (hash-table-keys coll)))) + +(defun a-vals (coll) + "Return the values in the collection COLL." + (cond + ((listp coll) + (mapcar #'cdr coll)) + + ((hash-table-p coll) + (hash-table-values coll)))) + +(defun a-reduce-kv (fn from coll) + "Reduce with FN starting from FROM the collection COLL. +Reduce an associative collection COLL, starting with an initial +value of FROM. The reducing function FN receives the intermediate +value, key, and value." + (seq-reduce (lambda (acc key) + (funcall fn acc key (a-get coll key))) + (a-keys coll) + from)) + +(defun a-count (coll) + "Count the number of key-value pairs in COLL. +Like length, but can also return the length of hash tables." + (cond + ((seqp coll) + (length coll)) + + ((hash-table-p coll) + (hash-table-count coll)))) + +(defun a-equal (a b) + "Compare collections A, B for value equality. + +Associative collections (hash tables and a-lists) are considered +equal if they contain equal key-value pairs, regardless of order. + +Sequences (lists or vectors) are considered equal if they contain +the same elements in the same order. + +Collection elements are compared using `a-equal'. In other words, +the equality check is recursive, resulting in a \"deep\" equality +check. + +Anything that isn't associative or a sequence is compared with +`equal'." + (cond + ((and (a-associative? a) (a-associative? b)) + (or (equal a b) + (when (eq (a-count a) (a-count b)) + (cl-block nil + (seq-doseq (k (a-keys a)) + (when (not (a-equal (a-get a k) (a-get b k))) + (cl-return nil))) + t)))) + ((and (sequencep a) (sequencep b)) + (and (eq (length a) (length b)) + (or (and (seq-empty-p a) (seq-empty-p b)) + (and (a-equal (elt a 0) (elt b 0)) + (a-equal (seq-drop a 1) (seq-drop b 1)))))) + (t + (equal a b)))) + +(defalias 'a-equal? 'a-equal) + +(defun a-merge (&rest colls) + "Merge multiple associative collections. +Return the type of the first collection COLLS." + (seq-reduce (lambda (this that) + (a-reduce-kv (lambda (coll k v) + (a-assoc coll k v)) + this + that)) + (cdr colls) + (car colls))) + +(defun a-merge-with (f &rest colls) + "Merge multiple associative collections. +Return the type of the first collection COLLS. If a key exists in +both, then combine the associated values by calling f on them." + (seq-reduce (lambda (this that) + (a-reduce-kv (lambda (coll k v) + (a-assoc coll k (if (a-has-key coll k) + (funcall f v (a-get coll k)) + v))) + this + that)) + (cdr colls) + (car colls))) + +(defun a-alist (&rest kvs) + "Create an association list from the given keys and values KVS. +Arguments are simply provided in sequence, rather than as lists or cons cells. +For example: (a-alist :foo 123 :bar 456)" + (mapcar (lambda (kv) (cons (car kv) (cadr kv))) (seq-partition kvs 2))) + +(defalias 'a-list 'a-alist) + +(defun a-hash-table (&rest kvs) + "Create a hash table from the given keys and values KVS. +Arguments are simply provided in sequence, rather than as lists +or cons cells. As \"test\" for the hash table, equal is used. The +hash table is created without extra storage space, so with a size +equal to amount of key-value pairs, since it is assumed to be +treated as immutable. +For example: (a-hash-table :foo 123 :bar 456)" + (let* ((kv-pairs (seq-partition kvs 2)) + (hash-map (make-hash-table :test 'equal :size (length kv-pairs)))) + (seq-do (lambda (pair) + (puthash (car pair) (cadr pair) hash-map)) + kv-pairs) + hash-map)) + +(defun a-assoc-in (coll keys value) + "In collection COLL, at location KEYS, associate value VALUE. +Associates a value in a nested associative collection COLL, where +KEYS is a sequence of keys and VALUE is the new value and returns +a new nested structure. If any levels do not exist, association +lists will be created." + (cl-case (length keys) + (0 coll) + (1 (a-assoc-1 coll (elt keys 0) value)) + (t (a-assoc-1 coll + (elt keys 0) + (a-assoc-in (a-get coll (elt keys 0)) + (seq-drop keys 1) + value))))) + +(defun a-dissoc--list (list keys) + "Return updated LIST with KEYS removed. +Internal helper. Use `a-dissoc' instead." + (a-reduce-kv (lambda (res k v) + (if (member k keys) + res + (cons (cons k v) res))) + nil + list)) + +(defun a-dissoc--hash-table (table keys) + "Return updated TABLE with KEYS removed. +Internal helper. Use `a-dissoc' instead." + (let ((new-table (make-hash-table :size (hash-table-count table) + :test (hash-table-test table))) + (rest-keys (seq-remove (lambda (k) + (member k keys)) + (a-keys table)))) + (seq-doseq (k rest-keys) + (puthash k (gethash k table) new-table)) + new-table)) + +(defun a-dissoc (coll &rest keys) + "Return an updated version of collection COLL with the KEY removed." + (cond + ((listp coll) (a-dissoc--list coll keys)) + ((hash-table-p coll) (a-dissoc--hash-table coll keys)))) + +(defun a-update (coll key fn &rest args) + "In collection COLL, at location KEY, apply FN with extra args ARGS. +'Updates' a value in an associative collection COLL, where KEY is +a key and FN is a function that will take the old value and any +supplied args and return the new value, and returns a new +structure. If the key does not exist, nil is passed as the old +value." + (a-assoc-1 coll + key + (apply #'funcall fn (a-get coll key) args))) + +(defun a-update-in (coll keys fn &rest args) + "In collection COLL, at location KEYS, apply FN with extra args ARGS. +'Updates' a value in a nested associative collection COLL, where +KEYS is a sequence of keys and FN is a function that will take +the old value and any supplied ARGS and return the new value, and +returns a new nested structure. If any levels do not exist, +association lists will be created." + (cl-case (length keys) + (0 coll) + (1 (apply #'a-update coll (elt keys 0) fn args)) + (t (a-assoc-1 coll + (elt keys 0) + (apply #'a-update-in + (a-get coll (elt keys 0)) + (seq-drop keys 1) + fn + args))))) + +(provide 'a) +;;; a.el ends here diff --git a/packages/ac-php-core-20181115.1442.tar b/packages/ac-php-core-20181115.1442.tar deleted file mode 100644 index 45fb293..0000000 Binary files a/packages/ac-php-core-20181115.1442.tar and /dev/null differ diff --git a/packages/ac-php-core-20190816.548.tar b/packages/ac-php-core-20190816.548.tar new file mode 100644 index 0000000..ddd0f03 Binary files /dev/null and b/packages/ac-php-core-20190816.548.tar differ diff --git a/packages/ace-link-20181103.2106.el b/packages/ace-link-20190716.920.el similarity index 86% rename from packages/ace-link-20181103.2106.el rename to packages/ace-link-20190716.920.el index 1af3e53..1e0d710 100644 --- a/packages/ace-link-20181103.2106.el +++ b/packages/ace-link-20190716.920.el @@ -4,7 +4,7 @@ ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/ace-link -;; Package-Version: 20181103.2106 +;; Package-Version: 20190716.920 ;; Version: 0.5.0 ;; Package-Requires: ((avy "0.4.0")) ;; Keywords: convenience, links, avy @@ -51,7 +51,7 @@ (cond ((eq major-mode 'Info-mode) (ace-link-info)) ((member major-mode '(help-mode package-menu-mode geiser-doc-mode elbank-report-mode - elbank-overview-mode slime-trace-dialog-mode)) + elbank-overview-mode slime-trace-dialog-mode helpful-mode)) (ace-link-help)) ((eq major-mode 'woman-mode) (ace-link-woman)) @@ -64,18 +64,24 @@ (ace-link-compilation)) ((eq major-mode 'gnus-article-mode) (ace-link-gnus)) - ((eq major-mode 'org-mode) + ((eq major-mode 'mu4e-view-mode) + (ace-link-mu4e)) + ((memq major-mode '(org-mode erc-mode elfeed-show-mode term-mode)) (ace-link-org)) ((eq major-mode 'org-agenda-mode) (ace-link-org-agenda)) ((eq major-mode 'Custom-mode) - (ace-link-org)) + (ace-link-custom)) ((eq major-mode 'sldb-mode) (ace-link-sldb)) ((eq major-mode 'slime-xref-mode) (ace-link-slime-xref)) ((eq major-mode 'slime-inspector-mode) (ace-link-slime-inspector)) + ((eq major-mode 'indium-inspector-mode) + (ace-link-indium-inspector)) + ((eq major-mode 'indium-debugger-frames-mode) + (ace-link-indium-debugger-frames)) ((and ace-link-fallback-function (funcall ace-link-fallback-function))) (t @@ -89,7 +95,7 @@ "Open a visible link in an `Info-mode' buffer." (interactive) (let ((pt (avy-with ace-link-info - (avy--process + (avy-process (mapcar #'cdr (ace-link--info-collect)) (avy--style-fn avy-style))))) @@ -141,7 +147,7 @@ "Open a visible link in a `help-mode' buffer." (interactive) (let ((pt (avy-with ace-link-help - (avy--process + (avy-process (mapcar #'cdr (ace-link--help-collect)) (avy--style-fn avy-style))))) (ace-link--help-action pt))) @@ -171,7 +177,7 @@ "Open a visible link in a `woman-mode' buffer." (interactive) (let ((pt (avy-with ace-link-woman - (avy--process + (avy-process (mapcar #'cdr (ace-link--woman-collect)) (avy--style-fn avy-style))))) (ace-link--woman-action pt))) @@ -200,7 +206,7 @@ "Open a visible link in an `eww-mode' buffer." (interactive) (let ((pt (avy-with ace-link-eww - (avy--process + (avy-process (mapcar #'cdr (ace-link--eww-collect)) (avy--style-fn avy-style))))) (ace-link--eww-action pt))) @@ -242,7 +248,7 @@ (interactive) (require 'w3m) (let ((pt (avy-with ace-link-w3m - (avy--process + (avy-process (mapcar #'cdr (ace-link--w3m-collect)) (avy--style-fn avy-style))))) (ace-link--w3m-action pt))) @@ -282,7 +288,7 @@ "Open a visible link in a `compilation-mode' buffer." (interactive) (let ((pt (avy-with ace-link-compilation - (avy--process + (avy-process (mapcar #'cdr (ace-link--eww-collect)) (avy--style-fn avy-style))))) (ace-link--compilation-action pt))) @@ -302,7 +308,7 @@ (when (eq major-mode 'gnus-summary-mode) (gnus-summary-widget-forward 1)) (let ((pt (avy-with ace-link-gnus - (avy--process + (avy-process (ace-link--gnus-collect) (avy--style-fn avy-style))))) (ace-link--gnus-action pt))) @@ -340,11 +346,13 @@ (defun ace-link-mu4e () "Open a visible link in an `mu4e-view-mode' buffer." (interactive) - (let ((pt (avy-with ace-link-mu4e - (avy--process - (mapcar #'cdr (ace-link--mu4e-collect)) - (avy--style-fn avy-style))))) - (ace-link--mu4e-action pt))) + (if (bound-and-true-p mu4e-view-use-gnus) + (ace-link-gnus) + (let ((pt (avy-with ace-link-mu4e + (avy-process + (mapcar #'cdr (ace-link--mu4e-collect)) + (avy--style-fn avy-style))))) + (ace-link--mu4e-action pt)))) (declare-function shr-browse-url "shr") (declare-function mu4e~view-browse-url-from-binding "ext:mu4e-view") @@ -405,7 +413,7 @@ (interactive) (require 'org) (let ((pt (avy-with ace-link-org - (avy--process + (avy-process (mapcar #'cdr (ace-link--org-collect)) (avy--style-fn avy-style))))) (ace-link--org-action pt))) @@ -445,7 +453,7 @@ (interactive) (require 'org-agenda) (let ((pt (avy-with ace-link-org-agenda - (avy--process + (avy-process (mapcar #'cdr (ace-link--org-agenda-collect)) (avy--style-fn avy-style))))) (ace-link--org-agenda-action pt))) @@ -476,7 +484,7 @@ "Open a visible link in an `xref--xref-buffer-mode' buffer." (interactive) (let ((pt (avy-with ace-link-xref - (avy--process + (avy-process (ace-link--xref-collect) (avy--style-fn avy-style))))) (ace-link--xref-action pt))) @@ -506,7 +514,7 @@ "Open a visible link in an `Custom-mode' buffer." (interactive) (let ((pt (avy-with ace-link-custom - (avy--process + (avy-process (ace-link--custom-collect) (avy--style-fn avy-style))))) (ace-link--custom-action pt))) @@ -541,7 +549,7 @@ "Open a visible link in a goto-address buffer." (interactive) (let ((pt (avy-with ace-link-addr - (avy--process + (avy-process (ace-link--addr-collect) (avy--style-fn avy-style))))) (ace-link--addr-action pt))) @@ -564,7 +572,7 @@ "Interact with a frame or local variable in a sldb buffer." (interactive) (let ((pt (avy-with ace-link-sldb - (avy--process + (avy-process (ace-link--sldb-collect) (avy--style-fn avy-style))))) (ace-link--sldb-action pt))) @@ -606,7 +614,7 @@ "Open a visible link in an `slime-xref-mode' buffer." (interactive) (let ((pt (avy-with ace-link-slime-xref - (avy--process + (avy-process (ace-link--slime-xref-collect) (avy--style-fn avy-style))))) (ace-link--slime-xref-action pt))) @@ -636,7 +644,7 @@ `slime-inspector-mode' buffer." (interactive) (let ((pt (avy-with ace-link-slime-inspector - (avy--process + (avy-process (ace-link--slime-inspector-collect) (avy--style-fn avy-style))))) (ace-link--slime-inspector-action pt))) @@ -665,10 +673,75 @@ (setq pt (next-property-change pt))) (nreverse candidates))) +;;* `ace-link-indium-inspector' +;;;###autoload +(defun ace-link-indium-inspector () + "Interact with a value, an action or a range button in a +`indium-inspector-mode' buffer." + (interactive) + (let ((pt (avy-with ace-link-indium-inspector + (avy-process + (ace-link--indium-inspector-collect) + (avy--style-fn avy-style))))) + (ace-link--indium-inspector-action pt))) + +(defun ace-link--indium-inspector-action (pt) + (when (numberp pt) + (goto-char pt) + (indium-follow-link))) + +(defun ace-link--indium-inspector-collect () + "Collect the positions of visible links in the current `indium-inspector-mode' buffer." + (let ((candidates) + (old-position)) + (save-excursion + (goto-char (point-max)) + (setq old-position (point)) + (indium-inspector-previous-reference) + (while (not (= (point) old-position)) + (push (point) candidates) + (setq old-position (point)) + (indium-inspector-previous-reference))) + candidates)) + +;;* `ace-link-indium-debugger-frames' +;;;###autoload +(defun ace-link-indium-debugger-frames () + "Interact with a value, an action or a range button in a +`indium-debugger-frames-mode' buffer." + (interactive) + (let ((pt (avy-with ace-link-indium-debugger-frames + (avy-process + (ace-link--indium-debugger-frames-collect) + (avy--style-fn avy-style))))) + (ace-link--indium-debugger-frames-action pt))) + +(defun ace-link--indium-debugger-frames-action (pt) + (when (numberp pt) + (goto-char pt) + (indium-follow-link))) + +(defun ace-link--indium-debugger-frames-collect () + "Collect the positions of visible links in the current `indium-debugger-frames-mode' buffer." + (let ((candidates) + (old-position)) + (save-excursion + (goto-char (point-max)) + (setq old-position (point)) + (indium-debugger-frames-previous-frame) + (while (and (not (= (point) old-position)) (not (= (point) (point-min)))) + (push (point) candidates) + (setq old-position (point)) + (indium-debugger-frames-previous-frame))) + candidates)) + ;;* Bindings (defvar eww-link-keymap) (defvar eww-mode-map) (defvar custom-mode-map) +(declare-function indium-follow-link "ext:indium") +(declare-function indium-inspector-previous-reference "ext:indium") +(declare-function indium-debugger-frames-previous-frame "ext:indium") ;;;###autoload (defun ace-link-setup-default (&optional key) @@ -731,7 +804,13 @@ (define-key elbank-overview-mode-map ,key 'ace-link-help))) (eval-after-load "elbank-report" `(progn - (define-key elbank-report-mode-map ,key 'ace-link-help)))) + (define-key elbank-report-mode-map ,key 'ace-link-help))) + (eval-after-load "indium-inspector" + `(progn + (define-key indium-inspector-mode-map ,key 'ace-link-indium-inspector))) + (eval-after-load "indium-debugger" + `(progn + (define-key indium-debugger-frames-mode-map ,key 'ace-link-indium-debugger-frames)))) (provide 'ace-link) diff --git a/packages/ace-pinyin-20170501.626.el b/packages/ace-pinyin-20190123.402.el similarity index 98% rename from packages/ace-pinyin-20170501.626.el rename to packages/ace-pinyin-20190123.402.el index a0a21d5..7f66cf9 100644 --- a/packages/ace-pinyin-20170501.626.el +++ b/packages/ace-pinyin-20190123.402.el @@ -4,7 +4,7 @@ ;; Author: Junpeng Qiu ;; URL: https://github.com/cute-jumper/ace-pinyin -;; Package-Version: 20170501.626 +;; Package-Version: 20190123.402 ;; Version: 0.2 ;; Package-Requires: ((avy "0.2.0") (pinyinlib "0.1.0")) ;; Keywords: extensions @@ -338,7 +338,7 @@ Default value is only using simplified Chinese characters.") (let ((regexp (ace-pinyin--build-regexp query-char prefix))) (if ace-pinyin-use-avy (avy-with avy-goto-char - (avy--generic-jump regexp nil avy-style)) + (avy--generic-jump regexp nil)) (if ace-jump-current-mode (ace-jump-done)) (if (eq (ace-jump-char-category query-char) 'other) (error "[AceJump] Non-printable character")) @@ -369,8 +369,7 @@ Default value is only using simplified Chinese characters.") (pinyinlib-build-regexp-string (string char1 char2) (not ace-pinyin-enable-punctuation-translation) (not ace-pinyin-simplified-chinese-only-p)) - arg - avy-style))) + arg))) (defun ace-pinyin-jump-char-in-line (char) "Ace-pinyn replacement of `avy-goto-char-in-line'." @@ -379,7 +378,6 @@ Default value is only using simplified Chinese characters.") (avy--generic-jump (ace-pinyin--build-regexp char nil) avy-all-windows - avy-style (line-beginning-position) (line-end-position)))) @@ -407,7 +405,7 @@ Default value is only using simplified Chinese characters.") (let ((chinese-regexp (ace-pinyin--build-regexp char t))) (unless (string= chinese-regexp "") (concat "\\|" chinese-regexp)))))))) - (avy--generic-jump regex arg avy-style)))) + (avy--generic-jump regex arg)))) (defun ace-pinyin-goto-subword-0 (&optional arg predicate) "Ace-pinyin replacement of `avy-goto-subword-0'." @@ -461,7 +459,7 @@ Default value is only using simplified Chinese characters.") (not ace-pinyin-simplified-chinese-only-p)))) (if ace-pinyin-use-avy (avy-with avy-goto-char - (avy--generic-jump regexp nil avy-style)) + (avy--generic-jump regexp nil)) (if ace-jump-current-mode (ace-jump-done)) (let ((case-fold-search nil)) diff --git a/packages/ace-window-20181008.1549.el b/packages/ace-window-20190708.933.el similarity index 79% rename from packages/ace-window-20181008.1549.el rename to packages/ace-window-20190708.933.el index 041b36b..7747b5a 100644 --- a/packages/ace-window-20181008.1549.el +++ b/packages/ace-window-20190708.933.el @@ -5,7 +5,7 @@ ;; Author: Oleh Krehel ;; Maintainer: Oleh Krehel ;; URL: https://github.com/abo-abo/ace-window -;; Package-Version: 20181008.1549 +;; Package-Version: 20190708.933 ;; Version: 0.9.0 ;; Package-Requires: ((avy "0.2.0")) ;; Keywords: window, location @@ -97,10 +97,9 @@ For example, to make SPC do the same as ?a, use "When non-nil, also display `ace-window-mode' string in the minibuffer when ace-window is active." :type 'boolean) -(defcustom aw-ignored-buffers '("*Calc Trail*" "*LV*") +(defcustom aw-ignored-buffers '("*Calc Trail*" " *LV*") "List of buffers and major-modes to ignore when choosing a window from the window list. -Active only when `aw-ignore-on' is non-nil. Windows displaying these -buffers can still be chosen by typing their specific labels." +Active only when `aw-ignore-on' is non-nil." :type '(repeat string)) (defcustom aw-ignore-on t @@ -160,13 +159,16 @@ Consider changing this if the overlay tends to overlap with other things." '((?x aw-delete-window "Delete Window") (?m aw-swap-window "Swap Windows") (?M aw-move-window "Move Window") + (?c aw-copy-window "Copy Window") (?j aw-switch-buffer-in-window "Select Buffer") (?n aw-flip-window) (?u aw-switch-buffer-other-window "Switch Buffer Other Window") - (?c aw-split-window-fair "Split Fair Window") + (?e aw-execute-command-other-window "Execute Command Other Window") + (?F aw-split-window-fair "Split Fair Window") (?v aw-split-window-vert "Split Vert Window") (?b aw-split-window-horz "Split Horz Window") (?o delete-other-windows "Delete Other Windows") + (?T aw-transpose-frame "Transpose Frame") (?? aw-show-dispatch-help)) "List of actions for `aw-dispatch-default'. Each action is a list of either: @@ -198,6 +200,10 @@ or (t (:foreground "gray100" :underline nil))) "Face for each window's leading char.") +(defface aw-minibuffer-leading-char-face + '((t :inherit aw-leading-char-face)) + "Face for minibuffer leading char.") + (defface aw-background-face '((t (:foreground "gray40"))) "Face for whole window background during selection.") @@ -218,6 +224,8 @@ or (or (memq (buffer-local-value 'major-mode (window-buffer window)) aw-ignored-buffers) (member (buffer-name (window-buffer window)) aw-ignored-buffers))) + ;; ignore child frames + (and (fboundp 'frame-parent) (frame-parent (window-frame window))) ;; Ignore selected window if `aw-ignore-current' is non-nil. (and aw-ignore-current (equal window (selected-window))) @@ -266,6 +274,14 @@ or "Store the read-only empty buffers which had to be modified. Modify them back eventually.") +(defvar aw--windows-hscroll nil + "List of (window . hscroll-columns) items, each listing a window whose + horizontal scroll will be restored upon ace-window action completion.") + +(defvar aw--windows-points nil + "List of (window . point) items. The point position had to be + moved in order to display the overlay.") + (defun aw--done () "Clean up mode line and overlays." ;; mode line @@ -279,7 +295,23 @@ Modify them back eventually.") (when (string= (buffer-string) " ") (let ((inhibit-read-only t)) (delete-region (point-min) (point-max)))))) - (setq aw-empty-buffers-list nil)) + (setq aw-empty-buffers-list nil) + (aw--restore-windows-hscroll) + (let (c) + (while (setq c (pop aw--windows-points)) + (with-selected-window (car c) + (goto-char (cdr c)))))) + +(defun aw--restore-windows-hscroll () + "Restore horizontal scroll of windows from `aw--windows-hscroll' list." + (let (wnd hscroll) + (mapc (lambda (wnd-and-hscroll) + (setq wnd (car wnd-and-hscroll) + hscroll (cdr wnd-and-hscroll)) + (when (window-live-p wnd) + (set-window-hscroll wnd hscroll))) + aw--windows-hscroll)) + (setq aw--windows-hscroll nil)) (defun aw--overlay-str (wnd pos path) "Return the replacement text for an overlay in WND at POS, @@ -310,39 +342,70 @@ accessible by typing PATH." (max 0 (1- (string-width old-str))) ?\ )))))) +(defun aw--point-visible-p () + "Return non-nil if point is visible in the selected window. +Return nil when horizontal scrolling has moved it off screen." + (and (>= (- (current-column) (window-hscroll)) 0) + (< (- (current-column) (window-hscroll)) + (window-width)))) + (defun aw--lead-overlay (path leaf) "Create an overlay using PATH at LEAF. LEAF is (PT . WND)." - (let ((wnd (cdr leaf))) + ;; Properly adds overlay in visible region of most windows except for any one + ;; receiving output while this function is executing, since that moves point, + ;; potentially shifting the added overlay outside the window's visible region. + (let ((wnd (cdr leaf)) + ;; Prevent temporary movement of point from scrolling any window. + (scroll-margin 0)) (with-selected-window wnd (when (= 0 (buffer-size)) (push (current-buffer) aw-empty-buffers-list) (let ((inhibit-read-only t)) (insert " "))) - - (let* ((pt (car leaf)) + ;; If point is not visible due to horizontal scrolling of the + ;; window, this next expression temporarily scrolls the window + ;; right until point is visible, so that the leading-char can be + ;; seen when it is inserted. When ace-window's action finishes, + ;; the horizontal scroll is restored by (aw--done). + (while (and (not (aw--point-visible-p)) + (not (zerop (window-hscroll))) + (progn (push (cons (selected-window) (window-hscroll)) aw--windows-hscroll) t) + (not (zerop (scroll-right))))) + (let* ((ws (window-start)) + (prev nil) + (vertical-pos (if (eq aw-char-position 'left) -1 0)) + (horizontal-pos (if (zerop (window-hscroll)) 0 (1+ (window-hscroll)))) + (old-pt (point)) + (pt + (progn + ;; If leading-char is to be displayed at the top-left, move + ;; to the first visible line in the window, otherwise, move + ;; to the last visible line. + (move-to-window-line vertical-pos) + (move-to-column horizontal-pos) + ;; Find a nearby point that is not at the end-of-line but + ;; is visible so have space for the overlay. + (setq prev (1- (point))) + (while (and (>= prev ws) (/= prev (point)) (eolp)) + (setq prev (point)) + (unless (bobp) + (line-move -1 t) + (move-to-column horizontal-pos))) + (recenter vertical-pos) + (point))) (ol (make-overlay pt (1+ pt) (window-buffer wnd)))) + (if (= (aw--face-rel-height) 1) + (goto-char old-pt) + (when (/= pt old-pt) + (goto-char (+ pt 1)) + (push (cons wnd old-pt) aw--windows-points))) (overlay-put ol 'display (aw--overlay-str wnd pt path)) - (overlay-put ol 'face 'aw-leading-char-face) + (if (window-minibuffer-p wnd) + (overlay-put ol 'face 'aw-minibuffer-leading-char-face) + (overlay-put ol 'face 'aw-leading-char-face)) (overlay-put ol 'window wnd) - (push ol avy--overlays-lead)) - - (when (eq aw-char-position 'left) - (let* ((pt - (save-excursion - ;; Move to the start of the last visible line in the buffer. - (move-to-window-line -1) - (move-beginning-of-line nil) - ;; If this line is empty, use the previous line so we - ;; have space for the overlay. - (when (equal (point) (point-max)) - (forward-line -1)) - (point))) - (ol (make-overlay pt (1+ pt) (window-buffer wnd)))) - (overlay-put ol 'display (aw--overlay-str wnd pt path)) - (overlay-put ol 'face 'aw-leading-char-face) - (overlay-put ol 'window wnd) - (push ol avy--overlays-lead)))))) + (push ol avy--overlays-lead))))) (defun aw--make-backgrounds (wnd-list) "Create a dim background overlay for each window on WND-LIST." @@ -429,7 +492,7 @@ The new frame is set to the same size as the previous frame, offset by (avy-mouse-event-window char))) ((= char (aref (kbd "C-g") 0)) (throw 'done 'exit)) - ((= char aw-make-frame-char) + ((and aw-make-frame-char (= char aw-make-frame-char)) ;; Make a new frame and perform any action on its window. (let ((start-win (selected-window)) (end-win (frame-selected-window (aw-make-frame)))) @@ -448,13 +511,21 @@ The new frame is set to the same size as the previous frame, offset by (if (and fn description) (prog1 (setq aw-action fn) (aw-set-mode-line (format " Ace - %s" description))) - (funcall fn) + (if (commandp fn) + (call-interactively fn) + (funcall fn)) (throw 'done 'exit))) (aw-clean-up-avy-current-path) ;; Prevent any char from triggering an avy dispatch command. (let ((avy-dispatch-alist)) (avy-handler-default char))))))) +(defcustom aw-display-mode-overlay t + "When nil, don't display overlays. Rely on the mode line instead." + :type 'boolean) + +(defvar ace-window-display-mode) + (defun aw-select (mode-line &optional action) "Return a selected other window. Amend MODE-LINE to the mode line for the duration of the selection." @@ -477,7 +548,8 @@ Amend MODE-LINE to the mode line for the duration of the selection." (when (eq aw-action 'exit) (setq aw-action nil))) (or (car wnd-list) start-window)) - ((and (<= (length wnd-list) aw-dispatch-when-more-than) + ((and (<= (+ (length wnd-list) (if (aw-ignored-p start-window) 1 0)) + aw-dispatch-when-more-than) (not aw-dispatch-always) (not aw-ignore-current)) (let ((wnd (next-window nil nil next-window-scope))) @@ -499,7 +571,10 @@ Amend MODE-LINE to the mode line for the duration of the selection." (let* ((avy-handler-function aw-dispatch-function) (avy-translate-char-function aw-translate-char-function) (res (avy-read (avy-tree candidate-list aw-keys) - #'aw--lead-overlay + (if (and ace-window-display-mode + (null aw-display-mode-overlay)) + (lambda (_path _leaf)) + #'aw--lead-overlay) #'avy--remove-leading-chars))) (if (eq res 'exit) (setq aw-action nil) @@ -539,6 +614,11 @@ Amend MODE-LINE to the mode line for the duration of the selection." (aw-select " Ace - Delete Other Windows" #'delete-other-windows)) +(declare-function transpose-frame "ext:transpose-frame") +(defun aw-transpose-frame (w) + "Select any window on frame and `tranpose-frame'." + (transpose-frame (window-frame w))) + (define-obsolete-function-alias 'ace-maximize-window 'ace-delete-other-windows "0.10.0") @@ -557,11 +637,11 @@ selected window). Prefixed with two \\[universal-argument]'s, deletes the selected window." (interactive "p") + (setq avy-current-path "") (cl-case arg (0 - (setq aw-ignore-on - (not aw-ignore-on)) - (ace-select-window)) + (let ((aw-ignore-on (not aw-ignore-on))) + (ace-select-window))) (4 (ace-swap-window)) (16 (ace-delete-window)) (t (ace-select-window)))) @@ -581,13 +661,16 @@ window." "Return true if WND1 is less than WND2. This is determined by their respective window coordinates. Windows are numbered top down, left to right." - (let ((f1 (window-frame wnd1)) - (f2 (window-frame wnd2)) - (e1 (window-edges wnd1)) - (e2 (window-edges wnd2))) - (cond ((< (car (frame-position f1)) (car (frame-position f2))) + (let* ((f1 (window-frame wnd1)) + (f2 (window-frame wnd2)) + (e1 (window-edges wnd1)) + (e2 (window-edges wnd2)) + (p1 (frame-position f1)) + (p2 (frame-position f2)) + (nl (or (null (car p1)) (null (car p2))))) + (cond ((and (not nl) (< (car p1) (car p2))) (not aw-reverse-frame-list)) - ((> (car (frame-position f1)) (car (frame-position f2))) + ((and (not nl) (> (car p1) (car p2))) aw-reverse-frame-list) ((< (car e1) (car e2)) t) @@ -657,8 +740,9 @@ Windows are numbered top down, left to right." (mapc #'delete-overlay aw-overlays-back) (call-interactively 'ace-window))) -(defun aw-delete-window (window) - "Delete window WINDOW." +(defun aw-delete-window (window &optional kill-buffer) + "Delete window WINDOW. +When KILL-BUFFER is non-nil, also kill the buffer." (let ((frame (window-frame window))) (when (and (frame-live-p frame) (not (eq frame (selected-frame)))) @@ -666,7 +750,10 @@ Windows are numbered top down, left to right." (if (= 1 (length (window-list))) (delete-frame frame) (if (window-live-p window) - (delete-window window) + (let ((buffer (window-buffer window))) + (delete-window window) + (when kill-buffer + (kill-buffer buffer))) (error "Got a dead window %S" window))))) (defun aw-switch-buffer-in-window (window) @@ -717,6 +804,12 @@ Switch the current window to the previous buffer." (aw-switch-to-window window) (switch-to-buffer buffer))) +(defun aw-copy-window (window) + "Copy the current buffer to WINDOW." + (let ((buffer (current-buffer))) + (aw-switch-to-window window) + (switch-to-buffer buffer))) + (defun aw-split-window-vert (window) "Split WINDOW vertically." (select-window window) @@ -743,10 +836,33 @@ Modify `aw-fair-aspect-ratio' to tweak behavior." (aw-split-window-vert window)))) (defun aw-switch-buffer-other-window (window) - "Switch buffer in WINDOW without selecting WINDOW." + "Switch buffer in WINDOW." (aw-switch-to-window window) - (aw--switch-buffer) - (aw-flip-window)) + (unwind-protect + (aw--switch-buffer) + (aw-flip-window))) + +(defun aw-execute-command-other-window (window) + "Execute a command in WINDOW." + (aw-switch-to-window window) + (unwind-protect + (funcall + (key-binding + (read-key-sequence + "Enter key sequence: "))) + (aw-flip-window))) + +(defun aw--face-rel-height () + (let ((h (face-attribute 'aw-leading-char-face :height))) + (cond + ((eq h 'unspecified) + 1) + ((floatp h) + (max (floor h) 1)) + ((integerp h) + 1) + (t + (error "unexpected: %s" h))))) (defun aw-offset (window) "Return point in WINDOW that's closest to top left corner. @@ -755,10 +871,15 @@ The point is writable, i.e. it's not part of space after newline." (beg (window-start window)) (end (window-end window)) (inhibit-field-text-motion t)) - (with-current-buffer - (window-buffer window) + (with-current-buffer (window-buffer window) (save-excursion (goto-char beg) + (forward-line (1- + (min + (count-lines + (point) + (point-max)) + (aw--face-rel-height)))) (while (and (< (point) end) (< (- (line-end-position) (line-beginning-position)) @@ -766,6 +887,10 @@ The point is writable, i.e. it's not part of space after newline." (forward-line)) (+ (point) h))))) +(defun aw--after-make-frame (f) + (aw-update) + (make-frame-visible f)) + ;;* Mode line ;;;###autoload (define-minor-mode ace-window-display-mode @@ -784,14 +909,14 @@ The point is writable, i.e. it's not part of space after newline." (force-mode-line-update t) (add-hook 'window-configuration-change-hook 'aw-update) ;; Add at the end so does not precede select-frame call. - (add-hook 'after-make-frame-functions (lambda (_) (aw-update)) t)) + (add-hook 'after-make-frame-functions #'aw--after-make-frame t)) (set-default 'mode-line-format (assq-delete-all 'ace-window-display-mode (default-value 'mode-line-format))) (remove-hook 'window-configuration-change-hook 'aw-update) - (remove-hook 'after-make-frame-functions 'aw-update))) + (remove-hook 'after-make-frame-functions 'aw--after-make-frame))) (defun aw-update () "Update ace-window-path window parameter for all windows. diff --git a/packages/aggressive-indent-20181018.236.el b/packages/aggressive-indent-20190218.2331.el similarity index 86% rename from packages/aggressive-indent-20181018.236.el rename to packages/aggressive-indent-20190218.2331.el index 3e51115..41a3d22 100644 --- a/packages/aggressive-indent-20181018.236.el +++ b/packages/aggressive-indent-20190218.2331.el @@ -4,7 +4,7 @@ ;; Author: Artur Malabarba ;; URL: https://github.com/Malabarba/aggressive-indent-mode -;; Package-Version: 20181018.236 +;; Package-Version: 20190218.2331 ;; Version: 1.8.4 ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5")) ;; Keywords: indent lisp maint tools @@ -105,7 +105,7 @@ Please include this in your report!" (defvar aggressive-indent-mode) -;;; Configuring indentarion +;;; Configuring indentation (defcustom aggressive-indent-dont-electric-modes nil "List of major-modes where `electric-indent' should be disabled." :type '(choice @@ -114,10 +114,13 @@ Please include this in your report!" :package-version '(aggressive-indent . "0.3.1")) (defcustom aggressive-indent-excluded-modes - '(inf-ruby-mode + '(elm-mode + haskell-mode + inf-ruby-mode makefile-mode makefile-gmake-mode python-mode + sql-interactive-mode text-mode yaml-mode) "Modes in which `aggressive-indent-mode' should not be activated. @@ -407,30 +410,76 @@ or messages." (setq aggressive-indent--changed-list (cdr aggressive-indent--changed-list)))))) +(defun aggressive-indent--clear-change-list () + "Clear cache of all changed regions. " + (setq aggressive-indent--changed-list nil)) + (defcustom aggressive-indent-sit-for-time 0.05 "Time, in seconds, to wait before indenting. If you feel aggressive-indent is causing Emacs to hang while typing, try tweaking this number." :type 'float) -(defvar aggressive-indent--idle-timer nil +(defvar-local aggressive-indent--idle-timer nil "Idle timer used for indentation") +;; Ripped from Emacs 27.0 subr.el. +;; See Github Issue#111 and Emacs bug#31692. +(defmacro aggressive-indent--while-no-input (&rest body) + "Execute BODY only as long as there's no pending input. +If input arrives, that ends the execution of BODY, +and `while-no-input' returns t. Quitting makes it return nil. +If BODY finishes, `while-no-input' returns whatever value BODY produced." + (declare (debug t) (indent 0)) + (let ((catch-sym (make-symbol "input"))) + `(with-local-quit + (catch ',catch-sym + (let ((throw-on-input ',catch-sym) + val) + (setq val (or (input-pending-p) + (progn ,@body))) + (cond + ;; When input arrives while throw-on-input is non-nil, + ;; kbd_buffer_store_buffered_event sets quit-flag to the + ;; value of throw-on-input. If, when BODY finishes, + ;; quit-flag still has the same value as throw-on-input, it + ;; means BODY never tested quit-flag, and therefore ran to + ;; completion even though input did arrive before it + ;; finished. In that case, we must manually simulate what + ;; 'throw' in process_quit_flag would do, and we must + ;; reset quit-flag, because leaving it set will cause us + ;; quit to top-level, which has undesirable consequences, + ;; such as discarding input etc. We return t in that case + ;; because input did arrive during execution of BODY. + ((eq quit-flag throw-on-input) + (setq quit-flag nil) + t) + ;; This is for when the user actually QUITs during + ;; execution of BODY. + (quit-flag + nil) + (t val))))))) + (defun aggressive-indent--indent-if-changed () "Indent any region that changed in the last command loop." - (when (and aggressive-indent-mode aggressive-indent--changed-list) - (save-excursion - (save-selected-window - (while-no-input - (aggressive-indent--proccess-changed-list-and-indent)))))) + (if (not (buffer-live-p (current-buffer))) + (cancel-timer aggressive-indent--idle-timer) + (when (and aggressive-indent-mode aggressive-indent--changed-list) + (save-excursion + (save-selected-window + (aggressive-indent--while-no-input + (aggressive-indent--proccess-changed-list-and-indent)))) + (when (timerp aggressive-indent--idle-timer) + (cancel-timer aggressive-indent--idle-timer))))) (defun aggressive-indent--keep-track-of-changes (l r &rest _) "Store the limits (L and R) of each change in the buffer." (when aggressive-indent-mode (push (list l r) aggressive-indent--changed-list) - (unless (timerp aggressive-indent--idle-timer) - (setq aggressive-indent--idle-timer - (run-with-idle-timer aggressive-indent-sit-for-time t #'aggressive-indent--indent-if-changed))))) + (when (timerp aggressive-indent--idle-timer) + (cancel-timer aggressive-indent--idle-timer)) + (setq aggressive-indent--idle-timer + (run-with-idle-timer aggressive-indent-sit-for-time t #'aggressive-indent--indent-if-changed)))) ;;; Minor modes ;;;###autoload @@ -460,12 +509,13 @@ typing, try tweaking this number." (aggressive-indent--local-electric nil) (aggressive-indent--local-electric t)) (add-hook 'after-change-functions #'aggressive-indent--keep-track-of-changes nil 'local) + (add-hook 'after-revert-hook #'aggressive-indent--clear-change-list nil 'local) (add-hook 'before-save-hook #'aggressive-indent--proccess-changed-list-and-indent nil 'local)) ;; Clean the hooks (when (timerp aggressive-indent--idle-timer) - (cancel-timer aggressive-indent--idle-timer) - (setq aggressive-indent--idle-timer nil)) + (cancel-timer aggressive-indent--idle-timer)) (remove-hook 'after-change-functions #'aggressive-indent--keep-track-of-changes 'local) + (remove-hook 'after-revert-hook #'aggressive-indent--clear-change-list 'local) (remove-hook 'before-save-hook #'aggressive-indent--proccess-changed-list-and-indent 'local) (remove-hook 'post-command-hook #'aggressive-indent--softly-indent-defun 'local))) diff --git a/packages/ahk-mode-20181113.1238.el b/packages/ahk-mode-20190323.623.el similarity index 99% rename from packages/ahk-mode-20181113.1238.el rename to packages/ahk-mode-20190323.623.el index 9ee62ea..ca96d33 100644 --- a/packages/ahk-mode-20181113.1238.el +++ b/packages/ahk-mode-20190323.623.el @@ -4,7 +4,7 @@ ;; Author: Rich Alesi ;; URL: https://github.com/ralesi/ahk-mode -;; Package-Version: 20181113.1238 +;; Package-Version: 20190323.623 ;; Version: 1.5.6 ;; Keywords: ahk, AutoHotkey, hotkey, keyboard shortcut, automation ;; Package-Requires: ((emacs "24.3")) @@ -181,9 +181,11 @@ ;;; imenu support (defconst ahk-imenu-generic-expression - '(("Functions" "^\s*\\(.*\\)(.*)[\n]{" 1) - ("Labels" "^\s*\\([^:]+\\):\n" 1) - ("Keybindings" "^\s*\\(.+?\\)::" 1)) + '(("Functions" "^[ \t]*\\([^ ]+\\)(.*)[\n]{" 1) + ("Labels" "^[ \t]*\\([^:;]+\\):\n" 1) + ("Keybindings" "^[ \t]*\\([^;: \t\r\n\v\f].*?\\)::" 1) + ("Hotstrings" "^[ \t]*\\(:.*?:.*?::\\)" 1) + ("Comments" "^;imenu \\(.+\\)" 1)) "imenu index for `ahk-mode'") (defun ahk-run-script () diff --git a/packages/alchemist-20180312.1304.tar b/packages/alchemist-20180312.1304.tar index 5711c45..6b394e8 100644 Binary files a/packages/alchemist-20180312.1304.tar and b/packages/alchemist-20180312.1304.tar differ diff --git a/packages/alda-mode-20180608.605.el b/packages/alda-mode-20180608.605.el new file mode 100644 index 0000000..5e98c60 --- /dev/null +++ b/packages/alda-mode-20180608.605.el @@ -0,0 +1,430 @@ +;;; alda-mode.el --- An Alda major mode -*- lexical-binding: t; -*- + +;; Copyright (C) 2016-2017 Jay Kamat +;; Author: Jay Kamat +;; Version: 0.3.0 +;; Package-Version: 20180608.605 +;; Keywords: alda, highlight +;; URL: http://gitlab.com/jgkamat/alda-mode +;; Package-Requires: ((emacs "24.0")) + +;; 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 . + +;;; Commentary: +;; This package provides syntax highlighting and basic alda integration. +;; Activate font-lock-mode to use the syntax features, and run 'alda-play-region' to play song files +;; +;; Variables: +;; alda-binary-location: Set to the location of the binary executable. +;; If nil, alda-mode will search for your binary executable on your path +;; If set to a string, alda-mode will use that binary instead of 'alda' on your path. +;; Ex: (setq alda-binary-location "/usr/local/bin/alda") +;; Ex: (setq alda-binary-location nil) ;; Use default alda location +;; alda-ess-keymap: Whether to add the default ess keymap. +;; If nil, alda-mode will not add the default ess keymaps. +;; Ex: (setq alda-ess-keymap nil) ;; before (require 'alda) + +;;; Constants: + +(defconst +alda-output-buffer+ "*alda-output*") +(defconst +alda-output-name+ "alda-playback") +(defconst +alda-comment-str+ "#") + +(require 'comint) + +;;; Code: +;;;; -- Variables -- +(defvar *alda-history* + "" + "Holds the history to be sent to the alda server. +If you are experiencing problems, try clearing your history with 'alda-history-clear'.") + +;;;; -- Region playback functions -- + +(defgroup Alda nil + "Alda customization options" + :group 'applications) + +(defgroup alda-mode-inf + nil + "Mode to interact with a Alda interpreter." + :group 'Alda + :tag "Inferior Alda") + +(defcustom alda-binary-location nil + "Alda binary location for `alda-mode'. +When set to nil, will attempt to use the binary found on your $PATH. +This must be a _full_ path to your alda binary." + :type 'string + :group 'Alda) + +;;;; -- Alda inferior process definitions -- + +(defconst alda-inf-buffer-name "*inferior-alda*") + +(define-derived-mode alda-mode-inf comint-mode "Inferior Alda" + "Major mode for interacting with a Alda interpreter. + +\\{inferior-alda-mode-map\\}" + (define-key alda-mode-inf-map [(meta return)] 'comint-accumulate) + + ;; Comint configuration + (make-local-variable 'comint-input-sender) + (setq comint-input-sender 'alda-input-sender)) + +(defun alda-input-sender (proc string) + (comint-send-string proc string) + (comint-send-string proc "\n")) + +(defun alda-interpreter-running-p-1 () + ;; True iff a Alda interpreter is currently running in a buffer. + (comint-check-proc alda-inf-buffer-name)) + +(defun alda-check-or-start-interpreter () + (unless (alda-interpreter-running-p-1) + (alda-run-alda))) + +(defun alda-location () + "Return what 'alda' should be called as in the shell based on 'alda-binary-location' or the path." + (if alda-binary-location + alda-binary-location + (locate-file "alda" exec-path))) + +(defun alda-repl () + "Return the 'alda' repl start command" + (format "%s repl" (alda-location))) + +(defun alda-run-alda () + "Run a Alda interpreter in an Emacs buffer" + (interactive) + (let* ((cmd-line (alda-repl)) + (cmd/args (split-string cmd-line))) + (unless (alda-interpreter-running-p-1) + (set-buffer + (apply 'make-comint "inferior-alda" (car cmd/args) nil (cdr cmd/args))) + (alda-mode-inf) + (pop-to-buffer alda-inf-buffer-name)))) + +(defun alda-switch-to-interpreter () + "Switch to buffer containing the interpreter" + (interactive) + (alda-check-or-start-interpreter) + (switch-to-buffer-other-window alda-inf-buffer-name)) + +(defcustom alda-ess-keymap t + "Whether to use ess keymap in 'alda-mode'. +When set to nil, will not set any ess keybindings" + :type 'boolean + :group 'Alda) + +(defcustom alda-play-region-in-repl nil + "Whether to send alda code region to repl in 'alda-mode'. +When set to nil, will not set to repl" + :type 'boolean + :group 'Alda) + +(defun alda-server () + "Start an alda server in an Emacs process." + (interactive) + (start-process +alda-output-name+ +alda-output-buffer+ (alda-location) "server")) + +(defun alda-run-cmd (&rest args) + "Run a given alda command with specified args. +Argument ARGS a list of arguments to pass to alda" + (interactive "sEnter alda command: ") + (let ((server-down + (if (string-match "[Ss]erver [Dd]own" (shell-command-to-string (concat (alda-location) " status"))) + (progn (message "Alda server down, starting in Emacs.") t) + nil))) + (if (not (alda-location)) + (message "Alda was not found on your $PATH and alda-binary-location was nil.") + (progn + (when server-down + (alda-server) + (sleep-for 2)) ;; Try to stop a race condition + (apply #'start-process +alda-output-name+ +alda-output-buffer+ + (alda-location) args))))) + +(defun alda-play-text (text) + "Plays the specified TEXT in the alda server. +This does include any history you might have added. +ARGUMENT TEXT The text to play with the current alda server." + (alda-run-cmd "play" "--history" *alda-history* "--code" text)) + +(defun alda-stop () + "Stop current alda playback." + (alda-run-cmd "stop")) + +(defun alda-play-file () + "Plays the current buffer's file in alda. +This does not include any history that you may have added" + (interactive) + (alda-run-cmd "play" "--file" (buffer-file-name))) + +;; This is the replacement for the old 'alda append' command +;; Previously, command history was stored on the server, now it is stored on the client. +;; 'alda-mode' is your client, so we will take care of history for you! +;; These commands are in beta, so report an issue if you find any problems! +(defun alda-history-append-text (text) + "Append the specified TEXT to the alda server instance. +ARGUMENT TEXT The text to append to the current alda server." + (setq *alda-history* (concat *alda-history* "\n" text))) + + +(defun alda-history-clear () + "Clears the current alda history. +This can help resolve problems if you are having problems running your score" + (interactive) + (setq *alda-history* "")) + +(defun alda-history-append-region (start end) + "Append the current selection to the alda history. +Argument START The start of the selection to append from. +Argument END The end of the selection to append from." + (interactive "r") + (if (eq start end) + (message "no mark was set") + (alda-history-append-text (buffer-substring-no-properties start end)))) + +(defun alda-history-append-buffer () + "Append the current buffer to alda history." + (interactive) + (alda-history-append-text (buffer-string))) + +(defun alda-history-append-block () + "Append the selected block of alda code to history." + (interactive) + (save-excursion + (mark-paragraph) + (alda-history-append-region (region-beginning) (region-end)))) + +(defun alda-history-append-line () + "Append the current line of alda code to history." + (interactive) + (alda-history-append-region (line-beginning-position) (line-end-position))) + +(defun alda-inf-eval-region (start end) + "Send current region to Alda interpreter." + (interactive "r") + (alda-check-or-start-interpreter) + (comint-send-region alda-inf-buffer-name start end) + (comint-send-string alda-inf-buffer-name "\n")) + +(defun alda-play-region (start end) + "Plays the current selection in alda. +Argument START The start of the selection to play from. +Argument END The end of the selection to play from." + (interactive "r") + (if (eq start end) + (message "No mark was set!") + (if alda-play-region-in-repl + (alda-inf-eval-region start end) + (alda-play-text (buffer-substring-no-properties start end))))) + +;; If evil is found, make evil commands as well. +(eval-when-compile + (unless (require 'evil nil 'noerror) + ;; Evil must be sourced in order to define this macro + (defmacro evil-define-operator (name &rest _) + ;; Define a dummy instead if not present. + `(defun ,name () (interactive) (message "Evil was not present while compiling alda-mode. Recompile with evil installed!"))))) + +;; Macro will be expanded based on the above dummy/evil load +(evil-define-operator alda-evil-play-region (beg end _type _register _yank-hanlder) + "Plays the text from BEG to END." + :move-point nil + :repeat nil + (interactive "") + (alda-play-region beg end)) + +(evil-define-operator alda-evil-history-append-region (beg end _type _register _yank-hanlder) + "Appends the text from BEG to END to alda history." + :move-point nil + :repeat nil + (interactive "") + (alda-history-append-region beg end)) + +;; Renamed stop -> down for consistency +(defun alda-down () + "Stops songs from playing, and cleans up idle alda runner processes. +Because alda runs in the background, the only way to do this is with alda restart as of now." + (interactive) + (shell-command (concat (alda-location) " down")) + (delete-process +alda-output-buffer+)) + +;;;; -- Font Lock Regexes -- +(let + ;; Prevent regexes from taking up memory + ((alda-instrument-regexp "\\([a-zA-Z]\\{2\\}[A-Za-z0-9_\-]*\\)\\(\s*\\(\"[A-Za-z0-9_\-]*\"\\)\\)?:") + (alda-voice-regexp "\\([Vv][0-9]+\\):") + (alda-timing-regexp "[a-gA-GrR][\s+-]*\\([~.0-9\s/]*\\(m?s\\)?\\)") + (alda-repeating-regexp "\\(\\*[0-9]+\\)") + (alda-cramming-regexp "\\({\\|}\\)") + (alda-grouping-regexp "\\(\\[\\|\\]\\)") + (alda-accidental-regexp "\\([a-gA-GrR]\s*[-+]+\\)") + (alda-bar-regexp "\\(|\\)") + (alda-set-octave-regexp "\\(o[0-9]+\\)") + (alda-shift-octave-regexp "\\(>\\|<\\)") + (alda-variable-regexp "\\(([a-zA-Z-]+!?\s+\\(\\([0-9]+\\)\\|\\(\\[\\(:[a-zA-Z]+\s?\\)+\\]\\)\\))\\)") + (alda-markers-regexp "\\([@%][a-zA-Z]\\{2\\}[a-zA-Z0-9()+-]*\\)")) + + (defvar alda-highlights nil + "Font lock highlights for 'alda-mode'") + (setq alda-highlights + `((,alda-bar-regexp . (1 font-lock-comment-face)) + (,alda-voice-regexp . (1 font-lock-function-name-face)) + (,alda-instrument-regexp . (1 font-lock-type-face)) + (,alda-variable-regexp . (1 font-lock-variable-name-face)) + (,alda-set-octave-regexp . (1 font-lock-constant-face)) + (,alda-shift-octave-regexp . (1 font-lock-constant-face)) + (,alda-markers-regexp . (1 font-lock-builtin-face)) + (,alda-timing-regexp . (1 font-lock-builtin-face)) + (,alda-repeating-regexp . (1 font-lock-builtin-face)) + (,alda-cramming-regexp . (1 font-lock-builtin-face)) + (,alda-grouping-regexp . (1 font-lock-builtin-face)) + (,alda-accidental-regexp . (1 font-lock-preprocessor-face))))) + +;;;; -- Indention code -- + +;; A duplicate of asm-mode.el with changes +;; changes were made to the naming convention and to how the labels are calculated. +(defun alda-indent-line () + "Auto-indent the current line." + (interactive) + (let* ((savep (point)) + (indent (condition-case nil + (save-excursion + (forward-line 0) + (skip-chars-forward " \t") + (if (>= (point) savep) (setq savep nil)) + (max (alda-calculate-indentation) 0)) + (error 0)))) + (if savep + (save-excursion (indent-line-to indent)) + (indent-line-to indent)))) + +(defun alda-indent-prev-level () + "Indent this line to the indention level of the previous non-whitespace line." + (save-excursion + (forward-line -1) + (while (and + (not (eq (point) (point-min))) ;; Point at start of bufffer + ;; Point has a empty line + (let ((match-str (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) + (or (string-match "^\\s-*$" match-str)) (eq 0 (length match-str)))) + (forward-line -1)) + (current-indentation))) + + +(defun alda-calculate-indentation () + "Calculates indentation for `alda-mode' code." + (or + ;; Flush labels to the left margin. + (and (looking-at "[A-Za-z0-9\" \\t-]+:\\s-*") 0) + ;; All comments indention are the previous line's indention. + (and (looking-at +alda-comment-str+) (alda-indent-prev-level)) + ;; The rest goes at the first tab stop. + (or (indent-next-tab-stop 0)))) + +(defun alda-colon () + "Insert a colon; if it follows a label, delete the label's indentation." + (interactive) + (let ((labelp nil)) + (save-excursion + (skip-chars-backward "A-Za-z\"\s\t") + (if (setq labelp (bolp)) (delete-horizontal-space))) + (call-interactively 'self-insert-command) + (when labelp + (delete-horizontal-space) + (tab-to-tab-stop)))) + +(defun alda-play-block () + "Plays the selected block of alda code." + (interactive) + (save-excursion + (mark-paragraph) + (alda-play-region (region-beginning) (region-end)))) + +(defun alda-play-line () + "Plays the current line of alda code." + (interactive) + (alda-play-region (line-beginning-position) (line-end-position))) + +(defun alda-play-buffer () + "Plays the current buffer of alda code." + (interactive) + (alda-play-text (buffer-string))) + +;;;; -- Alda Keymaps -- +;; TODO determine standard keymap for alda-mode + +(defvar alda-mode-map nil "Keymap for `alda-mode'.") +(when (not alda-mode-map) ; if it is not already defined + + ;; assign command to keys + (setq alda-mode-map (make-sparse-keymap)) + (define-key alda-mode-map (kbd ":") 'alda-colon) + + (define-key alda-mode-map [menu-bar alda-mode] (cons "Alda" (make-sparse-keymap))) + (define-key alda-mode-map [menu-bar alda-mode alda-colon] + '(menu-item "Insert Colon" alda-colon + :help "Insert a colon; if it follows a label, delete the label's indentation")) + + ;; Add alda-ess-keymap if requested + (when alda-ess-keymap + (define-key alda-mode-map "\C-c\C-i" 'alda-run-alda) + (define-key alda-mode-map "\C-c\C-r" 'alda-play-region) + (define-key alda-mode-map "\C-c\C-c" 'alda-play-block) + (define-key alda-mode-map "\C-c\C-n" 'alda-play-line) + (define-key alda-mode-map "\C-c\C-b" 'alda-play-buffer) + (define-key alda-mode-map "\C-c\C-z" 'alda-switch-to-interpreter))) + +;;;; -- Alda Syntax Table -- + +(defvar alda-mode-syntax-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?# "<" table) + (modify-syntax-entry ?\n ">" table) + table)) + + +;;;; -- Alda Mode Definition -- + +;;;###autoload +(define-derived-mode alda-mode prog-mode + "Alda" + "A major mode for alda-lang, providing syntax highlighting and basic indention." + + ;; Set alda comments + (setq comment-start +alda-comment-str+) + (setq comment-padding " ") + (setq comment-start-skip (concat +alda-comment-str+ "\\s-*")) + (setq comment-multi-line (concat +alda-comment-str+ " ")) + ;; Comments should use the indention of the last line + (setq comment-indent-function #'alda-indent-prev-level) + + ;; Set custom mappings + (use-local-map alda-mode-map) + (setq indent-line-function 'alda-indent-line) + + ;; Set alda highlighting + (setq font-lock-defaults '(alda-highlights))) + +;; Open alda files in alda-mode +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.alda\\'" . alda-mode)) + +(provide 'alda-mode) + +;;; alda-mode.el ends here diff --git a/packages/alect-themes-20180504.1720.tar b/packages/alect-themes-20190506.1440.tar similarity index 95% rename from packages/alect-themes-20180504.1720.tar rename to packages/alect-themes-20190506.1440.tar index 9772c28..81b2358 100644 Binary files a/packages/alect-themes-20180504.1720.tar and b/packages/alect-themes-20190506.1440.tar differ diff --git a/packages/alert-20181022.1742.el b/packages/alert-20190816.2205.el similarity index 98% rename from packages/alert-20181022.1742.el rename to packages/alert-20190816.2205.el index e4d41c6..3be52c3 100644 --- a/packages/alert-20181022.1742.el +++ b/packages/alert-20190816.2205.el @@ -6,7 +6,7 @@ ;; Created: 24 Aug 2011 ;; Updated: 16 Mar 2015 ;; Version: 1.2 -;; Package-Version: 20181022.1742 +;; Package-Version: 20190816.2205 ;; Package-Requires: ((gntp "0.1") (log4e "0.3.0") (cl-lib "0.5")) ;; Keywords: notification emacs message ;; X-URL: https://github.com/jwiegley/alert @@ -135,7 +135,7 @@ ;; notifier - Uses terminal-notifier on OS X, if it is on the PATH ;; osx-notifier - Native OSX notifier using AppleScript ;; toaster - Use the toast notification system -;; x11 - - Changes the urgency property of the window in the X Window System +;; x11 - Changes the urgency property of the window in the X Window System ;; ;; * Defining new styles ;; @@ -733,7 +733,7 @@ strings." (if urgency (symbol-name urgency) "normal"))) - alert-libnotify-additional-args)) + (copy-tree alert-libnotify-additional-args))) (category (plist-get info :category))) (nconc args (list "--expire-time" @@ -816,7 +816,11 @@ by the `notifications' style.") :timeout (if (plist-get info :persistent) 0 -1) :replaces-id (gethash (plist-get info :id) alert-notifications-ids) :urgency (cdr (assq (plist-get info :severity) - alert-notifications-priorities))))) + alert-notifications-priorities)) + :actions '("default" "Open corresponding buffer") + :on-action (lambda (id action) + (when (string= action "default") + (switch-to-buffer (plist-get info :buffer))))))) (when (plist-get info :id) (puthash (plist-get info :id) id alert-notifications-ids))) (alert-message-notify info)) @@ -865,6 +869,14 @@ From https://github.com/julienXX/terminal-notifier." (alert-encode-string (plist-get info :title))))) (alert-message-notify info)) +(when (fboundp 'mac-do-applescript) + ;; Use built-in AppleScript support when possible. + (defun alert-osx-notifier-notify (info) + (mac-do-applescript (format "display notification %S with title %S" + (alert-encode-string (plist-get info :message)) + (alert-encode-string (plist-get info :title)))) + (alert-message-notify info))) + (alert-define-style 'osx-notifier :title "Notify using native OSX notification" :notifier #'alert-osx-notifier-notify) (defun alert-frame-notify (info) diff --git a/packages/all-the-icons-20180125.1557.tar b/packages/all-the-icons-20190320.1809.tar similarity index 92% rename from packages/all-the-icons-20180125.1557.tar rename to packages/all-the-icons-20190320.1809.tar index 9656a92..119dd67 100644 Binary files a/packages/all-the-icons-20180125.1557.tar and b/packages/all-the-icons-20190320.1809.tar differ diff --git a/packages/ameba-20190720.1845.el b/packages/ameba-20190720.1845.el new file mode 100644 index 0000000..78de89d --- /dev/null +++ b/packages/ameba-20190720.1845.el @@ -0,0 +1,174 @@ +;;; ameba.el --- An interface to Crystal Ameba linter. -*- lexical-binding: t; -*- + +;; Copyright © 2018-2019 Vitalii Elenhaupt +;; Author: Vitalii Elenhaupt +;; URL: https://github.com/crystal-ameba/ameba.el +;; Package-Version: 20190720.1845 +;; Keywords: convenience +;; Version: 0 +;; Package-Requires: ((emacs "24.4")) + +;; This file is not part of GNU Emacs. + +;;; License: + +;; 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 . + +;;; Commentary: +;; +;; Ameba is a static code analysis tool for Crystal. +;; This package allows you to use this tool directly in Emacs. +;; +;; Usage: +;; +;; Run one of the predefined interactive functions. +;; +;; Run Ameba on the currently visited file: +;; +;; (ameba-check-current-file) +;; +;; Run Ameba on the entire project: +;; +;; (ameba-check-project) +;; +;; Prompt from a directory on which to run Ameba: +;; +;; (ameba-check-directory) + +;;; Code: + +(require 'tramp) + +(defgroup ameba nil + "An Emacs interface to Ameba" + :prefix "ameba-" + :group 'convenience + :group 'tools + :link '(url-link :tag "GitHub" "https://github.com/crystal-ameba/ameba.el")) + +(defcustom ameba-project-root-files + '(".projectile" ".git" ".hg" ".ameba.yml" "shard.yml") + "A list of files considered to mark the root of a project." + :type '(repeat string)) + +(defcustom ameba-check-command + "ameba --format flycheck" + "The command used to run Ameba checks." + :type 'string) + +(defcustom ameba-keymap-prefix (kbd "C-c C-r") + "Ameba keymap prefix." + :group 'ameba + :type 'string) + +(cl-defun ameba-local-file-name (file-name) + "Retrieve local filename if FILE-NAME is opened via TRAMP." + (cond ((tramp-tramp-file-p file-name) + (tramp-file-name-localname (tramp-dissect-file-name file-name))) + (t + file-name))) + +(cl-defun ameba-project-root (&optional no-error) + "Retrieve the root directory of a project if available. +When NO-ERROR is non-nil returns nil instead of raise an error." + (or + (car + (mapcar #'expand-file-name + (delq nil + (mapcar + (lambda (f) (locate-dominating-file default-directory f)) + ameba-project-root-files)))) + (if no-error + nil + (error "You're not into a project")))) + +(cl-defun ameba-project-lib () + "Returns the path to the lib directory in a project root." + (concat "!" (ameba-project-root) "lib")) + +(cl-defun ameba-buffer-name (file-or-dir) + "Generate a name for the Ameba buffer from FILE-OR-DIR." + (concat "*Ameba " file-or-dir "*")) + +(cl-defun ameba-build-command (command path) + "Build the full command to be run based on COMMAND and PATH." + (concat command " " path)) + +(cl-defun ameba-ensure-installed () + "Check if Ameba is installed." + (unless (executable-find "ameba") + (error "Ameba is not installed"))) + +(defun ameba--file-command (command) + "Run COMMAND on currently visited file." + (ameba-ensure-installed) + (let ((file-name (buffer-file-name (current-buffer)))) + (if file-name + (let ((default-directory (or (ameba-project-root 'no-error) default-directory))) + (compilation-start + (ameba-build-command command (ameba-local-file-name file-name)) + 'compilation-mode + (lambda (_arg) (ameba-buffer-name file-name)))) + (error "Buffer is not visiting a file")))) + +(defun ameba--dir-command (command &optional directory) + "Run COMMAND on the DIRECTORY if present, prompt user if not." + (ameba-ensure-installed) + (let ((directory + (or directory + (read-directory-name "Select directory: ")))) + (let ((default-directory (or (ameba-project-root 'no-error) default-directory))) + (compilation-start + (ameba-build-command command (ameba-local-file-name directory)) + 'compilation-mode + (lambda (arg) (message arg) (ameba-buffer-name directory)))))) + +;;;###autoload +(defun ameba-check-current-file () + "Run check on the current file." + (interactive) + (ameba--file-command ameba-check-command)) + +;;;###autoload +(defun ameba-check-project () + "Run check on the current project." + (interactive) + (ameba-check-directory + (concat (ameba-project-root) " " (ameba-project-lib)))) + +;;;###autoload +(defun ameba-check-directory (&optional directory) + "Run check on the DIRECTORY if present or prompt user if not." + (interactive) + (ameba--dir-command ameba-check-command directory)) + +;;; Minor mode +(defvar ameba-mode-map + (let ((map (make-sparse-keymap))) + (let ((prefix-map (make-sparse-keymap))) + (define-key prefix-map (kbd "f") #'ameba-check-current-file) + + (define-key map ameba-keymap-prefix prefix-map)) + map) + "Keymap for Ameba mode.") + +;;;###autoload +(define-minor-mode ameba-mode + "Minor mode to interface with Ameba." + :lighter " Ameba" + :keymap ameba-mode-map + :group 'ameba) + +(provide 'ameba) +;;; ameba.el ends here diff --git a/packages/ample-theme-20180207.1745.tar b/packages/ample-theme-20180207.1745.tar index 2c38995..062fa0d 100644 Binary files a/packages/ample-theme-20180207.1745.tar and b/packages/ample-theme-20180207.1745.tar differ diff --git a/packages/anaconda-mode-20181030.2109.el b/packages/anaconda-mode-20190616.1019.el similarity index 98% rename from packages/anaconda-mode-20181030.2109.el rename to packages/anaconda-mode-20190616.1019.el index b28733c..7402d37 100644 --- a/packages/anaconda-mode-20181030.2109.el +++ b/packages/anaconda-mode-20190616.1019.el @@ -4,7 +4,7 @@ ;; Author: Artem Malyshev ;; URL: https://github.com/proofit404/anaconda-mode -;; Package-Version: 20181030.2109 +;; Package-Version: 20190616.1019 ;; Version: 0.1.13 ;; Package-Requires: ((emacs "25") (pythonic "0.1.0") (dash "2.6.0") (s "1.9") (f "0.16.2")) @@ -158,11 +158,16 @@ else: # Define JSON-RPC application. import functools +import threading def script_method(f): @functools.wraps(f) def wrapper(source, line, column, path): - return f(jedi.Script(source, line, column, path, environment=virtual_environment)) + timer = threading.Timer(30.0, sys.exit) + timer.start() + result = f(jedi.Script(source, line, column, path, environment=virtual_environment)) + timer.cancel() + return result return wrapper def process_definitions(f): @@ -715,7 +720,8 @@ Show ERROR-MESSAGE if result is empty." \\{anaconda-mode-map}" :lighter anaconda-mode-lighter - :keymap anaconda-mode-map) + :keymap anaconda-mode-map + (setq-local url-http-attempt-keepalives nil)) ;;;###autoload (define-minor-mode anaconda-eldoc-mode diff --git a/packages/ansible-20180813.114.tar b/packages/ansible-20190619.1255.tar similarity index 72% rename from packages/ansible-20180813.114.tar rename to packages/ansible-20190619.1255.tar index df6829e..eb75545 100644 Binary files a/packages/ansible-20180813.114.tar and b/packages/ansible-20190619.1255.tar differ diff --git a/packages/anzu-20161017.1607.el b/packages/anzu-20190303.1701.el similarity index 99% rename from packages/anzu-20161017.1607.el rename to packages/anzu-20190303.1701.el index 18c77db..058545f 100644 --- a/packages/anzu-20161017.1607.el +++ b/packages/anzu-20190303.1701.el @@ -4,7 +4,7 @@ ;; Author: Syohei YOSHIDA ;; URL: https://github.com/syohex/emacs-anzu -;; Package-Version: 20161017.1607 +;; Package-Version: 20190303.1701 ;; Version: 0.62 ;; Package-Requires: ((emacs "24.3")) @@ -223,11 +223,16 @@ result)))))) (defun anzu--where-is-here (positions here) - (cl-loop for (start . end) in positions - for i = 1 then (1+ i) - when (and (>= here start) (<= here end)) - return i - finally return 0)) + ;; don't use loop for emacs 27 bug + (let ((poss positions) + (index 1) + (ret 0)) + (while poss + (let ((pos (car poss))) + (if (and (>= here (car pos)) (<= here (cdr pos))) + (setq ret index poss nil) + (setq poss (cdr poss) index (1+ index))))) + ret)) (defun anzu--use-result-cache-p (input) (and (eq (anzu--isearch-regexp-function) (car anzu--last-search-state)) diff --git a/packages/apiwrap-20180602.2231.el b/packages/apiwrap-20180602.2231.el deleted file mode 100644 index 9c94adb..0000000 --- a/packages/apiwrap-20180602.2231.el +++ /dev/null @@ -1,471 +0,0 @@ -;;; apiwrap.el --- api-wrapping macros -*- lexical-binding: t; -*- - -;; Copyright (C) 2017-2018 Sean Allred - -;; Author: Sean Allred -;; Keywords: tools, maint, convenience -;; Homepage: https://github.com/vermiculus/apiwrap.el -;; Package-Requires: ((emacs "25")) -;; Package-Version: 20180602.2231 -;; Package-X-Original-Version: 0.5 - -;; This file is not part of GNU Emacs. - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 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 . - -;;; Commentary: - -;; API-Wrap.el is a tool to interface with the APIs of your favorite -;; services. These macros make it easy to define efficient and -;; consistently-documented Elisp functions that use a natural syntax -;; for application development. - -;;; Code: - -(require 'cl-lib) -(require 'apropos) - -(defvar apiwrap-backends nil - "An alist of (BACKEND-NAME . BACKEND-PREFIX) for `apropos-api-endpoint'. -See also `apiwrap-new-backend'.") - -(defun apiwrap-genform-resolve-api-params (object url) - "Resolve parameters in URL to values in OBJECT. - -Example: - - \(apiwrap-genform-resolve-api-params - '\(\(name . \"Hello-World\"\) - \(owner \(login . \"octocat\"\)\)\) - \"/repos/:owner.login/:name/issues\"\) - - ;; \"/repos/octocat/Hello-World/issues\" - -" - (declare (indent 1)) - ;; Yes I know it's hacky, but it works and it's compile-time - ;; (which is to say: pull-requests welcome!) - (save-match-data - (with-temp-buffer - (insert url) - (goto-char 0) - (let ((param-regexp (rx ":" (group (+? (any alpha "-" "."))) (or (group "/") eos))) - replacements) - (while (search-forward-regexp param-regexp nil 'noerror) - (push (match-string-no-properties 1) replacements) - (if (null (match-string-no-properties 2)) - (replace-match "%s") - (replace-match "%s/"))) - (setq replacements - (mapcar (lambda (s) (list #'apiwrap--encode-url (make-symbol (concat "." s)))) - (nreverse replacements))) - (let ((object (if (or (symbolp object) - (and (listp object) - (not (consp (car object))))) - object - `',object)) - (str `(format ,(buffer-string) ,@replacements))) - (if object - (macroexpand-all `(let-alist ,object ,str)) - str)))))) - -(defun apiwrap--encode-url (thing) - (if (numberp thing) - (number-to-string thing) - (url-encode-url thing))) - -(defun apiwrap-plist->alist (plist) - "Convert PLIST to an alist. -If a PLIST key is a `:keyword', then it is converted into a -symbol `keyword'." - (when (= 1 (mod (length plist) 2)) - (error "bad plist")) - (let (alist) - (while plist - (push (cons (apiwrap--kw->sym (car plist)) - (cadr plist)) - alist) - (setq plist (cddr plist))) - alist)) - -(defun apiwrap--kw->sym (kw) - "Convert a keyword to a symbol." - (if (keywordp kw) - (intern (substring (symbol-name kw) 1)) - kw)) - -(defun apiwrap--docfn (service-name doc object-param-doc method external-resource link) - "Documentation string for resource-wrapping functions created -by `apiwrap--defresource'. - -SERVICE-NAME is the name of the API being wrapped (e.g., \"ghub\") - -DOC is the documentation string for this endpoint. - -OBJECT-PARAM-DOC is a string describing the standard parameters -this endpoint requires (usually provided by -`apiwrap-new-backend'). If it's not a string, nothing will be -inserted into the documentation string. - -METHOD is one of `get', `post', etc. - -EXTERNAL-RESOURCE is the API endpoint as documented in the API. -It does not usually include any syntax for reference-resolution. - -LINK is a link to the official documentation for this API -endpoint from the service provider." - (format "%s - -%sDATA is a data structure to be sent with this request. If it's -not required, it can simply be omitted. - -PARAMS is a plist of parameters appended to the method call. - -%s - -This generated function wraps the %s API endpoint - - %s %s - -which is documented at - - URL `%s'" - doc - (or (and (stringp object-param-doc) - (concat object-param-doc "\n\n")) - "") - (make-string 20 ?-) - service-name - (upcase (symbol-name method)) - external-resource link)) - -(defun apiwrap--docmacro (service-name method) - "Documentation string for macros created by -`apiwrap-new-backend' - -SERVICE-NAME is the name of the API being wrapped (e.g., \"ghub\") - -METHOD is one of `get', `post', etc." - (apply #'format "Define a new %s resource wrapper function. - -RESOURCE is the API endpoint as written in the %s API -documentation. Along with the backend prefix (from -`apiwrap-new-backend') and the method (%s), this string will be -used to create the symbol for the new function. - -DOC is a specific documentation string for the new function. -Usually, this can be copied from the %s API documentation. - -LINK is a link to the %s API documentation. - -If non-nil, OBJECTS is a list of symbols that will be used to -resolve parameters in the resource and will be required arguments -of the new function. Documentation for these parameters (from -the standard parameters of the call to `apiwrap-new-backend') -will be inserted into the docstring of the generated function. - -If non-nil, INTERNAL-RESOURCE is the resource-string used to -resolve OBJECT to the ultimate call instead of RESOURCE. This is -useful in the likely event that the advertised resource syntax -does not align with the structure of the object it works with. -For example, GitHub's endpoint - - GET /repos/:owner/:repo/issues - -would be written as - - \(defapiget- \"/repos/:owner/:repo/issues\" - \"List issues for a repository.\" - \"issues/#list-issues-for-a-repository\" - (repo) \"/repos/:repo.owner.login/:repo.name/issues\"\) - -defining a function called `-get-repos-owner-repo-issues' -and taking an object (a parameter called `repo') with the -structure - - \(\(owner \(login . \"octocat\"\)\) - \(name . \"hello-world\"\) - -See the documentation of `apiwrap-resolve-api-params' for more -details on that behavior. - -CONFIG is a list of override configuration parameters. Values -set here (notably those explicitly set to nil) will take -precedence over the defaults provided to `apiwrap-new-backend'." - (upcase (symbol-name method)) - service-name - (upcase (symbol-name method)) - (make-list 2 service-name))) - -(defun apiwrap-gensym (prefix api-method &optional resource) - "Generate a symbol for a macro/function." - (let ((api-method (symbol-name (apiwrap--kw->sym api-method)))) - (intern - (if resource - (format "%s-%s%s" prefix api-method - (replace-regexp-in-string - ":" "" - (replace-regexp-in-string "/" "-" resource))) - (format "defapi%s-%s" api-method prefix))))) - -(defun apiwrap-stdgenlink (alist) - "Standard link generation function." - (alist-get 'link alist)) - -(defconst apiwrap-primitives - '(get put head post patch delete) - "List of primitive methods. -The `:request' value given to `apiwrap-new-backend' must -appropriately handle all of these symbols as a METHOD.") - -(defun apiwrap-genmacros (name prefix standard-parameters functions) - "Validate arguments and generate all macro forms" - ;; Default to raw link entered in the macro - (unless (alist-get 'link functions) - (setcdr (last functions) (list '(link . apiwrap-stdgenlink)))) - - ;; Verify all extension functions are actually functions - (dolist (f functions) - (let ((key (car f)) (fn (cdr f))) - (unless (or (functionp fn) - (macrop fn) - (and (consp fn) - (eq 'function (car fn)) - (or (functionp (cadr fn)) - (macrop (cadr fn))))) - (byte-compile-warn "Unknown function for `%S': %S" key fn)))) - - ;; Build the macros - (let (super-form) - (dolist (method (reverse apiwrap-primitives)) - (let ((macrosym (apiwrap-gensym prefix method))) - (push `(defmacro ,macrosym (resource doc link - &optional objects internal-resource - &rest config) - ,(apiwrap--docmacro name method) - (declare (indent defun) (doc-string 2)) - (apiwrap-gendefun ,name ,prefix ',standard-parameters ',method - resource doc link objects internal-resource - ',functions config)) - super-form))) - super-form)) - -(defun apiwrap--maybe-apply (func value) - "Conditionally apply FUNC to VALUE. -If FUNC is non-nil, return a form to apply FUNC to VALUE. -Otherwise, just return VALUE quoted." - (if func `(funcall ,func ,value) value)) - -(defun apiwrap-gendefun (name prefix standard-parameters method resource doc link objects internal-resource std-functions override-functions) - "Generate a single defun form" - (let ((args '(&optional data &rest params)) - (funsym (apiwrap-gensym prefix method resource)) - resolved-resource-form form functions - data-massage-func params-massage-func - condition-case primitive-func link-func around) - - ;; Be smart about when configuration starts. Neither `objects' nor - ;; `internal-resource' can be keywords, so we know that if they - ;; are, then we need to shift things around. - (when (keywordp objects) - (push internal-resource override-functions) - (push objects override-functions) - (setq objects nil internal-resource nil)) - (when (keywordp internal-resource) - (push internal-resource override-functions) - (setq internal-resource nil)) - (setq functions (append (apiwrap-plist->alist override-functions) - std-functions)) - - ;; Now that our arguments have settled, let's use them - (when objects (setq args (append objects args))) - - (setq internal-resource (or internal-resource resource) - around (alist-get 'around functions) - condition-case (macroexpand-all (alist-get 'condition-case functions)) - primitive-func (alist-get 'request functions) - data-massage-func (alist-get 'pre-process-data functions) - params-massage-func (alist-get 'pre-process-params functions) - link-func (alist-get 'link functions)) - - ;; If our functions are already functions (and not quoted), we'll - ;; have to quote them for the actual defun - (when (functionp primitive-func) - (setq primitive-func `(function ,primitive-func))) - (when (functionp data-massage-func) - (setq data-massage-func `(function ,data-massage-func))) - (when (functionp params-massage-func) - (setq params-massage-func `(function ,params-massage-func))) - - ;; Alright, we're ready to build our function - (setq resolved-resource-form - (if objects - (apiwrap-genform-resolve-api-params - `(list ,@(mapcar (lambda (o) `(cons ',o ,o)) objects)) - internal-resource) - internal-resource) - form - `(apply ,primitive-func ',method ,resolved-resource-form - (if (keywordp data) - (list ,(apiwrap--maybe-apply params-massage-func '(cons data params)) nil) - (list ,(apiwrap--maybe-apply params-massage-func 'params) - ,(apiwrap--maybe-apply data-massage-func 'data))))) - - (when around - (unless (macrop around) - (error ":around must be a macro: %S" around)) - (setq form (macroexpand `(,around ,form)))) - - (when condition-case - (unless (and (listp condition-case) - (cl-every #'listp condition-case) - (cl-every (lambda (h) (get (car h) 'error-conditions)) ;is error - condition-case)) - (error ":condition-case must be a list of error handlers; see the documentation: %S" condition-case)) - (setq form `(condition-case it ,form ,@condition-case))) - - (let ((props `((prefix . ,prefix) - (method . ,method) - (endpoint . ,resource) - (link . ,link))) - fn-form) - (push `(put ',funsym 'apiwrap ',props) fn-form) - (push `(defun ,funsym ,args - ,(apiwrap--docfn name doc (alist-get objects standard-parameters) method resource - (funcall link-func props)) - (declare (indent ,(length objects))) - ,form) - fn-form) - (cons 'prog1 fn-form)))) - -(defmacro apiwrap-new-backend (name prefix standard-parameters &rest config) - "Define a new API backend. - -SERVICE-NAME is the name of the service this backend will wrap. -It will be used in docstrings of the primitive method macros. - -PREFIX is the prefix to use for the macros and for the -resource-wrapping functions. - -STANDARD-PARAMETERS is an alist of standard parameters that can -be used to resolve resource URLs like `/users/:user/info'. Each -key of the alist is the parameter name (as a symbol) and its -value is the documentation to insert in the docstring of -resource-wrapping functions. - -CONFIG is a list of arguments to configure the generated macros. - - Required: - - :request - - API request primitive. This function is expected to take - the following required arguments: - - (METHOD RESOURCE PARAMS DATA) - - METHOD is provided as a symbol, one of `apiwrap-primitives', - that specifies which HTTP method to use for the request. - - RESOURCE is the resource being accessed as a string. - This will be passed through from each method macro after - being resolved in the context of its parameters. See the - generated macro documentation (or `apiwrap--docmacro') - for more details. - - PARAMS is provided as a property list of parameters. - This will be passed in from each method function call. - - DATA is provided as an alist of data (e.g., for posting - data to RESOURCE). This will be passed in from each - method function call. - - Optional: - - :around - - Macro to wrap around the request form (which is passed as - the only argument). - - :condition-case - - List of error handlers of the form - - ((CONDITION-NAME BODY...) - (CONDITION-NAME BODY...)) - - to appropriately deal with signals in the `:request' - primitive. Caught signals are bound to the symbol `it'. - Note that the form will need to mention `it' in some way - to avoid compile warnings. If this is a problem for you, - track resolution of this issue in vermiculus/apiwrap#12. - - See also `condition-case'. - - :link - - Function to process an alist and return a link. This - function should take an alist as its sole parameter and - return a fully-qualified URL to be considered the - official documentation of the API endpoint. - - This function is passed an alist with the following - properties: - - endpoint string the documented endpoint being wrapped - link string the link passed as documentation - method symbol one of `get', `put', etc. - prefix string the prefix used to generate wrappers - - The default is `apiwrap-stdgenlink'. - - :pre-process-data - - Function to process request data before the request is - passed to the `:request' function. - - :pre-process-params - - Function to process request parameters before the request - is passed to the `:request' function." - (declare (indent 2)) - (let ((sname (cl-gensym)) (sprefix (cl-gensym)) - (sstdp (cl-gensym)) (sconfig (cl-gensym))) - `(let ((,sname ,name) - (,sprefix ,prefix) - (,sstdp ,standard-parameters) - (,sconfig ',(mapcar (lambda (f) (cons (car f) (eval (cdr f)))) - (apiwrap-plist->alist config)))) - (add-to-list 'apiwrap-backends (cons ,sname ,sprefix)) - (mapc #'eval (apiwrap-genmacros ,sname ,sprefix ,sstdp ,sconfig))))) - -(defun apropos-api-endpoint (backend pattern) - "Apropos for API endpoints of BACKEND matching PATTERN." - (interactive (let* ((b (completing-read "Search backend: " - (mapcar #'car apiwrap-backends))) - (b (assoc-string b apiwrap-backends)) - (name (car b)) - (prefix (cdr b))) - (list prefix (apropos-read-pattern (concat name " API endpoints"))))) - (apropos-parse-pattern pattern) - (apropos-symbols-internal - (apropos-internal apropos-regexp - (lambda (sym) - (let-alist (get sym 'apiwrap) - (and .prefix - (string= .prefix backend))))) - nil)) - -(provide 'apiwrap) -;;; apiwrap.el ends here diff --git a/packages/apropospriate-theme-20181111.2112.tar b/packages/apropospriate-theme-20190724.1729.tar similarity index 80% rename from packages/apropospriate-theme-20181111.2112.tar rename to packages/apropospriate-theme-20190724.1729.tar index 7123027..1769535 100644 Binary files a/packages/apropospriate-theme-20181111.2112.tar and b/packages/apropospriate-theme-20190724.1729.tar differ diff --git a/packages/archive-contents b/packages/archive-contents index fcad10f..e57bf09 100644 --- a/packages/archive-contents +++ b/packages/archive-contents @@ -1 +1 @@ -(1 (diminish . [(20170419 1736) nil "Diminished modes are minor modes with no modeline display" single ((:commit . "565a983a39d2e2cffab5df13b34f3b6116723208") (:keywords "extensions" "diminish" "minor" "codeprose") (:authors ("Will Mengarini" . "seldon@eskimo.com")) (:maintainer "Martin Yrjölä" . "martin.yrjola@gmail.com") (:url . "https://github.com/myrjola/diminish.el"))]) (bind-key . [(20180513 430) nil "A simple way to manage personal keybindings" single ((:commit . "d9f229453da31fdf9a55207db09e360c5071d706") (:keywords "keys" "keybinding" "config" "dotemacs") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:url . "https://github.com/jwiegley/use-package"))]) (use-package . [(20181110 1758) ((emacs (24 3)) (bind-key (2 4))) "A configuration macro for simplifying your .emacs" tar ((:commit . "d9f229453da31fdf9a55207db09e360c5071d706") (:keywords "dotemacs" "startup" "speed" "config" "package") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:url . "https://github.com/jwiegley/use-package"))]) (which-key . [(20181114 1432) ((emacs (24 4))) "Display available keybindings in popup" single ((:commit . "43e3e3d7641a8e1c298b37e6a277612bf0898708") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/emacs-which-key"))]) (dotenv-mode . [(20180207 1914) ((emacs (24 3))) "Major mode for .env files" single ((:commit . "f4c52bcd5313379b9f2460db7f7a33119dfa96ea") (:authors ("Preetpal S. Sohal")) (:maintainer "Preetpal S. Sohal") (:url . "https://github.com/preetpalS/emacs-dotenv-mode"))]) (packed . [(20180318 1729) ((emacs (24 3))) "package manager agnostic Emacs Lisp package utilities" single ((:commit . "c41c3dfda86ae33832ffc146923e2a4675cbacfa") (:keywords "compile" "convenience" "lisp" "package" "library") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/packed"))]) (auto-compile . [(20180321 1507) ((emacs (24 3)) (packed (2 0 0))) "automatically compile Emacs Lisp libraries" single ((:commit . "6ce4255ab9a0b010ef8414c5bd9a6d6d9eea012f") (:keywords "compile" "convenience" "lisp") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/auto-compile"))]) (elisp-slime-nav . [(20160128 1909) ((cl-lib (0 2))) "Make M-. and M-, work in elisp like they do in slime" single ((:commit . "34938422929800839e2f935aca890cd4a229ca99") (:keywords "navigation" "slime" "elisp" "emacs-lisp") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/elisp-slime-nav"))]) (evil-cleverparens . [(20170718 413) ((evil (1 0)) (paredit (1)) (smartparens (1 6 1)) (emacs (24 4)) (dash (2 12 0))) "Evil friendly minor-mode for editing lisp." tar ((:commit . "8c45879d49bfa6d4e414b6c1df700a4a51cbb869") (:keywords "cleverparens" "parentheses" "evil" "paredit" "smartparens") (:authors ("Olli Piepponen" . "opieppo@gmail.com")) (:maintainer "Olli Piepponen" . "opieppo@gmail.com") (:url . "https://github.com/luxbock/evil-cleverparens"))]) (ggtags . [(20181031 1803) ((emacs (25))) "emacs frontend to GNU Global source code tagging system" single ((:commit . "669676461c74ffd30b81dce60cf4f081270f2858") (:keywords "tools" "convenience") (:authors ("Leo Liu" . "sdl.web@gmail.com")) (:maintainer "Leo Liu" . "sdl.web@gmail.com") (:url . "https://github.com/leoliu/ggtags"))]) (counsel-gtags . [(20170326 1259) ((emacs (24 3)) (counsel (0 8 0))) "ivy for GNU global" single ((:commit . "220ebb48419ee6891ecbf9ea8fe130b494b17ee2") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-counsel-gtags"))]) (helm-gtags . [(20170116 529) ((emacs (24 4)) (helm (2 0))) "GNU GLOBAL helm interface" single ((:commit . "108e93d0d099ebb7b98847388f368311cf177033") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-gtags"))]) (nameless . [(20180215 2221) ((emacs (24 4))) "Hide package namespace in your emacs-lisp code" single ((:commit . "3cd4ade5433c8e2041dfff9d9624d9e676d9c5ee") (:keywords "convenience" "lisp") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/nameless"))]) (overseer . [(20180226 619) ((emacs (24)) (dash (2 10 0)) (pkg-info (0 4)) (f (0 18 1))) "Ert-runner Integration Into Emacs" single ((:commit . "02d49f582e80e36b4334c9187801c5ecfb027789") (:authors ("Samuel Tonini" . "tonini.samuel@gmail.com")) (:maintainer "Samuel Tonini" . "tonini.samuel@gmail.com") (:url . "http://www.github.com/tonini/overseer.el"))]) (parinfer . [(20180904 844) ((dash (2 13 0)) (cl-lib (0 5))) "Simpler Lisp editing" tar ((:commit . "a7c041454e05ec2b88333a73e72debaa671ed596") (:keywords "parinfer") (:authors ("Shi Tianshu")) (:maintainer "Shi Tianshu") (:url . "https://github.com/DogLooksGood/parinfer-mode"))]) (srefactor . [(20180703 1810) ((emacs (24 4))) "A refactoring tool based on Semantic parser framework" tar ((:commit . "6f2c97d17fb70f4ca2112f5a2b99a8ec162004f5") (:keywords "c" "languages" "tools") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:url . "https://github.com/tuhdo/semantic-refactor"))]) (twittering-mode . [(20180917 328) nil "Major mode for Twitter" single ((:commit . "ad7de82cf4b72fc166970d85849e2a9a9ae5a979") (:keywords "twitter" "web") (:authors ("Tadashi MATSUO" . "tad@mymail.twin.ne.jp") ("Y. Hayamizu" . "y.hayamizu@gmail.com") ("Tsuyoshi CHO" . "Tsuyoshi.CHO+develop@Gmail.com") ("Alberto Garcia" . "agarcia@igalia.com") ("Xavier Maillard" . "xavier@maillard.im")) (:maintainer "Tadashi MATSUO" . "tad@mymail.twin.ne.jp") (:url . "http://twmode.sf.net/"))]) (engine-mode . [(20180401 1646) ((cl-lib (0 5))) "Define and query search engines from within Emacs." single ((:commit . "fd5a235b2c93b95143d676e6b654e388d7cdd956") (:authors ("Harry R. Schwartz" . "hello@harryrschwartz.com")) (:maintainer "Harry R. Schwartz" . "hello@harryrschwartz.com") (:url . "https://github.com/hrs/engine-mode"))]) (geeknote . [(20160717 1249) ((emacs (24))) "Use Evernote in Emacs through geeknote" single ((:commit . "8ed607c76864afcc9c338972ab093caf4501cbf8") (:keywords "evernote" "geeknote" "note" "emacs-evernote" "evernote-mode") (:authors ("Evan Dale Aromin")) (:maintainer "Evan Dale Aromin") (:url . "http://github.com/avendael/emacs-geeknote"))]) (xml-rpc . [(20181002 1353) nil "An elisp implementation of clientside XML-RPC" single ((:commit . "8f624f8b964e9145acb504e4457c9510e87dd93c") (:keywords "xml" "rpc" "network") (:authors ("Mark A. Hershberger" . "mah@everybody.org")) (:maintainer "Mark A. Hershberger" . "mah@everybody.org") (:url . "http://github.com/hexmode/xml-rpc-el"))]) (confluence . [(20151021 128) ((xml-rpc (1 6 4))) "Emacs mode for interacting with confluence wikis" tar ((:commit . "4518d270a07760644c4204985c83d234ece4738b") (:keywords "confluence" "wiki" "xmlrpc") (:authors ("James Ahlborn")) (:maintainer "James Ahlborn") (:url . "http://code.google.com/p/confluence-el/"))]) (wakatime-mode . [(20180920 702) nil "Automatic time tracking extension for WakaTime" single ((:commit . "2531cb58287770883ba534d20b3288955c4d6ef3") (:keywords "calendar" "comm") (:authors ("Gabor Torok" . "gabor@20y.hu")) (:maintainer "Alan Hamlett" . "alan@wakatime.com"))]) (feature-mode . [(20170907 1448) nil "Major mode for editing Gherkin (i.e. Cucumber) user stories" tar ((:commit . "722b352c4f0b800a9356dd369c79612782b3b847"))]) (projectile-rails . [(20181009 1317) ((emacs (24 3)) (projectile (0 12 0)) (inflections (1 1)) (inf-ruby (2 2 6)) (f (0 13 0)) (rake (0 3 2))) "Minor mode for Rails projects based on projectile-mode" single ((:commit . "af0f826f2e1b1aad4e31e089e5fc7b5937e82359") (:keywords "rails" "projectile") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:url . "https://github.com/asok/projectile-rails"))]) (alchemist . [(20180312 1304) ((elixir-mode (2 2 5)) (dash (2 11 0)) (emacs (24 4)) (company (0 8 0)) (pkg-info (0 4)) (s (1 11 0))) "Elixir tooling integration into Emacs" tar ((:commit . "6f99367511ae209f8fe2c990779764bbb4ccb6ed") (:keywords "languages" "elixir" "elixirc" "mix" "hex" "alchemist") (:authors ("Samuel Tonini" . "tonini.samuel@gmail.com")) (:maintainer "Samuel Tonini" . "tonini.samuel@gmail.com") (:url . "http://www.github.com/tonini/alchemist.el"))]) (ember-mode . [(20181001 936) ((cl-lib (0 5))) "Ember navigation mode for emacs" single ((:commit . "88e5ffd33d8664b4d5124d6aa2ea9ed8d50c8c9e") (:keywords "ember" "ember.js" "emberjs") (:authors ("Aad Versteden" . "madnificent@gmail.com")) (:maintainer "Aad Versteden" . "madnificent@gmail.com"))]) (ember-yasnippets . [(20160526 1658) ((yasnippet (0 8 0))) "Snippets for Ember.js development" tar ((:commit . "3b5bd01569646237bf1b540d097e12f9118b67f4") (:keywords "tools" "abbrev" "languages") (:authors ("Ron White" . "ronco@costite.com")) (:maintainer "Ron White" . "ronco@costite.com"))]) (pony-mode . [(20170807 1522) nil "Minor mode for working with Django Projects" tar ((:commit . "760684d30b6c234d1b88c9a4673a808f36f7f341"))]) (add-node-modules-path . [(20180710 2342) nil "Add node_modules to your exec-path" single ((:commit . "f31e69ccb681f882aebb806ce6e9478e3ac39708") (:keywords "javascript" "node" "node_modules" "eslint") (:authors ("Neri Marschik" . "marschik_neri@cyberagent.co.jp")) (:maintainer "Neri Marschik" . "marschik_neri@cyberagent.co.jp") (:url . "https://github.com/codesuki/add-node-modules-path"))]) (emmet-mode . [(20180613 341) nil "Unofficial Emmet's support for emacs" single ((:commit . "1acb821e0142136344ccf40c1e5fb664d7db2e70") (:keywords "convenience") (:authors ("Shin Aoyama" . "smihica@gmail.com")) (:maintainer "Shin Aoyama" . "smihica@gmail.com") (:url . "https://github.com/smihica/emmet-mode"))]) (evil-matchit . [(20181111 604) ((evil (1 2 0)) (emacs (24 4))) "Vim matchit ported to Evil" tar ((:commit . "7d65b4167b1f0086c2b42b3aec805e47a0d355c4") (:keywords "matchit" "vim" "evil") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/evil-matchit"))]) (js-doc . [(20160715 434) nil "Insert JsDoc style comment easily" single ((:commit . "f0606e89d5aa89146f96edb38cf69af0068a9d1e") (:keywords "document" "comment") (:authors ("mooz" . "stillpedant@gmail.com")) (:maintainer "mooz" . "stillpedant@gmail.com") (:url . "https://github.com/mooz/js-doc"))]) (lsp-javascript-typescript . [(20180614 2011) ((lsp-mode (3 0)) (typescript-mode (0 1)) (emacs (25 1))) "Javascript/Typescript support for lsp-mode" single ((:commit . "ab62826962887e82f0bc968817be4fc89a6953e4") (:keywords "languages" "tools") (:authors ("George Pittarelli" . "g@gjp.cc")) (:maintainer "George Pittarelli" . "g@gjp.cc") (:url . "https://github.com/emacs-lsp/lsp-javascript"))]) (prettier-js . [(20180109 726) nil "Minor mode to format JS code on file save" single ((:commit . "fac9dd29720f8417bd8cd5dd8ab5138c6dd7d701") (:keywords "convenience" "wp" "edit" "js") (:authors ("James Long and contributors")) (:maintainer "James Long and contributors") (:url . "https://github.com/prettier/prettier-emacs"))]) (rjsx-mode . [(20180913 2224) ((emacs (24 4)) (js2-mode (20170504))) "Real support for JSX" single ((:commit . "89358fd230878a19e3232a3e4ce21b7fb608faae") (:keywords "languages") (:authors ("Felipe Ochoa" . "felipe@fov.space")) (:maintainer "Felipe Ochoa" . "felipe@fov.space") (:url . "https://github.com/felipeochoa/rjsx-mode/"))]) (web-beautify . [(20161115 2247) nil "Format HTML, CSS and JavaScript/JSON" single ((:commit . "e1b45321d8c11b404b12c8e55afe55eaa7c84ee9") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/web-beautify"))]) (flycheck-ocaml . [(20170730 2153) ((emacs (24 1)) (flycheck (0 22)) (merlin (3 0 1)) (let-alist (1 0 3))) "Flycheck: OCaml support" single ((:commit . "8707a7bf545a8639a6a5c600a98d9a2ea1487dc9") (:keywords "convenience" "tools" "languages") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-ocaml"))]) (merlin . [(20180816 815) nil "Mode for Merlin, an assistant for OCaml." tar ((:commit . "aac7b39eb5305faa0ddd6b1d6fe2f4b36ac85aed") (:keywords "ocaml" "languages") (:authors ("Frédéric Bour ")) (:maintainer "Frédéric Bour ") (:url . "https://github.com/ocaml/merlin"))]) (ocp-indent . [(20180417 1549) nil "automatic indentation with ocp-indent" single ((:commit . "4830ebf5d1c1b8f47bc152ff13d2c6aa1aad705b") (:keywords "ocaml" "languages") (:url . "http://www.typerex.org/ocp-indent.html"))]) (caml . [(20181011 1328) nil "OCaml code editing commands for Emacs" tar ((:commit . "8145641e8a27b924ab05a7bea05e6ff52f0a217f") (:keywords "ocaml") (:authors ("Jacques Garrigue" . "garrigue@kurims.kyoto-u.ac.jp") ("Ian T Zimmerman" . "itz@rahul.net")) (:maintainer "Damien Doligez" . "damien.doligez@inria.fr") (:url . "https://github.com/ocaml/ocaml/"))]) (tuareg . [(20180918 1913) ((caml (3 12 0 1))) "OCaml mode for Emacs." tar ((:commit . "c030be472c2aea4d4b770705f9099fb00e952618") (:keywords "ocaml" "languages") (:authors ("Albert Cohen" . "Albert.Cohen@inria.fr") ("Sam Steingold" . "sds@gnu.org") ("Christophe Troestler" . "Christophe.Troestler@umons.ac.be") ("Till Varoquaux" . "till@pps.jussieu.fr") ("Sean McLaughlin" . "seanmcl@gmail.com") ("Stefan Monnier" . "monnier@iro.umontreal.ca")) (:maintainer "Albert Cohen" . "Albert.Cohen@inria.fr") (:url . "https://github.com/ocaml/tuareg"))]) (utop . [(20181010 2155) ((emacs (24))) "Universal toplevel for OCaml" single ((:commit . "ea38850e606dd18c94e2ccabc28485fec1c8f91f") (:keywords "ocaml" "languages") (:authors ("Jeremie Dimino" . "jeremie@dimino.org")) (:maintainer "Jeremie Dimino" . "jeremie@dimino.org") (:url . "https://github.com/diml/utop"))]) (geiser . [(20181117 650) nil "GNU Emacs and Scheme talk to each other" tar ((:commit . "dcf754c0b9cdb87ffa5930ef8ffbae9256f2d07d") (:url . "http://www.nongnu.org/geiser/"))]) (plantuml-mode . [(20180816 1012) ((emacs (25 0))) "Major mode for PlantUML" single ((:commit . "b358a53bb0ab195f0193169d0d6869a3ef2c543e") (:keywords "uml" "plantuml" "ascii") (:authors ("Zhang Weize (zwz)")) (:maintainer "Carlo Sciolla (skuro)"))]) (powershell . [(20181011 1951) ((emacs (24))) "Mode for editing PowerShell scripts" single ((:commit . "c9a20e5a8b02dc5d7ccd2b1974eba28a9348ad5e") (:keywords "powershell" "languages") (:authors ("Frédéric Perrin ")) (:maintainer "Frédéric Perrin ") (:url . "http://github.com/jschaf/powershell.el"))]) (vimrc-mode . [(20181116 1919) nil "Major mode for vimrc files" single ((:commit . "13bc150a870d5d4a95f1111e4740e2b22813c30e") (:keywords "languages" "vim") (:url . "https://github.com/mcandre/vimrc-mode"))]) (dactyl-mode . [(20140906 1725) nil "Major mode for editing Pentadactyl config files" single ((:commit . "cc55fe6b987271d9647492b8df4c812d884f661f") (:keywords "languages" "vim") (:url . "https://github.com/luxbock/dactyl-mode"))]) (company-plsense . [(20180118 58) ((company (0 9 3)) (cl-lib (0 5 0)) (dash (2 12 0)) (s (1 12)) (emacs (24))) "Company backend for Perl" single ((:commit . "b48e3181e08ec597269621d621aa06636f02d883") (:authors ("Troy Hinckley" . "troy.hinckley@gmail.com")) (:maintainer "Troy Hinckley" . "troy.hinckley@gmail.com") (:url . "https://github.com/CeleritasCelery/company-plsense"))]) (test-simple . [(20170527 1532) ((cl-lib (0))) "Simple Unit Test Framework for Emacs Lisp" single ((:commit . "b3b69f52207d3a8111421ad7ab9ed82abbe85316") (:keywords "unit-test") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/rocky/emacs-test-simple"))]) (loc-changes . [(20160801 1708) nil "keep track of positions even after buffer changes" single ((:commit . "4d1dcdf7631c23b1259ad4f72bf9686cf95fb46c") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/rocky/emacs-loc-changes"))]) (load-relative . [(20170526 1010) nil "relative file load (within a multi-file Emacs package)" tar ((:commit . "738896e3da491b35399178ed2c6bc92cc728d119") (:keywords "internal") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/rocky/emacs-load-relative"))]) (realgud . [(20180925 10) ((load-relative (1 2)) (loc-changes (1 2)) (test-simple (1 2 0)) (cl-lib (0 5)) (emacs (24))) "A modular front-end for interacting with external debuggers" tar ((:commit . "36782d69c806079eb067705ef67fcb3b9299ae01") (:keywords "gdb" "python" "perl" "go" "bash" "nodejs" "zsh" "bashdb" "zshdb" "remake" "make" "trepan" "perldb" "pdb") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/realgud/realgud/"))]) (company-glsl . [(20171015 1749) ((company (0 9 4)) (glsl-mode (2 0)) (emacs (24 4))) "Support glsl in company-mode" single ((:commit . "a262c12c3bcd0807718c4edcaf2b054e30ef0e26") (:authors ("Guido Schmidt" . "git@guidoschmidt.cc")) (:maintainer "Guido Schmidt" . "git@guidoschmidt.cc") (:url . "https://github.com/guidoschmidt/company-glsl"))]) (cuda-mode . [(20151214 321) nil "NVIDIA CUDA Major Mode" single ((:commit . "9ae9eacfdba3559b5456342d0d03296290df8ff5") (:keywords "c" "languages") (:authors ("Jack Morrison" . "jackmorrison1@gmail.com")) (:maintainer "Jack Morrison" . "jackmorrison1@gmail.com"))]) (glsl-mode . [(20170927 1436) nil "major mode for Open GLSL shader files" single ((:commit . "384968506cf25c5c2df61b32fdfdbd041e3bf651") (:keywords "languages") (:url . "http://artis.inrialpes.fr/~Xavier.Decoret/resources/glsl-mode/"))]) (opencl-mode . [(20170816 1249) nil "Syntax coloring for opencl kernels" single ((:commit . "6e69434d0fa6e11a542acad370611bba18d3bc5c") (:keywords "c" "opencl") (:authors ("Salmane Bah" . "salmane.bah@u-bordeaux.fr")) (:maintainer "Salmane Bah" . "salmane.bah@u-bordeaux.fr") (:url . "https://github.com/salmanebah/opencl-mode"))]) (nasm-mode . [(20180711 1909) ((emacs (24 3))) "NASM x86 assembly major mode" single ((:commit . "1d4871ef184fc5da792bccbae1ea189f876706fc") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/nasm-mode"))]) (x86-lookup . [(20180528 1635) ((emacs (24 3)) (cl-lib (0 3))) "jump to x86 instruction documentation" single ((:commit . "609b2ba70dc5a246ac9b4b5f89eb5ef4331519bf") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/x86-lookup"))]) (company-go . [(20180427 1856) ((company (0 8 0)) (go-mode (1 0 0))) "company-mode backend for Go (using gocode)" single ((:commit . "6730ddbe5142ea62dc8fe415bb1909d2966f7d9e") (:keywords "languages") (:authors ("nsf" . "no.smile.face@gmail.com")) (:maintainer "nsf" . "no.smile.face@gmail.com"))]) (flycheck-gometalinter . [(20180424 941) ((emacs (24)) (flycheck (0 22))) "flycheck checker for gometalinter" single ((:commit . "422f6e4b77b27fd7370f0c88437ac5072c9d3413") (:keywords "convenience" "tools" "go") (:authors ("Diep Pham" . "me@favadi.com")) (:maintainer "Diep Pham" . "me@favadi.com") (:url . "https://github.com/favadi/flycheck-gometalinter"))]) (flycheck-golangci-lint . [(20180711 817) ((emacs (24)) (flycheck (0 22))) "Flycheck checker for golangci-lint" single ((:commit . "b4b51aa6fe5335c0f46f2f83c7dc32e4141ff9f1") (:keywords "convenience" "tools" "go") (:authors ("Wei Jian Gan" . "weijiangan@outlook.com")) (:maintainer "Wei Jian Gan" . "weijiangan@outlook.com") (:url . "https://github.com/weijiangan/flycheck-golangci-lint"))]) (go-eldoc . [(20170305 1427) ((emacs (24 3)) (go-mode (1 0 0))) "eldoc for go-mode" single ((:commit . "cbbd2ea1e94a36004432a9ac61414cb5a95a39bd") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-eldoc"))]) (go-fill-struct . [(20171225 331) ((emacs (24))) "Fill struct for golang." single ((:commit . "a613d0b378473eef39e8fd5724abe790aea84321") (:keywords "tools") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:url . "https://github.com/s-kostyaev/go-fill-struct"))]) (go-gen-test . [(20171023 358) ((emacs (24 3)) (s (1 12))) "Generate tests for go code with gotests" single ((:commit . "44c202ac97e728e93a35cee028a0ea8dd6e4292c") (:keywords "languages") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:url . "https://github.com/s-kostyaev/go-gen-test"))]) (go-guru . [(20181012 330) ((go-mode (1 3 1)) (cl-lib (0 5))) "Integration of the Go 'guru' analysis tool into Emacs." single ((:commit . "120fb911f1d8038f828da85eed8aaad977dabd8c") (:keywords "tools"))]) (go-impl . [(20170125 1552) ((emacs (24 3)) (go-mode (1 3 0))) "impl integration for go-mode" single ((:commit . "69f0d0ef05771487e15abec500cd06befd171abf") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-impl"))]) (go-rename . [(20180627 648) ((go-mode (1 3 1))) "Integration of the 'gorename' tool into Emacs." single ((:commit . "120fb911f1d8038f828da85eed8aaad977dabd8c") (:keywords "tools"))]) (go-mode . [(20181012 329) nil "Major mode for the Go programming language" single ((:commit . "120fb911f1d8038f828da85eed8aaad977dabd8c") (:keywords "languages" "go") (:authors ("The go-mode Authors")) (:maintainer "The go-mode Authors") (:url . "https://github.com/dominikh/go-mode.el"))]) (go-tag . [(20180227 411) ((emacs (24 0)) (go-mode (1 5 0))) "Edit Golang struct field tag" single ((:commit . "59b243f2fa079d9de9d56f6e2d94397e9560310a") (:keywords "tools") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/emacs-go-tag"))]) (godoctor . [(20180710 2152) nil "Frontend for godoctor" single ((:commit . "4b45ff3d0572f0e84056e4c3ba91fcc178199859") (:keywords "go" "golang" "refactoring") (:authors ("Sangho Na" . "microamp@protonmail.com")) (:maintainer "Sangho Na" . "microamp@protonmail.com") (:url . "https://github.com/microamp/godoctor.el"))]) (lsp-go . [(20180914 515) ((lsp-mode (3 0))) "Go support for lsp-mode" single ((:commit . "2327556e78682770a7a434610b08115f20ea5b1a") (:keywords "go" "golang") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-go"))]) (faceup . [(20170925 1946) nil "Markup language for faces and font-lock regression testing" single ((:commit . "6c92dad56a133e14e7b27831e1bcf9b3a71ff154") (:keywords "faces" "languages") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/faceup"))]) (racket-mode . [(20181117 229) ((emacs (24 3)) (faceup (0 0 2)) (s (1 9 0))) "Major mode for Racket language." tar ((:commit . "dd51668ad9d5293c5eb57f37bbc4c25a201ba467") (:authors ("Greg Hendershott")) (:maintainer "Greg Hendershott") (:url . "https://github.com/greghendershott/racket-mode"))]) (arduino-mode . [(20180509 36) ((emacs (25)) (cl-lib (0 5)) (spinner (1 7 3))) "Major mode for editing Arduino code." tar ((:commit . "e39cb1c02acb6676aea35f93fbd0d86badce6a38") (:keywords "languages" "arduino") (:maintainer "stardiviner" . "numbchild@gmail.com") (:url . "https://github.com/stardiviner/arduino-mode"))]) (kivy-mode . [(20180702 2029) nil "Emacs major mode for editing Kivy files" single ((:commit . "372b81964f55d2ca74641944ab8c908172306e59") (:authors ("Dean Serenevy" . "dean@serenevy.net")) (:maintainer "Dean Serenevy" . "dean@serenevy.net"))]) (matlab-mode . [(20180928 1526) nil "Major mode for MATLAB(R) dot-m files" tar ((:commit . "3fbca4259b2584bde08df07ba51944d7e3e2b4f4") (:url . "http://sourceforge.net/projects/matlab-emacs/") (:keywords "matlab" "programming" "language" "(X)emacs"))]) (pkgbuild-mode . [(20181116 1331) ((emacs (25 1))) "Interface to the ArchLinux package manager" single ((:commit . "c27b65c3deb116b296cef013f342159d9dec5c11") (:keywords "languages") (:authors ("Juergen Hoetzel" . "juergen@hoetzel.info")) (:maintainer "Juergen Hoetzel" . "juergen@hoetzel.info") (:url . "https://github.com/juergenhoetzel/pkgbuild-mode"))]) (qml-mode . [(20161016 31) nil "Major mode for editing QT Declarative (QML) code." single ((:commit . "6c5f33ba88ae010bf201a80ee8095e20a724558c") (:keywords "qml" "qt" "qt declarative") (:authors ("Yen-Chin Lee" . "coldnew.tw@gmail.com")) (:maintainer "Yen-Chin Lee" . "coldnew.tw@gmail.com") (:url . "https://github.com/coldnew/qml-mode"))]) (scad-mode . [(20180109 209) nil "A major mode for editing OpenSCAD code" single ((:commit . "d4d3504975f9bd08c09e10db665de3fc83542747") (:keywords "languages") (:authors ("Len Trigg, Åukasz Stelmach")) (:maintainer "Len Trigg" . "lenbok@gmail.com") (:url . "https://raw.github.com/openscad/openscad/master/contrib/scad-mode.el"))]) (stan-mode . [(20180110 2241) nil "Major mode for editing Stan files" tar ((:commit . "a8e88473ef996b455523dc3fbcf2d8520659652f") (:keywords "languanges") (:authors ("Jeffrey Arnold" . "jeffrey.arnold@gmail.com") ("Daniel Lee" . "bearlee@alum.mit.edu")) (:maintainer "Jeffrey Arnold" . "jeffrey.arnold@gmail.com") (:url . "http://github.com/stan-dev/stan-mode"))]) (thrift . [(20180905 1050) ((emacs (24))) "major mode for fbthrift and Apache Thrift files" single ((:commit . "c272a9a7abcea8a07bc4eebc308abaab6b1755d6") (:keywords "languages"))]) (vala-mode . [(20150324 2225) nil "Vala mode derived mode" single ((:commit . "fb2871a4492d75d03d72e60474919ab89adb267b") (:keywords "vala" "languages" "oop") (:authors ("2005 Dylan R. E. Moonfire") (" 2008 Étienne BERSAC")) (:maintainer "Étienne BERSAC" . "bersace03@laposte.net"))]) (vala-snippets . [(20150429 352) ((yasnippet (0 8 0))) "Yasnippets for Vala" tar ((:commit . "671439501060449bd100b9fffd524a86064fbfbb") (:authors ("Daniel Gopar")) (:maintainer "Daniel Gopar") (:url . "https://github.com/gopar/vala-snippets"))]) (wolfram-mode . [(20180307 13) ((emacs (24 3))) "Mathematica editing and inferior mode." single ((:commit . "be680190cac6ccf579dbce107deaae495928d1b3") (:keywords "languages" "processes" "tools") (:authors ("Daichi Mochihashi ")) (:maintainer "Daichi Mochihashi ") (:url . "https://github.com/kawabata/wolfram-mode/"))]) (flycheck-nim . [(20160715 428) ((dash (2 4 0)) (flycheck (0 20))) "Defines a flycheck syntax checker for nim" single ((:commit . "6d27349b66e44578851e6148299709d64d2bde41") (:authors ("Adam Schwalm" . "adamschwalm@gmail.com")) (:maintainer "Adam Schwalm" . "adamschwalm@gmail.com") (:url . "https://github.com/ALSchwalm/flycheck-nim"))]) (flycheck-nimsuggest . [(20171027 2208) ((flycheck (0 23)) (emacs (24 3))) "flycheck backend for Nim using nimsuggest" single ((:commit . "dc9a5de1cb3ee05db5794d824610959a1f603bc9") (:authors ("Yuta Yamada ")) (:maintainer "Yuta Yamada ") (:url . "https://github.com/yuutayamada/flycheck-nimsuggest"))]) (commenter . [(20160219 1627) ((emacs (24 4)) (let-alist (1 0 4))) "multiline-comment support package" single ((:commit . "6d1885419434ba779270c6fda0e30d390bb074bd") (:keywords "comment") (:authors ("Yuta Yamada ")) (:maintainer "Yuta Yamada ") (:url . "https://github.com/yuutayamada/commenter"))]) (nim-mode . [(20181028 1713) ((emacs (24 4)) (epc (0 1 1)) (let-alist (1 0 1)) (commenter (0 5 1)) (flycheck-nimsuggest (0 8 1))) "A major mode for the Nim programming language" tar ((:commit . "2acb601e6b3bf81f2fe29cfa1f3967e81bd12564") (:keywords "nim" "languages") (:authors ("Simon Hafner")) (:maintainer "Simon Hafner" . "hafnersimon@gmail.com"))]) (hy-mode . [(20180702 1940) ((dash (2 13 0)) (dash-functional (1 2 0)) (s (1 11 0)) (emacs (24))) "Major mode for Hylang" single ((:commit . "71a12a9208c4b87859bcbb6978e7915dd518e8dd") (:keywords "languages" "lisp" "python") (:url . "http://github.com/hylang/hy-mode"))]) (ob-hy . [(20180702 540) ((emacs (24 4))) "org-babel functions for Hy-lang evaluation" tar ((:commit . "a42ecaf440adc03e279afe43ee5ef6093ddd542a") (:keywords "hy" "literate programming" "reproducible research") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/ob-hy"))]) (pyenv-mode . [(20170801 2348) ((pythonic (0 1 0))) "Integrate pyenv with python-mode" single ((:commit . "eabb1c66f9e0c0500fef4d089508aad246d81dc0") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/pyenv-mode"))]) (pyvenv . [(20180831 847) nil "Python virtual environment interface" single ((:commit . "921ae2356b6a111ac0b7e44fd04cba8e95cbe936") (:keywords "python" "virtualenv" "tools") (:authors ("Jorgen Schaefer" . "contact@jorgenschaefer.de")) (:maintainer "Jorgen Schaefer" . "contact@jorgenschaefer.de") (:url . "http://github.com/jorgenschaefer/pyvenv"))]) (cython-mode . [(20180213 1654) nil "Major mode for editing Cython files" single ((:commit . "97f5e715acf082cb013169b57966f37708a717ee"))]) (helm-cscope . [(20170326 722) ((xcscope (1 0)) (helm (1 6 7)) (cl-lib (0 5)) (emacs (24 1))) "Helm interface for xcscope.el." single ((:commit . "3cc7259ab4989f9f7ca039e703cdac14b907530a") (:keywords "cscope" "helm") (:authors ("alpha22jp" . "alpha22jp@gmail.com")) (:maintainer "alpha22jp" . "alpha22jp@gmail.com") (:url . "https://github.com/alpha22jp/helm-cscope.el"))]) (helm-pydoc . [(20160918 542) ((helm-core (2 0)) (emacs (24 4))) "pydoc with helm interface" tar ((:commit . "85480a29b56dacde425655bc8f5a597c785afdf5") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-pydoc"))]) (epc . [(20140610 534) ((concurrent (0 3 1)) (ctable (0 1 2))) "A RPC stack for the Emacs Lisp" tar ((:commit . "e1bfa5ca163273859336e3cc89b4b6460f7f8cda") (:keywords "lisp" "rpc") (:authors ("SAKURAI Masashi ")) (:maintainer "SAKURAI Masashi ") (:url . "https://github.com/kiwanami/emacs-epc"))]) (concurrent . [(20161229 330) ((emacs (24 3)) (deferred (0 5 0))) "Concurrent utility functions for emacs lisp" single ((:commit . "2239671d94b38d92e9b28d4e12fd79814cfb9c16") (:keywords "deferred" "async" "concurrent") (:authors ("SAKURAI Masashi ")) (:maintainer "SAKURAI Masashi ") (:url . "https://github.com/kiwanami/emacs-deferred/blob/master/README-concurrent.markdown"))]) (importmagic . [(20180520 303) ((f (0 11 0)) (epc (0 1 0)) (emacs (24 3))) "Fix Python imports using importmagic." tar ((:commit . "bbc131278f8cd62f3e71b6f4a86b0c91792a3524") (:keywords "languages" "convenience") (:authors ("Nicolás Salas V." . "nikosalas@gmail.com")) (:maintainer "Nicolás Salas V." . "nikosalas@gmail.com") (:url . "https://github.com/anachronic/importmagic.el"))]) (live-py-mode . [(20181116 536) ((emacs (24 3))) "Live Coding in Python" tar ((:commit . "e823a86707a5821ad761fd27a9c9e90ac47d2319") (:keywords "live" "coding") (:authors ("Don Kirkby http://donkirkby.github.io")) (:maintainer "Don Kirkby http://donkirkby.github.io") (:url . "http://donkirkby.github.io/live-py-plugin/"))]) (nose . [(20140520 1648) nil "Easy Python test running in Emacs" single ((:keywords "nose" "python" "testing"))]) (pip-requirements . [(20181027 1629) ((dash (2 8 0))) "A major mode for editing pip requirements files." single ((:commit . "216cd1690f80cc965d4ae47b8753fc185f778ff6") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (pipenv . [(20180719 547) ((emacs (25 1)) (f (0 19 0)) (s (1 12 0))) "A Pipenv porcelain." single ((:commit . "5582bf60577de74e6301871c6b77ac86b6ce1970") (:authors ("Paul Walsh" . "paulywalsh@gmail.com")) (:maintainer "Paul Walsh" . "paulywalsh@gmail.com") (:url . "https://github.com/pwalsh/pipenv.el"))]) (pippel . [(20180710 856) ((emacs (25 1)) (s (1 11 0)) (dash (2 12 0))) "Frontend to python package manager pip" tar ((:commit . "21a5200e8e5ccaa1911abb4ebf090b76ca839756") (:authors ("Fritz Stelzer" . "brotzeitmacher@gmail.com")) (:maintainer "Fritz Stelzer" . "brotzeitmacher@gmail.com") (:url . "https://github.com/brotzeitmacher/pippel"))]) (py-isort . [(20160925 1018) nil "Use isort to sort the imports in a Python buffer" single ((:commit . "e67306f459c47c53a65604e4eea88a3914596560") (:authors ("Friedrich Paetzke" . "paetzke@fastmail.fm")) (:maintainer "Friedrich Paetzke" . "paetzke@fastmail.fm") (:url . "http://paetzke.me/project/py-isort.el"))]) (pytest . [(20181005 1524) ((s (1 9 0))) "Easy Python test running in Emacs" single ((:commit . "1bfa7549001e61ecd59cd6eae7c6656a924d1ba4") (:keywords "pytest" "python" "testing") (:url . "https://github.com/ionrock/pytest-el"))]) (python . [(0 26 1) ((emacs (24 1)) (cl-lib (1 0))) "Python's flying circus support for Emacs" single ((:url . "https://github.com/fgallina/python.el") (:keywords "languages"))]) (stickyfunc-enhance . [(20150429 1814) ((emacs (24 3))) "An enhancement to stock `semantic-stickyfunc-mode'" single ((:commit . "13bdba51fcd83ccbc3267959d23afc94d458dcb0") (:keywords "c" "languages" "tools") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:url . "https://github.com/tuhdo/semantic-stickyfunc-enhance"))]) (yapfify . [(20180830 733) nil "(automatically) format python buffers using YAPF." single ((:commit . "b858225e1debe6734ee718e5c3c209152652a8b3") (:authors ("Joris Engbers" . "info@jorisengbers.nl")) (:maintainer "Joris Engbers" . "info@jorisengbers.nl") (:url . "https://github.com/JorisE/yapfify"))]) (anaconda-mode . [(20181030 2109) ((emacs (25)) (pythonic (0 1 0)) (dash (2 6 0)) (s (1 9)) (f (0 16 2))) "Code navigation, documentation lookup and completion for Python" single ((:commit . "21a6218c2299575c82573a5c2c773d72b0f8be0d") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/anaconda-mode"))]) (pythonic . [(20180920 2315) ((emacs (25)) (s (1 9)) (f (0 17 2))) "Utility functions for writing pythonic emacs package." single ((:commit . "6a5a2a365e4ea6fc5adfa96359418c437aa351c8") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/pythonic"))]) (company-anaconda . [(20181025 1305) ((company (0 8 0)) (anaconda-mode (0 1 1)) (cl-lib (0 5 0)) (dash (2 6 0)) (s (1 9))) "Anaconda backend for company-mode" single ((:commit . "0ab70de1740e67cee451abcf3685c7525ff9e95a") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/anaconda-mode"))]) (lsp-python . [(20181108 754) ((lsp-mode (3 0))) "Python support for lsp-mode" single ((:commit . "9b67b63c4c8c53c77eda8b8081b8d458e655ba55") (:keywords "python") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-python"))]) (eval-sexp-fu . [(20180510 203) ((cl-lib (0)) (highlight (0))) "Tiny functionality enhancements for evaluating sexps." single ((:commit . "1cfd0f3e167d63080692fad97ffe0091b024ad73") (:keywords "lisp" "highlight" "convenience") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net"))]) (cider-eval-sexp-fu . [(20160907 800) ((emacs (24)) (highlight (0)) (eval-sexp-fu (0 4 0))) "Briefly highlights an evaluated sexp." single ((:commit . "5687e7b33e17f2be40b036dac82da4a5bc6705fb") (:keywords "languages" "clojure" "cider") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com"))]) (inflections . [(20170913 916) ((cl-lib (0 5)) (emacs (24))) "convert english words between singular and plural" single ((:commit . "e4f1372cf22e811faca52fc86bdd5d817498a4d8") (:keywords "languages" "tools" "wp") (:authors ("Dmitry Galinsky, Howard Yeh")) (:maintainer "Dmitry Galinsky, Howard Yeh") (:url . "https://github.com/eschulte/jump.el"))]) (edn . [(20160215 1219) ((cl-lib (0 3)) (emacs (24 1)) (peg (0 6))) "Support for reading and writing the edn data format from elisp" single ((:commit . "be9e32d1b49e35247b263b0243df7cfdc8d413ab") (:keywords "edn" "clojure") (:authors ("Lars Andersen" . "expez@expez.com")) (:maintainer "Lars Andersen" . "expez@expez.com") (:url . "https://www.github.com/expez/edn.el"))]) (paredit . [(20171127 205) nil "minor mode for editing parentheses" single ((:commit . "acbe10fdd85d2e91831adf70b6a828bc7e900da0") (:keywords "lisp") (:authors ("Taylor R. Campbell" . "campbell+paredit@mumble.net")) (:maintainer "Taylor R. Campbell" . "campbell+paredit@mumble.net"))]) (peg . [(20150708 641) nil "Parsing Expression Grammars in Emacs Lisp" single ((:commit . "081efeca91d790c7fbc90871ac22c40935f4833b"))]) (clj-refactor . [(20180826 2149) ((emacs (25 1)) (seq (2 19)) (yasnippet (0 6 1)) (paredit (24)) (multiple-cursors (1 2 2)) (clojure-mode (5 6 1)) (cider (0 17 0)) (edn (1 1 2)) (inflections (2 3)) (hydra (0 13 2))) "A collection of commands for refactoring Clojure code" tar ((:commit . "ec158357c4f7a375bc47f89de71ea28028a3bfa0") (:keywords "convenience" "clojure" "cider") (:authors ("Magnar Sveen" . "magnars@gmail.com") ("Lars Andersen" . "expez@expez.com") ("Benedek Fazekas" . "benedek.fazekas@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (clojure-cheatsheet . [(20180201 804) ((helm (1 7 7)) (cider (0 9 0))) "The Clojure Cheatsheet for Emacs" single ((:commit . "85c382317a56bbdfac03ae95999c28fc0cde65d7") (:keywords "clojure" "cider" "cheatsheet" "helm") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:url . "https://github.com/clojure-emacs/clojure-cheatsheet"))]) (clojure-snippets . [(20180314 1308) ((yasnippet (0 10 0))) "Yasnippets for clojure" tar ((:commit . "6068dca90467a0f4ebc2cd39338a173d6f5ddc04"))]) (cider . [(20181110 1413) ((emacs (25)) (clojure-mode (5 9)) (pkg-info (0 4)) (queue (0 2)) (spinner (1 7)) (seq (2 16)) (sesman (0 3 2))) "Clojure Interactive Development Environment that Rocks" tar ((:commit . "3a520ec76cdd5509bf231e49809715f20a87d74b") (:keywords "languages" "clojure" "cider") (:authors ("Tim King" . "kingtim@gmail.com") ("Phil Hagelberg" . "technomancy@gmail.com") ("Bozhidar Batsov" . "bozhidar@batsov.com") ("Artur Malabarba" . "bruce.connor.am@gmail.com") ("Hugo Duncan" . "hugo@hugoduncan.org") ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "http://www.github.com/clojure-emacs/cider"))]) (sesman . [(20181109 1100) ((emacs (25))) "Generic Session Manager" tar ((:commit . "2a1a9a4ccfd88127e13f2655ac130c82fe84f2f7") (:keywords "process") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/vspinu/sesman"))]) (queue . [(0 2) nil "Queue data structure" single ((:url . "http://www.dr-qubit.org/emacs.php") (:keywords "extensions" "data structures" "queue"))]) (clojure-mode . [(20181024 2224) ((emacs (25 1))) "Major mode for Clojure code" single ((:commit . "71b32ee95e8ec99098e212cd0ec74cb4c002e8c6") (:keywords "languages" "clojure" "clojurescript" "lisp") (:url . "http://github.com/clojure-emacs/clojure-mode"))]) (sayid . [(20181024 1838) ((cider (0 14 0))) "sayid nREPL middleware client" single ((:commit . "078378240277160b00d332065d8325e713c0b526") (:authors ("Bill Piel" . "bill@billpiel.com")) (:maintainer "Bill Piel" . "bill@billpiel.com") (:url . "https://github.com/clojure-emacs/sayid"))]) (elixir-mode . [(20180711 1245) ((emacs (24)) (pkg-info (0 4))) "Major mode for editing Elixir files" tar ((:commit . "bfd09392a0253e4b96c642472e5d5b757a5254f8") (:keywords "languages" "elixir") (:url . "https://github.com/elixir-lang/emacs-elixir"))]) (flycheck-mix . [(20170118 1430) ((flycheck (27)) (elixir-mode (1 8 0))) "Elixir mix flycheck integration" single ((:commit . "76684d4b5987925b98b254aab656f8bf8198ab88") (:keywords "elixir" "flycheck" "mix") (:authors ("Tomasz Kowal" . "tomekowal@gmail.com")) (:maintainer "Tomasz Kowal" . "tomekowal@gmail.com") (:url . "https://github.com/tomekowal/flycheck-mix"))]) (flycheck-credo . [(20170526 1545) ((flycheck (29))) "flycheck checker for elixir credo" single ((:commit . "e88f11ead53805c361ec7706e44c3dfee1daa19f") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/flycheck-credo"))]) (ob-elixir . [(20170725 1419) ((org (8))) "org-babel functions for elixir evaluation" single ((:commit . "8990a8178b2f7bd93504a9ab136622aab6e82e32") (:keywords "org" "babel" "elixir") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-elixir"))]) (clang-format . [(20180406 1514) ((cl-lib (0 3))) "Format code using clang-format" single ((:commit . "5556c31528af2661bed3011bd63ffc0ed44e18a0") (:keywords "tools" "c"))]) (company-c-headers . [(20180814 1730) ((emacs (24 1)) (company (0 8))) "Company mode backend for C/C++ header files" single ((:commit . "41331192b3961c8e3a51540678e1d11eaa346f03") (:keywords "development" "company") (:authors ("Alastair Rankine" . "alastair@girtby.net")) (:maintainer "Alastair Rankine" . "alastair@girtby.net"))]) (company-rtags . [(20180730 338) ((emacs (24 3)) (company (0 8 1)) (rtags (2 10))) "RTags back-end for company" single ((:commit . "6aa45cb37524fad6250ac4694b4a96c53eb29d0e") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (company-ycmd . [(20180520 1053) ((ycmd (1 3)) (company (0 9 3)) (deferred (0 5 1)) (s (1 11 0)) (dash (2 13 0)) (let-alist (1 0 5)) (f (0 19 0))) "company-mode backend for ycmd" single ((:commit . "ef87d020d3314efbac2e8925c115d0ac5c128c2a") (:url . "https://github.com/abingham/emacs-ycmd"))]) (disaster . [(20171016 2152) nil "Disassemble C/C++ code under cursor in Emacs" single ((:commit . "10a785facc60d89d78e0d5177985ab1af1741bb4") (:keywords "tools") (:authors ("Justine Tunney" . "jtunney@gmail.com")) (:maintainer "Justine Tunney" . "jtunney@gmail.com") (:url . "https://github.com/jart/disaster"))]) (flycheck-rtags . [(20180619 824) ((emacs (24)) (flycheck (0 23)) (rtags (2 10))) "RTags Flycheck integration." single ((:commit . "6aa45cb37524fad6250ac4694b4a96c53eb29d0e") (:authors ("Christian Schwarzgruber" . "c.schwarzgruber.cs@gmail.com")) (:maintainer "Christian Schwarzgruber" . "c.schwarzgruber.cs@gmail.com") (:url . "http://rtags.net"))]) (google-c-style . [(20180130 1736) nil "Google's C/C++ style for c-mode" single ((:commit . "ad22a7536d9cbc552c2d265d5df18be9b1b24faa") (:keywords "c" "tools"))]) (helm-rtags . [(20170813 411) ((helm (2 0)) (rtags (2 10))) "A front-end for rtags" single ((:commit . "6aa45cb37524fad6250ac4694b4a96c53eb29d0e") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (ivy-rtags . [(20170523 454) ((ivy (0 7 0)) (rtags (2 10))) "RTags completion back-end for ivy" single ((:commit . "6aa45cb37524fad6250ac4694b4a96c53eb29d0e") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (rtags . [(20181117 2108) nil "A front-end for rtags" single ((:commit . "6aa45cb37524fad6250ac4694b4a96c53eb29d0e") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (cquery . [(20180811 2131) ((emacs (25 1)) (lsp-mode (3 4)) (dash (0 13))) "cquery client for lsp-mode" tar ((:commit . "a803e92e77e1ffc74c13a753c1eb4f6f47127a97") (:keywords "languages" "lsp" "c++") (:authors ("Tobias Pisani")) (:maintainer "Tobias Pisani") (:url . "https://github.com/jacobdufault/cquery"))]) (ccls . [(20181106 546) ((emacs (25 1)) (lsp-mode (4 2)) (dash (0 14)) (projectile (1 0 0))) "ccls client for lsp-mode" tar ((:commit . "07ad553950e69f862f7c74c9b1f02c00ab450d22") (:keywords "languages" "lsp" "c++") (:authors ("Tobias Pisani, Fangrui Song")) (:maintainer "Tobias Pisani, Fangrui Song") (:url . "https://github.com/MaskRay/emacs-ccls"))]) (company-emoji . [(20180925 2008) ((cl-lib (0 5)) (company (0 8 0))) "company-mode backend for emoji" tar ((:commit . "f0d91d5be0077b20b418a3ba37d36f431fae322f") (:keywords "emoji" "company") (:authors ("Alex Dunn" . "dunn.alex@gmail.com")) (:maintainer "Alex Dunn" . "dunn.alex@gmail.com") (:url . "https://github.com/dunn/company-emoji.git"))]) (emoji-cheat-sheet-plus . [(20150617 1331) ((emacs (24)) (helm (1 6 4))) "emoji-cheat-sheet for emacs" tar ((:commit . "96a003127d646a2683d81ca906a17eace0a6413e") (:keywords "emacs" "emoji") (:authors ("Sylvain Benner (based on the work of Shingo Fukuyama)")) (:maintainer "Sylvain Benner (based on the work of Shingo Fukuyama)") (:url . "https://github.com/syl20bnr/emacs-emoji-cheat-sheet-plus"))]) (gh-md . [(20151207 1740) ((emacs (24))) "Render markdown using the Github api" single ((:commit . "693cb0dcadff70e813e1a9d303d227aff7898557") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/gh-md.el"))]) (markdown-toc . [(20170711 1949) ((s (1 9 0)) (dash (2 11 0)) (markdown-mode (2 1))) "A simple TOC generator for markdown file" tar ((:commit . "7038f4f6d5c2bc7e4aea89699a607ac2b7dd16a8"))]) (vmd-mode . [(20180223 1356) ((emacs (24 3))) "Fast Github-flavored Markdown preview using a vmd subprocess." single ((:commit . "24e38a20951dfad6e3e985c7cc6286c1e271da5f") (:keywords "markdown" "preview" "live" "vmd") (:authors ("Blake Miller" . "blak3mill3r@gmail.com")) (:maintainer "Blake Miller" . "blak3mill3r@gmail.com") (:url . "https://github.com/blak3mill3r/vmd-mode"))]) (auctex-latexmk . [(20170618 1636) ((auctex (11 87))) "Add LatexMk support to AUCTeX" single ((:commit . "4d353522650d7685acbf1d38f7dbc504f734bd84") (:keywords "tex") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/auctex-latexmk/"))]) (auctex . [(12 1 1) nil "Integrated environment for *TeX*" tar ((:url . "http://www.gnu.org/software/auctex/"))]) (company-auctex . [(20180725 1912) ((yasnippet (0 8 0)) (company (0 8 0)) (auctex (11 87))) "Company-mode auto-completion for AUCTeX" single ((:commit . "48c42c58ce2f0e693301b0cb2d085055410c1b25") (:authors ("Christopher Monsanto , Alexey Romanov" . "alexey.v.romanov@gmail.com")) (:maintainer "Christopher Monsanto , Alexey Romanov" . "alexey.v.romanov@gmail.com") (:url . "https://github.com/alexeyr/company-auctex/"))]) (magic-latex-buffer . [(20170531 5) ((cl-lib (0 5)) (emacs (24 3))) "Magically enhance LaTeX-mode font-locking for semi-WYSIWYG editing" single ((:commit . "c03277d5619d9adcd871f3e6480a1a27985810cb") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (typo . [(20171209 1023) nil "Minor mode for typographic editing" single ((:commit . "9dad93b6f367f02f52c8d9bf15d446d922cec294") (:keywords "convenience" "wp") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:url . "https://github.com/jorgenschaefer/typoel"))]) (tide . [(20181025 1201) ((dash (2 10 0)) (s (1 11 0)) (flycheck (27)) (typescript-mode (0 1)) (cl-lib (0 5))) "Typescript Interactive Development Environment" tar ((:commit . "b2af64e5926b9c1493f7e39d5e928d61975816fb") (:keywords "typescript") (:authors ("Anantha kumaran" . "ananthakumaran@gmail.com")) (:maintainer "Anantha kumaran" . "ananthakumaran@gmail.com") (:url . "http://github.com/ananthakumaran/tide"))]) (typescript-mode . [(20181018 553) nil "Major mode for editing typescript" tar ((:commit . "fbaad515c90df0f5c3634c471034e3041a4a8cfc") (:keywords "typescript" "languages") (:url . "http://github.com/ananthakumaran/typescript.el"))]) (web-mode . [(20181104 2004) ((emacs (23 1))) "major mode for editing web templates" single ((:commit . "29ced993bb1a435bd82d3e7395bed13b99e87de4") (:keywords "languages") (:authors ("François-Xavier Bois ")) (:maintainer "François-Xavier Bois") (:url . "http://web-mode.org"))]) (cargo . [(20181112 722) ((emacs (24 3)) (rust-mode (0 2 0)) (markdown-mode (2 4))) "Emacs Minor Mode for Cargo, Rust's Package Manager." tar ((:commit . "f8504cd51021741a3931c28dc5e87cc16687420b") (:keywords "tools") (:authors ("Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com")) (:maintainer "Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com"))]) (racer . [(20181023 2304) ((emacs (24 3)) (rust-mode (0 2 0)) (dash (2 13 0)) (s (1 10 0)) (f (0 18 2)) (pos-tip (0 4 6))) "code completion, goto-definition and docs browsing for Rust via racer" single ((:commit . "bf8f76f17c64eff2d6ca6029ee0ab7a466590128") (:keywords "abbrev" "convenience" "matching" "rust" "tools") (:authors ("Phil Dawes")) (:maintainer "Phil Dawes") (:url . "https://github.com/racer-rust/emacs-racer"))]) (flycheck-rust . [(20180904 1117) ((emacs (24 1)) (flycheck (28)) (dash (2 13 0)) (seq (2 3)) (let-alist (1 0 4))) "Flycheck: Rust additions and Cargo support" single ((:commit . "f1220ccd9acbdb2556765f49f2f3dcb00dca2970") (:keywords "tools" "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-rust"))]) (toml-mode . [(20161107 1800) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing TOML files" single ((:commit . "f6c61817b00f9c4a3cab1bae9c309e0fc45cdd06") (:keywords "data" "toml") (:authors ("Felix Chern" . "idryman@gmail.com")) (:maintainer "Felix Chern" . "idryman@gmail.com") (:url . "https://github.com/dryman/toml-mode.el"))]) (rust-mode . [(20181008 1628) ((emacs (24 0))) "A major emacs mode for editing Rust source code" single ((:commit . "12cb16964ce01f0e484b082ccc8a3430cc1c4158") (:keywords "languages") (:authors ("Mozilla")) (:maintainer "Mozilla") (:url . "https://github.com/rust-lang/rust-mode"))]) (lsp-rust . [(20180305 1308) ((emacs (25)) (lsp-mode (3 0)) (rust-mode (0 3 0)) (dash (1 0)) (markdown-mode (2 3))) "Rust support for lsp-mode" single ((:commit . "ecc889cc8735b280e0e6e84d2f4526b0048148b3") (:keywords "rust") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-rust"))]) (purescript-mode . [(20181028 838) ((cl-lib (0 6))) "A PureScript editing mode" tar ((:commit . "a6c7e4cc5ea29cf96478490a57d495e745d6e054"))]) (psci . [(20180418 1233) ((purescript-mode (13 10)) (dash (2 9 0)) (s (1 9 0)) (f (0 17 1))) "Major mode for purescript repl psci" tar ((:commit . "3f5ef1141a97c4b5507204d48e8aeccd553e4591") (:keywords "purescript" "psci" "repl" "major" "mode") (:authors ("Antoine R. Dumont ")) (:maintainer "Antoine R. Dumont ") (:url . "https://github.com/ardumont/emacs-psci"))]) (psc-ide . [(20181002 1319) ((dash (2 13 0)) (dash-functional (1 2 0)) (company (0 8 7)) (cl-lib (0 5)) (s (1 10 0)) (emacs (24 4)) (flycheck (0 24)) (let-alist (1 0 4)) (seq (1 11))) "Minor mode for PureScript's psc-ide tool." tar ((:commit . "01a158b77210fec9c1bfc0caffaf08fccc0412ac") (:keywords "languages") (:authors ("Erik Post" . "erik@shinsetsu.nl") ("Dmitry Bushenko" . "d.bushenko@gmail.com") ("Christoph Hegemann") ("Brian Sermons")) (:maintainer "Erik Post" . "erik@shinsetsu.nl") (:url . "https://github.com/epost/psc-ide-emacs"))]) (erlang . [(20181011 1236) ((emacs (24 1))) "Erlang major mode" tar ((:commit . "5873f86728d945be654e31d33fd72a9ecd9c6eaa"))]) (company-quickhelp . [(20180525 1003) ((emacs (24 3)) (company (0 8 9)) (pos-tip (0 4 6))) "Popup documentation for completion candidates" single ((:commit . "479676cade80a9f03802ca3d956591820ed5c537") (:keywords "company" "popup" "documentation" "quickhelp") (:authors ("Lars Andersen" . "expez@expez.com")) (:maintainer "Lars Andersen" . "expez@expez.com") (:url . "https://www.github.com/expez/company-quickhelp"))]) (fsharp-mode . [(20180518 1820) ((company (0 8 0)) (company-quickhelp (1 2 0)) (popup (0 5 3)) (pos-tip (0 4 5)) (s (1 3 1)) (dash (1 1 0)) (flycheck (0 25))) "F# mode for Emacs" tar ((:commit . "68d2121a7317d90fe3794c9295d117f4aebd1438"))]) (company-emacs-eclim . [(20180911 1121) ((eclim (0 3)) (company (0 7)) (cl-lib (0 5))) "Eclim company backend" single ((:commit . "23f5b294f833ce58516d7b9ae08a7792d70022a1"))]) (eclim . [(20181108 1134) ((dash (2 11 0)) (json (1 2)) (popup (0 5 2)) (s (1 9 0)) (cl-lib (0 5)) (yasnippet (0 10 0))) "An interface to the Eclipse IDE." tar ((:commit . "23f5b294f833ce58516d7b9ae08a7792d70022a1"))]) (ensime . [(20180615 1330) ((scala-mode (0 23)) (sbt-mode (0 2)) (yasnippet (0 10 0)) (company (0 9 0)) (dash (2 12 1)) (s (1 11 0)) (popup (0 5 3))) "ENhanced Scala Interaction Mode for Emacs" tar ((:commit . "34eb11dac3ec9d1c554c2e55bf056ece6983add7") (:keywords "languages") (:url . "https://github.com/ensime/ensime-emacs"))]) (gradle-mode . [(20150313 1905) ((s (1 8 0))) "Gradle integration with Emacs' compile" single ((:commit . "e4d665d5784ecda7ddfba015f07c69be3cfc45f2") (:keywords "gradle") (:authors ("Daniel Mijares" . "daniel.j.mijares@gmail.com")) (:maintainer "Daniel Mijares" . "daniel.j.mijares@gmail.com") (:url . "http://github.com/jacobono/emacs-gradle-mode"))]) (maven-test-mode . [(20141220 557) ((s (1 9)) (emacs (24))) "Utilities for navigating test files and running maven test tasks." single ((:commit . "a19151861df2ad8ae4880a2e7c86ddf848cb569a") (:keywords "java" "maven" "test") (:authors ("Renan Ranelli")) (:maintainer "Renan Ranelli") (:url . "http://github.com/rranelli/maven-test-mode"))]) (meghanada . [(20181116 1302) ((emacs (24 3)) (yasnippet (0 6 1)) (company (0 9 0)) (flycheck (0 23))) "A better java development mode" tar ((:commit . "4914ab1496d88251f179dc3b6158fc65e999804a") (:keywords "languages" "java") (:authors ("Yutaka Matsubara" . "yutaka.matsubara@gmail.com")) (:maintainer "Yutaka Matsubara" . "yutaka.matsubara@gmail.com") (:url . "https://github.com/mopemope/meghanada-emacs"))]) (mvn . [(20181002 1617) nil "helpers for compiling with maven" single ((:commit . "ffa40235b7dabb6c6c165f64f32a963cde8031f0") (:keywords "compilation" "maven" "java") (:authors ("Andrew Gwozdziewycz" . "git@apgwoz.com")) (:maintainer "Andrew Gwozdziewycz" . "git@apgwoz.com") (:url . "https://github.com/apgwoz/mvn-el"))]) (lsp-java . [(20181102 1943) ((emacs (25 1)) (lsp-mode (3 0)) (markdown-mode (2 3)) (dash (2 14 1)) (f (0 20 0)) (ht (2 0)) (dash-functional (1 2 0))) "Java support for lsp-mode" tar ((:commit . "7eebaf5d45763627a5e49180d9f76a82432d62e3") (:keywords "java") (:url . "https://github.com/emacs-lsp/lsp-java"))]) (elm-mode . [(20181114 2235) ((f (0 17)) (let-alist (1 0 5)) (seq (2 2)) (s (1 7 0)) (emacs (24 4)) (dash (2 13 0))) "Major mode for Elm" tar ((:commit . "a52c0c6216145ec1cf39d06541ad74f33f4816cc") (:authors ("Joseph Collard")) (:maintainer "Joseph Collard") (:url . "https://github.com/jcollard/elm-mode"))]) (elm-test-runner . [(20180918 2255) ((emacs (24 4))) "Enhanced support for running elm-test" single ((:commit . "73696add403cee6547fcb6eb4e49798e1583d0e2") (:authors ("Juan Edi")) (:maintainer "Juan Edi") (:url . "https://github.com/juanedi/elm-test-runner"))]) (flycheck-elm . [(20181107 146) ((flycheck (0 29 -4)) (emacs (24 4)) (let-alist (1 0 5)) (seq (2 20))) "Flycheck support for the elm language" single ((:commit . "debd0af563cb6c2944367a691c7fa3021d9378c1") (:authors ("Brian Sermons")) (:maintainer "Brian Sermons") (:url . "https://github.com/bsermons/flycheck-elm"))]) (web-completion-data . [(20160318 848) nil "Shared completion data for ac-html and company-web" tar ((:commit . "c272c94e8a71b779c29653a532f619acad433a4f") (:keywords "html" "auto-complete" "company") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:url . "https://github.com/osv/web-completion-data"))]) (company-web . [(20180402 1155) ((company (0 8 0)) (dash (2 8 0)) (cl-lib (0 5 0)) (web-completion-data (0 1 0))) "Company version of ac-html, complete for web,html,emmet,jade,slim modes" tar ((:commit . "f0cc9187c9c34f72ad71f5649a69c74f996bae9a") (:keywords "html" "company") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:url . "https://github.com/osv/company-web"))]) (counsel-css . [(20180302 1036) ((emacs (24 4)) (counsel (0 7 0)) (cl-lib (0 5))) "stylesheet-selector-aware swiper" single ((:commit . "0536af00236cdce1ed08b40dd46c917e8b4b8869") (:keywords "convenience" "tools" "counsel" "swiper" "selector" "css" "less" "scss") (:authors ("Henrik Lissner ")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-counsel-css"))]) (helm-css-scss . [(20140627 25) ((helm (1 0)) (emacs (24))) "CSS/SCSS/LESS Selectors with helm interface" single ((:commit . "ab8348aa98e0daa2f1b771e35bdb06bfacbe5016") (:keywords "scss" "css" "less" "selector" "helm") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:url . "https://github.com/ShingoFukuyama/helm-css-scss"))]) (impatient-mode . [(20181002 1231) ((cl-lib (0 3)) (simple-httpd (1 5 0)) (htmlize (1 40))) "Serve buffers live over HTTP" tar ((:commit . "96f6a05f8de74e19d570217fe83f0734623ddb0c") (:authors ("Brian Taylor" . "el.wubo@gmail.com")) (:maintainer "Brian Taylor" . "el.wubo@gmail.com") (:url . "https://github.com/netguy204/imp.el"))]) (less-css-mode . [(20161001 453) nil "Major mode for editing LESS CSS files (lesscss.org)" single ((:commit . "c7fa3d56d83206b28657f2e56439dc62280a2bf2") (:keywords "less" "css" "mode") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/less-css-mode"))]) (pug-mode . [(20180513 2126) ((emacs (24 4)) (cl-lib (0 5))) "Major mode for jade/pug template files" single ((:commit . "685fd3414d89736bf232f5d1a6bed9e0353b98fe") (:keywords "markup" "language" "jade" "pug") (:authors ("Nathan Weizenbaum")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-pug-mode"))]) (haml-mode . [(20170924 453) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing Haml files" single ((:commit . "1cbb2de8f0fc25f35448c5cad04642f28078f3bb") (:keywords "markup" "languages" "html") (:authors ("Natalie Weizenbaum")) (:maintainer "Natalie Weizenbaum") (:url . "https://github.com/nex3/haml-mode"))]) (sass-mode . [(20161007 626) ((haml-mode (3 0 15)) (cl-lib (0 5))) "Major mode for editing Sass files" single ((:commit . "37105f46f6ea3592039f2ea7d0463ae7f042616e") (:keywords "markup" "language" "css") (:authors ("Natalie Weizenbaum")) (:maintainer "Natalie Weizenbaum") (:url . "http://github.com/nex3/haml/tree/master"))]) (scss-mode . [(20180123 1708) nil "Major mode for editing SCSS files" single ((:commit . "cf58dbec5394280503eb5502938f3b5445d1b53d") (:keywords "scss" "css" "mode") (:authors ("Anton Johansson" . "anton.johansson@gmail.com")) (:maintainer "Anton Johansson" . "anton.johansson@gmail.com") (:url . "https://github.com/antonj/scss-mode"))]) (slim-mode . [(20170728 1348) nil "Major mode for editing Slim files" single ((:commit . "3636d18ab1c8b316eea71c4732eb44743e2ded87") (:keywords "markup" "language") (:authors ("Nathan Weizenbaum")) (:maintainer "Nathan Weizenbaum") (:url . "http://github.com/slim-template/emacs-slim"))]) (tagedit . [(20161121 855) ((s (1 3 1)) (dash (1 0 3))) "Some paredit-like features for html-mode" single ((:commit . "b3a70101a0dcf85498c92b7fcfa7fdbac869746c") (:keywords "convenience") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (flycheck-kotlin . [(20170122 1137) ((flycheck (0 18))) "Support kotlin in flycheck" single ((:commit . "cbb9fbf70dbe8efcc3971b3606ee95c97469b1fe") (:authors ("Elric Milon" . "whirm_REMOVETHIS__@gmx.com")) (:maintainer "Elric Milon" . "whirm_REMOVETHIS__@gmx.com"))]) (kotlin-mode . [(20181109 1818) ((emacs (24 3))) "Major mode for kotlin" single ((:commit . "666187a086c042e70b65b13ea83b34a493440d95") (:keywords "languages") (:authors ("Shodai Yokoyama" . "quantumcars@gmail.com")) (:maintainer "Shodai Yokoyama" . "quantumcars@gmail.com"))]) (flycheck-crystal . [(20180627 242) ((flycheck (30))) "Add support for Crystal to Flycheck" single ((:commit . "8649736fea8960a5e54c3ec934484f231a518ea5") (:keywords "tools" "crystal") (:url . "https://github.com/crystal-lang-tools/emacs-crystal-mode"))]) (crystal-mode . [(20180827 329) ((emacs (24 4))) "Major mode for editing Crystal files" single ((:commit . "8649736fea8960a5e54c3ec934484f231a518ea5") (:keywords "languages" "crystal") (:url . "https://github.com/crystal-lang-tools/emacs-crystal-mode"))]) (inf-crystal . [(20180119 211) ((emacs (24 3)) (crystal-mode (0 1 0))) "Run a Inferior-Crystal process in a buffer" single ((:commit . "02007b2a2a3bea44902d7c83c4acba1e39d278e3") (:keywords "languages" "crystal") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/inf-crystal.el"))]) (ob-crystal . [(20180126 718) ((emacs (24 3))) "org-babel functions for Crystal evaluation" tar ((:commit . "d84c1adee4b269cdba06a97caedb8071561a09af") (:keywords "crystal" "literate programming" "reproducible research") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/ob-crystal"))]) (play-crystal . [(20180114 1024) ((emacs (24 4)) (dash (2 12 0)) (request (0 2 0))) "https://play.crystal-lang.org integration." single ((:commit . "0b4810a9025213bd11dbcbfd38b3ca928829e0a5") (:keywords "convenience") (:authors ("Vitalii Elenhaupt")) (:maintainer "Vitalii Elenhaupt") (:url . "https://github.com/veelenga/play-crystal.el"))]) (cmm-mode . [(20150225 746) nil "Major mode for C-- source code" single ((:commit . "c3ad514dff3eb30434f6b20d953276d4c00de1ee"))]) (company-cabal . [(20170917 1317) ((cl-lib (0 5)) (company (0 8 0)) (emacs (24))) "company-mode cabal backend" tar ((:commit . "62112a7259e24bd6c08885629a185afe512b7d3d") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-cabal"))]) (company-ghci . [(20160311 200) ((company (0 8 11)) (haskell-mode (13))) "company backend which uses the current ghci process." single ((:commit . "c2d74a41166e76de2e78c87f582ba3a1179b2aa6") (:authors ("Hector Orellana" . "hofm92@gmail.com")) (:maintainer "Hector Orellana" . "hofm92@gmail.com"))]) (company-ghc . [(20170918 833) ((cl-lib (0 5)) (company (0 8 0)) (ghc (5 4 0 0)) (emacs (24))) "company-mode ghc-mod backend" single ((:commit . "8b264b5c3c0e42c0d0c4e9315559896c9b0edfdc") (:keywords "haskell" "completion") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-ghc"))]) (ghc . [(20180121 1218) ((haskell-mode (13 0))) "Sub mode for Haskell mode" tar ((:commit . "96c2207f0e9019f958d39582d4bf4af3bc9469d2"))]) (intero . [(20181109 1547) ((flycheck (0 25)) (company (0 8)) (emacs (24 4)) (haskell-mode (13 0))) "Complete development mode for Haskell" single ((:commit . "4be2a4a5de81bae504654a6b3a5d8a340be00e7e") (:keywords "haskell" "tools") (:authors ("Chris Done" . "chrisdone@fpcomplete.com")) (:maintainer "Chris Done" . "chrisdone@fpcomplete.com") (:url . "https://github.com/commercialhaskell/intero"))]) (lcr . [(20180902 1919) ((dash (2 12 0)) (emacs (25 1))) "lightweight coroutines" single ((:commit . "c14f40692292d59156c7632dbdd2867c086aa75f") (:keywords "tools") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:url . "https://github.com/jyp/lcr"))]) (dante . [(20180916 729) ((dash (2 12 0)) (emacs (25 1)) (f (0 19 0)) (flycheck (0 30)) (haskell-mode (13 14)) (s (1 11 0)) (lcr (1 0))) "Development mode for Haskell" single ((:commit . "f16562abe570f5ca0e7abbf8c7058c81976a921f") (:keywords "haskell" "tools") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:url . "https://github.com/jyp/dante"))]) (flycheck-haskell . [(20181117 1001) ((emacs (24 3)) (flycheck (0 25)) (haskell-mode (13 7)) (dash (2 4 0)) (seq (1 11)) (let-alist (1 0 1))) "Flycheck: Automatic Haskell configuration" tar ((:commit . "072c854a65a73b441624a90a8aa3b86ec64cdd1e") (:keywords "tools" "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-haskell"))]) (haskell-mode . [(20180917 923) ((emacs (24 3))) "A Haskell editing mode" tar ((:commit . "6a70c1858c7d505ba23185e209ef7eacf703ed8f") (:keywords "haskell" "cabal" "ghc" "repl") (:url . "https://github.com/haskell/haskell-mode"))]) (haskell-snippets . [(20160919 22) ((cl-lib (0 5)) (yasnippet (0 8 0))) "Yasnippets for Haskell" tar ((:commit . "07b0f460b946fd1be26c29652cb0468b47782f3a") (:keywords "snippets" "haskell") (:authors ("Luke Hoersten" . "luke@hoersten.org")) (:maintainer "Luke Hoersten" . "luke@hoersten.org") (:url . "https://github.com/haskell/haskell-snippets"))]) (helm-hoogle . [(20161027 534) ((helm (1 6 2)) (emacs (24 4))) "Use helm to navigate query results from Hoogle" single ((:commit . "73969a9d46d2121a849a01a9f7ed3636d01f7bbc") (:keywords "haskell" "programming" "hoogle") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:url . "https://github.com/jwiegley/haskell-config"))]) (hindent . [(20180518 902) ((cl-lib (0 5))) "Indent haskell code using the \"hindent\" program" single ((:commit . "ffe03701050d159387c06103ecaf8147716d5cb8") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com") (:url . "https://github.com/chrisdone/hindent"))]) (hlint-refactor . [(20170818 448) nil "Apply HLint suggestions" single ((:commit . "92c69aa01c65968e86c15db087bb1ea785e4736c") (:keywords "haskell" "refactor") (:url . "https://github.com/mpickering/hlint-refactor-mode"))]) (drupal-mode . [(20171120 2309) ((php-mode (1 5 0))) "Advanced minor mode for Drupal development" tar ((:commit . "47fda0a38a5b197f4606137d9c3b7d44aaeaa886") (:keywords "programming" "php" "drupal") (:authors ("Arne Jørgensen" . "arne@arnested.dk")) (:maintainer "Arne Jørgensen" . "arne@arnested.dk") (:url . "https://github.com/arnested/drupal-mode"))]) (php-auto-yasnippets . [(20170331 114) ((php-mode (1 11)) (yasnippet (0 8 0))) "Creates snippets for PHP functions" tar ((:commit . "03e1f0899c081813901ac15c2f7a675a37cca9f5") (:authors ("Eric James Michael Ritz")) (:maintainer "Eric James Michael Ritz") (:url . "https://github.com/ejmr/php-auto-yasnippets"))]) (phpcbf . [(20180519 838) ((s (1 9 0))) "Format PHP code in Emacs using PHP_CodeSniffer's phpcbf" single ((:commit . "a31020fc4c5add7339e009faea66894dc02a77f1") (:keywords "tools" "php") (:authors ("nishimaki10")) (:maintainer "nishimaki10") (:url . "https://github.com/nishimaki10/emacs-phpcbf"))]) (phpunit . [(20180829 1438) ((s (1 12 0)) (f (0 19 0)) (pkg-info (0 6)) (cl-lib (0 5)) (emacs (24 3))) "Launch PHP unit tests using phpunit" tar ((:commit . "fe6bc91c3bd8b329c6d26ad883a025f06b5121ee") (:keywords "tools" "php" "tests" "phpunit") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com") ("Eric Hansen" . "hansen.c.eric@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/phpunit.el"))]) (ac-php-core . [(20181115 1442) ((emacs (24)) (dash (1)) (php-mode (1)) (xcscope (1)) (s (1)) (f (0 17 0)) (popup (0 5 0))) "gen tags for php" tar ((:commit . "1883d3178ded71534a7e93189bc789d65e4a000e") (:keywords "completion" "convenience" "intellisense") (:authors (nil . "xcwenn@qq.com [https://github.com/xcwen]")) (:maintainer nil . "xcwenn@qq.com [https://github.com/xcwen]") (:url . "https://github.com/xcwen/ac-php"))]) (xcscope . [(20180426 712) nil "cscope interface for (X)Emacs" single ((:commit . "57bff67460c587acf60f513de622b4c7ab312081") (:keywords "languages" "c") (:authors ("Darryl Okahata" . "darrylo@sonic.net") ("Dima Kogan" . "dima@secretsauce.net")) (:maintainer "Dima Kogan" . "dima@secretsauce.net") (:url . "https://github.com/dkogan/xcscope.el"))]) (php-mode . [(20180829 520) ((emacs (24 3)) (cl-lib (0 5))) "Major mode for editing PHP code" tar ((:commit . "1f04813f46219e626b385d0d96abefad914bfae0") (:keywords "languages" "php") (:authors ("Eric James Michael Ritz")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/php-mode"))]) (company-php . [(20181110 303) ((cl-lib (0 5)) (ac-php-core (1)) (company (0 9))) "company completion source for php" single ((:commit . "1883d3178ded71534a7e93189bc789d65e4a000e") (:keywords "completion" "convenience" "intellisense") (:authors (nil . "xcwenn@qq.com [https://github.com/xcwen]")) (:maintainer nil . "xcwenn@qq.com [https://github.com/xcwen]") (:url . "https://github.com/xcwen/ac-php"))]) (cl-generic . [(0 3) nil "Forward cl-generic compatibility for Emacs<25" single ((:url . "http://elpa.gnu.org/packages/cl-generic.html") (:keywords))]) (ein . [(20181113 2117) ((websocket (1 7)) (auto-complete (1 4 0)) (request (0 3)) (deferred (0 5)) (request-deferred (0 2 0)) (cl-generic (0 3)) (dash (2 13 0)) (s (1 11 0)) (skewer-mode (1 6 2))) "Emacs IPython Notebook" tar ((:commit . "07bc906df91bc60d1f39426ea2e86482aa03370c"))]) (ob-ipython . [(20180224 953) ((s (1 9 0)) (dash (2 10 0)) (dash-functional (1 2 0)) (f (0 17 2)) (emacs (24))) "org-babel functions for IPython evaluation" tar ((:commit . "7147455230841744fb5b95dcbe03320313a77124") (:keywords "literate programming" "reproducible research") (:authors ("Greg Sexton" . "gregsexton@gmail.com")) (:maintainer "Greg Sexton" . "gregsexton@gmail.com") (:url . "http://www.gregsexton.org"))]) (company-lua . [(20171108 2306) ((company (0 8 12)) (s (1 10 0)) (f (0 17 0)) (lua-mode (20151025))) "Company backend for Lua" tar ((:commit . "29f6819de4d691e5fd0b62893a9f4fbc1c6fcb52") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net"))]) (lua-mode . [(20180323 1021) nil "a major-mode for editing Lua scripts" tar ((:commit . "99312b8d6c500ba3067da6d81efcfbbea05a1cbd") (:keywords "languages" "processes" "tools") (:authors ("2011-2013 immerrr" . "immerrr+lua@gmail.com") ("2010-2011 Reuben Thomas" . "rrt@sc3d.org") ("2006 Juergen Hoetzel" . "juergen@hoetzel.info") ("2004 various (support for Lua 5 and byte compilation)") ("2001 Christian Vogler" . "cvogler@gradient.cis.upenn.edu") ("1997 Bret Mogilefsky" . "mogul-lua@gelatinous.com") ("tcl-mode by Gregor Schmid" . "schmid@fb3-s7.math.tu-berlin.de") ("with tons of assistance from") ("Paul Du Bois" . "pld-lua@gelatinous.com") ("Aaron Smith" . "aaron-lua@gelatinous.com")) (:maintainer "2011-2013 immerrr" . "immerrr+lua@gmail.com") (:url . "http://immerrr.github.com/lua-mode"))]) (faust-mode . [(20180205 926) nil "Faust syntax colorizer for Emacs." single ((:commit . "7c31b22bdbfd2f8c16ec117d2975d56dd61ac15c") (:keywords "languages" "faust") (:authors ("rukano" . "rukano@gmail.com")) (:maintainer "Yassin Philip" . "xaccrocheur@gmail.com") (:url . "https://github.com/rukano/emacs-faust-mode"))]) (company-shell . [(20170518 541) ((emacs (24 4)) (company (0 8 12)) (dash (2 12 0)) (cl-lib (0 5))) "Company mode backend for shell functions" single ((:commit . "6ae625f80d90e0779c79de38e8f83a336c1d00fa") (:keywords "company" "shell" "auto-completion") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/company-shell"))]) (fish-mode . [(20180827 303) ((emacs (24))) "Major mode for fish shell scripts" single ((:commit . "35fc7c1e243a7410823088a571ecf378e9f3efa6") (:keywords "fish" "shell") (:authors ("Tony Wang" . "wwwjfy@gmail.com")) (:maintainer "Tony Wang" . "wwwjfy@gmail.com"))]) (flycheck-bashate . [(20160630 440) ((flycheck (0 24)) (emacs (24 4))) "Integrate bashate with flycheck" single ((:commit . "77fa03dbc578c34fe71ca44926bac2aff8f2b021") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-bashate"))]) (insert-shebang . [(20180403 1214) nil "Insert shebang line automatically." single ((:commit . "7bfea92ba1dae9d13d442e2f84f9fb6c05a0a9bd") (:keywords "shebang" "tool" "convenience") (:authors ("Sachin Patil" . "iclcoolster@gmail.com")) (:maintainer "Sachin Patil" . "iclcoolster@gmail.com") (:url . "http://github.com/psachin/insert-shebang"))]) (flycheck-perl6 . [(20180509 2201) ((emacs (24 3)) (flycheck (0 22))) "Perl 6 support in Flycheck" single ((:commit . "b804702305d7a6e26f762ff98cfdeec2e9dd4cb7") (:keywords "tools" "convenience") (:authors ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com")) (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") (:url . "https://github.com/hinrik/flycheck-perl6"))]) (perl6-mode . [(20180619 1159) ((emacs (24 4)) (pkg-info (0 1))) "Major mode for editing Perl 6 code" tar ((:commit . "88de065795d6863b23b6042576b9e90f8cbf8798") (:keywords "languages") (:authors ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com")) (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") (:url . "https://github.com/hinrik/perl6-mode"))]) (hierarchy . [(20171221 1151) ((emacs (25 1))) "Library to create and display hierarchy structures" single ((:commit . "06f21d3fc16c44c1fa45dc9c91d10100b4db9355") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/hierarchy"))]) (json-navigator . [(20171220 819) ((emacs (24 3)) (hierarchy (0 6 0))) "View and navigate JSON structures" single ((:commit . "7a1fec93500c46ccba4086d10115d8188607d0d0") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/json-navigator"))]) (key-chord . [(20160227 1238) nil "map pairs of simultaneously pressed keys to commands" single ((:commit . "72443e9ff3c4f1c3ccaced3130236801efde3d83") (:keywords "keyboard" "chord" "input") (:authors ("David Andersson ")) (:maintainer "David Andersson "))]) (org-ref . [(20181115 51) ((dash (2 11 0)) (htmlize (1 51)) (helm (1 5 5)) (helm-bibtex (2 0 0)) (ivy (0 8 0)) (hydra (0 13 2)) (key-chord (0)) (s (1 10 0)) (f (0 18 0)) (emacs (24 4)) (pdf-tools (0 7))) "citations, cross-references and bibliographies in org-mode" tar ((:commit . "1b5cf239d2abe203b9c64000c9010bbb6bf18fb4") (:keywords "org-mode" "cite" "ref" "label") (:authors ("John Kitchin" . "jkitchin@andrew.cmu.edu")) (:maintainer "John Kitchin" . "jkitchin@andrew.cmu.edu") (:url . "https://github.com/jkitchin/org-ref"))]) (parsebib . [(20181031 1021) ((emacs (24 3))) "A library for parsing bib files" single ((:commit . "27b30f5220b80637ed55f3b062ce2823adb40477") (:keywords "text" "bibtex") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (helm-bibtex . [(20181030 2142) ((helm (1 5 5)) (parsebib (1 0)) (s (1 9 0)) (dash (2 6 0)) (f (0 16 2)) (cl-lib (0 5)) (biblio (0 2))) "A bibliography manager based on Helm" tar ((:commit . "af05ccb498d89550644cc01c80628053d4d2d73f") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de"))]) (biblio . [(20161014 2304) ((emacs (24 3)) (biblio-core (0 2))) "Browse and import bibliographic references from CrossRef, arXiv, DBLP, HAL, Dissemin, and doi.org" tar ((:commit . "a5a68fcf677f286f205f32dc7486f6c9f66aa6af"))]) (biblio-core . [(20160901 1815) ((emacs (24 3)) (let-alist (1 0 4)) (seq (1 11)) (dash (2 12 1))) "A framework for looking up and displaying bibliographic entries" single ((:commit . "a5a68fcf677f286f205f32dc7486f6c9f66aa6af") (:keywords "bib" "tex" "convenience" "hypermedia") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:url . "http://github.com/cpitclaudel/biblio.el"))]) (ahk-mode . [(20181113 1238) ((emacs (24 3))) "Major mode for editing AHK (AutoHotkey and AutoHotkey_L)" single ((:commit . "fde5be2cd4a0a48dc876031fb25be82892f700e0") (:keywords "ahk" "autohotkey" "hotkey" "keyboard shortcut" "automation") (:authors ("Rich Alesi")) (:maintainer "Rich Alesi") (:url . "https://github.com/ralesi/ahk-mode"))]) (markup-faces . [(20141110 817) nil "collection of faces for markup language modes" single ((:commit . "98a807ed82473eb41c6a201ed7ef816d6bcd67b0") (:keywords "wp" "faces") (:authors ("Florian Kaufmann" . "sensorflo@gmail.com")) (:maintainer "Florian Kaufmann" . "sensorflo@gmail.com") (:url . "https://github.com/sensorflo/markup-faces"))]) (adoc-mode . [(20160314 2130) ((markup-faces (1 0 0))) "a major-mode for editing AsciiDoc files in Emacs" single ((:commit . "745884359a1b8826ede2c4cfd2f0b5478953ac40") (:keywords "wp" "asciidoc") (:authors ("Florian Kaufmann" . "sensorflo@gmail.com")) (:maintainer "Florian Kaufmann" . "sensorflo@gmail.com") (:url . "https://github.com/sensorflo/adoc-mode/wiki"))]) (scala-mode . [(20170802 1132) nil "Major mode for editing Scala" tar ((:commit . "56cba2903cf6e12c715dbb5c99b34c97b2679379") (:keywords "languages") (:url . "https://github.com/ensime/emacs-scala-mode"))]) (sbt-mode . [(20180511 1622) ((emacs (24 4))) "Interactive support for sbt projects" tar ((:commit . "e658af140547cbef495c33535c7f694a501d318c") (:keywords "languages") (:url . "https://github.com/ensime/emacs-sbt-mode"))]) (swift-mode . [(20181117 1202) ((emacs (24 4)) (seq (2 3))) "Major-mode for Apple's Swift programming language." tar ((:commit . "55ce4e53f856626938b50f014c5f82947a628d6a") (:keywords "languages" "swift") (:url . "https://github.com/swift-emacs/swift-mode"))]) (csv-mode . [(1 7) nil "Major mode for editing comma/char separated values" single ((:url . "http://elpa.gnu.org/packages/csv-mode.html") (:keywords "convenience"))]) (jsonnet-mode . [(20180822 1619) ((emacs (24))) "Major mode for editing jsonnet files" single ((:commit . "0d68681d501fd57ebde5ed4fe100033a5d3aafa8") (:keywords "languages") (:authors ("Nick Lanham")) (:maintainer "Nick Lanham") (:url . "https://github.com/mgyucht/jsonnet-mode"))]) (ctable . [(20171006 11) nil "Table component for Emacs Lisp" single ((:commit . "b8830d1ca95abb100a81bc32011bd17d5ecba000") (:keywords "table") (:authors ("SAKURAI Masashi ")) (:maintainer "SAKURAI Masashi ") (:url . "https://github.com/kiwanami/emacs-ctable"))]) (ess-R-data-view . [(20130509 1158) ((ctable (20130313 1743)) (popup (20130324 1305)) (ess (20130225 1754))) "Data viewer for GNU R" single ((:commit . "d6e98d3ae1e2a2ea39a56eebcdb73e99d29562e9") (:keywords "convenience") (:authors ("myuhe ")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/ess-R-data-view.el"))]) (ess . [(20181117 1705) ((julia-mode (0 3))) "Emacs Speaks Statistics" tar ((:commit . "58b011d78e6394e29dff173f66da652388eb87a8") (:authors ("David Smith" . "dsmith@stats.adelaide.edu.au") ("A.J. Rossini" . "blindglobe@gmail.com") ("Richard M. Heiberger" . "rmh@temple.edu") ("Kurt Hornik" . "Kurt.Hornik@R-project.org") ("Martin Maechler" . "maechler@stat.math.ethz.ch") ("Rodney A. Sparapani" . "rsparapa@mcw.edu") ("Stephen Eglen" . "stephen@gnu.org") ("Sebastian P. Luque" . "spluque@gmail.com") ("Henning Redestig" . "henning.red@googlemail.com") ("Vitalie Spinu" . "spinuvit@gmail.com") ("Lionel Henry" . "lionel.hry@gmail.com") ("J. Alexander Branham" . "alex.branham@gmail.com")) (:maintainer "ESS Core Team" . "ESS-core@r-project.org"))]) (ess-smart-equals . [(20150202 601) ((emacs (24)) (ess (5 0))) "better smart-assignment with =-key in R and S" single ((:commit . "e0f5f18f01ed252fde50d051adf1fa6254a254c9") (:keywords "r" "s" "ess" "convenience") (:authors ("Christopher R. Genovese" . "genovese@cmu.edu")) (:maintainer "Christopher R. Genovese" . "genovese@cmu.edu") (:url . "https://github.com/genovese/ess-smart-equals"))]) (golden-ratio . [(20150819 1120) nil "Automatic resizing of Emacs windows to the golden ratio" single ((:commit . "72b028808b41d23fa3f7e8c0d23d2c475e7b46ae") (:keywords "window" "resizing") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com"))]) (graphviz-dot-mode . [(20181118 551) nil "Mode for the dot-language used by graphviz (att)." single ((:commit . "243de72e09ddd5cdc4863613af8b749827a5e1cd") (:keywords "mode" "dot" "dot-language" "dotlanguage" "graphviz" "graphs" "att") (:maintainer "Pieter Pareit" . "pieter.pareit@gmail.com") (:url . "http://ppareit.github.com/graphviz-dot-mode/"))]) (sml-mode . [(6 9) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing (Standard) ML" single ((:url . "http://elpa.gnu.org/packages/sml-mode.html") (:keywords "sml"))]) (ob-sml . [(20130829 1843) ((sml-mode (6 4))) "org-babel functions for template evaluation" single ((:commit . "958165c92b6cff6cada5c85c8ae5887806b8451b") (:keywords "literate programming" "reproducible research") (:authors ("David Nolen")) (:maintainer "David Nolen") (:url . "http://orgmode.org"))]) (shut-up . [(20180628 1830) ((cl-lib (0 3)) (emacs (24))) "Shut up would you!" single ((:commit . "081d6b01e3ba0e60326558e545c4019219e046ce") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/shut-up.el"))]) (csharp-mode . [(20181011 718) nil "C# mode derived mode" single ((:commit . "239527c1f27cf5246505f1faf23269487fdbfdd2") (:keywords "c#" "languages" "oop" "mode") (:authors ("Dylan R. E. Moonfire (original)")) (:maintainer "Jostein Kjønigsen" . "jostein@gmail.com") (:url . "https://github.com/josteink/csharp-mode"))]) (omnisharp . [(20181023 505) ((emacs (24 4)) (flycheck (30)) (dash (2 12 0)) (auto-complete (1 4)) (popup (0 5 1)) (csharp-mode (0 8 7)) (cl-lib (0 5)) (s (1 10 0)) (shut-up (0 3 2)) (f (0 19 0))) "Omnicompletion (intellisense) and more for C#" tar ((:commit . "260b2423b7b909b12b98d84e5b05b5b4e20040d0") (:keywords "languages" "csharp" "c#" "ide" "auto-complete" "intellisense") (:authors ("Mika Vilpas and others")) (:maintainer "Mika Vilpas and others") (:url . "https://github.com/Omnisharp/omnisharp-emacs"))]) (ttl-mode . [(20160505 832) nil "mode for Turtle (and Notation 3)" single nil]) (sparql-mode . [(20180320 1802) ((cl-lib (0 5)) (emacs (24 3))) "Edit and interactively evaluate SPARQL queries." tar ((:commit . "a00bb622c54086ac1ee96c265bf7fbef12c68089") (:authors ("Craig Andera ")) (:maintainer "Bjarte Johansen ") (:url . "https://github.com/ljos/sparql-mode"))]) (julia-mode . [(20180816 2117) nil "Major mode for editing Julia source code" single ((:commit . "ec01995f60486480cf2240bbd3b9a2ff3fa9e0f0") (:keywords "languages") (:url . "https://github.com/JuliaLang/julia"))]) (julia-repl . [(20180923 1124) ((emacs (25))) "A minor mode for a Julia REPL" single ((:commit . "d8b94c6dbfa47fd51540b9d5b1bb0c2dfce3ebc2") (:keywords "languages") (:authors ("Tamas Papp" . "tkpapp@gmail.com")) (:maintainer "Tamas Papp" . "tkpapp@gmail.com") (:url . "https://github.com/tpapp/julia-repl"))]) (company-lsp . [(20181105 1644) ((emacs (25 1)) (lsp-mode (3 4)) (company (0 9 0)) (s (1 2 0)) (dash (2 11 0))) "Company completion backend for lsp-mode." single ((:commit . "d333e5594f8d5e5cb96309f8a913747ff83ab089") (:url . "https://github.com/tigersoldier/company-lsp"))]) (evil-surround . [(20181020 1248) ((evil (1 2 12))) "emulate surround.vim from Vim" single ((:commit . "63ce01848878ce011eb4fee59c51109dd1e3ddb5") (:keywords "emulation" "vi" "evil") (:authors ("Tim Harper ") ("Vegard Øye ")) (:maintainer "Tim Harper "))]) (groovy-imports . [(20161003 851) ((emacs (24 4)) (s (1 10 0)) (pcache (0 3 2))) "Code for dealing with Groovy imports" single ((:commit . "e56d7dda617555ec6205644d32ffddf2e1fa43d9") (:keywords "groovy") (:authors ("Miro Bezjak")) (:maintainer "Miro Bezjak") (:url . "http://www.github.com/mbezjak/emacs-groovy-imports"))]) (groovy-mode . [(20181111 1057) ((s (1 12 0)) (emacs (24 3)) (dash (2 13 0))) "Major mode for Groovy source files" tar ((:commit . "f80b6795f645aff592ffbdc6b500084955094f5c") (:keywords "languages") (:authors ("Russel Winder" . "russel@winder.org.uk") ("Jim Morris" . "morris@wolfman.com") ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Russel Winder" . "russel@winder.org.uk"))]) (coffee-mode . [(20170324 940) ((emacs (24 3))) "Major mode for CoffeeScript code" single ((:commit . "86ab8aae8662e8eff54d3013010b9c693b16eac5") (:keywords "coffeescript" "major" "mode") (:authors ("Chris Wanstrath" . "chris@ozmm.org")) (:maintainer "Chris Wanstrath" . "chris@ozmm.org") (:url . "http://github.com/defunkt/coffee-mode"))]) (ob-coffeescript . [(20180126 719) ((emacs (24 4))) "org-babel functions for coffee-script evaluation, and fully implementation!" single ((:commit . "5a5bb04aea9c2a6eab5b05f90f5c7cb6de7b4261") (:keywords "coffee-script" "literate programming" "reproducible research") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/ob-coffeescript"))]) (prop-menu . [(20150728 1118) ((emacs (24 3)) (cl-lib (0 5))) "Create and display a context menu based on text and overlay properties" single ((:commit . "50b102c1c0935fd3e0c465feed7f27d66b21cdf3") (:keywords "convenience") (:authors ("David Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Christiansen" . "david@davidchristiansen.dk") (:url . "https://github.com/david-christiansen/prop-menu-el"))]) (idris-mode . [(20180922 2051) ((emacs (24)) (prop-menu (0 1)) (cl-lib (0 5))) "Major mode for editing Idris code" tar ((:commit . "0e3508aca4d1f46f8c062f84c386d9e5533a21c3") (:keywords "languages") (:url . "https://github.com/idris-hackers/idris-mode"))]) (multiple-cursors . [(20180913 1237) ((cl-lib (0 5))) "Multiple cursors for Emacs." tar ((:commit . "6a7c3c0853e3fe9e4b8e5985dbed8fd4075f33ff"))]) (js2-refactor . [(20180502 1042) ((js2-mode (20101228)) (s (1 9 0)) (multiple-cursors (1 0 0)) (dash (1 0 0)) (s (1 0 0)) (yasnippet (0 9 0 1))) "A JavaScript refactoring library for emacs." tar ((:commit . "79124b3274c43ad1f9ec6205fa362576552db02f"))]) (livid-mode . [(20131116 1344) ((skewer-mode (1 5 3)) (s (1 8 0))) "Live browser eval of JavaScript every time a buffer changes" single ((:commit . "dfe5212fa64738bc4138bfebf349fbc8bc237c26") (:authors ("Murphy McMahon")) (:maintainer "Murphy McMahon") (:url . "https://github.com/pandeiro/livid-mode"))]) (js2-mode . [(20180724 801) ((emacs (24 1)) (cl-lib (0 5))) "Improved JavaScript editing mode" tar ((:commit . "5165f4dc3805add174e48f0d64c5617d10ac3507") (:keywords "languages" "javascript") (:authors ("Steve Yegge" . "steve.yegge@gmail.com") ("mooz" . "stillpedant@gmail.com") ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Steve Yegge" . "steve.yegge@gmail.com") (:url . "https://github.com/mooz/js2-mode/"))]) (skewer-mode . [(20180706 1807) ((simple-httpd (1 4 0)) (js2-mode (20090723)) (emacs (24))) "live browser JavaScript, CSS, and HTML interaction" tar ((:commit . "a381049acc4fa2087615b4b3b26c0865841386bd"))]) (forth-mode . [(20170527 1930) nil "Programming language mode for Forth" tar ((:commit . "522256d98d1a909983bcfd3ae20c65226d5929b6") (:keywords "languages" "forth") (:authors ("Lars Brinkhoff" . "lars@nocrew.org")) (:maintainer "Lars Brinkhoff" . "lars@nocrew.org") (:url . "http://github.com/larsbrinkhoff/forth-mode"))]) (company-math . [(20171016 1514) ((company (0 8 0)) (math-symbol-lists (1 2))) "Completion backends for unicode math symbols and latex tags" single ((:commit . "3481f03ebb6a613ff85b71ca8edd2d5842c49012") (:keywords "unicode" "symbols" "completion") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/vspinu/company-math"))]) (math-symbol-lists . [(20170221 1353) nil "Lists of Unicode math symbols and latex commands" tar ((:commit . "1af8fdcab7941a62287c2d04b8876e1538f39c60") (:keywords "unicode" "symbols" "mathematics") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/vspinu/math-symbol-lists"))]) (company-coq . [(20181107 2136) ((company-math (1 1)) (company (0 8 12)) (yasnippet (0 11 0)) (dash (2 12 1)) (cl-lib (0 5))) "A collection of extensions for Proof General's Coq mode" tar ((:commit . "24f33527c5917cdd4c3c139f966c49c33b21d4d0"))]) (proof-general . [(20181115 1610) ((emacs (24 3))) "A generic front-end for proof assistants (interactive theorem provers)" tar ((:commit . "05df29f7ff065d8da45b81691c602b6cf075e4a0"))]) (vi-tilde-fringe . [(20141028 242) ((emacs (24))) "Displays tildes in the fringe on empty lines a la Vi." single ((:commit . "f1597a8d54535bb1d84b442577b2024e6f910308") (:keywords "emulation") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/vi-tilde-fringe"))]) (flycheck-pact . [(20180920 2052) ((emacs (24 3)) (flycheck (0 25)) (pact-mode (0 0 4))) "Flycheck support for pact-mode" single ((:commit . "0e10045064ef89ec8b6f5a473073d47b976a2ca3") (:keywords "pact" "lisp" "languages" "blockchain" "smartcontracts" "tools" "linting") (:authors ("Stuart Popejoy")) (:maintainer "Stuart Popejoy" . "stuart@kadena.io") (:url . "http://github.com/kadena-io/flycheck-pact"))]) (pact-mode . [(20180905 1647) ((emacs (24 3))) "Mode for Pact, a LISPlike smart contract language." single ((:commit . "e4e4487c1d55b3fb8775abd948be28442efcffec") (:keywords "pact" "lisp" "languages" "blockchain" "smartcontracts" "tools" "mode") (:authors ("Stuart Popejoy")) (:maintainer "Stuart Popejoy" . "stuart@kadena.io") (:url . "https://github.com/kadena-io/pact-mode"))]) (company-dcd . [(20170516 910) ((company (0 9)) (flycheck-dmd-dub (0 7)) (yasnippet (0 8)) (popwin (0 7)) (cl-lib (0 5)) (ivy (20160804 326))) "Company backend for Dlang using DCD." single ((:commit . "4832188a9e42287539a69c372fe1643166a6a7aa") (:keywords "languages") (:authors ("tsukimizake ")) (:maintainer "tsukimizake ") (:url . "http://github.com/tsukimizake/company-dcd"))]) (d-mode . [(20181011 1927) ((emacs (24 3))) "D Programming Language major mode for (X)Emacs" single ((:commit . "385cda4afad79000b4cb7704861faf34009b0fc2") (:keywords "d" "programming" "language" "emacs" "cc-mode") (:authors ("William Baxter")) (:maintainer "Russel Winder" . "russel@winder.org.uk"))]) (flycheck-dmd-dub . [(20180625 1635) ((flycheck (0 24)) (f (0 18 2))) "Sets flycheck-dmd-include-paths from dub package information" single ((:commit . "d7df2895d7d27cc39916816e3c32a60ce0e1d2d9") (:keywords "languages") (:authors ("Atila Neves" . "atila.neves@gmail.com")) (:maintainer "Atila Neves" . "atila.neves@gmail.com") (:url . "http://github.com/atilaneves/flycheck-dmd-dub"))]) (auto-complete-rst . [(20140225 944) ((auto-complete (1 4))) "Auto-complete extension for ReST and Sphinx" tar ((:commit . "4803ce41a96224e6fa54e6741a5b5f40ebed7351") (:authors ("ARAKAKI, Takafumi")) (:maintainer "ARAKAKI, Takafumi") (:url . "https://github.com/tkf/auto-complete-rst"))]) (auto-highlight-symbol . [(20130313 943) nil "Automatic highlighting current symbol minor mode" single ((:commit . "26573de912d760e04321b350897aea70958cee8b") (:keywords "highlight" "face" "match" "convenience") (:authors ("Mitsuo Saito" . "arch320@NOSPAM.gmail.com")) (:maintainer "Mitsuo Saito" . "arch320@NOSPAM.gmail.com") (:url . "http://github.com/gennad/auto-highlight-symbol/raw/master/auto-highlight-symbol.el"))]) (common-lisp-snippets . [(20180226 1523) ((yasnippet (0 8 0))) "Yasnippets for Common Lisp" tar ((:commit . "1ddf808311ba4d9e8444a1cb50bd5ee75e4111f6") (:keywords "snippets") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/common-lisp-snippets"))]) (slime . [(20181112 1346) ((cl-lib (0 5)) (macrostep (0 9))) "Superior Lisp Interaction Mode for Emacs" tar ((:commit . "b7bf530d884371d6560cad37bd9b9e587ebc5e06") (:keywords "languages" "lisp" "slime") (:url . "https://github.com/slime/slime"))]) (macrostep . [(20161120 2106) ((cl-lib (0 5))) "interactive macro expander" tar ((:commit . "424e3734a1ee526a1bd7b5c3cd1d3ef19d184267") (:keywords "lisp" "languages" "macro" "debugging") (:authors ("joddie" . "j.j.oddie@gmail.com")) (:maintainer "joddie" . "j.j.oddie@gmail.com") (:url . "https://github.com/joddie/macrostep"))]) (slime-company . [(20180119 1843) ((emacs (24 4)) (slime (2 13)) (company (0 9 0))) "slime completion backend for company mode" single ((:commit . "4c2e2805540dea700130607fa235018a87e4a070") (:keywords "convenience" "lisp" "abbrev") (:authors ("Ole Arndt" . "anwyn@sugarshark.com")) (:maintainer "Ole Arndt" . "anwyn@sugarshark.com"))]) (protobuf-mode . [(20170526 1650) nil "major mode for editing protocol buffers." single ((:commit . "59133296a6e5d5017074e036557ebb658e49d435") (:keywords "google" "protobuf" "languages") (:authors ("Alexandre Vassalotti" . "alexandre@peadrop.com")) (:maintainer "Alexandre Vassalotti" . "alexandre@peadrop.com"))]) (bundler . [(20160815 915) ((inf-ruby (2 1)) (cl-lib (0 5))) "Interact with Bundler from Emacs" single ((:commit . "f981f67c33b42243e57a78c358dffff70022b56b") (:keywords "bundler" "ruby") (:authors ("Tobias Svensson" . "tob@tobiassvensson.co.uk")) (:maintainer "Tobias Svensson" . "tob@tobiassvensson.co.uk") (:url . "http://github.com/endofunky/bundler.el"))]) (chruby . [(20180114 1652) ((cl-lib (0 5))) "Emacs integration for chruby" single ((:commit . "42bc6d521f832eca8e2ba210f30d03ad5529788f") (:keywords "languages") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:url . "https://github.com/plexus/chruby.el"))]) (enh-ruby-mode . [(20180730 2309) ((emacs (24))) "Major mode for editing Ruby files" tar ((:commit . "09e1ed06c1cf323e3b4d45cd86353087e6a12fde") (:keywords "languages" "elisp" "ruby") (:authors ("Geoff Jacobsen")) (:maintainer "Geoff Jacobsen") (:url . "http://github.com/zenspider/Enhanced-Ruby-Mode"))]) (minitest . [(20160628 1820) ((dash (1 0 0))) "An Emacs mode for ruby minitest files" tar ((:commit . "1aadb7865c1dc69c201cecee275751ecec33a182") (:authors ("Arthur Neves")) (:maintainer "Arthur Neves") (:url . "https://github.com/arthurnn/minitest-emacs"))]) (rbenv . [(20141120 749) nil "Emacs integration for rbenv" single ((:commit . "2ea1a5bdc1266caef1dd77700f2c8f42429b03f1") (:keywords "ruby" "rbenv") (:authors ("Yves Senn" . "yves.senn@gmail.com")) (:maintainer "Yves Senn" . "yves.senn@gmail.com") (:url . "https://github.com/senny/rbenv.el"))]) (inf-ruby . [(20180521 1348) nil "Run a Ruby process in a buffer" single ((:commit . "49d59a7897f594e3be74ecbddae83719f9a6c0f0") (:keywords "languages" "ruby") (:authors ("Yukihiro Matsumoto") ("Nobuyoshi Nakada") ("Cornelius Mika" . "cornelius.mika@gmail.com") ("Dmitry Gutov" . "dgutov@yandex.ru") ("Kyle Hargraves" . "pd@krh.me")) (:maintainer "Yukihiro Matsumoto") (:url . "http://github.com/nonsequitur/inf-ruby"))]) (robe . [(20171116 2049) ((inf-ruby (2 5 1)) (emacs (24 4))) "Code navigation, documentation lookup and completion for Ruby" tar ((:commit . "7829f4fdda41eee0add8868646ab86e6b17de4b4") (:keywords "ruby" "convenience" "rails") (:authors ("Dmitry Gutov")) (:maintainer "Dmitry Gutov") (:url . "https://github.com/dgutov/robe"))]) (rspec-mode . [(20180614 1148) ((ruby-mode (1 0)) (cl-lib (0 4))) "Enhance ruby-mode for RSpec" tar ((:commit . "dda1ece81bd2802c4097e5c963fac33a444659cb") (:keywords "rspec" "ruby") (:authors ("Peter Williams, et al.")) (:maintainer "Peter Williams, et al.") (:url . "http://github.com/pezra/rspec-mode"))]) (rubocop . [(20170312 611) ((emacs (24))) "An Emacs interface for RuboCop" single ((:commit . "0ab1329a8634762bec5bdf5f415c05b32f990248") (:keywords "project" "convenience") (:authors ("Bozhidar Batsov")) (:maintainer "Bozhidar Batsov") (:url . "https://github.com/bbatsov/rubocop-emacs"))]) (ruby-hash-syntax . [(20180324 209) nil "Toggle ruby hash syntax between classic and 1.9 styles" single ((:commit . "89fc364a837d7a78ecce34380f09c073a83e30e0") (:keywords "languages") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/ruby-hash-syntax"))]) (ruby-refactor . [(20160214 1650) ((ruby-mode (1 2))) "A minor mode which presents various Ruby refactoring helpers." single ((:commit . "e6b7125878a08518bffec6942df0c606f748e9ee") (:keywords "refactor" "ruby") (:url . "https://github.com/ajvargo/ruby-refactor"))]) (pcre2el . [(20161120 2103) ((emacs (24)) (cl-lib (0 3))) "regexp syntax converter" single ((:commit . "0b5b2a2c173aab3fd14aac6cf5e90ad3bf58fa7d") (:authors ("joddie ")) (:maintainer "joddie ") (:url . "https://github.com/joddie/pcre2el"))]) (ruby-test-mode . [(20171016 1631) ((ruby-mode (1 0)) (pcre2el (1 8))) "Minor mode for Behaviour and Test Driven" single ((:commit . "87f6d770f8d2326c8d36099aeee5d577f3e2af69") (:keywords "ruby" "unit" "test" "rspec") (:authors ("Roman Scherer" . "roman.scherer@gmx.de") ("Caspar Florian Ebeling" . "florian.ebeling@gmail.com")) (:maintainer "Roman Scherer" . "roman.scherer@burningswell.com"))]) (ruby-tools . [(20151209 1615) nil "Collection of handy functions for ruby-mode." tar ((:commit . "6b97066b58a4f82eb2ecea6434a0a7e981aa4c18"))]) (rvm . [(20150402 1442) nil "Emacs integration for rvm" single ((:commit . "134497bc460990c71ab8fa75431156e62c17da2d") (:keywords "ruby" "rvm") (:authors ("Yves Senn" . "yves.senn@gmx.ch")) (:maintainer "Yves Senn" . "yves.senn@gmx.ch") (:url . "http://www.emacswiki.org/emacs/RvmEl"))]) (seeing-is-believing . [(20170214 1320) nil "minor mode for running the seeing-is-believing ruby gem" single ((:commit . "fbbe246c0fda87bb26227bb826eebadb418a220f") (:authors ("John Cinnamond")) (:maintainer "John Cinnamond"))]) (rake . [(20180212 1008) ((f (0 13 0)) (dash (1 5 0)) (cl-lib (0 5))) "Run rake commands" single ((:commit . "9c204334b03b4e899fadae6e59c20cf105404128") (:keywords "rake" "ruby") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:url . "https://github.com/asok/rake.el"))]) (sql-indent . [(1 3) ((cl-lib (0 5))) "Support for indenting code in SQL files." tar ((:keywords "languages" "sql") (:url . "http://elpa.gnu.org/packages/sql-indent.html"))]) (sqlup-mode . [(20170610 1537) nil "Upcase SQL words for you" single ((:commit . "04970977b4abb4d44301651618bbf1cdb0b263dd") (:keywords "sql" "tools" "redis" "upcase") (:authors ("Aldric Giacomoni" . "trevoke@gmail.com")) (:maintainer "Aldric Giacomoni" . "trevoke@gmail.com") (:url . "https://github.com/trevoke/sqlup-mode.el"))]) (browse-at-remote . [(20180622 631) ((f (0 17 2)) (s (1 9 0)) (cl-lib (0 5))) "Open github/gitlab/bitbucket/stash page from Emacs" single ((:commit . "99af94ada33badd3e1eceb704e07f62c1eef513a") (:keywords "github" "gitlab" "bitbucket" "convenience") (:authors ("Rustem Muslimov" . "r.muslimov@gmail.com")) (:maintainer "Rustem Muslimov" . "r.muslimov@gmail.com"))]) (diff-hl . [(20180201 1155) ((cl-lib (0 2)) (emacs (24 3))) "Highlight uncommitted changes using VC" tar ((:commit . "154c64affe7bdd16da814d198277d29bd1b6bb2a") (:keywords "vc" "diff") (:authors ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:url . "https://github.com/dgutov/diff-hl"))]) (git-gutter . [(20161105 1356) ((emacs (24 3))) "Port of Sublime Text plugin GitGutter" single ((:commit . "00c05264af046b5ce248e5b0bc42f117d9c27a09") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-git-gutter"))]) (git-gutter-fringe . [(20170113 533) ((git-gutter (0 88)) (fringe-helper (0 1 1)) (cl-lib (0 5)) (emacs (24))) "Fringe version of git-gutter.el" single ((:commit . "16226caab44174301f1659f7bf8cc67a76153445") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-git-gutter-fringe"))]) (fringe-helper . [(20140620 2109) nil "helper functions for fringe bitmaps" single ((:commit . "ef4a9c023bae18ec1ddd7265f1f2d6d2e775efdd") (:keywords "lisp") (:authors ("Nikolaj Schumacher ")) (:maintainer "Nikolaj Schumacher ") (:url . "http://nschum.de/src/emacs/fringe-helper/"))]) (git-gutter+ . [(20151204 1723) ((git-commit (0)) (dash (0))) "Manage Git hunks straight from the buffer" single ((:commit . "b7726997806d9a2da9fe84ff00ecf21d62b6f975") (:keywords "git" "vc") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/nonsequitur/git-gutter-plus"))]) (git-gutter-fringe+ . [(20140729 1103) ((git-gutter+ (0 1)) (fringe-helper (1 0 1))) "Fringe version of git-gutter+.el" single ((:commit . "7a2f49d2455a3a872e90e5f7dd4e6b27f1d96cfc") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/nonsequitur/git-gutter-fringe-plus"))]) (gist . [(20171128 406) ((emacs (24 1)) (gh (0 10 0))) "Emacs integration for gist.github.com" single ((:commit . "314fe6ab80fae35b95f0734eceb82f72813b6f41") (:keywords "tools") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:url . "https://github.com/defunkt/gist.el"))]) (github-clone . [(20160623 310) ((gh (0 7 2)) (magit (2 1 0)) (emacs (24 4))) "Fork and clone github repos" single ((:commit . "467b40ca60a6c26257466ebc43c74414df7f19cc") (:keywords "vc" "tools") (:authors ("Charles L.G. Comstock" . "dgtized@gmail.com")) (:maintainer "Charles L.G. Comstock" . "dgtized@gmail.com") (:url . "https://github.com/dgtized/github-clone.el"))]) (github-search . [(20170824 323) ((magit (0 8 1)) (gh (1 0 0))) "Clone repositories by searching github" single ((:commit . "c5fa1d9f8f9bcf201fa31478a6f5e02ed5ac086b") (:keywords "github" "search" "clone" "api" "gh" "magit" "vc" "tools") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/github-search"))]) (gh . [(20180308 2138) ((emacs (24 3)) (pcache (0 4 1)) (logito (0 1)) (marshal (0 6 3))) "A GitHub library for Emacs" tar ((:commit . "f029fc11f345ef04ab62ee91c38657e29c462fea"))]) (marshal . [(20180124 1239) ((eieio (1 4)) (json (1 3)) (ht (2 1))) "eieio extension for automatic (un)marshalling" single ((:commit . "f038689cbd5b3680b80b44edd0c7a63ca3038e26") (:keywords "eieio") (:authors ("Yann Hodique" . "hodiquey@vmware.com")) (:maintainer "Yann Hodique" . "hodiquey@vmware.com") (:url . "https://github.com/sigma/marshal.el"))]) (logito . [(20120225 2055) ((eieio (1 3))) "logging library for Emacs" single ((:commit . "824acb89d2cc18cb47281a4fbddd81ad244a2052") (:keywords "lisp" "tool") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com"))]) (magit-gh-pulls . [(20180716 1636) ((emacs (24 4)) (gh (0 9 1)) (magit (2 12 0)) (pcache (0 2 3)) (s (1 6 1))) "GitHub pull requests extension for Magit" single ((:commit . "6949e973f3e951cb0bfe75d889e0fcccc33ba733") (:keywords "git" "tools") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:url . "https://github.com/sigma/magit-gh-pulls"))]) (ghub+ . [(20181113 32) ((emacs (25)) (ghub (2 0)) (apiwrap (0 5))) "a thick GitHub API client built on ghub" single ((:commit . "51ebffe549286b3c0b0565a373f44f4d64fc57af") (:keywords "extensions" "multimedia" "tools") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:url . "https://github.com/vermiculus/ghub-plus"))]) (apiwrap . [(20180602 2231) ((emacs (25))) "api-wrapping macros" single ((:commit . "e4c9c57d6620a788ec8a715ff1bb50542edea3a6") (:keywords "tools" "maint" "convenience") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:url . "https://github.com/vermiculus/apiwrap.el"))]) (magithub . [(20181116 1355) ((emacs (25)) (magit (2 12)) (s (1 12 0)) (ghub+ (0 3)) (git-commit (2 12)) (markdown-mode (2 3))) "Magit interfaces for GitHub" tar ((:commit . "94e9f9a1a168e324ec7b79e3437afd1c1fb80200") (:keywords "git" "tools" "vc") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:url . "https://github.com/vermiculus/magithub"))]) (p4 . [(20150721 1937) nil "Simple Perforce-Emacs Integration" single ((:commit . "eff047caa75dbe4965defca9d1212454cdb755d5") (:authors ("Gareth Rees" . "gdr@garethrees.org")) (:maintainer "Gareth Rees" . "gdr@garethrees.org") (:url . "https://github.com/gareth-rees/p4.el"))]) (evil-magit . [(20180702 1553) ((evil (1 2 3)) (magit (2 6 0))) "evil-based key bindings for magit" single ((:commit . "9e2275b14807168451e10b93d69e420e435f21ef") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/evil-magit"))]) (fill-column-indicator . [(20171209 1924) nil "Graphically indicate the fill column" single ((:commit . "d2536b1c48f78679e15a2b50cd5d8c0ffde4b155") (:keywords "convenience") (:authors ("Alp Aker" . "alp.tekin.aker@gmail.com")) (:maintainer "Alp Aker" . "alp.tekin.aker@gmail.com"))]) (gitattributes-mode . [(20180318 1956) nil "Major mode for editing .gitattributes files" single ((:commit . "55468314a5f6b77d2c96be62c7005ac94545e217") (:keywords "convenience" "vc" "git") (:authors ("Rüdiger Sonderfeld" . "ruediger@c-plusplus.net")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/git-modes"))]) (gitconfig-mode . [(20180318 1956) nil "Major mode for editing .gitconfig files" single ((:commit . "55468314a5f6b77d2c96be62c7005ac94545e217") (:keywords "convenience" "vc" "git") (:authors ("Sebastian Wiesner" . "lunaryorn@gmail.com")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/git-modes"))]) (gitignore-templates . [(20180327 1326) ((emacs (24 3))) "Access GitHub .gitignore templates" single ((:commit . "b0705b8de4cbdd631c64c4e0024d62ba4ad68052") (:keywords "tools") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/gitignore-templates.el"))]) (git-link . [(20181031 259) ((emacs (24 3))) "Get the GitHub/Bitbucket/GitLab URL for a buffer location" single ((:commit . "976723dfdb9ae42e093a3cb32fc41841e94201e6") (:keywords "git" "vc" "github" "bitbucket" "gitlab" "convenience") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:url . "http://github.com/sshaw/git-link"))]) (git-messenger . [(20170102 440) ((emacs (24 3)) (popup (0 5 0))) "Pop up last commit information of current line" single ((:commit . "83815915eb8c1cb47443ff34bca3fecf7d2edf3a") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-git-messenger"))]) (git-timemachine . [(20181114 1342) ((emacs (24 3))) "Walk through git revisions of a file" single ((:commit . "4eb2ee6eabcc437bc3a1addc19ba38eed165743d") (:keywords "git") (:authors ("Peter Stiernström" . "peter@stiernstrom.se")) (:maintainer "Peter Stiernström" . "peter@stiernstrom.se") (:url . "https://github.com/pidu/git-timemachine"))]) (helm-git-grep . [(20170614 1411) ((helm-core (2 2 0))) "helm for git grep, an incremental git-grep(1)" single ((:commit . "744cea07dba6e6a5effbdba83f1b786c78fd86d3") (:authors ("mechairoi")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-git-grep"))]) (gitignore-mode . [(20180318 1956) nil "Major mode for editing .gitignore files" single ((:commit . "55468314a5f6b77d2c96be62c7005ac94545e217") (:keywords "convenience" "vc" "git") (:authors ("Sebastian Wiesner" . "lunaryorn@gmail.com")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/git-modes"))]) (helm-gitignore . [(20170211 8) ((gitignore-mode (1 1 0)) (helm (1 7 0)) (request (0 1 0)) (cl-lib (0 5))) "Generate .gitignore files with gitignore.io." single ((:commit . "2a2e7da7855a6db0ab3bb6a6a087863d7abd4391") (:keywords "helm" "gitignore" "gitignore.io") (:authors ("Juan Placencia")) (:maintainer "Juan Placencia") (:url . "https://github.com/jupl/helm-gitignore"))]) (magit-gitflow . [(20170929 824) ((magit (2 1 0)) (magit-popup (2 2 0))) "gitflow extension for magit" single ((:commit . "cc41b561ec6eea947fe9a176349fb4f771ed865b") (:keywords "vc" "tools") (:authors ("Jan Tatarik" . "Jan.Tatarik@gmail.com")) (:maintainer "Jan Tatarik" . "Jan.Tatarik@gmail.com") (:url . "https://github.com/jtatarik/magit-gitflow"))]) (magit-svn . [(20170213 1233) ((emacs (24 4)) (magit (2 1 0))) "Git-Svn extension for Magit" single ((:commit . "c833903732a14478f5c4cfc561bae7c50671b36c") (:keywords "vc" "tools") (:authors ("Phil Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Phil Jackson" . "phil@shellarchive.co.uk"))]) (magit . [(20181116 1412) ((emacs (25 1)) (async (20180527)) (dash (20180910)) (ghub (20181107)) (git-commit (20181104)) (magit-popup (20181003)) (with-editor (20181103))) "A Git porcelain inside Emacs." tar ((:commit . "36d89c88e1337ec2b33c75c3d426289c66f86b10"))]) (git-commit . [(20181116 1408) ((emacs (25 1)) (dash (20180910)) (with-editor (20181103))) "Edit Git commit messages" single ((:commit . "36d89c88e1337ec2b33c75c3d426289c66f86b10") (:keywords "git" "tools" "vc") (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/magit"))]) (ghub . [(20181112 1755) ((emacs (25 1)) (dash (2 14 1)) (graphql (0 1 1)) (let-alist (1 0 5)) (treepy (1 0 0))) "Minuscule client libraries for Git forge APIs." tar ((:commit . "f389fce41cd1bd1805bad18d12e237362af05283"))]) (treepy . [(20180724 656) ((emacs (25 1))) "Generic tree traversal tools" single ((:commit . "b40e6b09eb9be45da67b8c9e4990a5a0d7a2a09d") (:keywords "lisp" "maint" "tools") (:authors ("Daniel Barreto" . "daniel.barreto.n@gmail.com")) (:maintainer "Daniel Barreto" . "daniel.barreto.n@gmail.com") (:url . "https://github.com/volrath/treepy.el"))]) (graphql . [(20180912 31) ((emacs (25))) "GraphQL utilities" single ((:commit . "e2b309689f4faf9225f290080f836e988c5a576d") (:keywords "hypermedia" "tools" "lisp") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:url . "https://github.com/vermiculus/graphql.el"))]) (orgit . [(20180318 2001) ((emacs (24 4)) (dash (2 13 0)) (magit (2 10 0)) (org (8 3 3))) "support for Org links to Magit buffers" single ((:commit . "d909f92d3b1b42184143fd5e6d4c6a2762477ab7") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/orgit"))]) (smeargle . [(20161212 2358) ((emacs (24 3))) "Highlighting region by last updated time" single ((:commit . "0665b1ff5109731898bc4a0ca6d939933b804777") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-smeargle"))]) (afternoon-theme . [(20140104 1859) ((emacs (24 1))) "Dark color theme with a deep blue background" single ((:commit . "89b1d778a1f8b385775c122f2bd1c62f0fbf931a") (:keywords "themes") (:authors ("Ozan Sener" . "ozan@ozansener.com")) (:maintainer "Ozan Sener" . "ozan@ozansener.com") (:url . "http://github.com/osener/emacs-afternoon-theme"))]) (alect-themes . [(20180504 1720) ((emacs (24 0))) "Configurable light, dark and black themes for Emacs 24 or later" tar ((:commit . "4d90833a7381123a979f73fa97a013071ca7ff00") (:keywords "color" "theme") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/alect-themes"))]) (ample-theme . [(20180207 1745) nil "Calm Dark Theme for Emacs" tar ((:commit . "366698400c555211c2082962a5d74f3dd79a78c8") (:keywords "theme" "dark") (:authors ("Jordon Biondo" . "jordonbiondo@gmail.com")) (:maintainer "Jordon Biondo" . "jordonbiondo@gmail.com") (:url . "https://github.com/jordonbiondo/ample-theme"))]) (ample-zen-theme . [(20150119 2154) nil "AmpleZen Theme for Emacs 24" single ((:commit . "b277bb7abd4b6624e8d59f02474b79af50a007bd") (:keywords "theme" "dark" "emacs 24") (:authors ("Michael Wall")) (:maintainer "Michael Wall") (:url . "https://github.com/mjwall/ample-zen"))]) (apropospriate-theme . [(20181111 2112) nil "A colorful, low-contrast, light & dark theme set for Emacs with a fun name." tar ((:commit . "88c243ec90c1df7918c463b5a7ec875d057e8999") (:keywords "color" "theme") (:url . "https://github.com/waymondo/apropospriate-theme"))]) (anti-zenburn-theme . [(20180712 1838) nil "Low-contrast Zenburn-inverted theme" single ((:commit . "dbafbaa86be67c1d409873f57a5c0bbe1e7ca158") (:authors ("Andrey Kotlarski" . "m00naticus@gmail.com")) (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:url . "https://github.com/m00natic/anti-zenburn-theme"))]) (badwolf-theme . [(20161004 715) ((emacs (24))) "Bad Wolf color theme" single ((:commit . "ea01a3d9358e968f75e3ed15dec6a2a96ce3d9a1") (:keywords "themes") (:authors ("bkruczyk" . "bartlomiej.kruczyk@gmail.com")) (:maintainer "bkruczyk" . "bartlomiej.kruczyk@gmail.com") (:url . "https://github.com/bkruczyk/badwolf-emacs"))]) (birds-of-paradise-plus-theme . [(20130419 2129) nil "A brown/orange light-on-dark theme for Emacs 24 (deftheme)." single ((:commit . "bb9f9d4ef7f7872a388ec4eee1253069adcadb6f") (:keywords "themes") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:url . "https://github.com/jimeh/birds-of-paradise-plus-theme.el"))]) (bubbleberry-theme . [(20141017 944) ((emacs (24 1))) "A theme based on LightTable for Emacs24" single ((:commit . "22e9adf4586414024e4592972022ec297321b320") (:authors ("Jason Milkins" . "jasonm23@gmail.com") ("Gaurav Giri github.com/grvgr")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-bubbleberry-theme"))]) (busybee-theme . [(20170719 928) nil "port of vim's mustang theme" single ((:commit . "66b2315b030582d0ebee605cf455d386d8c30fcd") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/busybee-theme"))]) (cherry-blossom-theme . [(20150622 342) ((emacs (24 0))) "a soothing color theme for Emacs24." single ((:commit . "eea7653e00f35973857ee23b27bc2fae5e753e50") (:authors ("Ben Yelsey" . "byelsey1@gmail.com")) (:maintainer "Ben Yelsey" . "byelsey1@gmail.com") (:url . "https://github.com/inlinestyle/emacs-cherry-blossom-theme"))]) (clues-theme . [(20161213 1127) ((emacs (24 0))) "an Emacs 24 theme which may well be fully awesome..." single ((:commit . "abd61f2b7f3e98de58ca26e6d1230e70c6406cc7") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/emacsfodder/emacs-clues-theme"))]) (color-theme-sanityinc-solarized . [(20181021 2055) nil "A version of Ethan Schoonover's Solarized themes" tar ((:commit . "fa2afc66beebdf7936b9f1391878798d6426730c") (:keywords "themes") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "http://github.com/purcell/color-theme-sanityinc-solarized"))]) (color-theme-sanityinc-tomorrow . [(20181024 1728) nil "A version of Chris Kempson's \"tomorrow\" themes" tar ((:commit . "d3c694f4c423bc8cfc74bd80d624b974ebc94e02") (:keywords "faces" "themes") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "http://github.com/purcell/color-theme-sanityinc-tomorrow"))]) (cyberpunk-theme . [(20180609 509) nil "Cyberpunk Color Theme" single ((:commit . "f8967e46b8bdb3eaf7b72474f2d70997dc1152e9") (:keywords "color" "theme" "cyberpunk") (:authors ("Nicholas M. Van Horn" . "nvanhorn@protonmail.com")) (:maintainer "Nicholas M. Van Horn" . "nvanhorn@protonmail.com"))]) (dakrone-theme . [(20170801 1933) nil "dakrone's custom dark theme" single ((:commit . "232ad1be5f3572dcbdf528f1655109aa355a6937") (:keywords "color" "themes") (:authors ("Lee Hinman ")) (:maintainer "Lee Hinman ") (:url . "https://github.com/dakrone/dakrone-theme"))]) (darkburn-theme . [(20170423 1652) nil "A not-so-low contrast color theme for Emacs." single ((:commit . "0af794ff7fac19778ac8a7efb92455c6f6c2158f") (:authors ("Jonas Gorauskas" . "jgorauskas@gmail.com")) (:maintainer "Jonas Gorauskas" . "jgorauskas@gmail.com") (:url . "http://github.com/gorauskas/darkburn-theme"))]) (darkmine-theme . [(20160406 624) nil "Yet another emacs dark color theme." single ((:commit . "7f7e82ca03bcad52911fa41fb3e204e32d6ee63e") (:authors ("Pierre Lecocq" . "pierre.lecocq@gmail.com")) (:maintainer "Pierre Lecocq" . "pierre.lecocq@gmail.com") (:url . "https://github.com/pierre-lecocq/darkmine-theme"))]) (darkokai-theme . [(20181019 1859) nil "A darker variant on Monokai." single ((:commit . "b887fc6080f8e021058bff7f53fad84c82c81a7a") (:url . "http://github.com/sjrmanning/darkokai"))]) (darktooth-theme . [(20181013 906) ((autothemer (0 2))) "From the darkness... it watches" single ((:commit . "780f9e25ae4abccab4e053f2caba7add4bc9d3be") (:url . "http://github.com/emacsfodder/emacs-theme-darktooth"))]) (django-theme . [(20131022 902) nil "Custom face theme for Emacs" single ((:commit . "86c8142b3eb1addd94a43aa6f1d98dab06401af0") (:authors ("Andrzej Sliwa")) (:maintainer "Andrzej Sliwa") (:url . "http://github/anrzejsliwa/django-theme"))]) (doom-themes . [(20181101 218) ((emacs (24 4)) (all-the-icons (1 0 0)) (cl-lib (0 5))) "an opinionated pack of modern color-themes" tar ((:commit . "2aa163b8322a55a69296552bc03b1b84413d5abc") (:keywords "dark" "light" "blue" "atom" "one" "theme" "neotree" "icons" "faces" "nova") (:authors ("Henrik Lissner ")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-doom-theme"))]) (dracula-theme . [(20180710 1324) ((emacs (24))) "Dracula Theme" single ((:commit . "a1c9888b7876ace60a536d27fb290e788bffc9cb") (:authors ("film42")) (:maintainer "film42") (:url . "https://github.com/dracula/emacs"))]) (espresso-theme . [(20181025 826) nil "Espresso Tutti Colori port for Emacs" single ((:commit . "d2fa034eb833bf37cc6842017070725e0da9b046") (:authors ("Martin Kühl ")) (:maintainer "Martin Kühl ") (:url . "https://github.com/dgutov/espresso-theme"))]) (exotica-theme . [(20180212 2329) ((emacs (24))) "A dark theme with vibrant colors" single ((:commit . "ff3ef4f6fa38c93b99becad977c7810c990a4d2f") (:keywords "faces" "theme" "dark" "vibrant colors") (:authors ("Bharat Joshi" . "jbharat@outlook.com")) (:maintainer "Bharat Joshi" . "jbharat@outlook.com") (:url . "https://github.com/jbharat/exotica-theme"))]) (eziam-theme . [(20180414 1029) nil "A mostly monochrome theme, inspired by Tao and Leuven, with dark and light versions." tar ((:commit . "96595833110cd64c391e0ccd5230782a8f0a4e08"))]) (farmhouse-theme . [(20160713 2244) nil "Farmhouse Theme, Emacs edition" tar ((:commit . "7ddc1ff13b4a3d5466bd0d33ecb86100352e83a7") (:keywords "color" "theme") (:url . "https://github.com/mattly/emacs-farmhouse-theme"))]) (flatland-theme . [(20171113 1521) nil "A simple theme for Emacs based on the Flatland theme for Sublime Text" single ((:commit . "a98a6f19ad4dff0fa3fad1ea487b7d0ef634a19a") (:authors ("Greg Chapple" . "info@gregchapple.com")) (:maintainer "Greg Chapple" . "info@gregchapple.com") (:url . "http://github.com/gregchapple/flatland-emacs"))]) (flatui-theme . [(20160619 127) nil "A color theme for Emacs based on flatuicolors.com" single ((:commit . "9c15db5526c15c8dba55023f5698372b19c2a780") (:authors ("John Louis Del Rosario" . "john2x@gmail.com")) (:maintainer "John Louis Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/flatui-theme.el"))]) (gandalf-theme . [(20130809 947) nil "Gandalf color theme" single ((:commit . "4e472fc851431458537d458d09c1f5895e338536") (:keywords "color" "theme") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net"))]) (gotham-theme . [(20171013 1916) nil "A very dark Emacs color theme." single ((:commit . "5e97554d1f9639698faedb0660e63694be33bd84") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/gotham-theme"))]) (grandshell-theme . [(20180606 517) nil "Dark color theme for Emacs > 24 with intensive colors." tar ((:commit . "0ed8e4273607dd4fcaa742b4097259233b09eda6"))]) (gruber-darker-theme . [(20180529 712) nil "Gruber Darker color theme for Emacs 24." single ((:commit . "c7687ec0511941db1371dcd70b31061d74aa5668") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/rexim/gruber-darker-theme"))]) (gruvbox-theme . [(20181013 1144) ((autothemer (0 2))) "A retro-groove colour theme for Emacs" tar ((:commit . "39124183cf47d25780cd02e33e57743484b4c680") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "http://github.com/greduan/emacs-theme-gruvbox"))]) (hc-zenburn-theme . [(20150928 1633) nil "An higher contrast version of the Zenburn theme." single ((:commit . "fd0024a5191cdce204d91c8f1db99ba31640f6e9") (:authors ("Nantas Nardelli" . "nantas.nardelli@gmail.com")) (:maintainer "Nantas Nardelli" . "nantas.nardelli@gmail.com") (:url . "https:github.com/edran/hc-zenburn-emacs"))]) (hemisu-theme . [(20130508 1844) nil "Hemisu for Emacs." tar ((:commit . "5c206561aa2c844ecdf3e3b672c3235e559ddd7f") (:authors ("Andrzej Sliwa")) (:maintainer "Andrzej Sliwa") (:url . "http://github/anrzejsliwa/django-theme"))]) (heroku-theme . [(20150523 219) nil "Heroku color theme" single ((:commit . "8083643fe92ec3a1c3eb82f1b8dc2236c9c9691d") (:authors ("Jonathan Chu" . "me@jonathanchu.is")) (:maintainer "Jonathan Chu" . "me@jonathanchu.is") (:url . "https://github.com/jonathanchu/color-theme-heroku"))]) (inkpot-theme . [(20181026 509) nil "port of vim's inkpot theme" single ((:commit . "52fcb8ffc32a242a86956643ce9b8e8f726947aa") (:keywords "color" "theme") (:authors ("Sarah Iovan" . "sarah@hwaetageek.com") ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Sarah Iovan" . "sarah@hwaetageek.com") (:url . "https://github.com/ideasman42/emacs-inkpot-theme"))]) (ir-black-theme . [(20130303 755) nil "Port of ir-black theme" single ((:commit . "36e930d107604b5763c80294a6f92aaa02e6c272") (:keywords "faces") (:authors ("Jon-Michael Deldin" . "dev@jmdeldin.com")) (:maintainer "Jon-Michael Deldin" . "dev@jmdeldin.com"))]) (jazz-theme . [(20170411 1411) nil "A warm color theme for Emacs 24+." single ((:commit . "b1cb78a97cc4050f19d88a89e455c3e52d98240e") (:authors ("Roman Parykin" . "donderom@ymail.com")) (:maintainer "Roman Parykin" . "donderom@ymail.com") (:url . "https://github.com/donderom/jazz-theme"))]) (jbeans-theme . [(20180309 1625) ((emacs (24))) "Jbeans theme for GNU Emacs 24 (deftheme)" single ((:commit . "3caa95998d8492a2ca6c17971de499ca15609871") (:authors ("Adam Olsen" . "arolsen@gmail.com")) (:maintainer "Adam Olsen" . "arolsen@gmail.com") (:url . "https://github.com/synic/jbeans-emacs"))]) (autothemer . [(20180920 923) ((dash (2 10 0)) (emacs (24)) (cl-lib (0 5))) "Conveniently define themes." single ((:commit . "69488c71dfc182cf2e7be2d745037f230ade678e") (:authors ("Sebastian Sturm")) (:maintainer "Sebastian Sturm") (:url . "https://github.com/sebastiansturm/autothemer"))]) (kaolin-themes . [(20181117 836) ((emacs (25 1)) (autothemer (0 2 2)) (cl-lib (0 6))) "A set of eye pleasing themes" tar ((:commit . "7ddbe315c85082a6ed9ded576ed8b9e9ed8fe1f2") (:keywords "dark" "light" "teal" "blue" "violet" "purple" "brown" "theme" "faces") (:authors ("Ogden Webb" . "ogdenwebb@gmail.com")) (:maintainer "Ogden Webb" . "ogdenwebb@gmail.com") (:url . "https://github.com/ogdenwebb/emacs-kaolin-themes"))]) (light-soap-theme . [(20150607 1445) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "76a787bd40c6b567ae68ced7f5d9f9f10725e00d"))]) (lush-theme . [(20180816 2200) ((emacs (24))) "A dark theme with lush colors" single ((:commit . "7cfc993709d712f75c51b505078608c9e1c11466") (:keywords "theme" "dark" "strong colors") (:authors ("Andre Richter" . "andre.o.richter@gmail.com")) (:maintainer "Andre Richter" . "andre.o.richter@gmail.com") (:url . "https://github.com/andre-richter/emacs-lush-theme"))]) (madhat2r-theme . [(20170203 30) ((emacs (24))) "dark color theme that is easy on the eyes" single ((:commit . "6b387f09de055cfcc15d74981cd4f32f8f9a7323") (:keywords "color" "theme") (:authors ("Micah Duke")) (:maintainer "Micah Duke") (:url . "https://github.com/madhat2r/madhat2r-theme"))]) (majapahit-theme . [(20160817 1848) nil "Color theme with a dark and light versions" tar ((:commit . "77c96df7619666b2102d90d452eeadf04adc89a6") (:keywords "color" "theme") (:url . "https://gitlab.com/franksn/majapahit-theme"))]) (material-theme . [(20171123 1840) ((emacs (24 1))) "A Theme based on the colors of the Google Material Design" tar ((:commit . "b66838d220ad380a16da1d8878936974b26f815d") (:keywords "themes") (:authors ("Christoph Paulik" . "cpaulik@gmail.com")) (:maintainer "Christoph Paulik" . "cpaulik@gmail.com") (:url . "http://github.com/cpaulik/emacs-material-theme"))]) (minimal-theme . [(20160608 1022) nil "A light/dark minimalistic Emacs 24 theme." tar ((:commit . "430e0d3fc2044c16aa9f10961841febbd60df285") (:keywords "color" "theme" "minimal") (:authors ("Anler Hp ")) (:maintainer "Anler Hp ") (:url . "http://github.com/ikame/minimal-theme"))]) (moe-theme . [(20180617 200) nil "A colorful eye-candy theme. Moe, moe, kyun!" tar ((:commit . "ee6d7a1c84ac7a11fcc82dfc3b174eee1c8461fa") (:url . "https://github.com/kuanyui/moe-theme.el"))]) (molokai-theme . [(20151016 1545) nil "molokai theme with Emacs theme engine" single ((:commit . "04a44f21184b6a26caae4f2c92db9019d883309c") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/alloy-d/color-theme-molokai"))]) (monokai-theme . [(20180730 1329) nil "A fruity color theme for Emacs." single ((:commit . "f4ef092129f4a35edaee0a9b2219c17e86309730") (:authors ("Kelvin Smith" . "oneKelvinSmith@gmail.com")) (:maintainer "Kelvin Smith" . "oneKelvinSmith@gmail.com") (:url . "http://github.com/oneKelvinSmith/monokai-emacs"))]) (monochrome-theme . [(20140326 1050) nil "A dark Emacs 24 theme for your focused hacking sessions" tar ((:commit . "bfca67fe7365310bc47ae9ca96c417caada54896") (:authors ("Xavier Noria" . "fxn@hashref.com")) (:maintainer "Xavier Noria" . "fxn@hashref.com"))]) (mustang-theme . [(20170719 946) nil "port of vim's mustang theme" single ((:commit . "dda6d04803f1c9b196b620ef564e7768fee15de2") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/mustang-theme"))]) (naquadah-theme . [(20180212 1240) nil "A theme based on Tango color set" single ((:commit . "999056526db5095ce600c83672fc80cb744bd93e"))]) (noctilux-theme . [(20161113 1442) ((emacs (24))) "Dark theme inspired by LightTable" single ((:commit . "a3265a1be7f4d73f44acce6d968ca6f7add1f2ca") (:authors ("Simon Manning" . "simon@ecksdee.org")) (:maintainer "Simon Manning" . "simon@ecksdee.org") (:url . "https://github.com/sjrmanning/noctilux-theme"))]) (obsidian-theme . [(20170719 948) nil "port of the eclipse obsidian theme" single ((:commit . "f45efb2ebe9942466c1db6abbe2d0e6847b785ea") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/obsidian-theme"))]) (occidental-theme . [(20130312 1958) nil "Custom theme for faces based on Adwaita" single ((:commit . "fd2db7256d4f78c43d99c3cddb1c39106d479816") (:authors ("William Stevenson" . "yhvh2000@gmail.com") ("Erik Timan" . "dev@timan.info")) (:maintainer "William Stevenson" . "yhvh2000@gmail.com") (:url . "http://github.com/olcai/occidental-theme"))]) (omtose-phellack-theme . [(20161111 2120) nil "A dark theme, with cold bluish touch." tar ((:commit . "66f99633e199e65bd28641626435e8e59246529a"))]) (oldlace-theme . [(20150705 1300) ((emacs (24))) "Emacs 24 theme with an 'oldlace' background." single ((:commit . "5c6f437203b0783b36a7aff4a578de4a0c8c4ee6") (:authors ("martin haesler")) (:maintainer "martin haesler"))]) (organic-green-theme . [(20180522 1620) nil "Low-contrast green color theme." single ((:commit . "200ac4a636eeb6faf1793d1937e62a343debc437"))]) (phoenix-dark-mono-theme . [(20170729 1406) nil "Monochromatic version of the Phoenix theme" single ((:commit . "a54f515d162148bcb38676980bc2316adb3d7b8b") (:authors ("J Irving" . "j@lollyshouse.ca")) (:maintainer "J Irving" . "j@lollyshouse.ca") (:url . "http://github.com/j0ni/phoenix-dark-mono"))]) (phoenix-dark-pink-theme . [(20170729 1403) nil "Originally a port of the Sublime Text 2 theme" single ((:commit . "4defbb76b00c1a29f060813898578152d6be623d") (:authors ("J Irving" . "j@lollyshouse.ca")) (:maintainer "J Irving" . "j@lollyshouse.ca") (:url . "http://github.com/j0ni/phoenix-dark-pink"))]) (planet-theme . [(20161031 217) ((emacs (24))) "A dark theme inspired by Gmail's 'Planets' theme of yore" single ((:commit . "b0a310ff36565fe22224c407cf59569986698a32") (:keywords "themes") (:authors ("Charlie McMackin" . "charlie.mac@gmail.com")) (:maintainer "Charlie McMackin" . "charlie.mac@gmail.com") (:url . "https://github.com/cmack/emacs-planet-theme"))]) (professional-theme . [(20150315 1100) nil "Emacs port of Vim's professional theme" single ((:commit . "0927d1474049a193f9f366bde5eb1887b9ba20ed") (:keywords "theme" "light" "professional") (:authors ("Juanjo Alvarez" . "juanjo@juanjoalvarez.net")) (:maintainer "Juanjo Alvarez" . "juanjo@juanjoalvarez.net") (:url . "https://github.com/juanjux/emacs-professional-theme"))]) (purple-haze-theme . [(20141015 229) ((emacs (24 0))) "an overtly purple color theme for Emacs24." single ((:commit . "3e245cbef7cd09e6b3ee124963e372a04e9a6485") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-purple-haze-theme"))]) (railscasts-theme . [(20150219 1525) nil "Railscasts color theme for GNU Emacs." single ((:commit . "1340c3f6c2717761cab95617cf8dcbd962b1095b") (:keywords "railscasts" "color" "theme") (:authors ("Oleg Shaldybin")) (:maintainer "Oleg Shaldybin") (:url . "https://github.com/mikenichols/railscasts-theme"))]) (rebecca-theme . [(20180324 821) ((emacs (24))) "Rebecca Purple Theme" single ((:commit . "9ac0c71c2858b76dc5499f62c7c7fb7f9e8f16bc") (:keywords "theme" "dark") (:authors ("vic" . "vborja@apache.org")) (:maintainer "vic" . "vborja@apache.org") (:url . "https://github.com/vic/rebecca-theme"))]) (reverse-theme . [(20141205 145) nil "Reverse theme for Emacs" single ((:commit . "8319d0d5342890a3530ffa4daafdb7c35feda1ca") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-reverse-theme"))]) (seti-theme . [(20161208 1636) nil "A dark colored theme, inspired by Seti Atom Theme" single ((:commit . "cbfef2fc15d19ce4c8326e65fafdd61737077132") (:keywords "themes") (:authors ("Vlad Piersec" . "vlad.piersec@gmail.com")) (:maintainer "Vlad Piersec" . "vlad.piersec@gmail.com") (:url . "https://github.com/caisah/seti-theme"))]) (smyx-theme . [(20141127 828) nil "smyx Color Theme" single ((:commit . "6263f6b401bbabaed388c8efcfc0be2e58c51401") (:keywords "color" "theme" "smyx") (:authors ("Uriel G Maldonado" . "uriel781@gmail.com")) (:maintainer "Uriel G Maldonado" . "uriel781@gmail.com"))]) (soft-charcoal-theme . [(20140420 1643) nil "Dark charcoal theme with soft colors" single ((:commit . "5607ab977fae6638e78b1495e02da8955c9ba19f") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-charcoal-theme"))]) (soft-morning-theme . [(20150918 2041) nil "Emacs24 theme with a light background." single ((:commit . "c0f9c70c97ef2be2a093cf839c4bfe27740a111c") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-morning-theme"))]) (soft-stone-theme . [(20140614 835) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "fb475514cfb02cf30ce358a61c48e46614344d48") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-stone-theme"))]) (solarized-theme . [(20181030 1912) ((emacs (24 1)) (cl-lib (0 5)) (dash (2 6 0))) "The Solarized color theme, ported to Emacs." tar ((:commit . "87d4758e7ecc8ed873f3326e4f8b185fd2b9da0a"))]) (soothe-theme . [(20141027 1441) ((emacs (24 1))) "a dark colorful theme for Emacs24." single ((:commit . "0786fe70c6c1b4ddcfb932fdc6862b9611cfc09b") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-soothe-theme"))]) (spacegray-theme . [(20150719 1931) ((emacs (24 1))) "A Hyperminimal UI Theme" single ((:commit . "7f70ee36297e5ccf9bc90b1f81472024f5a7a749") (:keywords "themes") (:authors ("Bruce Williams" . "brwcodes@gmail.com")) (:maintainer "Bruce Williams" . "brwcodes@gmail.com") (:url . "http://github.com/bruce/emacs-spacegray-theme"))]) (subatomic-theme . [(20160126 1538) nil "Low contrast bluish color theme" single ((:commit . "6a4086af748b1ecb27f6ba2aa2614988db16d594") (:keywords "color-theme" "blue" "low contrast") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:url . "https://github.com/cryon/subatomic"))]) (subatomic256-theme . [(20130621 210) nil "Fork of subatomic-theme for terminals." single ((:commit . "326177d6f99cd2b1d30df695e67ee3bc441cd96f") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:url . "https://github.com/cryon/subatomic256"))]) (sublime-themes . [(20170606 1844) nil "A collection of themes based on Sublime Text" tar ((:commit . "60ee40af82eb55b79d5ed4026f1911326311603f") (:keywords "faces") (:authors ("Owain Lewis" . "owain@owainlewis.com")) (:maintainer "Owain Lewis" . "owain@owainlewis.com"))]) (sunny-day-theme . [(20140413 2125) nil "Emacs24 theme with a light background." single ((:commit . "420e0a6eb33fcc9b75c2c9e88ab60a975d782a00") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/sunny-day-theme"))]) (tango-2-theme . [(20120312 2025) nil "Tango 2 color theme for GNU Emacs 24" single ((:commit . "64e44c98e41ebbe3b827d54280e3b9615787daaa") (:authors ("Nick Parker")) (:maintainer "Nick Parker"))]) (tango-plus-theme . [(20170214 1708) nil "A color theme based on the tango palette" single ((:commit . "8ba8901397e3e9f1d53110487bfa0effc65015e7") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/tmalsburg/tango-plus-theme"))]) (tangotango-theme . [(20170924 1509) nil "Tango Palette color theme for Emacs 24." single ((:commit . "e2f2ea9c35f06dfc43a29c91c14cf0cdb19f2144") (:keywords "tango" "palette" "color" "theme" "emacs") (:authors ("Julien Barnier")) (:maintainer "Julien Barnier") (:url . "https://github.com/juba/color-theme-tangotango"))]) (tao-theme . [(20181020 1726) nil "This package provides two parametrized uncoloured color themes for Emacs: tao-yin and tao-yang." tar ((:commit . "c10ba53dad8aa3625191184a56c34ed456561771"))]) (toxi-theme . [(20160424 2126) ((emacs (24))) "A dark color theme by toxi" single ((:authors ("Karsten Schmidt" . "info@postspectacular.com")) (:maintainer "Karsten Schmidt" . "info@postspectacular.com") (:url . "http://bitbucket.org/postspectacular/toxi-theme/"))]) (twilight-anti-bright-theme . [(20160622 848) nil "A soothing Emacs 24 light-on-dark theme" single ((:commit . "523b95fcdbf4a6a6483af314ad05354a3d80f23f") (:keywords "themes") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:url . "https://github.com/jimeh/twilight-anti-bright-theme.el"))]) (twilight-bright-theme . [(20130605 843) nil "A Emacs 24 faces port of the TextMate theme" single ((:commit . "322157cb2f3bf7920ecd209dafc31bc1c7959f49") (:keywords "themes") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:url . "https://github.com/jimeh/twilight-bright-theme.el"))]) (twilight-theme . [(20120412 1303) nil "Twilight theme for GNU Emacs 24 (deftheme)" single ((:commit . "77c4741cb3dcf16e53d06d6c2ffdc660c40afb5b") (:authors ("Nick Parker" . "nickp@developernotes.com")) (:maintainer "Nick Parker" . "nickp@developernotes.com"))]) (ujelly-theme . [(20180214 1624) nil "Ujelly theme for GNU Emacs 24 (deftheme)" single ((:commit . "bf724ce7806a738d2043544061e5f9bbfc56e674") (:authors ("Mark Tran" . "mark.tran@gmail.com")) (:maintainer "Mark Tran" . "mark.tran@gmail.com") (:url . "http://github.com/marktran/color-theme-ujelly"))]) (underwater-theme . [(20131118 2) nil "A gentle, deep blue color theme" single ((:commit . "4eb9ef014f580adc135d91d1cd68d37a310640b6") (:keywords "faces") (:authors ("Jon-Michael Deldin" . "dev@jmdeldin.com")) (:maintainer "Jon-Michael Deldin" . "dev@jmdeldin.com"))]) (white-sand-theme . [(20151117 1648) ((emacs (24))) "Emacs theme with a light background." single ((:commit . "97621edd69267dd143760d94393db2c2558c9ea4") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))]) (zen-and-art-theme . [(20120622 1437) nil "zen and art color theme for GNU Emacs 24" single ((:commit . "a7226cbce0bca2501d69a620cb2aeabfc396c232") (:authors ("Nick Parker")) (:maintainer "Nick Parker"))]) (zenburn-theme . [(20181014 1555) nil "A low contrast color theme for Emacs." single ((:commit . "d71a0f0556c1db785738ab9b0c989df342705a81") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "http://github.com/bbatsov/zenburn-emacs"))]) (nyan-mode . [(20170423 740) nil "Nyan Cat shows position in current buffer in mode-line." tar ((:commit . "a85ac925367ddc542827182a2d9f0133b421c41b") (:keywords "nyan" "cat" "lulz" "scrolling" "pop tart cat" "build something amazing") (:authors ("Jacek \"TeMPOraL\" Zlydach" . "temporal.pl@gmail.com")) (:maintainer "Jacek \"TeMPOraL\" Zlydach" . "temporal.pl@gmail.com") (:url . "https://github.com/TeMPOraL/nyan-mode/"))]) (color-identifiers-mode . [(20181011 2114) ((dash (2 5 0)) (emacs (24))) "Color identifiers based on their names" single ((:commit . "91296e02dd5f03fe5ee9aa08f95120fb716d2128") (:keywords "faces" "languages") (:authors ("Ankur Dave" . "ankurdave@gmail.com")) (:maintainer "Ankur Dave" . "ankurdave@gmail.com") (:url . "https://github.com/ankurdave/color-identifiers-mode"))]) (rainbow-identifiers . [(20141102 1526) ((emacs (24))) "Highlight identifiers according to their names" single ((:commit . "19fbfded1baa98d12335f26f6d7b20e5ae44ce2e") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/rainbow-identifiers"))]) (rainbow-mode . [(1 0 1) nil "Colorize color names in buffers" single ((:url . "http://elpa.gnu.org/packages/rainbow-mode.html") (:keywords "faces"))]) (ucs-utils . [(20150826 1414) ((persistent-soft (0 8 8)) (pcache (0 2 3)) (list-utils (0 4 2))) "Utilities for Unicode characters" tar ((:commit . "cbfd42f822bf5717934fa2d92060e6e24a813433") (:keywords "i18n" "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/ucs-utils"))]) (font-utils . [(20150806 1751) ((persistent-soft (0 8 8)) (pcache (0 2 3))) "Utility functions for working with fonts" single ((:commit . "9192d3f8ee6a4e75f34c3fed10378674cc2b11d3") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/font-utils"))]) (unicode-fonts . [(20181001 1509) ((font-utils (0 7 8)) (ucs-utils (0 8 2)) (list-utils (0 4 2)) (persistent-soft (0 8 10)) (pcache (0 3 1))) "Configure Unicode fonts" single ((:commit . "7b88ae84e589f6c8b9386b2fb5a02ff4ccb91169") (:keywords "i18n" "faces" "frames" "wp" "interface") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/unicode-fonts"))]) (list-utils . [(20160414 1402) nil "List-manipulation utility functions" single ((:commit . "acf18aca1131a90f8d673974673e3c5d8fdc6a86") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/list-utils"))]) (pcache . [(20170105 2214) ((eieio (1 3))) "persistent caching for Emacs." single ((:commit . "1f8086077d770e524492e6fa59b07856e85a6fea") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com"))]) (persistent-soft . [(20150223 1853) ((pcache (0 3 1)) (list-utils (0 4 2))) "Persistent storage, returning nil on failure" single ((:commit . "a1e0ddf2a12a6f18cab565dee250f070384cbe02") (:keywords "data" "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/persistent-soft"))]) (mu4e-alert . [(20180305 646) ((alert (1 2)) (s (1 10 0)) (ht (2 0)) (emacs (24 3))) "Desktop notification for mu4e" single ((:commit . "96a293b28646f4620e257f24748becc4a06843cd") (:keywords "mail" "convenience") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:url . "https://github.com/iqbalansari/mu4e-alert"))]) (mu4e-maildirs-extension . [(20180606 812) ((dash (0 0 0))) "Show mu4e maildirs summary in mu4e-main-view" single ((:commit . "3ef4c48516be66e73d24fe764aadbcfc126b7964") (:authors ("Andreu Gil Pàmies" . "agpchil@gmail.com")) (:maintainer "Andreu Gil Pàmies" . "agpchil@gmail.com") (:url . "http://github.com/agpchil/mu4e-maildirs-extension"))]) (helm-mu . [(20180513 921) ((helm (1 5 5))) "Helm sources for searching emails and contacts" single ((:commit . "77e6fea24e01481418738421dbcfe28ef1bd63cf") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/emacs-helm/helm-mu"))]) (persp-mode . [(20180930 1720) nil "windows/buffers sets shared among frames + save/load." single ((:commit . "689f63e7370cd9424d84b9f7b2eb3d1955443313") (:keywords "perspectives" "session" "workspace" "persistence" "windows" "buffers" "convenience") (:authors ("Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com")) (:maintainer "Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com") (:url . "https://github.com/Bad-ptr/persp-mode.el"))]) (counsel-notmuch . [(20180714 40) ((emacs (24)) (ivy (0 10 0)) (notmuch (0 21)) (s (1 12 0))) "Search emails in Notmuch asynchronously with Ivy" single ((:commit . "f4c864eca400abe0bb7420bcee80f2f8259ca0ff") (:keywords "mail") (:authors ("Alexander Fu Xi" . "fuxialexander@gmail.com")) (:maintainer "Alexander Fu Xi" . "fuxialexander@gmail.com") (:url . "https://github.com/fuxialexander/counsel-notmuch"))]) (helm-notmuch . [(20180730 1722) ((helm (1 9 3)) (notmuch (0 21))) "Search emails with Notmuch and Helm" single ((:commit . "9988eb0f787c82c779f2417b5613b9142a5b1c9b") (:keywords "mail") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/helm-notmuch"))]) (notmuch . [(20181021 1330) nil "run notmuch within emacs" tar ((:commit . "7f726c6e87517eb9c84119a1c5e3a63bfaaa49f6") (:url . "https://notmuchmail.org/"))]) (company-terraform . [(20180703 1233) ((emacs (24 4)) (company (0 8 12)) (terraform-mode (0 6))) "A company backend for terraform" tar ((:commit . "9c1146bfe23d4c461f4a59577faf4e46fcca7fe9") (:keywords "abbrev" "convenience" "terraform" "company") (:authors ("RafaÅ‚ CieÅ›lak" . "rafalcieslak256@gmail.com")) (:maintainer "RafaÅ‚ CieÅ›lak" . "rafalcieslak256@gmail.com") (:url . "https://github.com/rafalcieslak/emacs-company-terraform"))]) (hcl-mode . [(20170107 827) ((emacs (24 3))) "Major mode for Hashicorp" single ((:commit . "0f2c5ec7e7bcf77c8548e8cac8721ea935ca1b5e") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-hcl-mode"))]) (terraform-mode . [(20170112 517) ((emacs (24 3)) (hcl-mode (0 3))) "Major mode for terraform configuration file" single ((:commit . "6973d1acaba2835dfdf174f5a5e27de6366002e1") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-terraform-mode"))]) (ranger . [(20170817 1557) ((emacs (24 4))) "Make dired more like ranger" single ((:commit . "6bbff5df2e55f56047fca5058d9ca93ba4963aef") (:keywords "files" "convenience" "dired") (:authors ("Rich Alesi ")) (:maintainer "Rich Alesi ") (:url . "https://github.com/ralesi/ranger"))]) (pandoc-mode . [(20180917 721) ((hydra (0 10 0)) (dash (2 10 0))) "Minor mode for interacting with Pandoc" tar ((:commit . "d594ce399fc75eb553a6d8572713b827f744d95b") (:keywords "text" "pandoc") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (ox-pandoc . [(20180510 1338) ((org (8 2)) (emacs (24)) (dash (2 8)) (ht (2 0)) (cl-lib (0 5))) "org exporter for pandoc." single ((:commit . "aa37dc7e94213d4ebedb85c384c1ba35007da18e") (:keywords "tools") (:authors ("KAWABATA, Taichi" . "kawabata.taichi@gmail.com")) (:maintainer "KAWABATA, Taichi" . "kawabata.taichi@gmail.com") (:url . "https://github.com/kawabata/ox-pandoc"))]) (json-mode . [(20180718 809) ((json-reformat (0 0 5)) (json-snatcher (1 0 0))) "Major mode for editing JSON files." single ((:commit . "ffc92b1eefc54963703b43be140f4c8c8ad348f7") (:authors ("Josh Johnston")) (:maintainer "Josh Johnston") (:url . "https://github.com/joshwnj/json-mode"))]) (magit-popup . [(20181003 921) ((emacs (24 4)) (async (1 9 2)) (dash (2 13 0))) "Define prefix-infix-suffix command combos" tar ((:commit . "8436447e3166b797edc596cf220f3bf9b41ff4d0") (:keywords "bindings") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/magit-popup"))]) (json-snatcher . [(20150512 347) ((emacs (24))) "Grabs the path to JSON values in a JSON file" single ((:commit . "c4cecc0a5051bd364373aa499c47a1bb7a5ac51c") (:authors ("Sterling Graham" . "sterlingrgraham@gmail.com")) (:maintainer "Sterling Graham" . "sterlingrgraham@gmail.com") (:url . "http://github.com/sterlingg/json-snatcher"))]) (json-reformat . [(20160212 853) nil "Reformatting tool for JSON" single ((:commit . "8eb6668ed447988aea06467ba8f42e1f2178246f") (:keywords "json") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:url . "https://github.com/gongo/json-reformat"))]) (docker . [(20181101 504) ((emacs (24 5)) (dash (2 14 1)) (docker-tramp (0 1)) (magit-popup (2 12 4)) (s (1 12 0)) (tablist (0 70)) (json-mode (1 7 0))) "Emacs interface to Docker" tar ((:commit . "c36bce1bad03833e0d35e260ed1e402c152606ba") (:keywords "filename" "convenience") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:url . "https://github.com/Silex/docker.el"))]) (docker-tramp . [(20170207 325) ((emacs (24)) (cl-lib (0 5))) "TRAMP integration for docker containers" tar ((:commit . "8e2b671eff7a81af43b76d9dfcf94ddaa8333a23") (:keywords "docker" "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/docker-tramp.el"))]) (dockerfile-mode . [(20181104 1800) ((emacs (24)) (s (1 12))) "Major mode for editing Docker's Dockerfiles" single ((:commit . "7223d92718f78fa3ab15667cdb2ed90cfeb579e7") (:url . "https://github.com/spotify/dockerfile-mode"))]) (ycmd . [(20180724 1256) ((emacs (24 4)) (dash (2 13 0)) (s (1 11 0)) (deferred (0 5 1)) (cl-lib (0 6 1)) (let-alist (1 0 5)) (request (0 3 0)) (request-deferred (0 3 0)) (pkg-info (0 6))) "emacs bindings to the ycmd completion server" tar ((:commit . "ef87d020d3314efbac2e8925c115d0ac5c128c2a") (:url . "https://github.com/abingham/emacs-ycmd"))]) (flycheck-ycmd . [(20181016 618) ((emacs (24)) (dash (2 13 0)) (flycheck (0 22)) (ycmd (1 2)) (let-alist (1 0 5))) "flycheck integration for ycmd" single ((:commit . "ef87d020d3314efbac2e8925c115d0ac5c128c2a") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/emacs-ycmd"))]) (levenshtein . [(20090830 1040) nil "Edit distance between two strings." single ((:commit . "070925197ebf6b704e6e00c4f2d2ec783f3df38c") (:keywords "lisp") (:authors ("Aaron S. Hawley ,") ("Art Taylor")) (:maintainer "Aaron S. Hawley ,"))]) (cmake-ide . [(20181023 1430) ((emacs (24 4)) (cl-lib (0 5)) (seq (1 11)) (levenshtein (0)) (s (1 11 0))) "Calls CMake to find out include paths and other compiler flags" single ((:commit . "0a90200a74913f07c0ed08d1a1d5ebe314af26a4") (:keywords "languages") (:authors ("Atila Neves" . "atila.neves@gmail.com")) (:maintainer "Atila Neves" . "atila.neves@gmail.com") (:url . "http://github.com/atilaneves/cmake-ide"))]) (cmake-mode . [(20180709 1426) nil "major-mode for editing CMake sources" single ((:commit . "be9ad8279a29893943b342cc5ffdbf9868fb1b4c"))]) (helm-ctest . [(20180821 1005) ((s (1 9 0)) (dash (2 11 0)) (helm-core (1 7 4))) "Run ctest from within emacs" single ((:commit . "0c73689692a290f56080e95325c15362e90d529b") (:keywords "helm" "ctest") (:authors ("Dan LaManna" . "me@danlamanna.com")) (:maintainer "Dan LaManna" . "me@danlamanna.com"))]) (bm . [(20181012 1631) nil "Visible bookmarks in buffer." tar ((:commit . "b85d407b53e1d852c47fcea2a245a4e67e48c38a") (:keywords "bookmark" "highlight" "faces" "persistent") (:authors ("Jo Odland ")) (:maintainer "Jo Odland ") (:url . "https://github.com/joodland/bm"))]) (ivy-pass . [(20170812 1955) ((emacs (24)) (ivy (0 8 0)) (password-store (1 6 5))) "ivy interface for pass" single ((:commit . "5b523de1151f2109fdd6a8114d0af12eef83d3c5") (:keywords "pass" "password" "convenience" "data") (:authors ("ecraven")) (:maintainer "ecraven") (:url . "https://github.com/ecraven/ivy-pass/"))]) (auth-source-pass . [(20181106 1348) ((emacs (25))) "Integrate auth-source with password-store" single ((:commit . "63c0631896b2f2ed6b359e026c6a7949932aa0bf") (:authors ("Damien Cassou" . "damien@cassou.me") ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/auth-password-store"))]) (helm-pass . [(20180607 2348) ((emacs (25)) (helm (0)) (password-store (0)) (auth-source-pass (4 0 0))) "helm interface of pass, the standard Unix password manager" single ((:commit . "fdff8f8f2e2b8a61caed7b6c171624700dbe1346") (:authors ("J. Alexander Branham" . "branham@utexas.edu")) (:maintainer "J. Alexander Branham" . "branham@utexas.edu") (:url . "https://github.com/jabranham/helm-pass"))]) (with-editor . [(20181113 1845) ((emacs (24 4)) (async (1 9))) "Use the Emacsclient as $EDITOR" tar ((:commit . "9dd9f176d96abc60365369de6d08c26c414ef1f3") (:keywords "tools") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/with-editor"))]) (password-store . [(20181031 1440) ((emacs (24)) (f (0 11 0)) (s (1 9 0)) (with-editor (2 5 11))) "Password store (pass) support" single ((:commit . "d29a389a40524c684595f51bb937f66958bc14ea") (:keywords "tools" "pass" "password" "password-store") (:authors ("Svend Sorensen" . "svend@svends.net")) (:maintainer "Svend Sorensen" . "svend@svends.net") (:url . "https://www.passwordstore.org/"))]) (esh-help . [(20170830 411) ((dash (1 4 0))) "Add some help functions and support for Eshell" single ((:commit . "8a8a9d4d9852f8bd96da3b94e95ff57097ac8ec6") (:keywords "eshell" "extensions") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/esh-help/"))]) (eshell-prompt-extras . [(20180110 634) nil "Display extra information for your eshell prompt." single ((:commit . "1d8825dcc005b488c6366d0b3015fc6686194eea") (:keywords "eshell" "prompt") (:authors ("Wei Zhao" . "kaihaosw@gmail.com")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/hiddenlotus/eshell-prompt-extras"))]) (eshell-z . [(20170117 438) ((cl-lib (0 5))) "cd to frequent directory in eshell" single ((:commit . "c9334cbc1552234df3437f35d98e32f4d18446b8") (:keywords "convenience") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/eshell-z"))]) (multi-term . [(20160619 933) nil "Managing multiple terminal buffers in Emacs." single ((:commit . "f954e4e18b0a035151d34852387e724d87a3316f") (:keywords "term" "terminal" "multiple buffer") (:authors ("Andy Stewart" . "lazycat.manatee@gmail.com")) (:maintainer "Andy Stewart" . "lazycat.manatee@gmail.com") (:url . "http://www.emacswiki.org/emacs/download/multi-term.el"))]) (shell-pop . [(20170304 1416) ((emacs (24)) (cl-lib (0 5))) "helps you to use shell easily on Emacs. Only one key action to work." single ((:commit . "4a3a9d093ad1add792bba764c601aa28de302b34") (:keywords "shell" "terminal" "tools") (:authors ("Kazuo YAGI" . "kazuo.yagi@gmail.com")) (:maintainer "Kazuo YAGI" . "kazuo.yagi@gmail.com") (:url . "http://github.com/kyagi/shell-pop-el"))]) (xterm-color . [(20180202 2318) ((cl-lib (0 5))) "ANSI & XTERM 256 color support" single ((:commit . "42374a98f1039e105cad9f16ce585dffc96a3f1c") (:keywords "faces") (:authors (nil . "xristos@sdf.lonestar.org")) (:maintainer nil . "xristos@sdf.lonestar.org") (:url . "https://github.com/atomontage/xterm-color"))]) (vagrant . [(20170301 2206) nil "Manage a vagrant box from emacs" single ((:commit . "636ce2f9af32ea199170335a9cf1201b64873440") (:keywords "vagrant" "chef") (:authors ("Robert Crim" . "rob@servermilk.com")) (:maintainer "Robert Crim" . "rob@servermilk.com") (:url . "https://github.com/ottbot/vagrant.el"))]) (vagrant-tramp . [(20160427 2332) ((dash (2 12 0))) "Vagrant method for TRAMP" tar ((:commit . "453ba605b28d2964bb4e10074f1e6891ebb4d2d6") (:keywords "vagrant") (:authors ("Doug MacEachern" . "dougm@vmware.com") ("Ryan Prior " . "ryanprior@gmail.com")) (:maintainer "Doug MacEachern" . "dougm@vmware.com") (:url . "https://github.com/dougm/vagrant-tramp"))]) (systemd . [(20180629 2106) ((emacs (24 4))) "Major mode for editing systemd units" tar ((:commit . "401d71c2dd24e424216ae5e4275c830f2a9c6b0c") (:keywords "tools" "unix") (:authors ("Mark Oteiza" . "mvoteiza@udel.edu")) (:maintainer "Mark Oteiza" . "mvoteiza@udel.edu"))]) (lsp-mode . [(20181115 308) ((emacs (25 1))) "Minor mode for interacting with Language Servers" tar ((:commit . "9e0426cf88190a5c350a5436ab11af6f8d4d412e") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-mode"))]) (lsp-ui . [(20181031 2002) ((emacs (25 1)) (dash (2 14)) (dash-functional (1 2 0)) (flycheck (31)) (lsp-mode (5 0)) (markdown-mode (2 3))) "UI modules for lsp-mode" tar ((:commit . "5138e720451dfbcae2f55a8380416340d5706583") (:keywords "lsp") (:authors ("Sebastien Chapuis , Fangrui Song" . "i@maskray.me")) (:maintainer "Sebastien Chapuis , Fangrui Song" . "i@maskray.me") (:url . "https://github.com/emacs-lsp/lsp-ui"))]) (ansible . [(20180813 114) ((s (1 9 0)) (f (0 16 2))) "Ansible minor mode" tar ((:commit . "8a097176d6772b6667254dbbe19c5fb64527bf5d") (:authors ("k1LoW (Kenichirou Oyama), ")) (:maintainer "k1LoW (Kenichirou Oyama), ") (:url . "http://101000lab.org"))]) (ansible-doc . [(20160924 824) ((emacs (24 3))) "Ansible documentation Minor Mode" single ((:commit . "86083a7bb2ed0468ca64e52076b06441a2f8e9e0") (:keywords "tools" "help") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn") (:url . "https://github.com/lunaryorn/ansible-doc.el"))]) (company-ansible . [(20180701 1813) ((emacs (24 4)) (company (0 8 12))) "A company back-end for ansible" tar ((:commit . "c6dc714e3a15f89671ae5e8fe668858b20ef63e8") (:keywords "ansible") (:authors ("Krzysztof Magosa" . "krzysztof@magosa.pl")) (:maintainer "Krzysztof Magosa" . "krzysztof@magosa.pl") (:url . "https://github.com/krzysztof-magosa/company-ansible"))]) (jinja2-mode . [(20141128 1007) nil "A major mode for jinja2" single ((:commit . "cfaa7bbe7bb290cc500440124ce89686f3e26f86") (:authors ("Florian Mounier aka paradoxxxzero")) (:maintainer "Florian Mounier aka paradoxxxzero"))]) (mmm-jinja2 . [(20170313 1420) ((mmm-mode (0 5 4))) "MMM submode class for Jinja2 Templates" single ((:commit . "c8cb763174fa2fb61b9a0e5e0ff8cb0210f8492f") (:authors ("Ben Hayden" . "hayden767@gmail.com")) (:maintainer "Ben Hayden" . "hayden767@gmail.com") (:url . "https://github.com/glynnforrest/mmm-jinja2"))]) (yaml-mode . [(20180409 607) ((emacs (24 1))) "Major mode for editing YAML files" single ((:commit . "40067a10ac1360f0b9533f0bbbb2eea128e2574d") (:keywords "data" "yaml") (:authors ("Yoshiki Kurihara" . "clouder@gmail.com") ("Marshall T. Vandegrift" . "llasram@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com"))]) (mmm-mode . [(0 5 7) ((cl-lib (0 2))) "Allow Multiple Major Modes in a buffer" tar ((:keywords "convenience" "faces" "languages" "tools") (:url . "https://github.com/purcell/mmm-mode"))]) (salt-mode . [(20181015 1025) ((emacs (24 4)) (yaml-mode (0 0 12)) (mmm-mode (0 5 4)) (mmm-jinja2 (0 1))) "Major mode for Salt States" single ((:commit . "432eaf8a48a79ec5e3b6149dac28370e140155e4") (:keywords "languages") (:authors ("Ben Hayden" . "hayden767@gmail.com")) (:maintainer "Glynn Forrest" . "me@glynnforrest.com") (:url . "https://github.com/glynnforrest/salt-mode"))]) (nginx-mode . [(20170612 437) nil "major mode for editing nginx config files" single ((:commit . "a2bab83c2eb233d57d76b236e7c141c2ccc97005") (:keywords "languages" "nginx") (:authors ("Andrew J Cosgriff" . "andrew@cosgriff.name")) (:maintainer "Andrew J Cosgriff" . "andrew@cosgriff.name"))]) (command-log-mode . [(20160413 447) nil "log keyboard commands to buffer" single ((:commit . "af600e6b4129c8115f464af576505ea8e789db27") (:keywords "help") (:authors ("Michael Weber" . "michaelw@foldr.org")) (:maintainer "Michael Weber" . "michaelw@foldr.org") (:url . "https://github.com/lewang/command-log-mode"))]) (rebox2 . [(20121113 1300) nil "Handling of comment boxes in various styles." single ((:commit . "00634eca420cc48657b81e40e599ff8548083985") (:authors ("François Pinard") ("Le Wang")) (:maintainer "Le Wang (lewang.emacs!!!gmayo.com remove exclamations, correct host, hint: google mail)") (:url . "https://github.com/lewang/rebox2"))]) (edit-server . [(20181016 1125) nil "server that responds to edit requests from Chrome" single ((:commit . "81eb5211f79cf5a2234b7a932f6006d27d506aa5") (:authors ("Alex Bennée" . "alex@bennee.com")) (:maintainer "Alex Bennée" . "alex@bennee.com") (:url . "https://github.com/stsquad/emacs_chrome"))]) (ham-mode . [(20150811 1306) ((html-to-markdown (1 2)) (markdown-mode (2 0))) "Html As Markdown. Transparently edit an html file using markdown" single ((:commit . "3a141986a21c2aa6eefb428983352abb8b7907d2") (:keywords "convenience" "emulation" "wp") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/ham-mode"))]) (markdown-mode . [(20181112 1529) ((emacs (24 4)) (cl-lib (0 5))) "Major mode for Markdown-formatted text" single ((:commit . "d18a8f856d19dfac8fa6e6e72b2448e262045fcc") (:keywords "markdown" "github flavored markdown" "itex") (:authors ("Jason R. Blevins" . "jblevins@xbeta.org")) (:maintainer "Jason R. Blevins" . "jblevins@xbeta.org") (:url . "https://jblevins.org/projects/markdown-mode/"))]) (html-to-markdown . [(20151105 840) ((cl-lib (0 5))) "HTML to Markdown converter written in Emacs-lisp." single ((:commit . "60c5498c801be186478cf7c05be05b4430c4a144") (:keywords "tools" "wp" "languages") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/html-to-markdown"))]) (gmail-message-mode . [(20160627 1847) ((ham-mode (1 0))) "A major-mode for editing gmail messages using markdown syntax." single ((:commit . "ec36672a9dc93c09ebe2f77597b498d11883d008") (:keywords "mail" "convenience" "emulation") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/gmail-message-mode"))]) (flymd . [(20160617 1214) ((cl-lib (0 5))) "On the fly markdown preview" tar ((:commit . "84d5a68bcfed4a295952c33ffcd11e880978d9d7") (:keywords "markdown" "convenience") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:url . "https://github.com/mola-T/flymd"))]) (osx-location . [(20150613 917) nil "Watch and respond to changes in geographical location on OS X" tar ((:commit . "8bb3a94cc9f04b922d2d730fe08596cc6ee12bf2"))]) (rase . [(20120928 2045) nil "Run At Sun Event daemon" single ((:commit . "59b5f7e8102570b65040e8d55781c7ea28de7338") (:keywords "solar" "sunrise" "sunset" "midday" "midnight") (:authors ("Andrey Kotlarski" . "m00naticus@gmail.com")) (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:url . "https://github.com/m00natic/rase/"))]) (sunshine . [(20181029 1654) ((cl-lib (0 5))) "Provide weather and forecast information." single ((:commit . "8959dea03377e61aaca0124ac8d2703daaae6b9a") (:keywords "tools" "weather") (:authors ("Aaron Bieber" . "aaron@aaronbieber.com")) (:maintainer "Aaron Bieber" . "aaron@aaronbieber.com") (:url . "https://github.com/aaronbieber/sunshine.el"))]) (theme-changer . [(20171221 1927) nil "Sunrise/Sunset Theme Changer for Emacs" single ((:commit . "61945695a30d678e6a5d47cbe7c8aff59a8c30ea") (:keywords "color-theme" "deftheme" "solar" "sunrise" "sunset") (:authors ("Joshua B. Griffith" . "josh.griffith@gmail.com")) (:maintainer "Joshua B. Griffith" . "josh.griffith@gmail.com") (:url . "https://github.com/hadronzoo/theme-changer"))]) (transmission . [(20180728 1717) ((emacs (24 4)) (let-alist (1 0 5))) "Interface to a Transmission session" single ((:commit . "bbe4077b89afe732d346eeed1ad0783537f33480") (:keywords "comm" "tools") (:authors ("Mark Oteiza" . "mvoteiza@udel.edu")) (:maintainer "Mark Oteiza" . "mvoteiza@udel.edu"))]) (prodigy . [(20180511 938) ((s (1 8 0)) (dash (2 4 0)) (f (0 14 0)) (emacs (24))) "Manage external services from within Emacs" single ((:commit . "701dccaa56de9e6a330c05bde33bce4f3b3d6a97") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/prodigy.el"))]) (flycheck-ledger . [(20180819 321) ((flycheck (0 15))) "Flycheck integration for ledger files" single ((:commit . "8d7f52a4c7f80ca396ef0fc6c7d8e9f005778dfc") (:keywords "convenience" "languages" "tools") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (ledger-mode . [(20181107 1942) ((emacs (24 3))) "Helper code for use with the \"ledger\" command-line tool" tar ((:commit . "1f5c68fb59d81d2fffe49436ee99a8c291a4fe41"))]) (evil-ledger . [(20180802 1612) ((emacs (24 4)) (evil (1 2 12)) (ledger-mode (0))) "Make `ledger-mode' more `evil'." single ((:commit . "7a9f9f5d39c42fffdba8004f8982642351f2b233") (:keywords "convenience" "evil" "languages" "ledger" "vim-emulation") (:authors ("Aaron Jacobs" . "atheriel@gmail.com")) (:maintainer "Aaron Jacobs" . "atheriel@gmail.com") (:url . "https://github.com/atheriel/evil-ledger"))]) (know-your-http-well . [(20160208 2304) nil "Look up the meaning of HTTP headers, methods, relations, status codes" tar ((:commit . "3cc5ab6d2764ab7aacb1b6e026abaccbeb6c37f2"))]) (company-restclient . [(20151202 1201) ((cl-lib (0 5)) (company (0 8 0)) (emacs (24)) (know-your-http-well (0 2 0)) (restclient (0 0 0))) "company-mode completion back-end for restclient-mode" single ((:commit . "19d819b14b7cd186a840369060963a08377d052e") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-restclient"))]) (ob-http . [(20180707 1448) ((s (1 9 0)) (cl-lib (0 5))) "http request in org-mode babel" tar ((:commit . "b1428ea2a63bcb510e7382a1bf5fe82b19c104a7") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-http"))]) (ob-restclient . [(20180904 709) ((restclient (0))) "org-babel functions for restclient-mode" single ((:commit . "00b2c5a6637ab6e504708612357ffb29b5416e4b") (:keywords "literate programming" "reproducible research") (:authors ("Alf LervÃ¥g")) (:maintainer "Alf LervÃ¥g") (:url . "http://orgmode.org"))]) (restclient . [(20180316 1551) nil "An interactive HTTP client for Emacs" single ((:commit . "859d944796ce298b5779d9d256bd8d271d57e221") (:keywords "http") (:authors ("Pavel Kurnosov" . "pashky@gmail.com")) (:maintainer "Pavel Kurnosov" . "pashky@gmail.com"))]) (restclient-helm . [(20170314 1554) ((restclient (0)) (helm (1 9 4))) "helm interface for restclient.el" single ((:commit . "859d944796ce298b5779d9d256bd8d271d57e221") (:keywords "http" "helm") (:authors ("Pavel Kurnosov" . "pashky@gmail.com")) (:maintainer "Pavel Kurnosov" . "pashky@gmail.com"))]) (ob-cfengine3 . [(20180102 1812) nil "Org Babel functions for CFEngine 3" single ((:commit . "93ebcfceec3734f4bd187ae123686187d66fd401") (:keywords "tools" "convenience") (:authors ("Nick Anderson" . "nick@cmdln.org")) (:maintainer "Nick Anderson" . "nick@cmdln.org") (:url . "https://github.com/nickanderson/ob-cfengine3"))]) (tern . [(20181108 722) ((json (1 2)) (cl-lib (0 5)) (emacs (24))) "Tern-powered JavaScript integration" single ((:commit . "e94e20be8510040744fc803c9fda6bbb9625c6d2") (:authors ("Marijn Haverbeke")) (:maintainer "Marijn Haverbeke") (:url . "http://ternjs.net/"))]) (company-tern . [(20161004 1847) ((company (0 8 0)) (tern (0 0 1)) (dash (2 8 0)) (dash-functional (2 8 0)) (s (1 9 0)) (cl-lib (0 5 0))) "Tern backend for company-mode" single ((:commit . "10ac058b065ae73c1f30e9fb7d969dd1a79387be") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/company-tern"))]) (puppet-mode . [(20180813 1947) ((emacs (24 1)) (pkg-info (0 4))) "Major mode for Puppet manifests" single ((:commit . "7dee1b5a5debac6e56f9107492a413b6c0edb94d") (:keywords "languages") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com") ("Russ Allbery" . "rra@stanford.edu")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "https://github.com/voxpupuli/puppet-mode"))]) (fasd . [(20180606 505) nil "Emacs integration for the command-line productivity booster `fasd'" single ((:commit . "020c6a4b5fd1498a84ae142d2e32c7ff678fb029") (:keywords "cli" "bash" "zsh" "autojump") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:url . "https://framagit.org/steckerhalter/emacs-fasd"))]) (evil-tutor-ja . [(20160917 132) ((evil (1 0 9)) (evil-tutor (0 1))) "Japanese Vimtutor adapted to Evil and wrapped in a major-mode" tar ((:commit . "99af7d82e02ce3bcdfaff47c5c80b57327a7ea8d") (:keywords "convenience" "editing" "evil" "japanese") (:authors ("Kenji Miyazaki" . "kenjizmyzk@gmail.com")) (:maintainer "Kenji Miyazaki" . "kenjizmyzk@gmail.com") (:url . "https://github.com/kenjimyzk/evil-tutor-ja"))]) (migemo . [(20160924 1441) ((cl-lib (0 5))) "Japanese incremental search through dynamic pattern expansion" single ((:commit . "e4744efae1b2fdea2bbd2ceaff0f6ea0bb739f5a") (:authors ("Satoru Takabayashi" . "satoru-t@is.aist-nara.ac.jp")) (:maintainer "Satoru Takabayashi" . "satoru-t@is.aist-nara.ac.jp") (:url . "https://github.com/emacs-jp/migemo"))]) (avy-migemo . [(20180716 1455) ((emacs (24 4)) (avy (0 4 0)) (migemo (1 9))) "avy with migemo" tar ((:commit . "922a6dd82c0bfa316b0fbb56a9d4dd4ffa5707e7") (:keywords "avy" "migemo") (:authors ("momomo5717")) (:maintainer "momomo5717") (:url . "https://github.com/momomo5717/avy-migemo"))]) (cdb . [(20151205 1343) nil "constant database (cdb) reader for Emacs Lisp" single ((:commit . "b05c610e27b86e71fb4e8d67292ef6a696dd5992") (:keywords "cdb") (:authors ("Yusuke Shinyama ")) (:maintainer "SKK Development Team" . "skk@ring.gr.jp"))]) (ccc . [(20151205 1343) nil "buffer local cursor color control library" single ((:commit . "b05c610e27b86e71fb4e8d67292ef6a696dd5992") (:keywords "cursor") (:authors ("Masatake YAMATO" . "masata-y@is.aist-nara.ac.jp")) (:maintainer "SKK Development Team" . "skk@ring.gr.jp") (:url . "https://github.com/skk-dev/ddskk/blob/master/READMEs/README.ccc.org"))]) (ddskk . [(20180707 532) ((ccc (1 43)) (cdb (20141201 754))) "Simple Kana to Kanji conversion program." tar ((:commit . "b05c610e27b86e71fb4e8d67292ef6a696dd5992"))]) (japanese-holidays . [(20160928 618) ((cl-lib (0 3))) "calendar functions for the Japanese calendar" single ((:commit . "0bccfac342d6ebda1c1a35c3babca0c800ff0c9b") (:keywords "calendar") (:authors ("Takashi Hattori" . "hattori@sfc.keio.ac.jp") ("Hiroya Murata" . "lapis-lazuli@pop06.odn.ne.jp")) (:maintainer "Takashi Hattori" . "hattori@sfc.keio.ac.jp") (:url . "https://github.com/emacs-jp/japanese-holidays"))]) (pangu-spacing . [(20170317 857) nil "Minor-mode to add space between Chinese and English characters." single ((:commit . "a4463dbb74abdeddb6c1c132a1f8fcf67ed87498") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/pangu-spacing"))]) (pyim-basedict . [(20170727 259) nil "The default pinyin dict of pyim" tar ((:commit . "3196cb210e056702c5a4ea1dac1d8e1e27740fab") (:keywords "convenience" "chinese" "pinyin" "input-method" "complete") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/pyim-basedict"))]) (pyim . [(20181109 1350) ((emacs (24 4)) (popup (0 1)) (async (1 6)) (pyim-basedict (0 1))) "A Chinese input method support quanpin, shuangpin, wubi and cangjie." tar ((:commit . "8648d467d79b3bf1c3a99623f9329939cacc40da") (:keywords "convenience" "chinese" "pinyin" "input-method") (:authors ("Ye Wenbin , Feng Shu" . "tumashu@163.com")) (:maintainer "Ye Wenbin , Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/pyim"))]) (chinese-wbim . [(20150624 350) nil "Enable Wubi Input Method in Emacs." tar ((:commit . "57ff61ff3895d77335709d24b40cefc4d10b0095"))]) (fcitx . [(20170914 200) nil "Make fcitx better in Emacs" single ((:commit . "095332fbeb994c908c533fe2ad068c0728211c3d") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/fcitx.el"))]) (find-by-pinyin-dired . [(20180210 218) ((pinyinlib (0 1 0))) "Find file by first PinYin character of Chinese Hanzi" single ((:commit . "3b4781148dddc84a701ad76c0934ed991ecd59d5") (:keywords "hanzi" "chinese" "dired" "find" "file" "pinyin") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/find-by-pinyin-dired"))]) (pinyinlib . [(20170827 2142) nil "Convert first letter of Pinyin to Simplified/Traditional Chinese characters" single ((:commit . "45f05d3dbb4fe957f7ab332ca6f94675848b6aa3") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (ace-pinyin . [(20170501 626) ((avy (0 2 0)) (pinyinlib (0 1 0))) "Jump to Chinese characters using avy or ace-jump-mode" single ((:commit . "a9df88c1e6a32a4f4895acbb8c45383693c494c1") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/ace-pinyin"))]) (names . [(20180321 1155) ((emacs (24 1)) (cl-lib (0 5))) "Namespaces for emacs-lisp. Avoid name clobbering without hiding symbols." tar ((:commit . "d8baba5360e5253938a25d3e005455b6d2d86971") (:keywords "extensions" "lisp") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/names"))]) (chinese-word-at-point . [(20170811 941) ((cl-lib (0 5))) "Add `chinese-word' thing to `thing-at-point'" single ((:commit . "8223d7439e005555b86995a005b225ae042f0538") (:keywords "convenience" "chinese") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/chinese-word-at-point.el"))]) (youdao-dictionary . [(20180714 414) ((popup (0 5 0)) (pos-tip (0 4 6)) (chinese-word-at-point (0 2)) (names (0 5)) (emacs (24))) "Youdao Dictionary interface for Emacs" single ((:commit . "9496ea3ba8aa999db3dbde88d6aa37f3579d8dea") (:keywords "convenience" "chinese" "dictionary") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/youdao-dictionary.el"))]) (chinese-conv . [(20170807 2128) ((cl-lib (0 5))) "Conversion between Chinese Characters with opencc or cconv" single ((:commit . "b56815bbb163d642e97fa73093b5a7e87cc32574") (:authors ("gucong" . "gucong43216@gmail.com")) (:maintainer "gucong" . "gucong43216@gmail.com") (:url . "https://github.com/gucong/emacs-chinese-conv"))]) (evil-escape . [(20180910 1234) nil "No description available." single ((:commit . "f4e9116bfbaac8c9d210c17ad488e0982291245f"))]) (eyebrowse . [(20180514 1919) ((dash (2 7 0)) (emacs (24 3 1))) "Easy window config switching" single ((:commit . "dfeea9e9cd6dcd78ddc9fccdf9a21f7317f754bc") (:keywords "convenience") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/eyebrowse"))]) (neotree . [(20181113 2125) ((cl-lib (0 5))) "A tree plugin like NerdTree for Vim" tar ((:commit . "6e3ae07b08d4dd218c119e91a101d7e7ed6ef4d9") (:authors ("jaypei" . "jaypei97159@gmail.com")) (:maintainer "jaypei" . "jaypei97159@gmail.com") (:url . "https://github.com/jaypei/emacs-neotree"))]) (exec-path-from-shell . [(20180324 204) nil "Get environment variables such as $PATH from the shell" single ((:commit . "9bc0f4a762f16d488376fb52409c58239a86d75d") (:keywords "unix" "environment") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/exec-path-from-shell"))]) (launchctl . [(20150518 1309) ((emacs (24 1))) "Interface to launchctl on Mac OS X." single ((:commit . "73f8f52a5aa9a0be9bdcf68c29ad0fa2b4a115a4") (:keywords "tools" "convenience") (:authors ("Peking Duck ")) (:maintainer "Peking Duck ") (:url . "http://github.com/pekingduck/launchctl-el"))]) (osx-dictionary . [(20171026 734) ((cl-lib (0 5))) "Interface for OSX Dictionary.app" tar ((:commit . "b16630ecf69f87ac873486d8b9c8c03e6c9ea7fa") (:keywords "mac" "dictionary") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/osx-dictionary.el"))]) (osx-trash . [(20160520 1300) ((emacs (24 1))) "System trash for OS X" tar ((:commit . "0f1dc052d0a750b8c75f14530a4897f5d4324b4e") (:keywords "files" "convenience" "tools" "unix") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/lunaryorn/osx-trash.el"))]) (reveal-in-osx-finder . [(20150802 1657) nil "Reveal file associated with buffer in OS X Finder" single ((:commit . "5710e5936e47139a610ec9a06899f72e77ddc7bc") (:keywords "os x" "finder") (:authors ("Kazuki YOSHIDA")) (:maintainer "Kazuki YOSHIDA") (:url . "https://github.com/kaz-yos/reveal-in-osx-finder"))]) (company-nixos-options . [(20160215 857) ((company (0 8 0)) (nixos-options (0 0 1)) (cl-lib (0 5 0))) "Company Backend for nixos-options" single ((:commit . "45c8d90748304c90e1503c9fa8db0443f3d4bd89") (:keywords "unix") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))]) (helm-nixos-options . [(20151013 2309) ((nixos-options (0 0 1)) (helm (1 5 6))) "Helm Interface for nixos-options" single ((:commit . "45c8d90748304c90e1503c9fa8db0443f3d4bd89") (:keywords "unix") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))]) (nix-mode . [(20181030 346) ((emacs (24 3))) "Major mode for editing .nix files" tar ((:commit . "84ee98019fbb48854ebd57cc74848b7e7327a78c") (:keywords "nix" "languages" "tools" "unix") (:maintainer "Matthew Bauer" . "mjbauer95@gmail.com") (:url . "https://github.com/NixOS/nix-mode"))]) (nixos-options . [(20160209 1841) ((emacs (24))) "Interface for browsing and completing NixOS options." single ((:commit . "45c8d90748304c90e1503c9fa8db0443f3d4bd89") (:keywords "unix") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))]) (selectric-mode . [(20170216 1111) nil "IBM Selectric mode for Emacs" tar ((:commit . "aed70015b29074b52a5d0c49b88b7a501d276dda") (:keywords "multimedia" "convenience" "typewriter" "selectric") (:authors ("Ricardo Bánffy" . "rbanffy@gmail.com")) (:maintainer "Ricardo Banffy" . "rbanffy@gmail.com") (:url . "https://github.com/rbanffy/selectric-mode"))]) (2048-game . [(20151026 1933) nil "play 2048 in Emacs" single ((:authors ("Zachary Kanfer" . "zkanfer@gmail.com")) (:maintainer "Zachary Kanfer" . "zkanfer@gmail.com") (:url . "https://bitbucket.org/zck/2048.el"))]) (pacmacs . [(20160131 832) ((emacs (24 4)) (dash (2 11 0)) (dash-functional (1 2 0)) (cl-lib (0 5)) (f (0 18 0))) "Pacman for Emacs" tar ((:commit . "d813e9c62c2540fe619234824fc60e128c786442") (:authors ("Codingteam" . "codingteam@conference.jabber.ru")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/codingteam/pacmacs.el"))]) (sudoku . [(20161111 706) ((emacs (24 4))) "Simple sudoku game, can download puzzles" single ((:commit . "77c11b5041b58fc943cf1668b44b40bae039cb5b") (:keywords "games") (:authors ("Zajcev Evgeny" . "zevlg@yandex.ru")) (:maintainer "Zajcev Evgeny" . "zevlg@yandex.ru"))]) (mmt . [(20180101 619) ((emacs (24 1)) (cl-lib (0 3))) "Missing macro tools for Emacs Lisp" single ((:commit . "e860009ce531ee05d2902309db5f804326596b45") (:keywords "macro" "emacs-lisp") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/mmt"))]) (typit . [(20180317 807) ((emacs (24 4)) (f (0 18)) (mmt (0 1 1))) "Typing game similar to tests on 10 fast fingers" tar ((:commit . "4fe50d616fc60e77eb9b5a824c0a1ca4010b0746") (:keywords "games") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/typit"))]) (xkcd . [(20160419 1130) ((json (1 3))) "View xkcd from Emacs" single ((:commit . "66e928706fd660cfdab204c98a347b49c4267bdf") (:keywords "xkcd" "webcomic") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/vibhavp/emacs-xkcd"))]) (rcirc-color . [(0 4 1) ((emacs (24 4))) "color nicks" single ((:url . "http://elpa.gnu.org/packages/rcirc-color.html") (:keywords "comm"))]) (rcirc-notify . [(20150219 2204) nil "libnotify popups" single ((:commit . "841a7b5a6cdb0c11a812df924d2c6a7d364fd455") (:keywords "lisp" "rcirc" "irc" "notify" "growl") (:authors ("Will Farrington, Alex Schroeder , Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk"))]) (srv . [(20180715 1959) ((emacs (24 3))) "perform SRV DNS requests" single ((:commit . "714387d5a5cf34d8d8cd96bdb1f9cb8ded823ff7") (:keywords "comm") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com") (:url . "https://github.com/legoscia/srv.el"))]) (fsm . [(0 2 1) ((emacs (24 1)) (cl-lib (0 5))) "state machine library" single ((:url . "http://elpa.gnu.org/packages/fsm.html") (:keywords "extensions"))]) (jabber . [(20180927 2325) ((fsm (0 2)) (srv (0 2))) "A Jabber client for Emacs." tar ((:commit . "fff33826f42e040dad7ef64ea312d85215d3b0a1"))]) (emojify . [(20180611 1538) ((seq (1 11)) (ht (2 0)) (emacs (24 3))) "Display emojis in Emacs" tar ((:commit . "38ae28d95b58e9fb86a3495a2dda3e5de254c4fc") (:keywords "multimedia" "convenience") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:url . "https://github.com/iqbalansari/emacs-emojify"))]) (circe . [(20180525 1231) ((cl-lib (0 5))) "Client for IRC in Emacs" tar ((:commit . "fedfa7eb8516a53fa70b6a1f4fce4b5ab66ea91f") (:url . "https://github.com/jorgenschaefer/circe"))]) (oauth2 . [(0 11) nil "OAuth 2.0 Authorization Protocol" single ((:url . "http://elpa.gnu.org/packages/oauth2.html") (:keywords "comm"))]) (websocket . [(20180423 16) ((cl-lib (0 5))) "Emacs WebSocket client and server" single ((:commit . "0d96ba2ff5a25c6cd6c66f417cc9b5f38a4308ba") (:keywords "communication" "websocket" "server") (:authors ("Andrew Hyatt" . "ahyatt@gmail.com")) (:maintainer "Andrew Hyatt" . "ahyatt@gmail.com"))]) (slack . [(20181113 336) ((websocket (1 8)) (request (0 2 0)) (oauth2 (0 10)) (circe (2 2)) (alert (1 2)) (emojify (0 2))) "Slack client for Emacs" tar ((:commit . "19af9a367b55ca79377058f4d9b5776dd98a9f99") (:url . "https://github.com/yuya373/emacs-slack"))]) (erc-hl-nicks . [(20180415 1946) nil "ERC nick highlighter that ignores uniquifying chars when colorizing" single ((:commit . "756c4438a8245ccd3e389bf6c9850ee8453783ec") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/erc-hl-nicks"))]) (erc-image . [(20180522 1424) nil "Show received image urls in the ERC buffer" single ((:commit . "82fb3871f02e24b1e880770b9a3d187aab43d0f0") (:keywords "multimedia") (:authors ("Jon de Andrés Frías" . "jondeandres@gmail.com") ("Raimon Grau Cuscó" . "raimonster@gmail.com")) (:maintainer "Jon de Andrés Frías" . "jondeandres@gmail.com"))]) (erc-social-graph . [(20150508 1204) nil "A social network graph module for ERC." single ((:commit . "e6ef3416a1c5064054bf054d9f0c1c7bf54a9cd0") (:keywords "erc" "graph") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/vibhavp/erc-social-graph"))]) (erc-terminal-notifier . [(20140115 1024) nil "OSX notifications via the terminal-notifier gem for Emacs ERC." single ((:commit . "a3dacb935845e4a20031212bbd82b2170f68d2a8") (:keywords "erc" "terminal-notifier" "nick") (:authors ("Julien Blanchard" . "julien@sideburns.eu")) (:maintainer "Julien Blanchard" . "julien@sideburns.eu") (:url . "http://github.com/julienXX/"))]) (erc-view-log . [(20140227 2039) nil "Major mode for viewing ERC logs" single ((:commit . "c5a25f0cbca84ed2e4f72068c02b66bd0ea3b266") (:keywords "erc" "viewer" "logs" "colors") (:authors ("Antoine Levitt") ("Thomas Riccardi" . "riccardi.thomas@gmail.com")) (:maintainer "Antoine Levitt") (:url . "http://github.com/Niluge-KiWi/erc-view-log/raw/master/erc-view-log.el"))]) (erc-yt . [(20150426 1249) ((dash (2 10 0))) "An erc module to display youtube links nicely" single ((:commit . "43e7d49325b17a3217a6ffb4a9daf75c5ff4e6f8") (:keywords "multimedia") (:authors ("William Stevenson" . "yhvh2000@gmail.com")) (:maintainer "William Stevenson" . "yhvh2000@gmail.com"))]) (spotify . [(20181030 810) ((cl-lib (0 5))) "Control the spotify application from emacs" single ((:commit . "29577cf1188161f98b8358c149aaf47b2c137902") (:keywords "convenience") (:authors ("R.W. van 't Veer")) (:maintainer "R.W. van 't Veer") (:url . "https://github.com/remvee/spotify-el"))]) (multi . [(20131013 1544) ((emacs (24))) "Clojure-style multi-methods for emacs lisp" single ((:commit . "0987ab71692717ed457cb3984de184db9185806d") (:keywords "multimethod" "generic" "predicate" "dispatch") (:authors ("Christina Whyte" . "kurisu.whyte@gmail.com")) (:maintainer "Christina Whyte" . "kurisu.whyte@gmail.com") (:url . "http://github.com/kurisuwhyte/emacs-multi"))]) (helm-spotify-plus . [(20180107 1138) ((emacs (24 4)) (helm (2 0 0)) (multi (2 0 1))) "Control Spotify search and select music with Helm." single ((:commit . "895f241f1259891d5c89cd42023f119f9fa121d6") (:authors ("Wanderson Ferreira and Luis Moneda ")) (:maintainer "Wanderson Ferreira and Luis Moneda "))]) (counsel-spotify . [(20180320 322) ((emacs (25)) (ivy (0 9 0))) "Control Spotify search and select music with Ivy." single ((:commit . "9033e207dccdfea7fe590d2e102d50fcd2bd22e3") (:authors ("Lautaro García ")) (:maintainer "Lautaro García "))]) (copy-as-format . [(20171216 16) ((cl-lib (0 5))) "Copy buffer locations as GitHub/Slack/JIRA/HipChat/... formatted code" single ((:commit . "971957166fe64d914ec4be209b4f80efeeabbb19") (:keywords "github" "slack" "jira" "hipchat" "gitlab" "bitbucket" "org-mode" "pod" "rst" "asciidoc" "tools" "convenience") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:url . "https://github.com/sshaw/copy-as-format"))]) (evil-mc . [(20180921 1727) ((emacs (24 3)) (evil (1 2 13)) (cl-lib (0 5))) "Multiple cursors for evil-mode" tar ((:commit . "2af29ecd2fbed1571c4cc2501dfb2e38ffd4bfa2") (:keywords "evil" "editing" "multiple-cursors" "vim" "evil-multiple-cursors" "evil-mc" "evil-mc") (:authors ("Gabriel Adomnicai" . "gabesoft@gmail.com")) (:maintainer "Gabriel Adomnicai" . "gabesoft@gmail.com") (:url . "https://github.com/gabesoft/evil-mc"))]) (auto-yasnippet . [(20180503 1908) ((yasnippet (0 8 0))) "Quickly create disposable yasnippets" single ((:commit . "623734aa418b18ff52cb65a0adb9e359aed31615") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/auto-yasnippet"))]) (auto-complete . [(20170125 245) ((popup (0 5 0)) (cl-lib (0 5))) "Auto Completion for GNU Emacs" tar ((:commit . "2e83566ddfa758c69afe50b8a1c62a66f47471e3"))]) (ac-ispell . [(20151101 226) ((auto-complete (1 4)) (cl-lib (0 5))) "ispell completion source for auto-complete" single ((:commit . "22bace7387e9012002a6a444922f75f9913077b0") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-ispell"))]) (company-statistics . [(20170210 1933) ((emacs (24 3)) (company (0 8 5))) "Sort candidates using completion history" single ((:commit . "e62157d43b2c874d2edbd547c3bdfb05d0a7ae5c") (:keywords "abbrev" "convenience" "matching") (:authors ("Ingo Lohmar" . "i.lohmar@gmail.com")) (:maintainer "Ingo Lohmar" . "i.lohmar@gmail.com") (:url . "https://github.com/company-mode/company-statistics"))]) (fuzzy . [(20150730 337) nil "Fuzzy Matching" single ((:commit . "534d723ad2e06322ff8d9bd0ba4863d243f698e7") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (company . [(20181105 2312) ((emacs (24 3))) "Modular text completion framework" tar ((:commit . "c95a6b41d621de4253b77e512aa61fc0e75acddc") (:keywords "abbrev" "convenience" "matching") (:authors ("Nikolaj Schumacher")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:url . "http://company-mode.github.io/"))]) (helm-company . [(20180828 1612) ((helm (1 5 9)) (company (0 6 13))) "Helm interface for company-mode" single ((:commit . "d3fc093a0e833b4dee6561c00d6df3d62aa50f3f") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Daniel Ralston" . "Sodel-the-Vociferous@users.noreply.github.com") (:url . "https://github.com/Sodel-the-Vociferous/helm-company"))]) (helm-c-yasnippet . [(20170128 1542) ((helm (1 7 7)) (yasnippet (0 8 0)) (cl-lib (0 3))) "helm source for yasnippet.el" single ((:commit . "65ca732b510bfc31636708aebcfe4d2d845b59b0") (:keywords "convenience" "emulation") (:authors ("Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com")) (:maintainer "Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com"))]) (ivy-yasnippet . [(20181002 1655) ((emacs (24)) (ivy (0 10 0)) (yasnippet (0 12 2)) (dash (2 14 1)) (cl-lib (0))) "Preview yasnippets with ivy" single ((:commit . "32580b4fd23ebf9ca7dde96704f7d53df6e253cd") (:keywords "convenience") (:authors ("MichaÅ‚ Krzywkowski" . "k.michal@zoho.com")) (:maintainer "MichaÅ‚ Krzywkowski" . "k.michal@zoho.com") (:url . "https://github.com/mkcms/ivy-yasnippet"))]) (yasnippet-snippets . [(20181107 2203) ((yasnippet (0 8 0))) "Collection of yasnippet snippets" tar ((:commit . "7d4e06dbd6e517d27e4f1407b6f5180f29048588") (:keywords "snippets") (:authors ("Andrea Crotti" . "andrea.crotti.0@gmail.com")) (:maintainer "Andrea Crotti" . "andrea.crotti.0@gmail.com"))]) (counsel-projectile . [(20181020 1906) ((counsel (0 10 0)) (projectile (1 0 0))) "Ivy integration for Projectile" single ((:commit . "7607fb8bb4eb7fbe0ec20f9644b6bbaa5c363330") (:keywords "project" "convenience") (:authors ("Eric Danan")) (:maintainer "Eric Danan") (:url . "https://github.com/ericdanan/counsel-projectile"))]) (helm-make . [(20181107 2126) ((helm (1 5 3)) (projectile (0 11 0))) "Select a Makefile target with helm" single ((:commit . "f86c3973af760df6d7d0ecc61c3d9d14e1d93e2b") (:keywords "makefile") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/helm-make"))]) (ivy-hydra . [(20180614 2200) ((emacs (24 1)) (ivy (0 9 0)) (hydra (0 13 4))) "Additional key bindings for Ivy" single ((:commit . "d76968a85f9dc5dcebdc25eb8e3af2cd2775319e") (:keywords "convenience") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (ivy-rich . [(20181001 1147) ((emacs (24 4)) (ivy (0 8 0))) "More friendly display transformer for ivy." single ((:commit . "dee5d60f655c93f4f9f0e40507244112bd90dab5") (:keywords "ivy") (:authors ("Yevgnen Koh" . "wherejoystarts@gmail.com")) (:maintainer "Yevgnen Koh" . "wherejoystarts@gmail.com"))]) (ivy-xref . [(20180821 1211) ((emacs (25 1)) (ivy (0 10 0))) "Ivy interface for xref results" single ((:commit . "61864f82e554121be0a26ba0a1d8f48b669dd5f0") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/ivy-xref"))]) (smex . [(20151212 2209) ((emacs (24))) "M-x interface with Ido-style fuzzy matching." single ((:commit . "55aaebe3d793c2c990b39a302eb26c184281c42c") (:keywords "convenience" "usability") (:authors ("Cornelius Mika" . "cornelius.mika@gmail.com")) (:maintainer "Cornelius Mika" . "cornelius.mika@gmail.com") (:url . "http://github.com/nonsequitur/smex/"))]) (wgrep . [(20180711 626) nil "Writable grep buffer and apply the changes to files" single ((:commit . "414be70bd313e482cd9f0b70fd2daad4ee23497c") (:keywords "grep" "edit" "extensions") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep.el"))]) (yasnippet . [(20181015 1212) ((cl-lib (0 5))) "Yet another snippet extension for Emacs." single ((:commit . "1d96da2e08664c31ff7f6f7441da1f4fa5680b1f") (:keywords "convenience" "emulation") (:maintainer "Noam Postavsky" . "npostavs@gmail.com") (:url . "http://github.com/joaotavora/yasnippet"))]) (yatemplate . [(20180617 952) ((yasnippet (0 8 1)) (emacs (24 3))) "File templates with yasnippet" tar ((:commit . "4f4fca9f04f7088c98aa195cf33635a35a6055cb") (:keywords "files" "convenience") (:authors ("Wieland Hoffmann" . "themineo+yatemplate@gmail.com")) (:maintainer "Wieland Hoffmann" . "themineo+yatemplate@gmail.com") (:url . "https://github.com/mineo/yatemplate"))]) (ace-jump-helm-line . [(20160918 1836) ((avy (0 4 0)) (helm (1 6 3))) "Ace-jump to a candidate in helm window" single ((:commit . "1483055255df3f8ae349f7520f05b1e43ea3ed37") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/ace-jump-helm-line"))]) (helm-ag . [(20170209 1545) ((emacs (24 4)) (helm (2 0))) "the silver searcher with helm interface" single ((:commit . "2fc02c4ead29bf0db06fd70740cc7c364cb650ac") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-ag"))]) (helm-descbinds . [(20180429 1456) ((helm (1 5))) "A convenient `describe-bindings' with `helm'" single ((:commit . "033be73f21778633813264ce1634a6e1ad873d8e") (:keywords "helm" "help") (:authors ("Taiki SUGAWARA" . "buzz.taiki@gmail.com")) (:maintainer "Taiki SUGAWARA" . "buzz.taiki@gmail.com") (:url . "https://github.com/emacs-helm/helm-descbinds"))]) (helm-flx . [(20180103 516) ((emacs (24 4)) (helm (1 7 9)) (flx (0 5))) "Sort helm candidates by flx score" single ((:commit . "6640fac5cb16bee73c95b8ed1248a4e5e113690e") (:keywords "convenience" "helm" "fuzzy" "flx") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:url . "https://github.com/PythonNut/helm-flx"))]) (helm-mode-manager . [(20151124 938) ((helm (1 5 3))) "Select and toggle major and minor modes with helm" single ((:commit . "5d9c3ca4f8205d07ff4e03c4c3e88f596751c1fc") (:authors ("istib")) (:maintainer "istib") (:url . "https://github.com/istib/helm-mode-manager"))]) (helm-projectile . [(20180815 1514) ((helm (1 9 9)) (projectile (0 14 0)) (cl-lib (0 3))) "Helm integration for Projectile" single ((:commit . "8a2dbc973548fac89356c11d70f7f474ea1367a5") (:keywords "project" "convenience") (:authors ("Bozhidar Batsov")) (:maintainer "Bozhidar Batsov") (:url . "https://github.com/bbatsov/helm-projectile"))]) (helm-swoop . [(20180215 1154) ((helm (1 0)) (emacs (24 3))) "Efficiently hopping squeezed lines powered by helm interface" single ((:commit . "c66336b8245ddc51c4206f19c119f1081920985c") (:keywords "helm" "swoop" "inner" "buffer" "search") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:url . "https://github.com/ShingoFukuyama/helm-swoop"))]) (helm-themes . [(20160918 545) ((helm-core (2 0)) (emacs (24 4))) "Color theme selection with helm interface" single ((:commit . "1160af42590b0d845a55e65e1e782d9e4027fd6e") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-themes"))]) (helm-xref . [(20180528 1516) ((emacs (25 1)) (helm (1 9 4))) "Helm interface for xref results" single ((:commit . "6f7e8eeec5cc4db64a76ba242c0f2f61e7ee1e46") (:authors ("Fritz Stelzer" . "brotzeitmacher@gmail.com")) (:maintainer "Fritz Stelzer" . "brotzeitmacher@gmail.com") (:url . "https://github.com/brotzeitmacher/helm-xref"))]) (winum . [(20181107 47) ((cl-lib (0 5)) (dash (2 13 0))) "Navigate windows and frames using numbers." single ((:commit . "8bafa66f800e43a2e5d596e000047a80b0e62cd7") (:keywords "convenience" "frames" "windows" "multi-screen") (:authors ("Thomas de Beauchêne" . "thomas.de.beauchene@gmail.com")) (:maintainer "Thomas de Beauchêne" . "thomas.de.beauchene@gmail.com") (:url . "http://github.com/deb0ch/winum.el"))]) (treemacs-evil . [(20180803 1017) ((evil (1 2 12)) (treemacs (0))) "Evil mode integration for treemacs" single ((:commit . "cb8b01dcd6fd19ea59e9277ea24c9786c83a5cd0") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))]) (treemacs . [(20181117 1604) ((emacs (25 2)) (cl-lib (0 5)) (dash (2 11 0)) (s (1 10 0)) (f (0 11 0)) (ace-window (0 9 0)) (pfuture (1 2)) (hydra (0 13 2)) (ht (2 2))) "A tree style file explorer package" tar ((:commit . "cb8b01dcd6fd19ea59e9277ea24c9786c83a5cd0") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))]) (ht . [(20180129 2234) ((dash (2 12 0))) "The missing hash table library for Emacs" single ((:commit . "5a665d00dc8fda77bad2a43277d8809c23e46ab8") (:keywords "hash table" "hash map" "hash") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (pfuture . [(20180922 1315) ((emacs (25 2))) "a simple wrapper around asynchronous processes" single ((:commit . "c06e78b37ac3fba72ea446f11da38a6a5cba428c") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/pfuture"))]) (ace-window . [(20181008 1549) ((avy (0 2 0))) "Quickly switch windows." single ((:commit . "5b88de026cea5fc57e62bb490034392815be5f0f") (:keywords "window" "location") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/ace-window"))]) (treemacs-projectile . [(20181029 624) ((projectile (0 14 0)) (treemacs (0))) "Projectile integration for treemacs" single ((:commit . "cb8b01dcd6fd19ea59e9277ea24c9786c83a5cd0") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))]) (pos-tip . [(20150318 1513) nil "Show tooltip at point" single ((:commit . "051e08fec5cf30b7574bdf439f79fef7d42d689d") (:keywords "tooltip") (:authors ("S. Irie")) (:maintainer "S. Irie"))]) (flycheck . [(20181018 1021) ((dash (2 12 1)) (pkg-info (0 4)) (let-alist (1 0 4)) (seq (1 11)) (emacs (24 3))) "On-the-fly syntax checking" tar ((:commit . "1702d2db3d8ba9bcb9b2bf810e791e907fcc3adc") (:keywords "convenience" "languages" "tools") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:url . "http://www.flycheck.org"))]) (flycheck-pos-tip . [(20180610 1615) ((emacs (24 1)) (flycheck (0 22)) (pos-tip (0 4 6))) "Display Flycheck errors in GUI tooltips" single ((:commit . "909113977d37739387c7f099d74a724cfe6efcec") (:keywords "tools" "convenience") (:authors ("Akiha Senda" . "senda.akiha@gmail.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-pos-tip"))]) (auto-dictionary . [(20150410 1610) nil "automatic dictionary switcher for flyspell" single ((:commit . "b364e08009fe0062cf0927d8a0582fad5a12b8e7") (:keywords "wp") (:authors ("Nikolaj Schumacher ")) (:maintainer "Nikolaj Schumacher ") (:url . "http://nschum.de/src/emacs/auto-dictionary/"))]) (flyspell-correct-ivy . [(20180929 1331) ((flyspell-correct (0 5 0)) (ivy (0 8 0))) "correcting words with flyspell via ivy interface" single ((:commit . "204f145678df5e34a48ea3beae888a1bd6809974") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-correct-helm . [(20180928 504) ((flyspell-correct (0 5 0)) (helm (1 9 0))) "correcting words with flyspell via helm interface" single ((:commit . "204f145678df5e34a48ea3beae888a1bd6809974") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-correct . [(20181106 801) nil "correcting words with flyspell via custom interface" tar ((:commit . "204f145678df5e34a48ea3beae888a1bd6809974") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-correct-popup . [(20180928 504) ((flyspell-correct (0 5 0)) (popup (0 5 3))) "correcting words with flyspell via popup interface" single ((:commit . "204f145678df5e34a48ea3beae888a1bd6809974") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-popup . [(20170529 815) ((popup (0 5 0))) "Correcting words with Flyspell in popup menus" single ((:commit . "29311849bfd253b9b689bf331860b4c4d3bd4dde") (:keywords "convenience") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/flyspell-popup"))]) (highlight . [(20181002 1151) nil "Highlighting commands." single ((:commit . "ea733e17884aeae19172407e20559fc693fdd3a7") (:keywords "faces" "help" "local") (:authors ("Drew Adams")) (:maintainer nil . "Drew Adams (concat \"drew.adams\" \"@\" \"oracle\" \".com\")") (:url . "https://www.emacswiki.org/emacs/download/highlight.el"))]) (floobits . [(20180801 524) ((json (1 2)) (highlight (0))) "Floobits plugin for real-time collaborative editing" tar ((:commit . "489b294a7f30ecd2af2edc0823dead8102f27af6") (:keywords "comm" "tools") (:authors ("Matt Kaniaris") ("Geoff Greer")) (:maintainer "Matt Kaniaris") (:url . "http://github.com/Floobits/floobits-emacs"))]) (mwim . [(20181110 1900) nil "Switch between the beginning/end of line or code" single ((:commit . "b4f3edb4c0fb8f8b71cecbf8095c2c25a8ffbf85") (:keywords "convenience") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/mwim.el"))]) (unfill . [(20170723 146) nil "Unfill paragraphs or regions, and toggle between filled & unfilled" single ((:commit . "df0c4dee19a3874b11c7c7f04e8a2fba629fda9b") (:keywords "utilities") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/unfill"))]) (evil-org . [(20180323 2306) ((emacs (24 4)) (evil (1 0))) "evil keybindings for org-mode" tar ((:commit . "b6d652a9163d3430a9e0933a554bdbee5244bbf6") (:keywords "evil" "vim-emulation" "org-mode" "key-bindings" "presets") (:maintainer "Somelauw") (:url . "https://github.com/Somelauw/evil-org-mode.git"))]) (gnuplot . [(20141231 2137) nil "drive gnuplot from within emacs" tar ((:commit . "21f9046e3f5caad41b750b5c9cee02fa4fd20fb9") (:keywords "gnuplot" "plotting") (:authors ("Bruce Ravel" . "bruceravel1@gmail.com")) (:maintainer "Bruce Ravel" . "bruceravel1@gmail.com"))]) (helm-org-rifle . [(20180923 2209) ((emacs (24 4)) (dash (2 12)) (f (0 18 1)) (helm (1 9 4)) (s (1 10 0))) "Rifle through your Org files" single ((:commit . "e272fc43b964ef06a2673afd7c341dba87ae9ac4") (:keywords "hypermedia" "outlines") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/helm-org-rifle"))]) (htmlize . [(20180923 1829) nil "Convert buffer text and decorations to HTML." single ((:commit . "8db0aa6aab77475a732b7363f0d57bd3933c18fd") (:keywords "hypermedia" "extensions") (:authors ("Hrvoje Niksic" . "hniksic@gmail.com")) (:maintainer "Hrvoje Niksic" . "hniksic@gmail.com"))]) (org-brain . [(20181114 2246) ((emacs (25)) (org (9))) "Org-mode concept mapping" single ((:commit . "d2bd1461e69189a39bbe40ae0d0be080b13d0ba0") (:keywords "outlines" "hypermedia") (:authors ("Erik Sjöstrand" . "sjostrand.erik@gmail.com")) (:maintainer "Erik Sjöstrand" . "sjostrand.erik@gmail.com") (:url . "http://github.com/Kungsgeten/org-brain"))]) (org-journal . [(20181115 714) ((emacs (25 1))) "a simple org-mode based journaling mode" single ((:commit . "3ae2e7d7e372dee08143282a9137bf4dfc946645") (:authors ("Bastian Bechtold")) (:maintainer "Bastian Bechtold") (:url . "http://github.com/bastibe/org-journal"))]) (org-download . [(20180925 1528) ((async (1 2))) "Image drag-and-drop for Emacs org-mode" single ((:commit . "07b98eb4f7252e3f64a306c09dfb618be6ac181d") (:keywords "images" "screenshots" "download") (:authors ("Oleh Krehel")) (:maintainer "Oleh Krehel") (:url . "https://github.com/abo-abo/org-download"))]) (org-mime . [(20181023 2314) ((emacs (24 4)) (cl-lib (0 5))) "org html export for text/html MIME emails" single ((:commit . "1e792ef0616069b3ec74a4b7d96fced8c9c6eb8a") (:keywords "mime" "mail" "email" "html") (:authors ("Eric Schulte")) (:maintainer "Chen Bin (redguardtoo)") (:url . "http://github.com/org-mime/org-mime"))]) (alert . [(20181022 1742) ((gntp (0 1)) (log4e (0 3 0)) (cl-lib (0 5))) "Growl-style notification system for Emacs" single ((:commit . "9f329be87820474925f29b52a1131084c8ea95b9") (:keywords "notification" "emacs" "message") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:url . "https://github.com/jwiegley/alert"))]) (log4e . [(20170401 1304) nil "provide logging framework for elisp" single ((:commit . "c69424e407be0d9d0e54b427d8b18b1ac5a607e2") (:keywords "log") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/log4e"))]) (gntp . [(20141025 250) nil "Growl Notification Protocol for Emacs" single ((:commit . "767571135e2c0985944017dc59b0be79af222ef5") (:authors ("Engelke Eschner" . "tekai@gmx.li")) (:maintainer "Engelke Eschner" . "tekai@gmx.li"))]) (org-pomodoro . [(20171108 2114) ((alert (0 5 10)) (cl-lib (0 5))) "Pomodoro implementation for org-mode." tar ((:commit . "3deed1c26dcbda4d5231b9085ddf68e302b0f9dc") (:authors ("Arthur Leonard Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Leonard Andersen" . "leoc.git@gmail.com") (:url . "https://github.com/lolownia/org-pomodoro"))]) (org-present . [(20180303 2330) ((org (7))) "Minimalist presentation minor-mode for Emacs org-mode." single ((:commit . "d13acd70eff6a1608bc991920232146a0de76b21") (:authors ("Ric Lister")) (:maintainer "Ric Lister") (:url . "https://github.com/rlister/org-present"))]) (org-category-capture . [(20180601 242) ((org (9 0 0)) (emacs (24))) "Contextualy capture of org-mode TODOs." single ((:commit . "c798b1dff1d94304fa3621a905cbb572c7cb1d33") (:keywords "org-mode" "todo" "tools" "outlines") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/org-projectile"))]) (org-projectile . [(20180601 242) ((projectile (0 11 0)) (dash (2 10 0)) (emacs (24)) (s (1 9 0)) (org-category-capture (0 0 0))) "Repository todo management for org-mode" single ((:commit . "c798b1dff1d94304fa3621a905cbb572c7cb1d33") (:keywords "org-mode" "projectile" "todo" "tools" "outlines") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/org-projectile"))]) (ox-twbs . [(20161103 2016) nil "Bootstrap compatible HTML Back-End for Org" single ((:commit . "2414e6b1de7deb6dd2ae79a7be633fdccb9c2f28") (:keywords "org" "html" "publish" "twitter" "bootstrap") (:authors ("Carsten Dominik ") ("Jambunathan K ") ("Brandon van Beekum ")) (:maintainer "Carsten Dominik ") (:url . "https://github.com/marsmining/ox-twbs"))]) (ox-gfm . [(20170628 2102) nil "Github Flavored Markdown Back-End for Org Export Engine" single ((:commit . "99f93011b069e02b37c9660b8fcb45dab086a07f") (:keywords "org" "wp" "markdown" "github") (:authors ("Lars Tveito")) (:maintainer "Lars Tveito"))]) (ox-reveal . [(20161027 926) ((org (20150330))) "reveal.js Presentation Back-End for Org Export Engine" single ((:commit . "001567cc12d50ba07612edd1718b86a12e8c2547") (:keywords "outlines" "hypermedia" "slideshow" "presentation") (:authors ("Yujie Wen ")) (:maintainer "Yujie Wen "))]) (ox-hugo . [(20181106 2350) ((emacs (24 4)) (org (9 0))) "Hugo Markdown Back-End for Org Export Engine" tar ((:commit . "7fb284ec4b7f47ff1286598220650c5b24b56b45") (:keywords "org" "markdown" "docs") (:url . "https://ox-hugo.scripter.co"))]) (request-deferred . [(20160419 2305) ((deferred (0 3 1)) (request (0 2 0))) "Wrap request.el by deferred" single ((:commit . "a3d080e57eb8be606fbf39d1baff94e1b16e1fb8") (:authors ("Takafumi Arakaki ")) (:maintainer "Takafumi Arakaki "))]) (deferred . [(20170901 1330) ((emacs (24 4))) "Simple asynchronous functions for emacs lisp" single ((:commit . "2239671d94b38d92e9b28d4e12fd79814cfb9c16") (:keywords "deferred" "async") (:authors ("SAKURAI Masashi ")) (:maintainer "SAKURAI Masashi ") (:url . "https://github.com/kiwanami/emacs-deferred"))]) (org-trello . [(20180331 631) ((request-deferred (0 2 0)) (deferred (0 4 0)) (s (1 11 0)) (dash-functional (2 12 1)) (dash (2 12 1))) "Minor mode to synchronize org-mode buffer and trello board" tar ((:commit . "e2e8a3d45057645e4caae7d46a79d2d9be2894bd"))]) (projectile . [(20181106 1631) ((emacs (25 1)) (pkg-info (0 4))) "Manage and navigate projects in Emacs easily" single ((:commit . "9482d69e5ca6549ec7baea58f86c1445b544563b") (:keywords "project" "convenience") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "https://github.com/bbatsov/projectile"))]) (pkg-info . [(20150517 1143) ((epl (0 8))) "Information about packages" single ((:commit . "76ba7415480687d05a4353b27fea2ae02b8d9d61") (:keywords "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/lunaryorn/pkg-info.el"))]) (epl . [(20180205 2049) ((cl-lib (0 3))) "Emacs Package Library" single ((:commit . "78ab7a85c08222cd15582a298a364774e3282ce6") (:keywords "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/cask/epl"))]) (ibuffer-projectile . [(20180325 325) ((projectile (0 11 0))) "Group ibuffer's list by projectile root" single ((:commit . "1e89bfa7cae0629d29f24af3d81774b88b3cede0") (:keywords "themes") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "http://github.com/purcell/ibuffer-projectile"))]) (tablist . [(20170220 335) ((emacs (24 3))) "Extended tabulated-list-mode" tar ((:commit . "c834a84efb6efa32497efe1e73160fade741b836") (:keywords "extensions" "lisp") (:authors ("Andreas Politz" . "politza@fh-trier.de")) (:maintainer "Andreas Politz" . "politza@fh-trier.de"))]) (pdf-tools . [(20181117 1939) ((emacs (24 3)) (tablist (0 70)) (let-alist (1 0 4))) "Support library for PDF documents." tar ((:commit . "105dd014fea424c5556f8e0a3e3d652722c46084") (:keywords "files" "multimedia") (:authors ("Andreas Politz" . "politza@fh-trier.de")) (:maintainer "Andreas Politz" . "politza@fh-trier.de"))]) (spray . [(20160304 2220) nil "a speed reading mode" single ((:commit . "00638bc916227f2f961013543d10e85a43a32e29") (:keywords "convenience") (:authors ("Ian Kelling" . "ian@iankelling.org")) (:maintainer "Ian Kelling" . "ian@iankelling.org") (:url . "https://github.com/ian-kelling/spray"))]) (ace-jump-mode . [(20140616 815) nil "a quick cursor location minor mode for emacs" single ((:commit . "8351e2df4fbbeb2a4003f2fb39f46d33803f3dac") (:keywords "motion" "location" "cursor") (:authors ("winterTTr" . "winterTTr@gmail.com")) (:maintainer "winterTTr" . "winterTTr@gmail.com") (:url . "https://github.com/winterTTr/ace-jump-mode/"))]) (noflet . [(20141102 1454) nil "locally override functions" single ((:commit . "7ae84dc3257637af7334101456dafe1759c6b68a") (:keywords "lisp") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "https://github.com/nicferrier/emacs-noflet"))]) (popwin . [(20150315 1300) nil "Popup Window Manager." single ((:commit . "95dea14c60019d6cccf9a3b33e0dec4e1f22c304") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (elfeed-goodies . [(20171127 651) ((popwin (1 0 0)) (powerline (2 2)) (elfeed (2 0 0)) (cl-lib (0 5)) (noflet (0 0 10)) (ace-jump-mode (2 0))) "Elfeed goodies" tar ((:commit . "fc0c3e72f9fcd7bbf5237f6f2323bc666e8240b4") (:authors ("Gergely Nagy")) (:maintainer "Gergely Nagy") (:url . "https://github.com/algernon/elfeed-goodies"))]) (org . [(20181112) nil "Outline-based notes management and organizer" tar nil]) (elfeed-org . [(20181015 1100) ((elfeed (1 1 1)) (org (8 2 7)) (dash (2 10 0)) (s (1 9 0)) (cl-lib (0 5))) "Configure elfeed with one or more org-mode files" single ((:commit . "607b8bf4923a995260a072559b77bee188614a06") (:keywords "news") (:authors ("Remy Honig" . "remyhonig@gmail.com")) (:maintainer "Remy Honig" . "remyhonig@gmail.com") (:url . "https://github.com/remyhonig/elfeed-org"))]) (elfeed . [(20180916 1338) ((emacs (24 3))) "an Emacs Atom/RSS feed reader" tar ((:commit . "afafa1f7d9e29de55ce5b1709074738a7e185f2a"))]) (simple-httpd . [(20180528 1603) ((cl-lib (0 3))) "pure elisp HTTP server" single ((:commit . "49721d5b791bee0fc25b1fdd69696371d546093a") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacs-http-server"))]) (elfeed-web . [(20180829 1716) ((simple-httpd (1 4 3)) (elfeed (1 4 0)) (emacs (24 1))) "web interface to Elfeed" tar ((:commit . "afafa1f7d9e29de55ce5b1709074738a7e185f2a"))]) (dash-at-point . [(20180710 1356) nil "Search the word at point with Dash" single ((:commit . "4d795a23a8428c421d5107f1b005c9d8e0d1816c") (:authors ("Shinji Tanaka" . "shinji.tanaka@gmail.com")) (:maintainer "Shinji Tanaka" . "shinji.tanaka@gmail.com") (:url . "https://github.com/stanaka/dash-at-point"))]) (counsel . [(20181111 1805) ((emacs (24 3)) (swiper (0 9 0))) "Various completion functions using Ivy" single ((:commit . "d76968a85f9dc5dcebdc25eb8e3af2cd2775319e") (:keywords "convenience" "matching" "tools") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (helm-dash . [(20180503 918) ((helm (1 9 2)) (cl-lib (0 5))) "Offline documentation browser for +150 APIs using Dash docsets." single ((:commit . "0ac2db529577fa63f2ed32310062873c585b91de") (:keywords "docs") (:authors ("Raimon Grau" . "raimonster@gmail.com") ("Toni Reina " . "areina0@gmail.com")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:url . "http://github.com/areina/helm-dash"))]) (dash-functional . [(20180107 1618) ((dash (2 0 0)) (emacs (24))) "Collection of useful combinators for Emacs Lisp" single ((:commit . "6514359b8606a6a9a94068ccd601fcd6379d6584") (:keywords "lisp" "functions" "combinators"))]) (swiper . [(20181008 1731) ((emacs (24 1)) (ivy (0 9 0))) "Isearch with an overview. Oh, man!" single ((:commit . "d76968a85f9dc5dcebdc25eb8e3af2cd2775319e") (:keywords "matching") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (counsel-dash . [(20160729 1529) ((emacs (24 4)) (dash (2 12 1)) (dash-functional (1 2 0)) (helm-dash (1 3 0)) (counsel (0 8 0))) "Browse dash docsets using Ivy" single ((:commit . "07fa74a94ff4da5b6c8c4810f5e143e701b480d2") (:keywords "dash" "ivy" "counsel") (:authors ("Nathan Kot" . "nk@nathankot.com")) (:maintainer "Nathan Kot" . "nk@nathankot.com") (:url . "https://github.com/nathankot/counsel-dash"))]) (zeal-at-point . [(20180131 2354) nil "Search the word at point with Zeal" single ((:commit . "0fc3263f44e95acd3e9d91057677621ce4d297ee") (:authors ("Jinzhu" . "wosmvp@gmail.com")) (:maintainer "Jinzhu" . "wosmvp@gmail.com") (:url . "https://github.com/jinzhu/zeal-at-point"))]) (esxml . [(20171129 807) nil "Library for working with xml via esxml and sxml" tar ((:commit . "5548ceba17deae0c3c6d0092672edc4de3c75ce3"))]) (nov . [(20181118 750) ((dash (2 12 0)) (esxml (0 3 3)) (emacs (24 4))) "Featureful EPUB reader mode" single ((:commit . "3bb7a4038f0c2100df671c9f1f33b785ed4ae296") (:keywords "hypermedia" "multimedia" "epub") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:url . "https://github.com/wasamasa/nov.el"))]) (deft . [(20181029 213) nil "quickly browse, filter, and edit plain text notes" single ((:commit . "47d268355b0d988804e19896770b29da7f01c7aa") (:keywords "plain text" "notes" "simplenote" "notational velocity") (:authors ("Jason R. Blevins" . "jrblevin@xbeta.org")) (:maintainer "Jason R. Blevins" . "jrblevin@xbeta.org") (:url . "https://jblevins.org/projects/deft/"))]) (aggressive-indent . [(20181018 236) ((emacs (24 1)) (cl-lib (0 5))) "Minor mode to aggressively keep your code always indented" single ((:commit . "cc8da01e32684e1b75d2901400e6723b2c2d42f8") (:keywords "indent" "lisp" "maint" "tools") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/aggressive-indent-mode"))]) (bracketed-paste . [(20160407 2348) ((emacs (24 3))) "bracketed paste mode support within emacs -nw" single ((:commit . "843ce3bbb63d560face889e13a57a2f7543957d5") (:keywords "terminals") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net"))]) (clean-aindent-mode . [(20171017 2043) nil "Simple indent and unindent, trims indent white-space" single ((:commit . "a97bcae8f43a9ff64e95473e4ef0d8bafe829211") (:keywords "indentation" "whitespace" "backspace") (:authors ("peter marinov" . "efravia@gmail.com")) (:maintainer "peter marinov" . "efravia@gmail.com") (:url . "https://github.com/pmarinov/clean-aindent-mode"))]) (editorconfig . [(20181115 709) ((cl-lib (0 5))) "EditorConfig Emacs Plugin" tar ((:commit . "d6e48c863ed246be8894c6ee3c3c088ab4db4711") (:authors ("EditorConfig Team" . "editorconfig@googlegroups.com")) (:maintainer "EditorConfig Team" . "editorconfig@googlegroups.com") (:url . "https://github.com/editorconfig/editorconfig-emacs#readme"))]) (expand-region . [(20180817 1134) nil "Increase selected region by semantic units." tar ((:commit . "ed3292473035dc8f3d2f321e82974ef87327808f"))]) (hungry-delete . [(20170412 102) nil "hungry delete minor mode" single ((:commit . "0434458d3f6b2b585f332271feaa054bf4ec96d7") (:authors ("Nathaniel Flath" . "flat0103@gmail.com")) (:maintainer "Nathaniel Flath" . "flat0103@gmail.com") (:url . "http://github.com/nflath/hungry-delete"))]) (link-hint . [(20180519 2130) ((avy (0 4 0)) (emacs (24 1)) (cl-lib (0 5))) "Use avy to open, copy, etc. visible links." single ((:commit . "23df5fa36ab182452be6b772475eab67b846dd92") (:keywords "convenience" "url" "avy" "link" "links" "hyperlink") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:url . "https://github.com/noctuid/link-hint.el"))]) (lorem-ipsum . [(20140911 2108) nil "Insert dummy pseudo Latin text." single ((:commit . "4b39f6fed455d67f635b3837cf5668bf74d0f6cd") (:keywords "tools" "language" "convenience") (:authors ("Jean-Philippe Theberge" . "jphil21@sourceforge.net")) (:maintainer "Joe Schafer" . "joe@jschaf.com"))]) (move-text . [(20170909 330) nil "Move current line or region with M-up or M-down." single ((:commit . "7cbc941a9150468609010a93c429117da2523903") (:keywords "edit") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/emacsfodder/move-text"))]) (origami . [(20180101 1553) ((s (1 9 0)) (dash (2 5 0)) (emacs (24)) (cl-lib (0 5))) "Flexible text folding" tar ((:commit . "1f38085c8f9af7842765ed63f7d6dfe4dab59366") (:keywords "folding") (:authors ("Greg Sexton" . "gregsexton@gmail.com")) (:maintainer "Greg Sexton" . "gregsexton@gmail.com") (:url . "https://github.com/gregsexton/origami.el"))]) (password-generator . [(20150222 2040) nil "Password generator for humans. Good, Bad, Phonetic passwords included." single ((:commit . "c8193d5e963bda0a2f8e51fd4a94dcf37c76f282") (:authors ("Zargener" . "zargener@gmail.com")) (:maintainer "Zargener" . "zargener@gmail.com") (:url . "http://github.com/zargener/emacs-password-genarator"))]) (string-inflection . [(20180827 1301) nil "underscore -> UPCASE -> CamelCase -> lowerCamelCase conversion of names" single ((:commit . "e9a50855a4c718592c28a5a892f164ecf46e39a8") (:keywords "elisp") (:authors ("akicho8" . "akicho8@gmail.com")) (:maintainer "akicho8" . "akicho8@gmail.com"))]) (uuidgen . [(20140918 2301) nil "Provides various UUID generating functions" single ((:commit . "7eb96415484c3854a3f383d1a3e10b87ae674e22") (:keywords "extensions" "lisp" "tools") (:authors ("Kan-Ru Chen" . "koster@debian.org")) (:maintainer "Kan-Ru Chen" . "koster@debian.org"))]) (ws-butler . [(20170111 2334) nil "Unobtrusively remove trailing whitespace." single ((:commit . "52321b99be69aa1b661da7743c4421a30d8b6bcb") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/ws-butler"))]) (flx . [(20151030 1812) ((cl-lib (0 3))) "fuzzy matching with good sorting" single ((:commit . "46040d0b096a0340d91235561f27a959a61d0fef") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/flx"))]) (flx-ido . [(20180117 1519) ((flx (0 1)) (cl-lib (0 3))) "flx integration for ido" single ((:commit . "46040d0b096a0340d91235561f27a959a61d0fef") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/flx"))]) (ido-vertical-mode . [(20180618 2101) nil "Makes ido-mode display vertically." single ((:commit . "16c4c1a112796ee0bcf401ea39d3e2643a89feaf") (:keywords "convenience") (:authors ("Steven Degutis")) (:maintainer "Christopher Reichert" . "creichert07@gmail.com") (:url . "https://github.com/creichert/ido-vertical-mode.el"))]) (avy . [(20181009 1648) ((emacs (24 1)) (cl-lib (0 5))) "Jump to arbitrary positions in visible text and select text quickly." single ((:commit . "df4c4ac488ee59bc44f8658d9fcca0c86fb32c5c") (:keywords "point" "location") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/avy"))]) (ace-link . [(20181103 2106) ((avy (0 4 0))) "Quickly follow links" single ((:commit . "dfd0fdf649703790a9a5ee027f2f86d6f1269d55") (:keywords "convenience" "links" "avy") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/ace-link"))]) (centered-cursor-mode . [(20180112 1555) nil "cursor stays vertically centered" single ((:commit . "00fb47d227f9e211ec1c58161a501a1550c3a60d") (:keywords "convenience") (:authors ("André Riemann" . "andre.riemann@web.de")) (:maintainer "André Riemann" . "andre.riemann@web.de") (:url . "https://github.com/andre-r/centered-cursor-mode.el"))]) (open-junk-file . [(20161210 1114) nil "Open a junk (memo) file to try-and-error" single ((:commit . "558bec7372b0fed4c4cb6074ab906535fae615bd") (:keywords "convenience" "tools") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/open-junk-file.el"))]) (hydra . [(20181110 1740) ((cl-lib (0 5))) "Make bindings that stick around." tar ((:commit . "5c5b9ca3262594c92f8f73c98db5ed0f1efd0319") (:keywords "bindings") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/hydra"))]) (spinner . [(1 7 3) nil "Add spinners and progress-bars to the mode-line for ongoing operations" single ((:url . "https://github.com/Malabarba/spinner.el") (:keywords "processes" "mode-line"))]) (seq . [(2 20) nil "Sequence manipulation functions" tar ((:keywords "sequences") (:url . "http://elpa.gnu.org/packages/seq.html"))]) (paradox . [(20181027 2234) ((emacs (24 4)) (seq (1 7)) (let-alist (1 0 3)) (spinner (1 7 3)) (hydra (0 13 2))) "A modern Packages Menu. Colored, with package ratings, and customizable." tar ((:commit . "798bdabdca6575d677631b1c482e975c9372d536") (:keywords "package" "packages") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/paradox"))]) (restart-emacs . [(20180601 1031) nil "Restart emacs from within emacs" single ((:commit . "9aa90d3df9e08bc420e1c9845ee3ff568e911bd9") (:keywords "convenience") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:url . "https://github.com/iqbalansari/restart-emacs"))]) (smooth-scrolling . [(20161002 1949) nil "Make emacs scroll smoothly" single ((:commit . "2462c13640aa4c75ab3ddad443fedc29acf68f84") (:keywords "convenience") (:authors ("Adam Spiers" . "emacs-ss@adamspiers.org") ("Jeremy Bondeson" . "jbondeson@gmail.com") ("Ryan C. Thompson" . "rct+github@thompsonclan.org")) (:maintainer "Adam Spiers" . "emacs-ss@adamspiers.org") (:url . "http://github.com/aspiers/smooth-scrolling/"))]) (helm . [(20181117 731) ((emacs (24 4)) (async (1 9 3)) (popup (0 5 3)) (helm-core (3 0))) "Helm is an Emacs incremental and narrowing framework" tar ((:commit . "84a59b1e47528221dcb746058f95a6faffe4a5ae") (:url . "https://emacs-helm.github.io/helm/"))]) (helm-core . [(20181117 1055) ((emacs (24 4)) (async (1 9 3))) "Development files for Helm" tar ((:commit . "84a59b1e47528221dcb746058f95a6faffe4a5ae") (:url . "https://emacs-helm.github.io/helm/"))]) (async . [(20180527 1730) nil "Asynchronous processing in Emacs" tar ((:commit . "d17c11e6082aa51f421bb037b828bdb15f405618") (:keywords "async") (:url . "https://github.com/jwiegley/emacs-async"))]) (helm-purpose . [(20170114 1636) ((emacs (24)) (helm (1 9 2)) (window-purpose (1 4))) "Helm Interface for Purpose" single ((:commit . "9ff4c21c1e9ebc7afb851b738f815df7343bb287") (:authors ("Bar Magal (2016)")) (:maintainer "Bar Magal (2016)") (:url . "https://github.com/bmag/helm-purpose"))]) (ivy . [(20181111 1757) ((emacs (24 1))) "Incremental Vertical completYon" tar ((:commit . "d76968a85f9dc5dcebdc25eb8e3af2cd2775319e") (:keywords "matching") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (ivy-purpose . [(20160724 1003) ((emacs (24)) (ivy (0 8)) (window-purpose (1 5))) "Ivy Interface for Purpose" single ((:commit . "0495f2f3aed64d7e0028125e76a9a68f8fc4107e") (:authors ("Bar Magal (2016)")) (:maintainer "Bar Magal (2016)") (:url . "https://github.com/bmag/ivy-purpose"))]) (imenu-list . [(20180601 1402) ((cl-lib (0 5))) "Show imenu entries in a separate buffer" single ((:commit . "04f0632f7b8c81be8747617768c57b66e5d60994") (:authors ("Bar Magal (2015)")) (:maintainer "Bar Magal (2015)") (:url . "https://github.com/bmag/imenu-list"))]) (let-alist . [(1 0 5) ((emacs (24 1))) "Easily let-bind values of an assoc-list by their names" single ((:url . "http://elpa.gnu.org/packages/let-alist.html") (:keywords "extensions" "lisp"))]) (window-purpose . [(20180926 1047) ((emacs (24 4)) (let-alist (1 0 3)) (imenu-list (0 1))) "Purpose-based window management for Emacs" tar ((:commit . "2b640955235d0a50dd1e3128612f41d595bc6dc8") (:keywords "frames") (:authors ("Bar Magal")) (:maintainer "Bar Magal") (:url . "https://github.com/bmag/emacs-purpose"))]) (define-word . [(20180706 2029) ((emacs (24 3))) "display the definition of word at point." single ((:commit . "637cd29837d4bd5567e17a11a479fd2edfb0e2c1") (:keywords "dictionary" "convenience") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/define-word"))]) (google-translate . [(20180926 1925) nil "Emacs interface to Google Translate." tar ((:commit . "eb1c4f51d522d2252dadfb4cd7ea045ccd344b98"))]) (org-plus-contrib . [(20181112) nil "Outline-based notes management and organizer" tar nil]) (org-bullets . [(20180208 2343) nil "Show bullets in org-mode as UTF-8 characters" single ((:commit . "b56f2e3812626f2c4ac1686073d102c71f4a8513") (:authors ("sabof")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacsorphanage/org-bullets"))]) (toc-org . [(20181108 1621) nil "add table of contents to org-mode files (formerly, org-toc)" single ((:commit . "4315afd2a408c0d432ba3d8d040c2326c222fdbf") (:keywords "org-mode" "org-toc" "toc-org" "org" "toc" "table" "of" "contents") (:authors ("Sergei Nosov ")) (:maintainer "Sergei Nosov ") (:url . "https://github.com/snosov1/toc-org"))]) (column-enforce-mode . [(20171030 1900) nil "Highlight text that extends beyond a column" single ((:commit . "2341a2b6a33d4b8b74c35062ec9cfe1bffd61944") (:authors ("Jordon Biondo")) (:maintainer "Jordon Biondo") (:url . "www.github.com/jordonbiondo/column-enforce-mode"))]) (highlight-indentation . [(20171218 937) nil "Minor modes for highlighting indentation" single ((:commit . "35e2c1d4f8f368685893128f77f90454cb9c2708") (:authors ("Anton Johansson" . "anton.johansson@gmail.com")) (:maintainer "Anton Johansson" . "anton.johansson@gmail.com") (:url . "https://github.com/antonj/Highlight-Indentation-for-Emacs"))]) (parent-mode . [(20150824 2300) nil "get major mode's parent modes" single ((:commit . "db692cf08deff2f0e973e6e86e26662b44813d1b") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/parent-mode"))]) (highlight-numbers . [(20181013 1744) ((emacs (24)) (parent-mode (2 0))) "Highlight numbers in source code" single ((:commit . "8b4744c7f46c72b1d3d599d4fb75ef8183dee307") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/highlight-numbers"))]) (highlight-parentheses . [(20180704 1102) nil "highlight surrounding parentheses" single ((:commit . "f0bd58c8dadd2db703b7bfd09e911b5fda05b3df") (:keywords "faces" "matching") (:authors ("Nikolaj Schumacher ")) (:maintainer "Tassilo Horn" . "tsdh@gnu.org") (:url . "https://github.com/tsdh/highlight-parentheses.el"))]) (hl-anything . [(20160422 1708) ((emacs (24 3))) "Highlight symbols, selections, enclosing parens and more." tar ((:commit . "8696bc55a8cba408f0fc83a907a9ec529d79e558") (:authors ("boyw165")) (:maintainer "boyw165"))]) (indent-guide . [(20170221 1127) nil "show vertical lines to guide indentation" single ((:commit . "d64f43011c72068e008621e620009ec592b35913") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (rainbow-delimiters . [(20170929 1132) nil "Highlight brackets according to their depth" single ((:commit . "19b93892afa0494ba749c2ca9c154e04447ad778") (:keywords "faces" "convenience" "lisp" "tools") (:authors ("Jeremy Rayman" . "opensource@jeremyrayman.com") ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/rainbow-delimiters"))]) (volatile-highlights . [(20160612 155) nil "Minor mode for visual feedback on some operations." single ((:commit . "9a20091f0ce7fc0a6b3e641a6a46d5f3ac4d8392") (:keywords "emulations" "convenience" "wp") (:authors ("K-talo Miyazaki ")) (:maintainer "K-talo Miyazaki ") (:url . "http://www.emacswiki.org/emacs/download/volatile-highlights.el"))]) (hl-todo . [(20181031 1909) nil "highlight TODO and similar keywords" single ((:commit . "24b9925b1b2c7ad6bf7b66800395f74abf035c5f") (:keywords "convenience") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/hl-todo"))]) (page-break-lines . [(20171210 831) ((emacs (24 4))) "Display ^L page breaks as tidy horizontal lines" single ((:commit . "fd3b7e38ad8747cd009ead7ef1bb150849ccc693") (:keywords "convenience" "faces") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/page-break-lines"))]) (evil-anzu . [(20170124 718) ((evil (1 0 0)) (anzu (0 46))) "anzu for evil-mode" single ((:commit . "9bca6ca14d865e7e005bc02a28a09b4ae74facc9") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com") ("Fredrik Bergroth" . "fbergroth@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-evil-anzu"))]) (evil-args . [(20180908 2157) ((evil (1 0 8))) "Motions and text objects for delimited arguments in Evil." single ((:commit . "758ad5ae54ad34202064fec192c88151c08cb387") (:keywords "evil" "vim-emulation") (:authors ("Connor Smith" . "wconnorsmith@gmail.com")) (:maintainer "Connor Smith" . "wconnorsmith@gmail.com") (:url . "http://github.com/wcsmith/evil-args"))]) (evil-ediff . [(20170724 1923) ((evil (1 2 3))) "Make ediff a little evil" single ((:commit . "50d26cb0654fca8f8fd7227410e5cbf0b8f681cf") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/evil-ediff"))]) (evil-exchange . [(20170511 259) ((evil (1 2 8)) (cl-lib (0 3))) "Exchange text more easily within Evil" single ((:commit . "47691537815150715e64e6f6ec79be7746c96120") (:keywords "evil" "plugin") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:url . "http://github.com/Dewdrops/evil-exchange"))]) (evil-goggles . [(20180725 952) ((emacs (24 4)) (evil (1 0 0))) "Add a visual hint to evil operations" single ((:commit . "d7876e6566ac82b7c3251a59651e7db6ab756589") (:keywords "emulations" "evil" "vim" "visual") (:authors ("edkolev" . "evgenysw@gmail.com")) (:maintainer "edkolev" . "evgenysw@gmail.com") (:url . "http://github.com/edkolev/evil-goggles"))]) (iedit . [(20181114 950) nil "Edit multiple regions in the same way simultaneously." tar ((:commit . "35505ad860be27feaee71e8caf646706bf8ee31d") (:keywords "occurrence" "region" "simultaneous" "refactoring") (:authors ("Victor Ren" . "victorhge@gmail.com")) (:maintainer "Victor Ren" . "victorhge@gmail.com") (:url . "https://www.emacswiki.org/emacs/Iedit"))]) (evil-iedit-state . [(20180607 558) ((evil (1 0 9)) (iedit (0 97))) "Evil states to interface iedit mode." single ((:commit . "f75cff4ecbd5beaa9ca64a6c157c4105f078daec") (:keywords "convenience" "editing" "evil" "iedit" "mnemonic") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/evil-iedit-state"))]) (evil-indent-plus . [(20151109 1906) ((evil (0)) (cl-lib (0 5))) "Evil textobjects based on indentation" single ((:commit . "0c7501e6efed661242c3a20e0a6c79a6455c2c40") (:keywords "convenience" "evil") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:url . "http://github.com/TheBB/evil-indent-plus"))]) (evil-lion . [(20170811 614) ((emacs (24 3)) (evil (1 0 0))) "Evil align operator, port of vim-lion" single ((:commit . "aaa3874ad54c31b4322ac5bbc63e331498b11d61") (:keywords "emulations" "evil" "vim") (:authors ("edkolev" . "evgenysw@gmail.com")) (:maintainer "edkolev" . "evgenysw@gmail.com") (:url . "http://github.com/edkolev/evil-lion"))]) (smartparens . [(20181028 1005) ((dash (2 13 0)) (cl-lib (0 3))) "Automatic insertion, wrapping and paredit-like navigation with user defined pairs." tar ((:commit . "d65f3c0f47413c1a67ced979dc2062a073d907af"))]) (bind-map . [(20161207 1511) ((emacs (24 3))) "Bind personal keymaps in multiple locations" single ((:commit . "bf4181e3a41463684adfffc6c5c305b30480e30f") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/emacs-bind-map"))]) (evil-lisp-state . [(20160404 248) ((evil (1 0 9)) (bind-map (0)) (smartparens (1 6 1))) "An evil state to edit Lisp code" single ((:commit . "3c65fecd9917a41eaf6460f22187e2323821f3ce") (:keywords "convenience" "editing" "evil" "smartparens" "lisp" "mnemonic") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/evil-lisp-state"))]) (evil-nerd-commenter . [(20180722 2325) ((emacs (24 4))) "Comment/uncomment lines efficiently. Like Nerd Commenter in Vim" tar ((:commit . "275c95c89cc09c7096bd6fd0deabd49f29634f5d") (:keywords "commenter" "vim" "line" "evil") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/evil-nerd-commenter"))]) (evil-numbers . [(20140606 1251) nil "increment/decrement numbers like in vim" single ((:commit . "6ea1c8c3a9b37bed63d48f1128e9a4910e68187e") (:keywords "numbers" "increment" "decrement" "octal" "hex" "binary") (:authors ("Michael Markert" . "markert.michael@googlemail.com")) (:maintainer "Michael Markert" . "markert.michael@googlemail.com") (:url . "http://github.com/cofi/evil-numbers"))]) (evil-tutor . [(20150103 650) ((evil (1 0 9))) "Vimtutor adapted to Evil and wrapped in a major-mode" tar ((:commit . "4e124cd3911dc0d1b6817ad2c9e59b4753638f28") (:keywords "convenience" "editing" "evil") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/evil-tutor"))]) (evil-visual-mark-mode . [(20150202 1800) ((evil (1 0 9)) (dash (2 10))) "Display evil marks on buffer" single ((:commit . "094ee37599492885ff3144918fcdd9b74dadaaa0") (:keywords "evil") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com"))]) (evil-visualstar . [(20160223 48) ((evil (0))) "Starts a * or # search from the visual selection" single ((:commit . "06c053d8f7381f91c53311b1234872ca96ced752") (:keywords "evil" "vim" "visualstar") (:authors ("Bailey Ling")) (:maintainer "Bailey Ling") (:url . "https://github.com/bling/evil-visualstar"))]) (linum-relative . [(20180124 1047) nil "display relative line number in emacs." single ((:commit . "c74a6981b688a5e1e6b8e0809363963ff558ce4d") (:keywords "converience") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/linum-relative"))]) (anzu . [(20161017 1607) ((emacs (24 3))) "Show number of matches in mode-line while searching" single ((:commit . "e6c56ca8b23ac433f7be58b6f3f50801dd4164e4") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-anzu"))]) (eldoc-eval . [(20180607 1157) nil "Enable eldoc support when minibuffer is in use." single ((:commit . "f59a1ae7ecfa97ef659c7adb93e0673419acc485") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com"))]) (shrink-path . [(20170813 247) ((emacs (24)) (s (1 6 1)) (dash (1 8 0)) (f (0 10 0))) "fish-style path" single ((:commit . "9d06c453d1537df46a4b703a29213cc7f7857aa0") (:authors ("Benjamin Andresen")) (:maintainer "Benjamin Andresen") (:url . "https://gitlab.com/bennya/shrink-path.el"))]) (doom-modeline . [(20181117 2008) ((emacs (25 1)) (all-the-icons (1 0 0)) (shrink-path (0 2 0)) (eldoc-eval (0 1)) (dash (2 11 0))) "A minimal and modern modeline" single ((:commit . "700a0107f28a5f321485fa1e2f03a067be122594") (:keywords "faces" "mode-line") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:url . "https://github.com/seagle0128/doom-modeline"))]) (fancy-battery . [(20150101 1204) ((emacs (24 1))) "Fancy battery display" single ((:commit . "9b88ae77a01aa3edc529840338bcb2db7f445822") (:keywords "convenience" "tools" "hardware") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/lunaryorn/fancy-battery.el"))]) (spaceline . [(20180628 746) ((emacs (24 4)) (cl-lib (0 5)) (powerline (2 3)) (dash (2 11 0)) (s (1 10 0))) "Modeline configuration library for powerline" tar ((:commit . "29ced71ed0097cd5eba15d6bfdbafd9d18f5bd82") (:keywords "mode-line" "powerline" "spacemacs") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:url . "https://github.com/TheBB/spaceline"))]) (all-the-icons . [(20180125 1557) ((emacs (24 3)) (memoize (1 0 1))) "A library for inserting Developer icons" tar ((:commit . "52d1f2d36468146c93aaf11399f581401a233306") (:keywords "convenient" "lisp") (:authors ("Dominic Charlesworth" . "dgc336@gmail.com")) (:maintainer "Dominic Charlesworth" . "dgc336@gmail.com") (:url . "https://github.com/domtronn/all-the-icons.el"))]) (memoize . [(20180614 1930) nil "Memoization functions" single ((:commit . "9a561268ffb550b257a08710489a95cd087998b6") (:authors ("Christopher Wellons" . "mosquitopsu@gmail.com")) (:maintainer "Christopher Wellons" . "mosquitopsu@gmail.com") (:url . "https://github.com/skeeto/emacs-memoize"))]) (powerline . [(20180322 248) ((cl-lib (0 2))) "Rewrite of Powerline" tar ((:commit . "af5ef31a33c3589a9be0b2a55a2741582e605efd") (:keywords "mode-line") (:authors ("Donald Ephraim Curtis" . "dcurtis@milkbox.net")) (:maintainer "Donald Ephraim Curtis" . "dcurtis@milkbox.net") (:url . "http://github.com/milkypostman/powerline/"))]) (spaceline-all-the-icons . [(20170829 820) ((emacs (24 4)) (all-the-icons (2 6 0)) (spaceline (2 0 0)) (memoize (1 0 1))) "A Spaceline theme using All The Icons" tar ((:commit . "e2e195f64a541d72b6d0ba0451f1e3072234b820") (:keywords "convenience" "lisp" "tools") (:authors ("Dominic Charlesworth" . "dgc336@gmail.com")) (:maintainer "Dominic Charlesworth" . "dgc336@gmail.com") (:url . "https://github.com/domtronn/spaceline-all-the-icons.el"))]) (symon . [(20170224 833) nil "tiny graphical system monitor" single ((:commit . "8dd8b6df49b03cd7d31b85aedbe9dd08fb922335") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (popup . [(20160709 1429) ((cl-lib (0 5))) "Visual Popup User Interface" single ((:commit . "80829dd46381754639fb764da11c67235fe63282") (:keywords "lisp") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (f . [(20180106 922) ((s (1 7 0)) (dash (2 2 0))) "Modern API for working with files and directories" single ((:commit . "de6d4d40ddc844eee643e92d47b9d6a63fbebb48") (:keywords "files" "directories") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/f.el"))]) (dash . [(20180910 1856) nil "A modern list library for Emacs" single ((:commit . "6514359b8606a6a9a94068ccd601fcd6379d6584") (:keywords "lists") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (s . [(20180406 808) nil "The long lost Emacs string manipulation library." single ((:commit . "03410e6a7a2b11e47e1fea3b7d9899c7df26435e") (:keywords "strings") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (dumb-jump . [(20181022 2224) ((emacs (24 3)) (f (0 20 0)) (s (1 11 0)) (dash (2 9 0)) (popup (0 5 3))) "jump to definition for multiple languages without configuration." single ((:commit . "0c893392f6f5e797fc4dcda67cdc44c7ceed31ca") (:keywords "programming") (:authors ("jack angers")) (:maintainer "jack angers"))]) (request . [(20170201 147) ((emacs (24 4))) "Compatible layer for URL request in Emacs" single ((:commit . "a3d080e57eb8be606fbf39d1baff94e1b16e1fb8") (:authors ("Takafumi Arakaki ")) (:maintainer "Takafumi Arakaki "))]) (evil-snipe . [(20180731 1731) ((emacs (24 4)) (evil (1 2 12)) (cl-lib (0 5))) "emulate vim-sneak & vim-seek" single ((:commit . "8dd076cc56eb9b04494e4e303b86a959b048350b") (:keywords "emulation" "vim" "evil" "sneak" "seek") (:authors ("Henrik Lissner ")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/evil-snipe"))]) (evil . [(20181107 1016) ((emacs (24 1)) (undo-tree (0 6 3)) (goto-chg (1 6)) (cl-lib (0 5))) "Extensible Vi layer for Emacs." tar ((:commit . "99bcf8c31ee72a3a571e013f40d105618fb92d19"))]) (cl-lib . [(0 6 1) nil "Properly prefixed CL functions and macros" single ((:url . "http://elpa.gnu.org/packages/cl-lib.html") (:keywords))]) (goto-chg . [(20180105 1833) nil "goto last change" single ((:commit . "e5b38e4e1378f6ea48fa9e8439f49c2998654aa4") (:keywords "convenience" "matching") (:authors ("David Andersson ")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@github.com") (:url . "https://github.com/emacs-evil/goto-chg"))]) (undo-tree . [(0 6 5) nil "Treat undo history as a tree" single ((:url . "http://www.dr-qubit.org/emacs.php") (:keywords "convenience" "files" "undo" "redo" "history" "tree"))]) (evil-commentary . [(20170413 1451) ((evil (1 0 0))) "Comment stuff out. A port of vim-commentary." tar ((:commit . "395f91014b69844b81660c155f42eb9b1b3d199d") (:keywords "evil" "comment" "commentary" "evil-commentary") (:authors ("Quang Linh LE" . "linktohack@gmail.com")) (:maintainer "Quang Linh LE" . "linktohack@gmail.com") (:url . "http://github.com/linktohack/evil-commentary"))]) (vim-empty-lines-mode . [(20150111 426) ((emacs (23))) "Vim-like empty line indicator at end of files." single ((:commit . "d4a5034ca8ea0c962ad6e92c86c0fa2a74d2964b") (:keywords "emulations") (:authors ("Jonne Mickelin" . "jonne@ljhms.com")) (:maintainer "Jonne Mickelin" . "jonne@ljhms.com") (:url . "https://github.com/jmickelin/vim-empty-lines-mode"))])) \ No newline at end of file +(1 (diminish . [(20170419 1736) nil "Diminished modes are minor modes with no modeline display" single ((:commit . "565a983a39d2e2cffab5df13b34f3b6116723208") (:keywords "extensions" "diminish" "minor" "codeprose") (:authors ("Will Mengarini" . "seldon@eskimo.com")) (:maintainer "Martin Yrjölä" . "martin.yrjola@gmail.com") (:url . "https://github.com/myrjola/diminish.el"))]) (bind-key . [(20180513 430) nil "A simple way to manage personal keybindings" single ((:commit . "1d5ffb2e0d1427066ced58febbba68c1328bf001") (:keywords "keys" "keybinding" "config" "dotemacs") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:url . "https://github.com/jwiegley/use-package"))]) (use-package . [(20190716 1829) ((emacs (24 3)) (bind-key (2 4))) "A configuration macro for simplifying your .emacs" tar ((:commit . "1d5ffb2e0d1427066ced58febbba68c1328bf001") (:keywords "dotemacs" "startup" "speed" "config" "package") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:url . "https://github.com/jwiegley/use-package"))]) (which-key . [(20190802 240) ((emacs (24 4))) "Display available keybindings in popup" single ((:commit . "42a25055163141165aa0269dbca69735e704825c") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/emacs-which-key"))]) (dotenv-mode . [(20180207 1914) ((emacs (24 3))) "Major mode for .env files" single ((:commit . "f4c52bcd5313379b9f2460db7f7a33119dfa96ea") (:authors ("Preetpal S. Sohal")) (:maintainer "Preetpal S. Sohal") (:url . "https://github.com/preetpalS/emacs-dotenv-mode"))]) (packed . [(20180318 1729) ((emacs (24 3))) "package manager agnostic Emacs Lisp package utilities" single ((:commit . "f350cc446c65b85bcc213265cd6dcadee1568762") (:keywords "compile" "convenience" "lisp" "package" "library") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/packed"))]) (auto-compile . [(20181230 2216) ((emacs (25 1)) (packed (3 0 0))) "automatically compile Emacs Lisp libraries" single ((:commit . "f043133f37fe6d707fa03a1ec4ba619da24c2f35") (:keywords "compile" "convenience" "lisp") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/auto-compile"))]) (elisp-slime-nav . [(20160128 1909) ((cl-lib (0 2))) "Make M-. and M-, work in elisp like they do in slime" single ((:commit . "34938422929800839e2f935aca890cd4a229ca99") (:keywords "navigation" "slime" "elisp" "emacs-lisp") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/elisp-slime-nav"))]) (evil-cleverparens . [(20170718 413) ((evil (1 0)) (paredit (1)) (smartparens (1 6 1)) (emacs (24 4)) (dash (2 12 0))) "Evil friendly minor-mode for editing lisp." tar ((:commit . "8c45879d49bfa6d4e414b6c1df700a4a51cbb869") (:keywords "cleverparens" "parentheses" "evil" "paredit" "smartparens") (:authors ("Olli Piepponen" . "opieppo@gmail.com")) (:maintainer "Olli Piepponen" . "opieppo@gmail.com") (:url . "https://github.com/luxbock/evil-cleverparens"))]) (package-lint . [(20190807 1837) ((cl-lib (0 5)) (emacs (24))) "A linting library for elisp package authors" single ((:commit . "c5ba20dead0df743a699f502f5d034d03b367f65") (:keywords "lisp") (:authors ("Steve Purcell" . "steve@sanityinc.com") ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/package-lint"))]) (flycheck-package . [(20161111 2251) ((flycheck (0 22)) (package-lint (0 2))) "A Flycheck checker for elisp package authors" single ((:commit . "6d99248b45eea1e5236062f38e524230efdb1a84") (:keywords "lisp") (:authors ("Steve Purcell" . "steve@sanityinc.com") ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (ggtags . [(20190320 2208) ((emacs (25))) "emacs frontend to GNU Global source code tagging system" single ((:commit . "4d9000034d352cd983ae6626f560e434d0b3e9ca") (:keywords "tools" "convenience") (:authors ("Leo Liu" . "sdl.web@gmail.com")) (:maintainer "Leo Liu" . "sdl.web@gmail.com") (:url . "https://github.com/leoliu/ggtags"))]) (counsel-gtags . [(20190422 1501) ((emacs (25 1)) (counsel (0 8 0)) (seq (1 0))) "ivy for GNU global" single ((:commit . "3ebfd4159856e9dbd9531b2a43410f72175a90bb") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-counsel-gtags"))]) (helm-gtags . [(20170116 529) ((emacs (24 4)) (helm (2 0))) "GNU GLOBAL helm interface" single ((:commit . "108e93d0d099ebb7b98847388f368311cf177033") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-gtags"))]) (nameless . [(20190429 1202) ((emacs (24 4))) "Hide package namespace in your emacs-lisp code" single ((:commit . "a3a1ce3ec0c5724bcbfe553d831bd4f6b3fe863a") (:keywords "convenience" "lisp") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/nameless"))]) (overseer . [(20180226 619) ((emacs (24)) (dash (2 10 0)) (pkg-info (0 4)) (f (0 18 1))) "Ert-runner Integration Into Emacs" single ((:commit . "02d49f582e80e36b4334c9187801c5ecfb027789") (:authors ("Samuel Tonini" . "tonini.samuel@gmail.com")) (:maintainer "Samuel Tonini" . "tonini.samuel@gmail.com") (:url . "http://www.github.com/tonini/overseer.el"))]) (parinfer . [(20180904 844) ((dash (2 13 0)) (cl-lib (0 5))) "Simpler Lisp editing" tar ((:commit . "a7c041454e05ec2b88333a73e72debaa671ed596") (:keywords "parinfer") (:authors ("Shi Tianshu")) (:maintainer "Shi Tianshu") (:url . "https://github.com/DogLooksGood/parinfer-mode"))]) (srefactor . [(20180703 1810) ((emacs (24 4))) "A refactoring tool based on Semantic parser framework" tar ((:commit . "6f2c97d17fb70f4ca2112f5a2b99a8ec162004f5") (:keywords "c" "languages" "tools") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:url . "https://github.com/tuhdo/semantic-refactor"))]) (twittering-mode . [(20181121 1402) nil "Major mode for Twitter" single ((:commit . "114891e8fdb4f06b1326a6cf795e49c205cf9e29") (:keywords "twitter" "web") (:authors ("Tadashi MATSUO" . "tad@mymail.twin.ne.jp") ("Y. Hayamizu" . "y.hayamizu@gmail.com") ("Tsuyoshi CHO" . "Tsuyoshi.CHO+develop@Gmail.com") ("Alberto Garcia" . "agarcia@igalia.com") ("Xavier Maillard" . "xavier@maillard.im")) (:maintainer "Tadashi MATSUO" . "tad@mymail.twin.ne.jp") (:url . "http://twmode.sf.net/"))]) (engine-mode . [(20181222 2027) ((cl-lib (0 5))) "Define and query search engines from within Emacs." single ((:commit . "117a9c0cbc1ff8ade7f17cd40d1d2f5eb24f51a3") (:authors ("Harry R. Schwartz" . "hello@harryrschwartz.com")) (:maintainer "Harry R. Schwartz" . "hello@harryrschwartz.com") (:url . "https://github.com/hrs/engine-mode"))]) (geeknote . [(20160717 1249) ((emacs (24))) "Use Evernote in Emacs through geeknote" single ((:commit . "8ed607c76864afcc9c338972ab093caf4501cbf8") (:keywords "evernote" "geeknote" "note" "emacs-evernote" "evernote-mode") (:authors ("Evan Dale Aromin")) (:maintainer "Evan Dale Aromin") (:url . "http://github.com/avendael/emacs-geeknote"))]) (xml-rpc . [(20181002 1353) nil "An elisp implementation of clientside XML-RPC" single ((:commit . "8f624f8b964e9145acb504e4457c9510e87dd93c") (:keywords "xml" "rpc" "network") (:authors ("Mark A. Hershberger" . "mah@everybody.org")) (:maintainer "Mark A. Hershberger" . "mah@everybody.org") (:url . "http://github.com/hexmode/xml-rpc-el"))]) (confluence . [(20151021 128) ((xml-rpc (1 6 4))) "Emacs mode for interacting with confluence wikis" tar ((:commit . "4518d270a07760644c4204985c83d234ece4738b") (:keywords "confluence" "wiki" "xmlrpc") (:authors ("James Ahlborn")) (:maintainer "James Ahlborn") (:url . "http://code.google.com/p/confluence-el/"))]) (wakatime-mode . [(20180920 702) nil "Automatic time tracking extension for WakaTime" single ((:commit . "2531cb58287770883ba534d20b3288955c4d6ef3") (:keywords "calendar" "comm") (:authors ("Gabor Torok" . "gabor@20y.hu")) (:maintainer "Alan Hamlett" . "alan@wakatime.com"))]) (feature-mode . [(20190801 1137) nil "Major mode for editing Gherkin (i.e. Cucumber) user stories" tar ((:commit . "11ae1671629bfedaa553c7b819676d64eb320992"))]) (projectile-rails . [(20190706 1231) ((emacs (24 3)) (projectile (0 12 0)) (inflections (1 1)) (inf-ruby (2 2 6)) (f (0 13 0)) (rake (0 3 2))) "Minor mode for Rails projects based on projectile-mode" single ((:commit . "b0c88a381cc15b0aaba2629949e10ae6373d209a") (:keywords "rails" "projectile") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:url . "https://github.com/asok/projectile-rails"))]) (alchemist . [(20180312 1304) ((elixir-mode (2 2 5)) (dash (2 11 0)) (emacs (24 4)) (company (0 8 0)) (pkg-info (0 4)) (s (1 11 0))) "Elixir tooling integration into Emacs" tar ((:commit . "6f99367511ae209f8fe2c990779764bbb4ccb6ed") (:keywords "languages" "elixir" "elixirc" "mix" "hex" "alchemist") (:authors ("Samuel Tonini" . "tonini.samuel@gmail.com")) (:maintainer "Samuel Tonini" . "tonini.samuel@gmail.com") (:url . "http://www.github.com/tonini/alchemist.el"))]) (ember-mode . [(20190403 1652) ((cl-lib (0 5))) "Ember navigation mode for emacs" single ((:commit . "3510afc5023d760a66aef260ba601c15a31dc878") (:keywords "ember" "ember.js" "emberjs") (:authors ("Aad Versteden" . "madnificent@gmail.com")) (:maintainer "Aad Versteden" . "madnificent@gmail.com"))]) (ember-yasnippets . [(20160526 1658) ((yasnippet (0 8 0))) "Snippets for Ember.js development" tar ((:commit . "3b5bd01569646237bf1b540d097e12f9118b67f4") (:keywords "tools" "abbrev" "languages") (:authors ("Ron White" . "ronco@costite.com")) (:maintainer "Ron White" . "ronco@costite.com"))]) (pony-mode . [(20170807 1522) nil "Minor mode for working with Django Projects" tar ((:commit . "760684d30b6c234d1b88c9a4673a808f36f7f341"))]) (add-node-modules-path . [(20180710 2342) nil "Add node_modules to your exec-path" single ((:commit . "f31e69ccb681f882aebb806ce6e9478e3ac39708") (:keywords "javascript" "node" "node_modules" "eslint") (:authors ("Neri Marschik" . "marschik_neri@cyberagent.co.jp")) (:maintainer "Neri Marschik" . "marschik_neri@cyberagent.co.jp") (:url . "https://github.com/codesuki/add-node-modules-path"))]) (emmet-mode . [(20180613 341) nil "Unofficial Emmet's support for emacs" single ((:commit . "1acb821e0142136344ccf40c1e5fb664d7db2e70") (:keywords "convenience") (:authors ("Shin Aoyama" . "smihica@gmail.com")) (:maintainer "Shin Aoyama" . "smihica@gmail.com") (:url . "https://github.com/smihica/emmet-mode"))]) (evil-matchit . [(20190808 1056) ((evil (1 2 0)) (emacs (24 4))) "Vim matchit ported to Evil" tar ((:commit . "43be86d8c41841a20733718d177e8299d5379218") (:keywords "matchit" "vim" "evil") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/evil-matchit"))]) (grizzl . [(20160818 737) ((cl-lib (0 5)) (emacs (24 3))) "Fast fuzzy search index for Emacs." single ((:commit . "1e917253ce2b846f0272b8356fad3dbff9cd513a") (:keywords "convenience" "usability") (:authors ("Chris Corbyn" . "chris@w3style.co.uk")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "https://github.com/grizzl/grizzl"))]) (import-js . [(20180709 1833) ((grizzl (0 1 0)) (emacs (24))) "Import Javascript dependencies" single ((:commit . "fb1f167e33c388b09a2afd32fbda90a67bfb2e40") (:keywords "javascript") (:authors ("Kevin Kehl" . "kevin.kehl@gmail.com")) (:maintainer "Kevin Kehl" . "kevin.kehl@gmail.com") (:url . "http://github.com/Galooshi/emacs-import-js/"))]) (js-doc . [(20160715 434) nil "Insert JsDoc style comment easily" single ((:commit . "f0606e89d5aa89146f96edb38cf69af0068a9d1e") (:keywords "document" "comment") (:authors ("mooz" . "stillpedant@gmail.com")) (:maintainer "mooz" . "stillpedant@gmail.com") (:url . "https://github.com/mooz/js-doc"))]) (prettier-js . [(20180109 726) nil "Minor mode to format JS code on file save" single ((:commit . "e9b73e81d3e1642aec682195f127a42dfb0b5774") (:keywords "convenience" "wp" "edit" "js") (:authors ("James Long and contributors")) (:maintainer "James Long and contributors") (:url . "https://github.com/prettier/prettier-emacs"))]) (rjsx-mode . [(20190614 2215) ((emacs (24 4)) (js2-mode (20170504))) "Real support for JSX" single ((:commit . "0e7fa6b4facdec4f85a7a8865bdf59dfd57217b5") (:keywords "languages") (:authors ("Felipe Ochoa" . "felipe@fov.space")) (:maintainer "Felipe Ochoa" . "felipe@fov.space") (:url . "https://github.com/felipeochoa/rjsx-mode/"))]) (web-beautify . [(20161115 2247) nil "Format HTML, CSS and JavaScript/JSON" single ((:commit . "e1b45321d8c11b404b12c8e55afe55eaa7c84ee9") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/web-beautify"))]) (dune . [(20190808 345) nil "Integration with the dune build system" tar ((:commit . "888a64db60b973da5685f8e4f2d9f2b2e1a4f264") (:url . "https://github.com/ocaml/dune"))]) (flycheck-ocaml . [(20170730 2153) ((emacs (24 1)) (flycheck (0 22)) (merlin (3 0 1)) (let-alist (1 0 3))) "Flycheck: OCaml support" single ((:commit . "8707a7bf545a8639a6a5c600a98d9a2ea1487dc9") (:keywords "convenience" "tools" "languages") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-ocaml"))]) (merlin . [(20190718 1023) nil "Mode for Merlin, an assistant for OCaml." tar ((:commit . "bd94d345bf19e612c11737de2d7d401bcc4348a6") (:keywords "ocaml" "languages") (:authors ("Frédéric Bour ")) (:maintainer "Frédéric Bour ") (:url . "https://github.com/ocaml/merlin"))]) (ocp-indent . [(20190726 1452) nil "automatic indentation with ocp-indent" single ((:commit . "bdd84a71da8eac87447e35b55782ec07f0d2aead") (:keywords "ocaml" "languages") (:url . "http://www.typerex.org/ocp-indent.html"))]) (caml . [(20190413 1205) nil "OCaml code editing commands for Emacs" tar ((:commit . "38ebde12d3d529e6ef8078967997d32226e69e82") (:keywords "ocaml") (:authors ("Jacques Garrigue" . "garrigue@kurims.kyoto-u.ac.jp") ("Ian T Zimmerman" . "itz@rahul.net")) (:maintainer "Damien Doligez" . "damien.doligez@inria.fr") (:url . "https://github.com/ocaml/ocaml/"))]) (tuareg . [(20190805 958) ((caml (3 12 0 1)) (emacs (24 4))) "OCaml mode for Emacs." tar ((:commit . "74e7f66f31290f6599fda0067d795e201270be43") (:keywords "ocaml" "languages") (:authors ("Albert Cohen" . "Albert.Cohen@inria.fr") ("Sam Steingold" . "sds@gnu.org") ("Christophe Troestler" . "Christophe.Troestler@umons.ac.be") ("Till Varoquaux" . "till@pps.jussieu.fr") ("Sean McLaughlin" . "seanmcl@gmail.com") ("Stefan Monnier" . "monnier@iro.umontreal.ca")) (:maintainer "Albert Cohen" . "Albert.Cohen@inria.fr") (:url . "https://github.com/ocaml/tuareg"))]) (utop . [(20190715 1836) ((emacs (24))) "Universal toplevel for OCaml" single ((:commit . "2405c8dd8f1cb995baeffb90324dc9c0e1966edc") (:keywords "ocaml" "languages") (:authors ("Jeremie Dimino" . "jeremie@dimino.org")) (:maintainer "Jeremie Dimino" . "jeremie@dimino.org") (:url . "https://github.com/diml/utop"))]) (geiser . [(20190820 1931) nil "GNU Emacs and Scheme talk to each other" tar ((:commit . "56e3149aa1158743f96a5a0bdf5940eaf510a35f") (:url . "http://www.nongnu.org/geiser/"))]) (plantuml-mode . [(20190821 1234) ((dash (2 0 0)) (emacs (25 0))) "Major mode for PlantUML" single ((:commit . "ae8593d66205ac8808f91658ea205f4f4e898089") (:keywords "uml" "plantuml" "ascii") (:authors ("Zhang Weize (zwz)")) (:maintainer "Carlo Sciolla (skuro)"))]) (powershell . [(20190421 2038) ((emacs (24))) "Mode for editing PowerShell scripts" single ((:commit . "87826777bd3ebd53740be99b4546bfc11ccc625d") (:keywords "powershell" "languages") (:authors ("Frédéric Perrin ")) (:maintainer "Frédéric Perrin ") (:url . "http://github.com/jschaf/powershell.el"))]) (ediprolog . [(1 2) nil "Emacs Does Interactive Prolog" single ((:keywords "languages" "processes") (:authors ("Markus Triska" . "triska@metalevel.at")) (:maintainer "Markus Triska" . "triska@metalevel.at") (:url . "https://www.metalevel.at/ediprolog/"))]) (zig-mode . [(20190109 217) ((emacs (24))) "A major mode for the Zig programming language" single ((:commit . "c2deea85dd65c3e73c2771c56a998cbdeb9ff717") (:keywords "zig" "languages") (:authors ("Andrea Orru , Andrew Kelley" . "superjoe30@gmail.com")) (:maintainer "Andrea Orru , Andrew Kelley" . "superjoe30@gmail.com") (:url . "https://github.com/zig-lang/zig-mode"))]) (vimrc-mode . [(20181116 1919) nil "Major mode for vimrc files" single ((:commit . "13bc150a870d5d4a95f1111e4740e2b22813c30e") (:keywords "languages" "vim") (:url . "https://github.com/mcandre/vimrc-mode"))]) (dactyl-mode . [(20140906 1725) nil "Major mode for editing Pentadactyl config files" single ((:commit . "cc55fe6b987271d9647492b8df4c812d884f661f") (:keywords "languages" "vim") (:url . "https://github.com/luxbock/dactyl-mode"))]) (company-plsense . [(20180118 58) ((company (0 9 3)) (cl-lib (0 5 0)) (dash (2 12 0)) (s (1 12)) (emacs (24))) "Company backend for Perl" single ((:commit . "b48e3181e08ec597269621d621aa06636f02d883") (:authors ("Troy Hinckley" . "troy.hinckley@gmail.com")) (:maintainer "Troy Hinckley" . "troy.hinckley@gmail.com") (:url . "https://github.com/CeleritasCelery/company-plsense"))]) (test-simple . [(20170527 1532) ((cl-lib (0))) "Simple Unit Test Framework for Emacs Lisp" single ((:commit . "cfd383d36dc6853917acb753fdfa0eebf33856f3") (:keywords "unit-test") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/rocky/emacs-test-simple"))]) (loc-changes . [(20160801 1708) nil "keep track of positions even after buffer changes" single ((:commit . "4d1dcdf7631c23b1259ad4f72bf9686cf95fb46c") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/rocky/emacs-loc-changes"))]) (load-relative . [(20190601 1221) nil "Relative file load (within a multi-file Emacs package)" tar ((:commit . "dbcd7cbcca6503ef93f4b8d19bf7a9efd7f6bf9b") (:keywords "internal") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/rocky/emacs-load-relative"))]) (realgud . [(20190724 2001) ((load-relative (1 3 1)) (loc-changes (1 2)) (test-simple (1 3 0)) (emacs (25))) "A modular front-end for interacting with external debuggers" tar ((:commit . "11c57cd2ea898c2167ad6c7f80eb1807109d8260") (:keywords "debugger" "gdb" "python" "perl" "go" "bash" "zsh" "bashdb" "zshdb" "remake" "trepan" "perldb" "pdb") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/realgud/realgud/"))]) (company-glsl . [(20171015 1749) ((company (0 9 4)) (glsl-mode (2 0)) (emacs (24 4))) "Support glsl in company-mode" single ((:commit . "a262c12c3bcd0807718c4edcaf2b054e30ef0e26") (:authors ("Guido Schmidt" . "git@guidoschmidt.cc")) (:maintainer "Guido Schmidt" . "git@guidoschmidt.cc") (:url . "https://github.com/guidoschmidt/company-glsl"))]) (cuda-mode . [(20151214 321) nil "NVIDIA CUDA Major Mode" single ((:commit . "9ae9eacfdba3559b5456342d0d03296290df8ff5") (:keywords "c" "languages") (:authors ("Jack Morrison" . "jackmorrison1@gmail.com")) (:maintainer "Jack Morrison" . "jackmorrison1@gmail.com"))]) (glsl-mode . [(20190514 145) nil "major mode for Open GLSL shader files" single ((:commit . "eaea63a45d0dcb04ddbf069b4bcfd99f10919e44") (:keywords "languages" "opengl" "gpu" "spir-v" "vulkan") (:url . "https://github.com/jimhourihan/glsl-mode"))]) (opencl-mode . [(20190615 1957) nil "Syntax coloring for opencl kernels" single ((:commit . "55cb49c8243e6420961d719faced035bc547c1ef") (:keywords "c" "opencl") (:authors ("Salmane Bah" . "salmane.bah@u-bordeaux.fr")) (:maintainer "Salmane Bah" . "salmane.bah@u-bordeaux.fr") (:url . "https://github.com/salmanebah/opencl-mode"))]) (nasm-mode . [(20190410 342) ((emacs (24 3))) "NASM x86 assembly major mode" single ((:commit . "65ca6546fc395711fac5b3b4299e76c2303d43a8") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/nasm-mode"))]) (x86-lookup . [(20180528 1635) ((emacs (24 3)) (cl-lib (0 3))) "jump to x86 instruction documentation" single ((:commit . "609b2ba70dc5a246ac9b4b5f89eb5ef4331519bf") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/x86-lookup"))]) (company-go . [(20190203 19) ((company (0 8 0)) (go-mode (1 0 0))) "company-mode backend for Go (using gocode)" single ((:commit . "7fb65232883f19a8305706b4b4ff32916ffbcaf5") (:keywords "languages") (:authors ("nsf" . "no.smile.face@gmail.com")) (:maintainer "nsf" . "no.smile.face@gmail.com"))]) (flycheck-gometalinter . [(20180424 941) ((emacs (24)) (flycheck (0 22))) "flycheck checker for gometalinter" single ((:commit . "422f6e4b77b27fd7370f0c88437ac5072c9d3413") (:keywords "convenience" "tools" "go") (:authors ("Diep Pham" . "me@favadi.com")) (:maintainer "Diep Pham" . "me@favadi.com") (:url . "https://github.com/favadi/flycheck-gometalinter"))]) (flycheck-golangci-lint . [(20190330 1412) ((emacs (24)) (flycheck (0 22))) "Flycheck checker for golangci-lint" single ((:commit . "8e446c68311048f0b87febf8ef0379e29d358851") (:keywords "convenience" "tools" "go") (:authors ("Wei Jian Gan" . "weijiangan@outlook.com")) (:maintainer "Wei Jian Gan" . "weijiangan@outlook.com") (:url . "https://github.com/weijiangan/flycheck-golangci-lint"))]) (go-eldoc . [(20170305 1427) ((emacs (24 3)) (go-mode (1 0 0))) "eldoc for go-mode" single ((:commit . "cbbd2ea1e94a36004432a9ac61414cb5a95a39bd") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-eldoc"))]) (go-fill-struct . [(20171225 331) ((emacs (24))) "Fill struct for golang." single ((:commit . "a613d0b378473eef39e8fd5724abe790aea84321") (:keywords "tools") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:url . "https://github.com/s-kostyaev/go-fill-struct"))]) (go-gen-test . [(20171023 358) ((emacs (24 3)) (s (1 12))) "Generate tests for go code with gotests" single ((:commit . "44c202ac97e728e93a35cee028a0ea8dd6e4292c") (:keywords "languages") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:url . "https://github.com/s-kostyaev/go-gen-test"))]) (go-guru . [(20181012 330) ((go-mode (1 3 1)) (cl-lib (0 5))) "Integration of the Go 'guru' analysis tool into Emacs." single ((:commit . "9ab06b3deb1cbf00802d7824bf7107c31865f9fb") (:keywords "tools"))]) (go-impl . [(20170125 1552) ((emacs (24 3)) (go-mode (1 3 0))) "impl integration for go-mode" single ((:commit . "69f0d0ef05771487e15abec500cd06befd171abf") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-impl"))]) (go-rename . [(20190805 2101) ((go-mode (1 3 1))) "Integration of the 'gorename' tool into Emacs." single ((:commit . "9ab06b3deb1cbf00802d7824bf7107c31865f9fb") (:keywords "tools"))]) (go-mode . [(20190819 2109) nil "Major mode for the Go programming language" single ((:commit . "9ab06b3deb1cbf00802d7824bf7107c31865f9fb") (:keywords "languages" "go") (:authors ("The go-mode Authors")) (:maintainer "The go-mode Authors") (:url . "https://github.com/dominikh/go-mode.el"))]) (go-tag . [(20180227 411) ((emacs (24 0)) (go-mode (1 5 0))) "Edit Golang struct field tag" single ((:commit . "59b243f2fa079d9de9d56f6e2d94397e9560310a") (:keywords "tools") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/emacs-go-tag"))]) (godoctor . [(20180710 2152) nil "Frontend for godoctor" single ((:commit . "4b45ff3d0572f0e84056e4c3ba91fcc178199859") (:keywords "go" "golang" "refactoring") (:authors ("Sangho Na" . "microamp@protonmail.com")) (:maintainer "Sangho Na" . "microamp@protonmail.com") (:url . "https://github.com/microamp/godoctor.el"))]) (faceup . [(20170925 1946) nil "Markup language for faces and font-lock regression testing" single ((:commit . "6c92dad56a133e14e7b27831e1bcf9b3a71ff154") (:keywords "faces" "languages") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/faceup"))]) (racket-mode . [(20190803 1820) ((emacs (24 3)) (faceup (0 0 2))) "Major mode for Racket language." tar ((:commit . "5300aa004f08535c3fac99f1af78462f129aca81") (:authors ("Greg Hendershott")) (:maintainer "Greg Hendershott") (:url . "https://www.racket-mode.com/"))]) (arduino-mode . [(20180509 36) ((emacs (25)) (cl-lib (0 5)) (spinner (1 7 3))) "Major mode for editing Arduino code." tar ((:commit . "23ae47c9f28f559e70b790b471f20310e163a39b") (:keywords "languages" "arduino") (:maintainer "stardiviner" . "numbchild@gmail.com") (:url . "https://github.com/stardiviner/arduino-mode"))]) (kivy-mode . [(20180702 2029) nil "Emacs major mode for editing Kivy files" single ((:commit . "3d87584b963a79465ed52e09f4de17395c6aae60") (:authors ("Dean Serenevy" . "dean@serenevy.net")) (:maintainer "Dean Serenevy" . "dean@serenevy.net"))]) (matlab-mode . [(20180928 1526) nil "Major mode for MATLAB(R) dot-m files" tar ((:commit . "3fbca4259b2584bde08df07ba51944d7e3e2b4f4") (:url . "http://sourceforge.net/projects/matlab-emacs/") (:keywords "matlab" "programming" "language" "(X)emacs"))]) (pkgbuild-mode . [(20181216 1331) ((emacs (25 1))) "Interface to the ArchLinux package manager" single ((:commit . "e30e37730b5f30bc0dd5b9328fbf4cb3e6f46fdd") (:keywords "languages") (:authors ("Juergen Hoetzel" . "juergen@hoetzel.info")) (:maintainer "Juergen Hoetzel" . "juergen@hoetzel.info") (:url . "https://github.com/juergenhoetzel/pkgbuild-mode"))]) (qml-mode . [(20161016 31) nil "Major mode for editing QT Declarative (QML) code." single ((:commit . "6c5f33ba88ae010bf201a80ee8095e20a724558c") (:keywords "qml" "qt" "qt declarative") (:authors ("Yen-Chin Lee" . "coldnew.tw@gmail.com")) (:maintainer "Yen-Chin Lee" . "coldnew.tw@gmail.com") (:url . "https://github.com/coldnew/qml-mode"))]) (scad-mode . [(20190413 1246) nil "A major mode for editing OpenSCAD code" single ((:commit . "c060053d3b4818bf6d0620b0711be845795c4157") (:keywords "languages") (:authors ("Len Trigg, Åukasz Stelmach")) (:maintainer "Len Trigg" . "lenbok@gmail.com") (:url . "https://raw.github.com/openscad/openscad/master/contrib/scad-mode.el"))]) (stan-mode . [(20190805 1427) nil "Major mode for editing Stan files" tar ((:commit . "e60fe0caecb8e84d0b8fc160a0cdf8343e33d905") (:keywords "languanges") (:authors ("Jeffrey Arnold" . "jeffrey.arnold@gmail.com") ("Daniel Lee" . "bearlee@alum.mit.edu")) (:maintainer "Jeffrey Arnold" . "jeffrey.arnold@gmail.com") (:url . "http://github.com/stan-dev/stan-mode"))]) (thrift . [(20180905 1050) ((emacs (24))) "major mode for fbthrift and Apache Thrift files" single ((:commit . "dbb639ee4da40e8a1fe424c234af7af8a7042aa0") (:keywords "languages"))]) (vala-mode . [(20150324 2225) nil "Vala mode derived mode" single ((:commit . "fb2871a4492d75d03d72e60474919ab89adb267b") (:keywords "vala" "languages" "oop") (:authors ("2005 Dylan R. E. Moonfire") (" 2008 Étienne BERSAC")) (:maintainer "Étienne BERSAC" . "bersace03@laposte.net"))]) (vala-snippets . [(20150429 352) ((yasnippet (0 8 0))) "Yasnippets for Vala" tar ((:commit . "671439501060449bd100b9fffd524a86064fbfbb") (:authors ("Daniel Gopar")) (:maintainer "Daniel Gopar") (:url . "https://github.com/gopar/vala-snippets"))]) (wolfram-mode . [(20180307 13) ((emacs (24 3))) "Mathematica editing and inferior mode." single ((:commit . "be680190cac6ccf579dbce107deaae495928d1b3") (:keywords "languages" "processes" "tools") (:authors ("Daichi Mochihashi ")) (:maintainer "Daichi Mochihashi ") (:url . "https://github.com/kawabata/wolfram-mode/"))]) (flycheck-nim . [(20160715 428) ((dash (2 4 0)) (flycheck (0 20))) "Defines a flycheck syntax checker for nim" single ((:commit . "6d27349b66e44578851e6148299709d64d2bde41") (:authors ("Adam Schwalm" . "adamschwalm@gmail.com")) (:maintainer "Adam Schwalm" . "adamschwalm@gmail.com") (:url . "https://github.com/ALSchwalm/flycheck-nim"))]) (flycheck-nimsuggest . [(20171027 2208) ((flycheck (0 23)) (emacs (24 3))) "flycheck backend for Nim using nimsuggest" single ((:commit . "dc9a5de1cb3ee05db5794d824610959a1f603bc9") (:authors ("Yuta Yamada ")) (:maintainer "Yuta Yamada ") (:url . "https://github.com/yuutayamada/flycheck-nimsuggest"))]) (commenter . [(20160219 1627) ((emacs (24 4)) (let-alist (1 0 4))) "multiline-comment support package" single ((:commit . "6d1885419434ba779270c6fda0e30d390bb074bd") (:keywords "comment") (:authors ("Yuta Yamada ")) (:maintainer "Yuta Yamada ") (:url . "https://github.com/yuutayamada/commenter"))]) (nim-mode . [(20190710 2254) ((emacs (24 4)) (epc (0 1 1)) (let-alist (1 0 1)) (commenter (0 5 1)) (flycheck-nimsuggest (0 8 1))) "A major mode for the Nim programming language" tar ((:commit . "0d46c05cdfa65d37f8cb5da860ff3052782f6bbd") (:keywords "nim" "languages") (:authors ("Simon Hafner")) (:maintainer "Simon Hafner" . "hafnersimon@gmail.com"))]) (hy-mode . [(20190620 1804) ((dash (2 13 0)) (dash-functional (1 2 0)) (s (1 11 0)) (emacs (24))) "Major mode for Hylang" tar ((:commit . "8699b744c03e0399c049757b7819d69768cac3bc") (:keywords "languages" "lisp" "python") (:url . "http://github.com/hylang/hy-mode"))]) (ob-hy . [(20180702 540) ((emacs (24 4))) "org-babel functions for Hy-lang evaluation" tar ((:commit . "a42ecaf440adc03e279afe43ee5ef6093ddd542a") (:keywords "hy" "literate programming" "reproducible research") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/ob-hy"))]) (pyenv-mode . [(20170801 2348) ((pythonic (0 1 0))) "Integrate pyenv with python-mode" single ((:commit . "eabb1c66f9e0c0500fef4d089508aad246d81dc0") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/pyenv-mode"))]) (yang-mode . [(20190507 724) nil "major mode for editing YANG files" single ((:commit . "4b4ab4d4a79d37d6c31c6ea7cccbc425e0b1eded") (:authors ("Martin Bjorklund" . "mbj4668@gmail.com")) (:maintainer "Martin Bjorklund" . "mbj4668@gmail.com"))]) (blacken . [(20190521 841) ((emacs (25 2))) "Reformat python buffers using the \"black\" formatter" single ((:commit . "1874018ae242176d0780cdcd0109e8f9a123a914") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/blacken"))]) (cython-mode . [(20190111 2150) nil "Major mode for editing Cython files" single ((:commit . "0ab70ccae4dbdc20aabf718db63440e4dc874915"))]) (helm-cscope . [(20190615 41) ((xcscope (1 0)) (helm (1 6 7)) (cl-lib (0 5)) (emacs (24 1))) "Helm interface for xcscope.el." single ((:commit . "af1d9e7f4460a88d7400b5a74d5da68084089ac1") (:keywords "cscope" "helm") (:authors ("alpha22jp" . "alpha22jp@gmail.com")) (:maintainer "alpha22jp" . "alpha22jp@gmail.com") (:url . "https://github.com/alpha22jp/helm-cscope.el"))]) (helm-pydoc . [(20160918 542) ((helm-core (2 0)) (emacs (24 4))) "pydoc with helm interface" tar ((:commit . "85480a29b56dacde425655bc8f5a597c785afdf5") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-pydoc"))]) (epc . [(20140610 534) ((concurrent (0 3 1)) (ctable (0 1 2))) "A RPC stack for the Emacs Lisp" tar ((:commit . "e1bfa5ca163273859336e3cc89b4b6460f7f8cda") (:keywords "lisp" "rpc") (:authors ("SAKURAI Masashi ")) (:maintainer "SAKURAI Masashi ") (:url . "https://github.com/kiwanami/emacs-epc"))]) (concurrent . [(20161229 330) ((emacs (24 3)) (deferred (0 5 0))) "Concurrent utility functions for emacs lisp" single ((:commit . "2239671d94b38d92e9b28d4e12fd79814cfb9c16") (:keywords "deferred" "async" "concurrent") (:authors ("SAKURAI Masashi ")) (:maintainer "SAKURAI Masashi ") (:url . "https://github.com/kiwanami/emacs-deferred/blob/master/README-concurrent.markdown"))]) (importmagic . [(20180520 303) ((f (0 11 0)) (epc (0 1 0)) (emacs (24 3))) "Fix Python imports using importmagic." tar ((:commit . "bbc131278f8cd62f3e71b6f4a86b0c91792a3524") (:keywords "languages" "convenience") (:authors ("Nicolás Salas V." . "nikosalas@gmail.com")) (:maintainer "Nicolás Salas V." . "nikosalas@gmail.com") (:url . "https://github.com/anachronic/importmagic.el"))]) (live-py-mode . [(20190614 433) ((emacs (24 3))) "Live Coding in Python" tar ((:commit . "4c378e4afdffb09ab3ca338d3b37d9a2b69d9584") (:keywords "live" "coding") (:authors ("Don Kirkby http://donkirkby.github.io")) (:maintainer "Don Kirkby http://donkirkby.github.io") (:url . "http://donkirkby.github.io/live-py-plugin/"))]) (nose . [(20140520 1648) nil "Easy Python test running in Emacs" single ((:commit . "194d7789bf797f31ea0adc45f08beb66ae9ea98e") (:keywords "nose" "python" "testing"))]) (pip-requirements . [(20181027 1629) ((dash (2 8 0))) "A major mode for editing pip requirements files." single ((:commit . "216cd1690f80cc965d4ae47b8753fc185f778ff6") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (pyvenv . [(20181228 1722) nil "Python virtual environment interface" single ((:commit . "fa6a028349733b0ecb407c4cfb3a715b71931eec") (:keywords "python" "virtualenv" "tools") (:authors ("Jorgen Schaefer" . "contact@jorgenschaefer.de")) (:maintainer "Jorgen Schaefer" . "contact@jorgenschaefer.de") (:url . "http://github.com/jorgenschaefer/pyvenv"))]) (pipenv . [(20190522 803) ((emacs (25 1)) (f (0 19 0)) (s (1 12 0)) (pyvenv (1 20))) "A Pipenv porcelain." single ((:commit . "03edaaa44a5a4212d2e5a14e3ae6303189d76703") (:authors ("Paul Walsh" . "paulywalsh@gmail.com")) (:maintainer "Paul Walsh" . "paulywalsh@gmail.com") (:url . "https://github.com/pwalsh/pipenv.el"))]) (pippel . [(20180710 856) ((emacs (25 1)) (s (1 11 0)) (dash (2 12 0))) "Frontend to python package manager pip" tar ((:commit . "21a5200e8e5ccaa1911abb4ebf090b76ca839756") (:authors ("Fritz Stelzer" . "brotzeitmacher@gmail.com")) (:maintainer "Fritz Stelzer" . "brotzeitmacher@gmail.com") (:url . "https://github.com/brotzeitmacher/pippel"))]) (py-isort . [(20160925 1018) nil "Use isort to sort the imports in a Python buffer" single ((:commit . "e67306f459c47c53a65604e4eea88a3914596560") (:authors ("Friedrich Paetzke" . "paetzke@fastmail.fm")) (:maintainer "Friedrich Paetzke" . "paetzke@fastmail.fm") (:url . "http://paetzke.me/project/py-isort.el"))]) (pytest . [(20181005 1524) ((s (1 9 0))) "Easy Python test running in Emacs" single ((:commit . "1bfa7549001e61ecd59cd6eae7c6656a924d1ba4") (:keywords "pytest" "python" "testing") (:url . "https://github.com/ionrock/pytest-el"))]) (stickyfunc-enhance . [(20150429 1814) ((emacs (24 3))) "An enhancement to stock `semantic-stickyfunc-mode'" single ((:commit . "13bdba51fcd83ccbc3267959d23afc94d458dcb0") (:keywords "c" "languages" "tools") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:url . "https://github.com/tuhdo/semantic-stickyfunc-enhance"))]) (yapfify . [(20180830 733) nil "(automatically) format python buffers using YAPF." single ((:commit . "b858225e1debe6734ee718e5c3c209152652a8b3") (:authors ("Joris Engbers" . "info@jorisengbers.nl")) (:maintainer "Joris Engbers" . "info@jorisengbers.nl") (:url . "https://github.com/JorisE/yapfify"))]) (anaconda-mode . [(20190616 1019) ((emacs (25)) (pythonic (0 1 0)) (dash (2 6 0)) (s (1 9)) (f (0 16 2))) "Code navigation, documentation lookup and completion for Python" single ((:commit . "24aa81ba62f13d7bb505a03fe244181c461fec68") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/anaconda-mode"))]) (pythonic . [(20190725 1258) ((emacs (25)) (s (1 9)) (f (0 17 2))) "Utility functions for writing pythonic emacs package." single ((:commit . "1ba07048cffa0f95d7d1c75eab2d2be175e67cb6") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/pythonic"))]) (company-anaconda . [(20181025 1305) ((company (0 8 0)) (anaconda-mode (0 1 1)) (cl-lib (0 5 0)) (dash (2 6 0)) (s (1 9))) "Anaconda backend for company-mode" single ((:commit . "0ab70de1740e67cee451abcf3685c7525ff9e95a") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/anaconda-mode"))]) (python . [(0 26 1) ((emacs (24 1)) (cl-lib (1 0))) "Python's flying circus support for Emacs" single ((:keywords "languages") (:authors ("Fabián E. Gallina" . "fgallina@gnu.org")) (:maintainer nil . "emacs-devel@gnu.org") (:url . "https://github.com/fgallina/python.el"))]) (lsp-python-ms . [(20190809 640) ((cl-lib (0 6 1)) (lsp-mode (6 0)) (python (0 26 1)) (json (1 4)) (emacs (24 4))) "lsp-mode client for Microsoft python-language-server" single ((:commit . "8b18a98ad68373aa4d7ef24ec728a250ca570a2a") (:keywords "languages" "tools") (:authors ("Charl Botha")) (:maintainer "Andrew Christianson") (:url . "https://github.com/andrew-christianson/lsp-python-ms"))]) (eval-sexp-fu . [(20190109 809) ((cl-lib (0))) "Tiny functionality enhancements for evaluating sexps." single ((:commit . "e1d7165383c941b3f11c2715707adc3d91d129a0") (:keywords "lisp" "highlight" "convenience") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net"))]) (cider-eval-sexp-fu . [(20190311 2152) ((emacs (24)) (eval-sexp-fu (0 5 0))) "Briefly highlights an evaluated sexp." single ((:commit . "7fd229f1441356866aedba611fd0cf4e89b50921") (:keywords "languages" "clojure" "cider") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com"))]) (inflections . [(20170913 916) ((cl-lib (0 5)) (emacs (24))) "convert english words between singular and plural" single ((:commit . "e4f1372cf22e811faca52fc86bdd5d817498a4d8") (:keywords "languages" "tools" "wp") (:authors ("Dmitry Galinsky, Howard Yeh")) (:maintainer "Dmitry Galinsky, Howard Yeh") (:url . "https://github.com/eschulte/jump.el"))]) (edn . [(20160215 1219) ((cl-lib (0 3)) (emacs (24 1)) (peg (0 6))) "Support for reading and writing the edn data format from elisp" single ((:commit . "be9e32d1b49e35247b263b0243df7cfdc8d413ab") (:keywords "edn" "clojure") (:authors ("Lars Andersen" . "expez@expez.com")) (:maintainer "Lars Andersen" . "expez@expez.com") (:url . "https://www.github.com/expez/edn.el"))]) (paredit . [(20171127 205) nil "minor mode for editing parentheses" single ((:commit . "acbe10fdd85d2e91831adf70b6a828bc7e900da0") (:keywords "lisp") (:authors ("Taylor R. Campbell" . "campbell+paredit@mumble.net")) (:maintainer "Taylor R. Campbell" . "campbell+paredit@mumble.net"))]) (peg . [(20150708 641) nil "Parsing Expression Grammars in Emacs Lisp" single ((:commit . "081efeca91d790c7fbc90871ac22c40935f4833b"))]) (clj-refactor . [(20190618 716) ((emacs (25 1)) (seq (2 19)) (yasnippet (0 6 1)) (paredit (24)) (multiple-cursors (1 2 2)) (clojure-mode (5 6 1)) (cider (0 17 0)) (edn (1 1 2)) (inflections (2 3)) (hydra (0 13 2))) "A collection of commands for refactoring Clojure code" tar ((:commit . "50d2d8aad5e0bd8002173b300f8419d72ceab7af") (:keywords "convenience" "clojure" "cider") (:authors ("Magnar Sveen" . "magnars@gmail.com") ("Lars Andersen" . "expez@expez.com") ("Benedek Fazekas" . "benedek.fazekas@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (clojure-snippets . [(20180314 1308) ((yasnippet (0 10 0))) "Yasnippets for clojure" tar ((:commit . "6068dca90467a0f4ebc2cd39338a173d6f5ddc04"))]) (flycheck-clojure . [(20190611 2351) ((cider (0 22 0)) (flycheck (32 -4)) (let-alist (1 0 1)) (emacs (25))) "Flycheck: Clojure support" single ((:commit . "4c5d0c723bd564d632a4b93046679ed19d0e49d9") (:authors ("Peter Fraenkel" . "pnf@podsnap.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Peter Fraenkel" . "pnf@podsnap.com") (:url . "https://github.com/clojure-emacs/squiggly-clojure"))]) (cider . [(20190821 1002) ((emacs (25)) (clojure-mode (5 9)) (parseedn (0 1)) (pkg-info (0 4)) (queue (0 2)) (spinner (1 7)) (seq (2 16)) (sesman (0 3 2))) "Clojure Interactive Development Environment that Rocks" tar ((:commit . "bad9995772c07467c945161552a035f32de66008") (:keywords "languages" "clojure" "cider") (:authors ("Tim King" . "kingtim@gmail.com") ("Phil Hagelberg" . "technomancy@gmail.com") ("Bozhidar Batsov" . "bozhidar@batsov.com") ("Artur Malabarba" . "bruce.connor.am@gmail.com") ("Hugo Duncan" . "hugo@hugoduncan.org") ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "http://www.github.com/clojure-emacs/cider"))]) (sesman . [(20190623 1123) ((emacs (25))) "Generic Session Manager" tar ((:commit . "e8bfb0e37940bf5f370ae300b896dd04afbc63c8") (:keywords "process") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/vspinu/sesman"))]) (queue . [(0 2) nil "Queue data structure" single ((:keywords "extensions" "data structures" "queue") (:authors ("Inge Wallin" . "inge@lysator.liu.se") ("Toby Cubitt" . "toby-predictive@dr-qubit.org")) (:maintainer "Toby Cubitt" . "toby-predictive@dr-qubit.org") (:url . "http://www.dr-qubit.org/emacs.php"))]) (parseedn . [(20190331 1058) ((emacs (25)) (a (0 1 0 -3 4)) (parseclj (0 1 0))) "Clojure/EDN parser" single ((:commit . "ddf824bc1df1585867cb7f27f2dd8ca8df760569") (:keywords "lisp" "clojure" "edn" "parser") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net"))]) (clojure-mode . [(20190725 654) ((emacs (25 1))) "Major mode for Clojure code" single ((:commit . "f23eb209a8bedec95e0ad0542762bd13998ba048") (:keywords "languages" "clojure" "clojurescript" "lisp") (:url . "http://github.com/clojure-emacs/clojure-mode"))]) (parseclj . [(20190531 711) ((emacs (25)) (a (0 1 0 -3 4))) "Clojure/EDN parser" tar ((:commit . "b34d3e13a249d4b92f1a008cdc1df20a92f866c5") (:keywords "lisp" "clojure" "edn" "parser") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net"))]) (a . [(20180907 953) ((emacs (25))) "Associative data structure functions" single ((:commit . "18966975db7110d0aac726be95b593e2fc3d44ed") (:keywords "lisp") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:url . "https://github.com/plexus/a.el"))]) (sayid . [(20181223 835) ((cider (0 14 0))) "sayid nREPL middleware client" single ((:commit . "a0a4c73574af7ebb116b39cd8c30f95c169d7d60") (:authors ("Bill Piel" . "bill@billpiel.com")) (:maintainer "Bill Piel" . "bill@billpiel.com") (:url . "https://github.com/clojure-emacs/sayid"))]) (elixir-mode . [(20190422 155) ((emacs (24)) (pkg-info (0 4))) "Major mode for editing Elixir files" tar ((:commit . "694d133e847e9a6db6abd1c19850cec6d867ccce") (:keywords "languages" "elixir") (:url . "https://github.com/elixir-lang/emacs-elixir"))]) (flycheck-mix . [(20190714 958) ((flycheck (27)) (elixir-mode (1 8 0))) "Elixir mix flycheck integration" single ((:commit . "04681608e52ac660f74989a045579da75bc489f2") (:keywords "elixir" "flycheck" "mix") (:authors ("Tomasz Kowal" . "tomekowal@gmail.com")) (:maintainer "Tomasz Kowal" . "tomekowal@gmail.com") (:url . "https://github.com/tomekowal/flycheck-mix"))]) (flycheck-credo . [(20170526 1545) ((flycheck (29))) "flycheck checker for elixir credo" single ((:commit . "e88f11ead53805c361ec7706e44c3dfee1daa19f") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/flycheck-credo"))]) (ob-elixir . [(20170725 1419) ((org (8))) "org-babel functions for elixir evaluation" single ((:commit . "8990a8178b2f7bd93504a9ab136622aab6e82e32") (:keywords "org" "babel" "elixir") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-elixir"))]) (dart-mode . [(20190808 2226) ((emacs (24 3))) "Major mode for editing Dart files" single ((:commit . "9b65aae8c79132275733ee4324948446c88a6b93") (:keywords "languages") (:authors ("Brady Trainor" . "mail@bradyt.net")) (:maintainer "Brady Trainor" . "mail@bradyt.net") (:url . "https://github.com/bradyt/dart-mode"))]) (clang-format . [(20180406 1514) ((cl-lib (0 3))) "Format code using clang-format" single ((:commit . "1469728c61dcba8fa09c456e841f97e9eb75fa85") (:keywords "tools" "c"))]) (company-c-headers . [(20180814 1730) ((emacs (24 1)) (company (0 8))) "Company mode backend for C/C++ header files" single ((:commit . "41331192b3961c8e3a51540678e1d11eaa346f03") (:keywords "development" "company") (:authors ("Alastair Rankine" . "alastair@girtby.net")) (:maintainer "Alastair Rankine" . "alastair@girtby.net"))]) (company-rtags . [(20190821 449) ((emacs (24 3)) (company (0 8 1)) (rtags (2 10))) "RTags back-end for company" single ((:commit . "9048a6f1e5bb6ef1e3f9eb3ccfc4368f52825bea") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (company-ycmd . [(20180520 1053) ((ycmd (1 3)) (company (0 9 3)) (deferred (0 5 1)) (s (1 11 0)) (dash (2 13 0)) (let-alist (1 0 5)) (f (0 19 0))) "company-mode backend for ycmd" single ((:commit . "6f4f7384b82203cccf208e3ec09252eb079439f9") (:url . "https://github.com/abingham/emacs-ycmd"))]) (cpp-auto-include . [(20160426 412) ((cl-lib (0 5))) "auto include header file for C++" single ((:commit . "f3b9bfa668fcd38da8a9dbef0e33a536be239468") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-cpp-auto-include"))]) (disaster . [(20171016 2152) nil "Disassemble C/C++ code under cursor in Emacs" single ((:commit . "10a785facc60d89d78e0d5177985ab1af1741bb4") (:keywords "tools") (:authors ("Justine Tunney" . "jtunney@gmail.com")) (:maintainer "Justine Tunney" . "jtunney@gmail.com") (:url . "https://github.com/jart/disaster"))]) (flycheck-rtags . [(20180619 824) ((emacs (24)) (flycheck (0 23)) (rtags (2 10))) "RTags Flycheck integration." single ((:commit . "9048a6f1e5bb6ef1e3f9eb3ccfc4368f52825bea") (:authors ("Christian Schwarzgruber" . "c.schwarzgruber.cs@gmail.com")) (:maintainer "Christian Schwarzgruber" . "c.schwarzgruber.cs@gmail.com") (:url . "http://rtags.net"))]) (google-c-style . [(20180130 1736) nil "Google's C/C++ style for c-mode" single ((:commit . "5beae3f4dacad9b0b86a8a4ab308459475feda0e") (:keywords "c" "tools"))]) (helm-rtags . [(20170813 411) ((helm (2 0)) (rtags (2 10))) "A front-end for rtags" single ((:commit . "9048a6f1e5bb6ef1e3f9eb3ccfc4368f52825bea") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (ivy-rtags . [(20170523 454) ((ivy (0 7 0)) (rtags (2 10))) "RTags completion back-end for ivy" single ((:commit . "9048a6f1e5bb6ef1e3f9eb3ccfc4368f52825bea") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (rtags . [(20190820 502) nil "A front-end for rtags" single ((:commit . "9048a6f1e5bb6ef1e3f9eb3ccfc4368f52825bea") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (cquery . [(20190118 542) ((emacs (25 1)) (lsp-mode (3 4)) (dash (0 13))) "cquery client for lsp-mode" tar ((:commit . "555e50984ebda177421fdcdc8c76cb29235d9694") (:keywords "languages" "lsp" "c++") (:authors ("Tobias Pisani")) (:maintainer "Tobias Pisani") (:url . "https://github.com/jacobdufault/cquery"))]) (ccls . [(20190720 935) ((emacs (25 1)) (lsp-mode (4 2)) (dash (0 14)) (projectile (1 0 0))) "ccls client for lsp-mode" tar ((:commit . "9061ebbf9d5ec3ee7e88dbd226c77017cf0447b1") (:keywords "languages" "lsp" "c++") (:authors ("Tobias Pisani, Fangrui Song")) (:maintainer "Tobias Pisani, Fangrui Song") (:url . "https://github.com/MaskRay/emacs-ccls"))]) (company-emoji . [(20180925 2008) ((cl-lib (0 5)) (company (0 8 0))) "company-mode backend for emoji" tar ((:commit . "f0d91d5be0077b20b418a3ba37d36f431fae322f") (:keywords "emoji" "company") (:authors ("Alex Dunn" . "dunn.alex@gmail.com")) (:maintainer "Alex Dunn" . "dunn.alex@gmail.com") (:url . "https://github.com/dunn/company-emoji.git"))]) (emoji-cheat-sheet-plus . [(20150617 1331) ((emacs (24)) (helm (1 6 4))) "emoji-cheat-sheet for emacs" tar ((:commit . "96a003127d646a2683d81ca906a17eace0a6413e") (:keywords "emacs" "emoji") (:authors ("Sylvain Benner (based on the work of Shingo Fukuyama)")) (:maintainer "Sylvain Benner (based on the work of Shingo Fukuyama)") (:url . "https://github.com/syl20bnr/emacs-emoji-cheat-sheet-plus"))]) (gh-md . [(20151207 1740) ((emacs (24))) "Render markdown using the Github api" single ((:commit . "693cb0dcadff70e813e1a9d303d227aff7898557") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/gh-md.el"))]) (markdown-toc . [(20170711 1949) ((s (1 9 0)) (dash (2 11 0)) (markdown-mode (2 1))) "A simple TOC generator for markdown file" tar ((:commit . "7038f4f6d5c2bc7e4aea89699a607ac2b7dd16a8"))]) (vmd-mode . [(20180223 1356) ((emacs (24 3))) "Fast Github-flavored Markdown preview using a vmd subprocess." single ((:commit . "24e38a20951dfad6e3e985c7cc6286c1e271da5f") (:keywords "markdown" "preview" "live" "vmd") (:authors ("Blake Miller" . "blak3mill3r@gmail.com")) (:maintainer "Blake Miller" . "blak3mill3r@gmail.com") (:url . "https://github.com/blak3mill3r/vmd-mode"))]) (auctex-latexmk . [(20170618 1636) ((auctex (11 87))) "Add LatexMk support to AUCTeX" single ((:commit . "4d353522650d7685acbf1d38f7dbc504f734bd84") (:keywords "tex") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/auctex-latexmk/"))]) (auctex . [(12 1 2) ((emacs (24 1)) (cl-lib (0 5))) "Integrated environment for *TeX*" tar ((:url . "http://www.gnu.org/software/auctex/") (:maintainer nil . "auctex-devel@gnu.org") (:keywords "tex" "latex" "texinfo" "context" "doctex" "preview-latex"))]) (company-auctex . [(20180725 1912) ((yasnippet (0 8 0)) (company (0 8 0)) (auctex (11 87))) "Company-mode auto-completion for AUCTeX" single ((:commit . "48c42c58ce2f0e693301b0cb2d085055410c1b25") (:authors ("Christopher Monsanto , Alexey Romanov" . "alexey.v.romanov@gmail.com")) (:maintainer "Christopher Monsanto , Alexey Romanov" . "alexey.v.romanov@gmail.com") (:url . "https://github.com/alexeyr/company-auctex/"))]) (company-reftex . [(20181222 906) ((emacs (25 1)) (s (1 12)) (company (0 8))) "Company backend based on RefTeX." single ((:commit . "33935e96540201adab43f3a765d62289eba9e286") (:keywords "bib" "tex" "company" "latex" "reftex" "references" "labels" "citations") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:url . "https://github.com/TheBB/company-reftex"))]) (magic-latex-buffer . [(20170531 5) ((cl-lib (0 5)) (emacs (24 3))) "Magically enhance LaTeX-mode font-locking for semi-WYSIWYG editing" single ((:commit . "c03277d5619d9adcd871f3e6480a1a27985810cb") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (typo . [(20171209 1023) nil "Minor mode for typographic editing" single ((:commit . "9dad93b6f367f02f52c8d9bf15d446d922cec294") (:keywords "convenience" "wp") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:url . "https://github.com/jorgenschaefer/typoel"))]) (tide . [(20190706 2322) ((dash (2 10 0)) (s (1 11 0)) (flycheck (27)) (typescript-mode (0 1)) (cl-lib (0 5))) "Typescript Interactive Development Environment" tar ((:commit . "dd90f5ad6c537d38b5f56599687c3bc9b21072a6") (:keywords "typescript") (:authors ("Anantha kumaran" . "ananthakumaran@gmail.com")) (:maintainer "Anantha kumaran" . "ananthakumaran@gmail.com") (:url . "http://github.com/ananthakumaran/tide"))]) (typescript-mode . [(20190710 2011) ((emacs (24 3))) "Major mode for editing typescript" tar ((:commit . "32146510b8ebb031e468c6c0898a9b253c73617e") (:keywords "typescript" "languages") (:url . "http://github.com/ananthakumaran/typescript.el"))]) (web-mode . [(20190625 1951) ((emacs (23 1))) "major mode for editing web templates" single ((:commit . "a723d3ecd3606d1c1948871f46fc8c8d7f879fe4") (:keywords "languages") (:authors ("François-Xavier Bois ")) (:maintainer "François-Xavier Bois") (:url . "http://web-mode.org"))]) (cargo . [(20190816 1046) ((emacs (24 3)) (rust-mode (0 2 0)) (markdown-mode (2 4))) "Emacs Minor Mode for Cargo, Rust's Package Manager." tar ((:commit . "f70b060c97f0df6ec6487968dfdfae8ec97a080f") (:keywords "tools") (:authors ("Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com")) (:maintainer "Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com"))]) (racer . [(20190610 800) ((emacs (24 3)) (rust-mode (0 2 0)) (dash (2 13 0)) (s (1 10 0)) (f (0 18 2)) (pos-tip (0 4 6))) "code completion, goto-definition and docs browsing for Rust via racer" single ((:commit . "ea6a09c16f8ec646195f942c12fe3ed7d65cc971") (:keywords "abbrev" "convenience" "matching" "rust" "tools") (:authors ("Phil Dawes")) (:maintainer "Phil Dawes") (:url . "https://github.com/racer-rust/emacs-racer"))]) (flycheck-rust . [(20190319 1546) ((emacs (24 1)) (flycheck (28)) (dash (2 13 0)) (seq (2 3)) (let-alist (1 0 4))) "Flycheck: Rust additions and Cargo support" single ((:commit . "a139cd53c5062697e9ed94ad80b803c37d999600") (:keywords "tools" "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-rust"))]) (rust-mode . [(20190517 2037) ((emacs (24 0))) "A major emacs mode for editing Rust source code" single ((:commit . "c62185ae1c6edf0335261f169241eb8ee9713ad5") (:keywords "languages") (:authors ("Mozilla")) (:maintainer "Mozilla") (:url . "https://github.com/rust-lang/rust-mode"))]) (toml-mode . [(20161107 1800) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing TOML files" single ((:commit . "f6c61817b00f9c4a3cab1bae9c309e0fc45cdd06") (:keywords "data" "toml") (:authors ("Felix Chern" . "idryman@gmail.com")) (:maintainer "Felix Chern" . "idryman@gmail.com") (:url . "https://github.com/dryman/toml-mode.el"))]) (dhall-mode . [(20190526 2113) ((emacs (24 4)) (reformatter (0 3))) "a major mode for dhall configuration language" single ((:commit . "1b71e8e7123647761d8f35916c06b7280b2929ea") (:keywords "languages") (:authors ("Sibi Prabakaran" . "sibi@psibi.in")) (:maintainer "Sibi Prabakaran" . "sibi@psibi.in") (:url . "https://github.com/psibi/dhall-mode"))]) (purescript-mode . [(20190522 2230) ((emacs (24)) (cl-lib (0 6))) "A PureScript editing mode" tar ((:commit . "8db1d0243c03da31adac4d7c5287407a4df6aff2"))]) (psci . [(20190308 24) ((emacs (24 4)) (purescript-mode (13 10)) (dash (2 9 0))) "Major mode for purescript repl psci" tar ((:commit . "3c10918a3a1d1dc613c222801deb465d4fbb2143") (:keywords "languages" "purescript" "psci" "repl") (:authors ("Antoine R. Dumont ")) (:maintainer "Antoine R. Dumont ") (:url . "https://github.com/purescript-emacs/emacs-psci"))]) (psc-ide . [(20190326 2110) ((emacs (25)) (dash (2 13 0)) (dash-functional (1 2 0)) (company (0 8 7)) (s (1 10 0)) (flycheck (0 24)) (let-alist (1 0 4)) (seq (1 11))) "Minor mode for PureScript's psc-ide tool." tar ((:commit . "a10cc85565f330ee277698b27f3f715fef2e1ce2") (:keywords "languages") (:authors ("Erik Post" . "erik@shinsetsu.nl") ("Dmitry Bushenko" . "d.bushenko@gmail.com") ("Christoph Hegemann") ("Brian Sermons")) (:maintainer "Erik Post" . "erik@shinsetsu.nl") (:url . "https://github.com/epost/psc-ide-emacs"))]) (erlang . [(20190404 928) ((emacs (24 1))) "Erlang major mode" tar ((:commit . "9f220c8ed81719b3fec4f3032b1140df20ffe046"))]) (company-quickhelp . [(20180525 1003) ((emacs (24 3)) (company (0 8 9)) (pos-tip (0 4 6))) "Popup documentation for completion candidates" single ((:commit . "479676cade80a9f03802ca3d956591820ed5c537") (:keywords "company" "popup" "documentation" "quickhelp") (:authors ("Lars Andersen" . "expez@expez.com")) (:maintainer "Lars Andersen" . "expez@expez.com") (:url . "https://www.github.com/expez/company-quickhelp"))]) (fsharp-mode . [(20190609 1317) ((company (0 8 0)) (company-quickhelp (1 2 0)) (popup (0 5 3)) (pos-tip (0 4 5)) (s (1 3 1)) (dash (1 1 0)) (flycheck (0 25))) "F# mode for Emacs" tar ((:commit . "e2a63296681d65969d9c21144a22c6fd2f9dd57d"))]) (company-emacs-eclim . [(20180911 1121) ((eclim (0 3)) (company (0 7)) (cl-lib (0 5))) "Eclim company backend" single ((:commit . "23f5b294f833ce58516d7b9ae08a7792d70022a1"))]) (eclim . [(20181108 1134) ((dash (2 11 0)) (json (1 2)) (popup (0 5 2)) (s (1 9 0)) (cl-lib (0 5)) (yasnippet (0 10 0))) "An interface to the Eclipse IDE." tar ((:commit . "23f5b294f833ce58516d7b9ae08a7792d70022a1"))]) (ensime . [(20180615 1330) ((scala-mode (0 23)) (sbt-mode (0 2)) (yasnippet (0 10 0)) (company (0 9 0)) (dash (2 12 1)) (s (1 11 0)) (popup (0 5 3))) "ENhanced Scala Interaction Mode for Emacs" tar ((:commit . "34eb11dac3ec9d1c554c2e55bf056ece6983add7") (:keywords "languages") (:url . "https://github.com/ensime/ensime-emacs"))]) (gradle-mode . [(20150313 1905) ((s (1 8 0))) "Gradle integration with Emacs' compile" single ((:commit . "e4d665d5784ecda7ddfba015f07c69be3cfc45f2") (:keywords "gradle") (:authors ("Daniel Mijares" . "daniel.j.mijares@gmail.com")) (:maintainer "Daniel Mijares" . "daniel.j.mijares@gmail.com") (:url . "http://github.com/jacobono/emacs-gradle-mode"))]) (maven-test-mode . [(20141220 557) ((s (1 9)) (emacs (24))) "Utilities for navigating test files and running maven test tasks." single ((:commit . "a19151861df2ad8ae4880a2e7c86ddf848cb569a") (:keywords "java" "maven" "test") (:authors ("Renan Ranelli")) (:maintainer "Renan Ranelli") (:url . "http://github.com/rranelli/maven-test-mode"))]) (meghanada . [(20190526 548) ((emacs (24 3)) (yasnippet (0 6 1)) (company (0 9 0)) (flycheck (0 23))) "A better java development mode" tar ((:commit . "24813cf364f1c857c2ee412d0a088f0ceff53842") (:keywords "languages" "java") (:authors ("Yutaka Matsubara" . "yutaka.matsubara@gmail.com")) (:maintainer "Yutaka Matsubara" . "yutaka.matsubara@gmail.com") (:url . "https://github.com/mopemope/meghanada-emacs"))]) (mvn . [(20181002 1617) nil "helpers for compiling with maven" single ((:commit . "ffa40235b7dabb6c6c165f64f32a963cde8031f0") (:keywords "compilation" "maven" "java") (:authors ("Andrew Gwozdziewycz" . "git@apgwoz.com")) (:maintainer "Andrew Gwozdziewycz" . "git@apgwoz.com") (:url . "https://github.com/apgwoz/mvn-el"))]) (lsp-java . [(20190817 1436) ((emacs (25 1)) (lsp-mode (6 0)) (markdown-mode (2 3)) (dash (2 14 1)) (f (0 20 0)) (ht (2 0)) (dash-functional (1 2 0)) (request (0 3 0))) "Java support for lsp-mode" tar ((:commit . "ccc40d3249c031e34fec13d4b82da694addb0274") (:keywords "java") (:url . "https://github.com/emacs-lsp/lsp-java"))]) (reformatter . [(20190529 2238) ((emacs (24 3))) "Define commands which run reformatters on the current buffer" single ((:commit . "c6919a6549b12f624a97e3535409737096e6532e") (:keywords "convenience" "tools") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/reformatter.el"))]) (elm-mode . [(20190815 555) ((f (0 17)) (let-alist (1 0 4)) (seq (2 2)) (s (1 7 0)) (emacs (24 4)) (dash (2 13 0)) (reformatter (0 3))) "Major mode for Elm" tar ((:commit . "834fb5037424c47155518ed27537ef7ad6addcc5") (:authors ("Joseph Collard")) (:maintainer "Joseph Collard") (:url . "https://github.com/jcollard/elm-mode"))]) (elm-test-runner . [(20190105 1923) ((emacs (24 4))) "Enhanced support for running elm-test" single ((:commit . "a31d567a64d86d36e3675347abd696824a731e0c") (:authors ("Juan Edi")) (:maintainer "Juan Edi") (:url . "https://github.com/juanedi/elm-test-runner"))]) (flycheck-elm . [(20181107 146) ((flycheck (0 29 -4)) (emacs (24 4)) (let-alist (1 0 5)) (seq (2 20))) "Flycheck support for the elm language" single ((:commit . "debd0af563cb6c2944367a691c7fa3021d9378c1") (:authors ("Brian Sermons")) (:maintainer "Brian Sermons") (:url . "https://github.com/bsermons/flycheck-elm"))]) (web-completion-data . [(20160318 848) nil "Shared completion data for ac-html and company-web" tar ((:commit . "c272c94e8a71b779c29653a532f619acad433a4f") (:keywords "html" "auto-complete" "company") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:url . "https://github.com/osv/web-completion-data"))]) (company-web . [(20180402 1155) ((company (0 8 0)) (dash (2 8 0)) (cl-lib (0 5 0)) (web-completion-data (0 1 0))) "Company version of ac-html, complete for web,html,emmet,jade,slim modes" tar ((:commit . "f0cc9187c9c34f72ad71f5649a69c74f996bae9a") (:keywords "html" "company") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:url . "https://github.com/osv/company-web"))]) (counsel-css . [(20180302 1036) ((emacs (24 4)) (counsel (0 7 0)) (cl-lib (0 5))) "stylesheet-selector-aware swiper" single ((:commit . "0536af00236cdce1ed08b40dd46c917e8b4b8869") (:keywords "convenience" "tools" "counsel" "swiper" "selector" "css" "less" "scss") (:authors ("Henrik Lissner ")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-counsel-css"))]) (helm-css-scss . [(20140627 25) ((helm (1 0)) (emacs (24))) "CSS/SCSS/LESS Selectors with helm interface" single ((:commit . "ab8348aa98e0daa2f1b771e35bdb06bfacbe5016") (:keywords "scss" "css" "less" "selector" "helm") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:url . "https://github.com/ShingoFukuyama/helm-css-scss"))]) (impatient-mode . [(20181002 1231) ((cl-lib (0 3)) (simple-httpd (1 5 0)) (htmlize (1 40))) "Serve buffers live over HTTP" tar ((:commit . "96f6a05f8de74e19d570217fe83f0734623ddb0c") (:authors ("Brian Taylor" . "el.wubo@gmail.com")) (:maintainer "Brian Taylor" . "el.wubo@gmail.com") (:url . "https://github.com/netguy204/imp.el"))]) (less-css-mode . [(20161001 453) nil "Major mode for editing LESS CSS files (lesscss.org)" single ((:commit . "c7fa3d56d83206b28657f2e56439dc62280a2bf2") (:keywords "less" "css" "mode") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/less-css-mode"))]) (pug-mode . [(20180513 2126) ((emacs (24 4)) (cl-lib (0 5))) "Major mode for jade/pug template files" single ((:commit . "685fd3414d89736bf232f5d1a6bed9e0353b98fe") (:keywords "markup" "language" "jade" "pug") (:authors ("Nathan Weizenbaum")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-pug-mode"))]) (haml-mode . [(20190219 2102) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing Haml files" single ((:commit . "bf5b6c11b1206759d2b28af48765e04882dd1fc4") (:keywords "markup" "languages" "html") (:authors ("Natalie Weizenbaum")) (:maintainer "Natalie Weizenbaum") (:url . "https://github.com/nex3/haml-mode"))]) (sass-mode . [(20190502 53) ((haml-mode (3 0 15)) (cl-lib (0 5))) "Major mode for editing Sass files" single ((:commit . "247a0d4b509f10b28e4687cd8763492bca03599b") (:keywords "markup" "language" "css") (:authors ("Natalie Weizenbaum")) (:maintainer "Natalie Weizenbaum") (:url . "http://github.com/nex3/haml/tree/master"))]) (scss-mode . [(20180123 1708) nil "Major mode for editing SCSS files" single ((:commit . "cf58dbec5394280503eb5502938f3b5445d1b53d") (:keywords "scss" "css" "mode") (:authors ("Anton Johansson" . "anton.johansson@gmail.com")) (:maintainer "Anton Johansson" . "anton.johansson@gmail.com") (:url . "https://github.com/antonj/scss-mode"))]) (slim-mode . [(20170728 1348) nil "Major mode for editing Slim files" single ((:commit . "3636d18ab1c8b316eea71c4732eb44743e2ded87") (:keywords "markup" "language") (:authors ("Nathan Weizenbaum")) (:maintainer "Nathan Weizenbaum") (:url . "http://github.com/slim-template/emacs-slim"))]) (tagedit . [(20161121 855) ((s (1 3 1)) (dash (1 0 3))) "Some paredit-like features for html-mode" single ((:commit . "b3a70101a0dcf85498c92b7fcfa7fdbac869746c") (:keywords "convenience") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (flycheck-kotlin . [(20190808 630) ((flycheck (0 20))) "Support kotlin in flycheck" single ((:commit . "5104ee9a3fdb7f0a0a3d3bcfd8dd3c45a9929310") (:authors ("Elric Milon" . "whirm_REMOVETHIS__@gmx.com")) (:maintainer "Elric Milon" . "whirm_REMOVETHIS__@gmx.com"))]) (kotlin-mode . [(20190116 2055) ((emacs (24 3))) "Major mode for kotlin" single ((:commit . "0e542ae2f78420618df8b0123dfe168a37dce333") (:keywords "languages") (:authors ("Shodai Yokoyama" . "quantumcars@gmail.com")) (:maintainer "Shodai Yokoyama" . "quantumcars@gmail.com"))]) (ameba . [(20190720 1845) ((emacs (24 4))) "An interface to Crystal Ameba linter." single ((:commit . "8383f07d760a31a0737be9b7bdaff2f1cff67bfd") (:keywords "convenience") (:authors ("Vitalii Elenhaupt")) (:maintainer "Vitalii Elenhaupt") (:url . "https://github.com/crystal-ameba/ameba.el"))]) (flycheck-crystal . [(20180627 242) ((flycheck (30))) "Add support for Crystal to Flycheck" single ((:commit . "34124f546ff5c1136aed95bf0059015f9f6a1d60") (:keywords "tools" "crystal") (:url . "https://github.com/crystal-lang-tools/emacs-crystal-mode"))]) (crystal-mode . [(20190604 1254) ((emacs (24 4))) "Major mode for editing Crystal files" single ((:commit . "34124f546ff5c1136aed95bf0059015f9f6a1d60") (:keywords "languages" "crystal") (:url . "https://github.com/crystal-lang-tools/emacs-crystal-mode"))]) (inf-crystal . [(20180119 211) ((emacs (24 3)) (crystal-mode (0 1 0))) "Run a Inferior-Crystal process in a buffer" single ((:commit . "02007b2a2a3bea44902d7c83c4acba1e39d278e3") (:keywords "languages" "crystal") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/inf-crystal.el"))]) (ob-crystal . [(20180126 718) ((emacs (24 3))) "org-babel functions for Crystal evaluation" tar ((:commit . "d84c1adee4b269cdba06a97caedb8071561a09af") (:keywords "crystal" "literate programming" "reproducible research") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/ob-crystal"))]) (play-crystal . [(20180114 1024) ((emacs (24 4)) (dash (2 12 0)) (request (0 2 0))) "https://play.crystal-lang.org integration." single ((:commit . "0b4810a9025213bd11dbcbfd38b3ca928829e0a5") (:keywords "convenience") (:authors ("Vitalii Elenhaupt")) (:maintainer "Vitalii Elenhaupt") (:url . "https://github.com/veelenga/play-crystal.el"))]) (alda-mode . [(20180608 605) ((emacs (24 0))) "An Alda major mode" single ((:commit . "1692b9003d2c3de403251ec452c6ce43ec819c84") (:keywords "alda" "highlight") (:authors ("Jay Kamat" . "jaygkamat@gmail.com")) (:maintainer "Jay Kamat" . "jaygkamat@gmail.com") (:url . "http://gitlab.com/jgkamat/alda-mode"))]) (cmm-mode . [(20150225 746) nil "Major mode for C-- source code" single ((:commit . "c3ad514dff3eb30434f6b20d953276d4c00de1ee"))]) (company-cabal . [(20170917 1317) ((cl-lib (0 5)) (company (0 8 0)) (emacs (24))) "company-mode cabal backend" tar ((:commit . "62112a7259e24bd6c08885629a185afe512b7d3d") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-cabal"))]) (company-ghci . [(20190707 311) ((company (0 8 11)) (haskell-mode (13))) "company backend which uses the current ghci process." single ((:commit . "a1d25652583ab4666c5a78cac18cd8039776b50d") (:authors ("Hector Orellana" . "hofm92@gmail.com")) (:maintainer "Hector Orellana" . "hofm92@gmail.com"))]) (company-ghc . [(20170918 833) ((cl-lib (0 5)) (company (0 8 0)) (ghc (5 4 0 0)) (emacs (24))) "company-mode ghc-mod backend" single ((:commit . "8b264b5c3c0e42c0d0c4e9315559896c9b0edfdc") (:keywords "haskell" "completion") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-ghc"))]) (ghc . [(20180121 1218) ((haskell-mode (13 0))) "Sub mode for Haskell mode" tar ((:commit . "391e187a5dfef4421aab2508fa6ff7875cc8259d"))]) (intero . [(20190530 1308) ((flycheck (0 25)) (company (0 8)) (emacs (24 4)) (haskell-mode (13 0))) "Complete development mode for Haskell" single ((:commit . "61caa798bd385acf918b3639cf03f336b618e78b") (:keywords "haskell" "tools") (:authors ("Chris Done" . "chrisdone@fpcomplete.com")) (:maintainer "Chris Done" . "chrisdone@fpcomplete.com") (:url . "https://github.com/commercialhaskell/intero"))]) (lcr . [(20180902 1919) ((dash (2 12 0)) (emacs (25 1))) "lightweight coroutines" single ((:commit . "c14f40692292d59156c7632dbdd2867c086aa75f") (:keywords "tools") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:url . "https://github.com/jyp/lcr"))]) (dante . [(20190818 847) ((dash (2 12 0)) (emacs (25 1)) (f (0 19 0)) (flycheck (0 30)) (company (0 9)) (haskell-mode (13 14)) (s (1 11 0)) (lcr (1 0))) "Development mode for Haskell" single ((:commit . "ebffc84c6ae60495b54dc2532216c1f28f737a21") (:keywords "haskell" "tools") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:url . "https://github.com/jyp/dante"))]) (attrap . [(20190805 1829) ((dash (2 12 0)) (emacs (25 1)) (f (0 19 0)) (flycheck (0 30)) (s (1 11 0))) "ATtempt To Repair At Point" single ((:commit . "25d34a6c5f13ee6de5da60f3dae25d7e4961d991") (:keywords "programming" "tools") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:url . "https://github.com/jyp/attrap"))]) (lsp-haskell . [(20190602 825) ((lsp-mode (3 0)) (haskell-mode (1 0))) "Haskell support for lsp-mode" single ((:commit . "64106be79350f9ce6903d22c66b29761dadb5001") (:keywords "haskell") (:url . "https://github.com/emacs-lsp/lsp-haskell"))]) (flycheck-haskell . [(20181207 1646) ((emacs (24 3)) (flycheck (0 25)) (haskell-mode (13 7)) (dash (2 4 0)) (seq (1 11)) (let-alist (1 0 1))) "Flycheck: Automatic Haskell configuration" tar ((:commit . "32ddff87165a7d3a35e7318bee997b5b4bd41278") (:keywords "tools" "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-haskell"))]) (haskell-mode . [(20190801 50) ((emacs (24 3))) "A Haskell editing mode" tar ((:commit . "56d67ee282294c786a92e2d83c5bebf1a6d919c1") (:keywords "haskell" "cabal" "ghc" "repl") (:url . "https://github.com/haskell/haskell-mode"))]) (haskell-snippets . [(20160919 22) ((cl-lib (0 5)) (yasnippet (0 8 0))) "Yasnippets for Haskell" tar ((:commit . "07b0f460b946fd1be26c29652cb0468b47782f3a") (:keywords "snippets" "haskell") (:authors ("Luke Hoersten" . "luke@hoersten.org")) (:maintainer "Luke Hoersten" . "luke@hoersten.org") (:url . "https://github.com/haskell/haskell-snippets"))]) (helm-hoogle . [(20161027 534) ((helm (1 6 2)) (emacs (24 4))) "Use helm to navigate query results from Hoogle" single ((:commit . "73969a9d46d2121a849a01a9f7ed3636d01f7bbc") (:keywords "haskell" "programming" "hoogle") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:url . "https://github.com/jwiegley/haskell-config"))]) (hindent . [(20180518 902) ((cl-lib (0 5))) "Indent haskell code using the \"hindent\" program" single ((:commit . "1583be4a8a01b765841f7306284528ae713abb7b") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com") (:url . "https://github.com/chrisdone/hindent"))]) (hlint-refactor . [(20190115 900) nil "Apply HLint suggestions" single ((:commit . "c4307f86aad6d02e32e9b30cb6edc115584c791c") (:keywords "haskell" "refactor") (:url . "https://github.com/mpickering/hlint-refactor-mode"))]) (fuel . [(20190611 1350) ((cl-lib (0 2)) (emacs (24 2))) "Major mode for the Factor programming language." tar ((:commit . "e6eb7be61c35d4a7b7d5eeb528b582639c57f08f"))]) (drupal-mode . [(20171120 2309) ((php-mode (1 5 0))) "Advanced minor mode for Drupal development" tar ((:commit . "47fda0a38a5b197f4606137d9c3b7d44aaeaa886") (:keywords "programming" "php" "drupal") (:authors ("Arne Jørgensen" . "arne@arnested.dk")) (:maintainer "Arne Jørgensen" . "arne@arnested.dk") (:url . "https://github.com/arnested/drupal-mode"))]) (php-auto-yasnippets . [(20170331 114) ((php-mode (1 11)) (yasnippet (0 8 0))) "Creates snippets for PHP functions" tar ((:commit . "03e1f0899c081813901ac15c2f7a675a37cca9f5") (:authors ("Eric James Michael Ritz")) (:maintainer "Eric James Michael Ritz") (:url . "https://github.com/ejmr/php-auto-yasnippets"))]) (phpcbf . [(20181228 423) ((s (1 9 0))) "Format PHP code in Emacs using PHP_CodeSniffer's phpcbf" single ((:commit . "fb0bc6073a57126cf1a8404723aa0a715dd761aa") (:keywords "tools" "php") (:authors ("nishimaki10")) (:maintainer "nishimaki10") (:url . "https://github.com/nishimaki10/emacs-phpcbf"))]) (phpunit . [(20180829 1438) ((s (1 12 0)) (f (0 19 0)) (pkg-info (0 6)) (cl-lib (0 5)) (emacs (24 3))) "Launch PHP unit tests using phpunit" tar ((:commit . "fe6bc91c3bd8b329c6d26ad883a025f06b5121ee") (:keywords "tools" "php" "tests" "phpunit") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com") ("Eric Hansen" . "hansen.c.eric@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/phpunit.el"))]) (ac-php-core . [(20190816 548) ((dash (1)) (php-mode (1)) (s (1)) (f (0 17 0)) (popup (0 5 0)) (xcscope (1 0))) "The core library of the ac-php." tar ((:commit . "4490d168778a61a4ee8623defe760164cd9745b8") (:keywords "completion" "convenience" "intellisense") (:authors ("jim" . "xcwenn@qq.com") ("Serghei Iakovlev" . "sadhooklay@gmail.com")) (:maintainer "jim") (:url . "https://github.com/xcwen/ac-php"))]) (xcscope . [(20190723 629) nil "cscope interface for (X)Emacs" single ((:commit . "f3e2c84bd92f5a78182cc8d81f5358979a6c241c") (:keywords "languages" "c") (:authors ("Darryl Okahata" . "darrylo@sonic.net") ("Dima Kogan" . "dima@secretsauce.net")) (:maintainer "Dima Kogan" . "dima@secretsauce.net") (:url . "https://github.com/dkogan/xcscope.el"))]) (php-mode . [(20190818 932) ((emacs (24 3)) (cl-lib (0 5))) "Major mode for editing PHP code" tar ((:commit . "7e630bffd5f75c29aa98aed71e5b775651a13611") (:keywords "languages" "php") (:authors ("Eric James Michael Ritz")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/php-mode"))]) (company-php . [(20190424 222) ((cl-lib (0 5)) (ac-php-core (2 0)) (company (0 9))) "A company back-end for PHP." single ((:commit . "4490d168778a61a4ee8623defe760164cd9745b8") (:keywords "completion" "convenience" "intellisense") (:authors ("jim" . "xcwenn@qq.com")) (:maintainer "jim") (:url . "https://github.com/xcwen/ac-php"))]) (polymode . [(20190714 2017) ((emacs (25))) "Extensible framework for multiple major modes" tar ((:commit . "01232ad3800e974938199c9ac07fad57fcec540c") (:keywords "languages" "multi-modes" "processes") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/vitoshka/polymode"))]) (ein . [(20190813 2156) ((emacs (25)) (websocket (20190620 338)) (auto-complete (1 4 0)) (request (20190621 1622)) (deferred (0 5)) (polymode (20190426 1729)) (markdown-mode (20171116 756)) (dash (2 13 0)) (s (1 11 0)) (skewer-mode (1 6 2))) "Emacs IPython Notebook" tar ((:commit . "a2872eff6c18a0706c531e9316c792a9fb99826f"))]) (ob-ipython . [(20180224 953) ((s (1 9 0)) (dash (2 10 0)) (dash-functional (1 2 0)) (f (0 17 2)) (emacs (24))) "org-babel functions for IPython evaluation" tar ((:commit . "7147455230841744fb5b95dcbe03320313a77124") (:keywords "literate programming" "reproducible research") (:authors ("Greg Sexton" . "gregsexton@gmail.com")) (:maintainer "Greg Sexton" . "gregsexton@gmail.com") (:url . "http://www.gregsexton.org"))]) (company-lua . [(20171108 2306) ((company (0 8 12)) (s (1 10 0)) (f (0 17 0)) (lua-mode (20151025))) "Company backend for Lua" tar ((:commit . "29f6819de4d691e5fd0b62893a9f4fbc1c6fcb52") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net"))]) (lua-mode . [(20190113 1050) nil "a major-mode for editing Lua scripts" tar ((:commit . "95c64bb5634035630e8c59d10d4a1d1003265743") (:keywords "languages" "processes" "tools") (:authors ("2011-2013 immerrr" . "immerrr+lua@gmail.com") ("2010-2011 Reuben Thomas" . "rrt@sc3d.org") ("2006 Juergen Hoetzel" . "juergen@hoetzel.info") ("2004 various (support for Lua 5 and byte compilation)") ("2001 Christian Vogler" . "cvogler@gradient.cis.upenn.edu") ("1997 Bret Mogilefsky" . "mogul-lua@gelatinous.com") ("tcl-mode by Gregor Schmid" . "schmid@fb3-s7.math.tu-berlin.de") ("with tons of assistance from") ("Paul Du Bois" . "pld-lua@gelatinous.com") ("Aaron Smith" . "aaron-lua@gelatinous.com")) (:maintainer "2011-2013 immerrr" . "immerrr+lua@gmail.com") (:url . "http://immerrr.github.com/lua-mode"))]) (faust-mode . [(20180205 926) nil "Faust syntax colorizer for Emacs." single ((:commit . "7c31b22bdbfd2f8c16ec117d2975d56dd61ac15c") (:keywords "languages" "faust") (:authors ("rukano" . "rukano@gmail.com")) (:maintainer "Yassin Philip" . "xaccrocheur@gmail.com") (:url . "https://github.com/rukano/emacs-faust-mode"))]) (company-shell . [(20170518 541) ((emacs (24 4)) (company (0 8 12)) (dash (2 12 0)) (cl-lib (0 5))) "Company mode backend for shell functions" single ((:commit . "6ae625f80d90e0779c79de38e8f83a336c1d00fa") (:keywords "company" "shell" "auto-completion") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/company-shell"))]) (fish-mode . [(20180827 303) ((emacs (24))) "Major mode for fish shell scripts" single ((:commit . "35fc7c1e243a7410823088a571ecf378e9f3efa6") (:keywords "fish" "shell") (:authors ("Tony Wang" . "wwwjfy@gmail.com")) (:maintainer "Tony Wang" . "wwwjfy@gmail.com"))]) (flycheck-bashate . [(20160630 440) ((flycheck (0 24)) (emacs (24 4))) "Integrate bashate with flycheck" single ((:commit . "77fa03dbc578c34fe71ca44926bac2aff8f2b021") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-bashate"))]) (insert-shebang . [(20180403 1214) nil "Insert shebang line automatically." single ((:commit . "7bfea92ba1dae9d13d442e2f84f9fb6c05a0a9bd") (:keywords "shebang" "tool" "convenience") (:authors ("Sachin Patil" . "iclcoolster@gmail.com")) (:maintainer "Sachin Patil" . "iclcoolster@gmail.com") (:url . "http://github.com/psachin/insert-shebang"))]) (flycheck-perl6 . [(20180509 2201) ((emacs (24 3)) (flycheck (0 22))) "Perl 6 support in Flycheck" single ((:commit . "b804702305d7a6e26f762ff98cfdeec2e9dd4cb7") (:keywords "tools" "convenience") (:authors ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com")) (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") (:url . "https://github.com/hinrik/flycheck-perl6"))]) (perl6-mode . [(20180619 1159) ((emacs (24 4)) (pkg-info (0 1))) "Major mode for editing Perl 6 code" tar ((:commit . "88de065795d6863b23b6042576b9e90f8cbf8798") (:keywords "languages") (:authors ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com")) (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") (:url . "https://github.com/hinrik/perl6-mode"))]) (hierarchy . [(20190425 842) ((emacs (25 1))) "Library to create and display hierarchy structures" single ((:commit . "a1d13c40102e833192c3bd6acf930013bdcbc819") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/hierarchy"))]) (json-navigator . [(20190131 1031) ((emacs (24 3)) (hierarchy (0 6 0))) "View and navigate JSON structures" single ((:commit . "f4cde60c4203fc70cc7ff22ed1d6579159ce2598") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/json-navigator"))]) (key-chord . [(20160227 1238) nil "map pairs of simultaneously pressed keys to commands" single ((:commit . "72443e9ff3c4f1c3ccaced3130236801efde3d83") (:keywords "keyboard" "chord" "input") (:authors ("David Andersson ")) (:maintainer "David Andersson "))]) (org-ref . [(20190802 1327) ((dash (2 11 0)) (htmlize (1 51)) (helm (1 5 5)) (helm-bibtex (2 0 0)) (ivy (0 8 0)) (hydra (0 13 2)) (key-chord (0)) (s (1 10 0)) (f (0 18 0)) (emacs (24 4)) (pdf-tools (0 7))) "citations, cross-references and bibliographies in org-mode" tar ((:commit . "9ab74270c1543e4743ca0436de567d8205403b43") (:keywords "org-mode" "cite" "ref" "label") (:authors ("John Kitchin" . "jkitchin@andrew.cmu.edu")) (:maintainer "John Kitchin" . "jkitchin@andrew.cmu.edu") (:url . "https://github.com/jkitchin/org-ref"))]) (parsebib . [(20181219 928) ((emacs (24 3))) "A library for parsing bib files" single ((:commit . "9a5f1730b8ef1fb6c29262a8ba79f8136e5548d4") (:keywords "text" "bibtex") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (helm-bibtex . [(20190814 1056) ((helm (1 5 5)) (parsebib (1 0)) (s (1 9 0)) (dash (2 6 0)) (f (0 16 2)) (cl-lib (0 5)) (biblio (0 2))) "A bibliography manager based on Helm" tar ((:commit . "7e87161463c9c5ade3ed0e65aa3cde48c51b57de") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de"))]) (biblio . [(20190624 1408) ((emacs (24 3)) (biblio-core (0 2))) "Browse and import bibliographic references from CrossRef, arXiv, DBLP, HAL, Dissemin, and doi.org" tar ((:commit . "efeeab720cb8e3f95ddb4298d0cc62393cf237e9"))]) (biblio-core . [(20190624 1408) ((emacs (24 3)) (let-alist (1 0 4)) (seq (1 11)) (dash (2 12 1))) "A framework for looking up and displaying bibliographic entries" single ((:commit . "efeeab720cb8e3f95ddb4298d0cc62393cf237e9") (:keywords "bib" "tex" "convenience" "hypermedia") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:url . "http://github.com/cpitclaudel/biblio.el"))]) (ahk-mode . [(20190323 623) ((emacs (24 3))) "Major mode for editing AHK (AutoHotkey and AutoHotkey_L)" single ((:commit . "66e02a3b44d672787b1f13a30008801a9efca65b") (:keywords "ahk" "autohotkey" "hotkey" "keyboard shortcut" "automation") (:authors ("Rich Alesi")) (:maintainer "Rich Alesi") (:url . "https://github.com/ralesi/ahk-mode"))]) (markup-faces . [(20141110 817) nil "collection of faces for markup language modes" single ((:commit . "98a807ed82473eb41c6a201ed7ef816d6bcd67b0") (:keywords "wp" "faces") (:authors ("Florian Kaufmann" . "sensorflo@gmail.com")) (:maintainer "Florian Kaufmann" . "sensorflo@gmail.com") (:url . "https://github.com/sensorflo/markup-faces"))]) (adoc-mode . [(20160314 2130) ((markup-faces (1 0 0))) "a major-mode for editing AsciiDoc files in Emacs" single ((:commit . "745884359a1b8826ede2c4cfd2f0b5478953ac40") (:keywords "wp" "asciidoc") (:authors ("Florian Kaufmann" . "sensorflo@gmail.com")) (:maintainer "Florian Kaufmann" . "sensorflo@gmail.com") (:url . "https://github.com/sensorflo/adoc-mode/wiki"))]) (scala-mode . [(20170802 1132) nil "Major mode for editing Scala" tar ((:commit . "56cba2903cf6e12c715dbb5c99b34c97b2679379") (:keywords "languages") (:url . "https://github.com/ensime/emacs-scala-mode"))]) (sbt-mode . [(20180511 1622) ((emacs (24 4))) "Interactive support for sbt projects" tar ((:commit . "e658af140547cbef495c33535c7f694a501d318c") (:keywords "languages") (:url . "https://github.com/ensime/emacs-sbt-mode"))]) (swift-mode . [(20190609 507) ((emacs (24 4)) (seq (2 3))) "Major-mode for Apple's Swift programming language." tar ((:commit . "be8d7700cdbf47576d7c4e0a7e0855cce0fe9ad8") (:keywords "languages" "swift") (:url . "https://github.com/swift-emacs/swift-mode"))]) (csv-mode . [(1 7) nil "Major mode for editing comma/char separated values" single ((:url . "http://elpa.gnu.org/packages/csv-mode.html") (:keywords "convenience") (:authors ("\"Francis J. Wright\"" . "F.J.Wright@qmul.ac.uk")) (:maintainer "\"Francis J. Wright\"" . "F.J.Wright@qmul.ac.uk"))]) (jsonnet-mode . [(20181211 1853) ((emacs (24))) "Major mode for editing jsonnet files" single ((:commit . "2b90b4e12a11c42df0f1e5db327a50555b6ff023") (:keywords "languages") (:authors ("Nick Lanham")) (:maintainer "Nick Lanham") (:url . "https://github.com/mgyucht/jsonnet-mode"))]) (ess . [(20190814 1054) ((emacs (25 1)) (julia-mode (0 3))) "Emacs Speaks Statistics" tar ((:commit . "0f725b7f0cd92b968cf980ec6159b52fbe5793fa") (:authors ("David Smith" . "dsmith@stats.adelaide.edu.au") ("A.J. Rossini" . "blindglobe@gmail.com") ("Richard M. Heiberger" . "rmh@temple.edu") ("Kurt Hornik" . "Kurt.Hornik@R-project.org") ("Martin Maechler" . "maechler@stat.math.ethz.ch") ("Rodney A. Sparapani" . "rsparapa@mcw.edu") ("Stephen Eglen" . "stephen@gnu.org") ("Sebastian P. Luque" . "spluque@gmail.com") ("Henning Redestig" . "henning.red@googlemail.com") ("Vitalie Spinu" . "spinuvit@gmail.com") ("Lionel Henry" . "lionel.hry@gmail.com") ("J. Alexander Branham" . "alex.branham@gmail.com")) (:maintainer "ESS Core Team" . "ESS-core@r-project.org") (:url . "https://ess.r-project.org/"))]) (ctable . [(20171006 11) nil "Table component for Emacs Lisp" single ((:commit . "b8830d1ca95abb100a81bc32011bd17d5ecba000") (:keywords "table") (:authors ("SAKURAI Masashi ")) (:maintainer "SAKURAI Masashi ") (:url . "https://github.com/kiwanami/emacs-ctable"))]) (ess-R-data-view . [(20130509 1158) ((ctable (20130313 1743)) (popup (20130324 1305)) (ess (20130225 1754))) "Data viewer for GNU R" single ((:commit . "d6e98d3ae1e2a2ea39a56eebcdb73e99d29562e9") (:keywords "convenience") (:authors ("myuhe ")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/ess-R-data-view.el"))]) (golden-ratio . [(20150819 1120) nil "Automatic resizing of Emacs windows to the golden ratio" single ((:commit . "72b028808b41d23fa3f7e8c0d23d2c475e7b46ae") (:keywords "window" "resizing") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com"))]) (graphviz-dot-mode . [(20181118 551) nil "Mode for the dot-language used by graphviz (att)." single ((:commit . "243de72e09ddd5cdc4863613af8b749827a5e1cd") (:keywords "mode" "dot" "dot-language" "dotlanguage" "graphviz" "graphs" "att") (:maintainer "Pieter Pareit" . "pieter.pareit@gmail.com") (:url . "http://ppareit.github.com/graphviz-dot-mode/"))]) (sml-mode . [(6 9) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing (Standard) ML" single ((:url . "http://elpa.gnu.org/packages/sml-mode.html") (:keywords "sml") (:authors ("Lars Bo Nielsen") (" Olin Shivers") (" Fritz Knabe (?)") (" Steven Gilmore (?)") (" Matthew Morley" . "mjm@scs.leeds.ac.uk") (" Matthias Blume" . "blume@cs.princeton.edu") (" (Stefan Monnier)" . "monnier@iro.umontreal.ca")) (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))]) (ob-sml . [(20130829 1843) ((sml-mode (6 4))) "org-babel functions for template evaluation" single ((:commit . "958165c92b6cff6cada5c85c8ae5887806b8451b") (:keywords "literate programming" "reproducible research") (:authors ("David Nolen")) (:maintainer "David Nolen") (:url . "http://orgmode.org"))]) (csharp-mode . [(20190717 1024) nil "C# mode derived mode" single ((:commit . "e7e96e3b0cb69d98b4e12eda269719c9b23453ed") (:keywords "c#" "languages" "oop" "mode") (:authors ("Dylan R. E. Moonfire (original)")) (:maintainer "Jostein Kjønigsen" . "jostein@gmail.com") (:url . "https://github.com/josteink/csharp-mode"))]) (omnisharp . [(20190809 341) ((emacs (24 4)) (flycheck (30)) (dash (2 12 0)) (auto-complete (1 4)) (popup (0 5 1)) (csharp-mode (0 8 7)) (cl-lib (0 5)) (s (1 10 0)) (f (0 19 0))) "Omnicompletion (intellisense) and more for C#" tar ((:commit . "b5afa053c8d3771d5567538bae89a03cc66e826c") (:keywords "languages" "csharp" "c#" "ide" "auto-complete" "intellisense") (:authors ("Mika Vilpas and others")) (:maintainer "Mika Vilpas and others") (:url . "https://github.com/Omnisharp/omnisharp-emacs"))]) (ttl-mode . [(20160505 832) nil "mode for Turtle (and Notation 3)" single nil]) (sparql-mode . [(20180320 1802) ((cl-lib (0 5)) (emacs (24 3))) "Edit and interactively evaluate SPARQL queries." tar ((:commit . "a00bb622c54086ac1ee96c265bf7fbef12c68089") (:authors ("Craig Andera ")) (:maintainer "Bjarte Johansen ") (:url . "https://github.com/ljos/sparql-mode"))]) (julia-mode . [(20190813 1326) nil "Major mode for editing Julia source code" tar ((:commit . "db84928742b3e4189dcc81997e4a3cad3eac7b68") (:keywords "languages") (:url . "https://github.com/JuliaLang/julia"))]) (julia-repl . [(20190420 1455) ((emacs (25))) "A minor mode for a Julia REPL" single ((:commit . "71380e8139e28ea527a85ddb9146f2980d62c1f8") (:keywords "languages") (:authors ("Tamas Papp" . "tkpapp@gmail.com")) (:maintainer "Tamas Papp" . "tkpapp@gmail.com") (:url . "https://github.com/tpapp/julia-repl"))]) (company-lsp . [(20190612 1553) ((emacs (25 1)) (lsp-mode (6 0)) (company (0 9 0)) (s (1 2 0)) (dash (2 11 0))) "Company completion backend for lsp-mode." single ((:commit . "f921ffa0cdc542c21dc3dd85f2c93df4288e83bd") (:url . "https://github.com/tigersoldier/company-lsp"))]) (evil-surround . [(20190403 418) ((evil (1 2 12))) "emulate surround.vim from Vim" single ((:commit . "5ad01dfa86424c4b22cd1dfa375f13bd8c656f43") (:keywords "emulation" "vi" "evil") (:authors ("Tim Harper ") ("Vegard Øye ")) (:maintainer "Tim Harper "))]) (groovy-imports . [(20161003 851) ((emacs (24 4)) (s (1 10 0)) (pcache (0 3 2))) "Code for dealing with Groovy imports" single ((:commit . "e56d7dda617555ec6205644d32ffddf2e1fa43d9") (:keywords "groovy") (:authors ("Miro Bezjak")) (:maintainer "Miro Bezjak") (:url . "http://www.github.com/mbezjak/emacs-groovy-imports"))]) (groovy-mode . [(20190407 2314) ((s (1 12 0)) (emacs (24 3)) (dash (2 13 0))) "Major mode for Groovy source files" tar ((:commit . "aa531c659758b896ff8fbd307080ce0d1d04ebfb") (:keywords "languages") (:authors ("Russel Winder" . "russel@winder.org.uk") ("Jim Morris" . "morris@wolfman.com") ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Russel Winder" . "russel@winder.org.uk"))]) (coffee-mode . [(20170324 940) ((emacs (24 3))) "Major mode for CoffeeScript code" single ((:commit . "86ab8aae8662e8eff54d3013010b9c693b16eac5") (:keywords "coffeescript" "major" "mode") (:authors ("Chris Wanstrath" . "chris@ozmm.org")) (:maintainer "Chris Wanstrath" . "chris@ozmm.org") (:url . "http://github.com/defunkt/coffee-mode"))]) (ob-coffeescript . [(20180126 719) ((emacs (24 4))) "org-babel functions for coffee-script evaluation, and fully implementation!" single ((:commit . "5a5bb04aea9c2a6eab5b05f90f5c7cb6de7b4261") (:keywords "coffee-script" "literate programming" "reproducible research") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/ob-coffeescript"))]) (prop-menu . [(20150728 1118) ((emacs (24 3)) (cl-lib (0 5))) "Create and display a context menu based on text and overlay properties" single ((:commit . "50b102c1c0935fd3e0c465feed7f27d66b21cdf3") (:keywords "convenience") (:authors ("David Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Christiansen" . "david@davidchristiansen.dk") (:url . "https://github.com/david-christiansen/prop-menu-el"))]) (idris-mode . [(20190427 1539) ((emacs (24)) (prop-menu (0 1)) (cl-lib (0 5))) "Major mode for editing Idris code" tar ((:commit . "acc8835449475d7cd205aba213fdd3d41c38ba40") (:keywords "languages") (:url . "https://github.com/idris-hackers/idris-mode"))]) (js2-refactor . [(20190630 2108) ((js2-mode (20101228)) (s (1 9 0)) (multiple-cursors (1 0 0)) (dash (1 0 0)) (s (1 0 0)) (yasnippet (0 9 0 1))) "A JavaScript refactoring library for emacs." tar ((:commit . "d4c40b5fc86d3edd7c6a7d83ac86483ee1cb7a28"))]) (livid-mode . [(20131116 1344) ((skewer-mode (1 5 3)) (s (1 8 0))) "Live browser eval of JavaScript every time a buffer changes" single ((:commit . "dfe5212fa64738bc4138bfebf349fbc8bc237c26") (:authors ("Murphy McMahon")) (:maintainer "Murphy McMahon") (:url . "https://github.com/pandeiro/livid-mode"))]) (nodejs-repl . [(20190616 1753) nil "Run Node.js REPL" single ((:commit . "d43b8b276a90ccf980150a7d6fbb1f4d2a7cbe20") (:authors ("Takeshi Arabiki")) (:maintainer "Takeshi Arabiki"))]) (js2-mode . [(20190815 1327) ((emacs (24 1)) (cl-lib (0 5))) "Improved JavaScript editing mode" tar ((:commit . "b3841a7a304d9d1328fdb0868fbbecf0c2f9831f") (:keywords "languages" "javascript") (:authors ("Steve Yegge" . "steve.yegge@gmail.com") ("mooz" . "stillpedant@gmail.com") ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Steve Yegge" . "steve.yegge@gmail.com") (:url . "https://github.com/mooz/js2-mode/"))]) (skewer-mode . [(20180706 1807) ((simple-httpd (1 4 0)) (js2-mode (20090723)) (emacs (24))) "live browser JavaScript, CSS, and HTML interaction" tar ((:commit . "a381049acc4fa2087615b4b3b26c0865841386bd"))]) (forth-mode . [(20170527 1930) nil "Programming language mode for Forth" tar ((:commit . "522256d98d1a909983bcfd3ae20c65226d5929b6") (:keywords "languages" "forth") (:authors ("Lars Brinkhoff" . "lars@nocrew.org")) (:maintainer "Lars Brinkhoff" . "lars@nocrew.org") (:url . "http://github.com/larsbrinkhoff/forth-mode"))]) (company-math . [(20190507 2006) ((company (0 8 0)) (math-symbol-lists (1 2))) "Completion backends for unicode math symbols and latex tags" single ((:commit . "600e49449644f6835f9dc3501bc58461999e8ab9") (:keywords "unicode" "symbols" "completion") (:authors ("Vitalie Spinu" . "spinuvit@gmail.com")) (:maintainer "Vitalie Spinu" . "spinuvit@gmail.com") (:url . "https://github.com/vspinu/company-math"))]) (math-symbol-lists . [(20190605 2058) nil "Lists of Unicode math symbols and latex commands" tar ((:commit . "dc7531cff0c845d5470a50c24d5d7309b2ced7eb") (:keywords "unicode" "symbols" "mathematics") (:authors ("Vitalie Spinu" . "spinuvit@gmail.com")) (:maintainer "Vitalie Spinu" . "spinuvit@gmail.com") (:url . "https://github.com/vspinu/math-symbol-lists"))]) (company-coq . [(20190425 1851) ((company-math (1 1)) (company (0 8 12)) (yasnippet (0 11 0)) (dash (2 12 1)) (cl-lib (0 5))) "A collection of extensions for Proof General's Coq mode" tar ((:commit . "779dabd2925fc786dc278270a20f2ff05a3c673c"))]) (proof-general . [(20190821 848) ((emacs (24 3))) "A generic front-end for proof assistants (interactive theorem provers)" tar ((:commit . "d53ded580e30d49e7a783280fd9ba96bc9c1c39c"))]) (vi-tilde-fringe . [(20141028 242) ((emacs (24))) "Displays tildes in the fringe on empty lines a la Vi." single ((:commit . "f1597a8d54535bb1d84b442577b2024e6f910308") (:keywords "emulation") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/vi-tilde-fringe"))]) (flycheck-pact . [(20180920 2052) ((emacs (24 3)) (flycheck (0 25)) (pact-mode (0 0 4))) "Flycheck support for pact-mode" single ((:commit . "0e10045064ef89ec8b6f5a473073d47b976a2ca3") (:keywords "pact" "lisp" "languages" "blockchain" "smartcontracts" "tools" "linting") (:authors ("Stuart Popejoy")) (:maintainer "Stuart Popejoy" . "stuart@kadena.io") (:url . "http://github.com/kadena-io/flycheck-pact"))]) (pact-mode . [(20190710 1817) ((emacs (24 3))) "Mode for Pact, a LISPlike smart contract language." single ((:commit . "5df7032cf9b61ae5aff36ac7d2a23b2ab0e00904") (:keywords "pact" "lisp" "languages" "blockchain" "smartcontracts" "tools" "mode") (:authors ("Stuart Popejoy")) (:maintainer "Stuart Popejoy" . "stuart@kadena.io") (:url . "https://github.com/kadena-io/pact-mode"))]) (company-dcd . [(20190116 256) ((company (0 9)) (flycheck-dmd-dub (0 7)) (yasnippet (0 8)) (popwin (0 7)) (cl-lib (0 5)) (ivy (20160804 326))) "Company backend for Dlang using DCD." single ((:commit . "11e90949e546fcff1b1cd40887ad7b6701aa1653") (:keywords "languages") (:authors ("tsukimizake ")) (:maintainer "tsukimizake ") (:url . "http://github.com/tsukimizake/company-dcd"))]) (d-mode . [(20181205 607) ((emacs (24 3))) "D Programming Language major mode for (X)Emacs" single ((:commit . "b5d936dfd4c1d0b68a0d911aadd4ba25df7af0e4") (:keywords "d" "programming" "language" "emacs" "cc-mode") (:authors ("William Baxter")) (:maintainer "Russel Winder" . "russel@winder.org.uk"))]) (flycheck-dmd-dub . [(20180625 1635) ((flycheck (0 24)) (f (0 18 2))) "Sets flycheck-dmd-include-paths from dub package information" single ((:commit . "d7df2895d7d27cc39916816e3c32a60ce0e1d2d9") (:keywords "languages") (:authors ("Atila Neves" . "atila.neves@gmail.com")) (:maintainer "Atila Neves" . "atila.neves@gmail.com") (:url . "http://github.com/atilaneves/flycheck-dmd-dub"))]) (auto-complete-rst . [(20140225 944) ((auto-complete (1 4))) "Auto-complete extension for ReST and Sphinx" tar ((:commit . "4803ce41a96224e6fa54e6741a5b5f40ebed7351") (:authors ("ARAKAKI, Takafumi")) (:maintainer "ARAKAKI, Takafumi") (:url . "https://github.com/tkf/auto-complete-rst"))]) (auto-highlight-symbol . [(20130313 943) nil "Automatic highlighting current symbol minor mode" single ((:commit . "26573de912d760e04321b350897aea70958cee8b") (:keywords "highlight" "face" "match" "convenience") (:authors ("Mitsuo Saito" . "arch320@NOSPAM.gmail.com")) (:maintainer "Mitsuo Saito" . "arch320@NOSPAM.gmail.com") (:url . "http://github.com/gennad/auto-highlight-symbol/raw/master/auto-highlight-symbol.el"))]) (common-lisp-snippets . [(20180226 1523) ((yasnippet (0 8 0))) "Yasnippets for Common Lisp" tar ((:commit . "c82ebf18f4ad49f390dd96ffcc59f8683c1a868b") (:keywords "snippets") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/common-lisp-snippets"))]) (slime . [(20190818 1634) ((cl-lib (0 5)) (macrostep (0 9))) "Superior Lisp Interaction Mode for Emacs" tar ((:commit . "cbab3e9a1bc4f1a03ee21f392a499f01333af816") (:keywords "languages" "lisp" "slime") (:url . "https://github.com/slime/slime"))]) (macrostep . [(20161120 2106) ((cl-lib (0 5))) "interactive macro expander" tar ((:commit . "424e3734a1ee526a1bd7b5c3cd1d3ef19d184267") (:keywords "lisp" "languages" "macro" "debugging") (:authors ("joddie" . "j.j.oddie@gmail.com")) (:maintainer "joddie" . "j.j.oddie@gmail.com") (:url . "https://github.com/joddie/macrostep"))]) (slime-company . [(20190117 1538) ((emacs (24 4)) (slime (2 13)) (company (0 9 0))) "slime completion backend for company mode" single ((:commit . "7290cbad711a62f76c28e5638d1a4d77197a358c") (:keywords "convenience" "lisp" "abbrev") (:authors ("Ole Arndt" . "anwyn@sugarshark.com")) (:maintainer "Ole Arndt" . "anwyn@sugarshark.com"))]) (protobuf-mode . [(20170526 1650) nil "major mode for editing protocol buffers." single ((:commit . "63e4a3ecc956cbab6714b25e8b868765ea7e6fe5") (:keywords "google" "protobuf" "languages") (:authors ("Alexandre Vassalotti" . "alexandre@peadrop.com")) (:maintainer "Alexandre Vassalotti" . "alexandre@peadrop.com"))]) (bundler . [(20190701 1013) ((inf-ruby (2 1)) (cl-lib (0 5))) "Interact with Bundler from Emacs" single ((:commit . "05a91d68e21e129b6c4d5462c888ea249c2ea001") (:keywords "bundler" "ruby") (:authors ("Tobias Svensson" . "tob@tobiassvensson.co.uk")) (:maintainer "Tobias Svensson" . "tob@tobiassvensson.co.uk") (:url . "http://github.com/endofunky/bundler.el"))]) (chruby . [(20180114 1652) ((cl-lib (0 5))) "Emacs integration for chruby" single ((:commit . "42bc6d521f832eca8e2ba210f30d03ad5529788f") (:keywords "languages") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:url . "https://github.com/plexus/chruby.el"))]) (enh-ruby-mode . [(20190513 254) ((emacs (24 3))) "Major mode for editing Ruby files" tar ((:commit . "f334c42986e93c60fba144d732becfcbdb13bb7d") (:keywords "languages" "elisp" "ruby") (:authors ("Geoff Jacobsen")) (:maintainer "Ryan Davis") (:url . "http://github.com/zenspider/Enhanced-Ruby-Mode"))]) (minitest . [(20160628 1820) ((dash (1 0 0))) "An Emacs mode for ruby minitest files" tar ((:commit . "1aadb7865c1dc69c201cecee275751ecec33a182") (:authors ("Arthur Neves")) (:maintainer "Arthur Neves") (:url . "https://github.com/arthurnn/minitest-emacs"))]) (rbenv . [(20141120 749) nil "Emacs integration for rbenv" single ((:commit . "2ea1a5bdc1266caef1dd77700f2c8f42429b03f1") (:keywords "ruby" "rbenv") (:authors ("Yves Senn" . "yves.senn@gmail.com")) (:maintainer "Yves Senn" . "yves.senn@gmail.com") (:url . "https://github.com/senny/rbenv.el"))]) (inf-ruby . [(20190609 1126) nil "Run a Ruby process in a buffer" single ((:commit . "928b1dd2c24c62be1900476cb4b7219eb2350856") (:keywords "languages" "ruby") (:authors ("Yukihiro Matsumoto") ("Nobuyoshi Nakada") ("Cornelius Mika" . "cornelius.mika@gmail.com") ("Dmitry Gutov" . "dgutov@yandex.ru") ("Kyle Hargraves" . "pd@krh.me")) (:maintainer "Yukihiro Matsumoto") (:url . "http://github.com/nonsequitur/inf-ruby"))]) (robe . [(20190521 58) ((inf-ruby (2 5 1)) (emacs (24 4))) "Code navigation, documentation lookup and completion for Ruby" tar ((:commit . "8190cb7c7beb8385dd3abf6ea357f33d8981ae8a") (:keywords "ruby" "convenience" "rails") (:authors ("Dmitry Gutov")) (:maintainer "Dmitry Gutov") (:url . "https://github.com/dgutov/robe"))]) (rspec-mode . [(20190609 1123) ((ruby-mode (1 0)) (cl-lib (0 4))) "Enhance ruby-mode for RSpec" tar ((:commit . "bc2618a71e0bbef60258cf59bad0796f469a2685") (:keywords "rspec" "ruby") (:authors ("Peter Williams, et al.")) (:maintainer "Peter Williams, et al.") (:url . "http://github.com/pezra/rspec-mode"))]) (rubocop . [(20190326 1424) ((emacs (24))) "An Emacs interface for RuboCop" single ((:commit . "03bf15558a6eb65e4f74000cab29412efd46660e") (:keywords "project" "convenience") (:authors ("Bozhidar Batsov")) (:maintainer "Bozhidar Batsov") (:url . "https://github.com/bbatsov/rubocop-emacs"))]) (rubocopfmt . [(20181009 1703) ((cl-lib (0 5))) "Minor-mode to format Ruby code with RuboCop on save" single ((:commit . "fc96145719a65b2551339d087ddd95b72e14646f") (:keywords "convenience" "wp" "edit" "ruby" "rubocop") (:authors ("Jim Myhrberg")) (:maintainer "Jim Myhrberg") (:url . "https://github.com/jimeh/rubocopfmt.el"))]) (ruby-hash-syntax . [(20190109 2227) nil "Toggle ruby hash syntax between => and 1.9+ styles" single ((:commit . "577ab383c142e3a0697ce73480158a8b489038da") (:keywords "languages") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/ruby-hash-syntax"))]) (ruby-refactor . [(20160214 1650) ((ruby-mode (1 2))) "A minor mode which presents various Ruby refactoring helpers." single ((:commit . "e6b7125878a08518bffec6942df0c606f748e9ee") (:keywords "refactor" "ruby") (:url . "https://github.com/ajvargo/ruby-refactor"))]) (pcre2el . [(20161120 2103) ((emacs (24)) (cl-lib (0 3))) "regexp syntax converter" single ((:commit . "0b5b2a2c173aab3fd14aac6cf5e90ad3bf58fa7d") (:authors ("joddie ")) (:maintainer "joddie ") (:url . "https://github.com/joddie/pcre2el"))]) (ruby-test-mode . [(20190412 909) ((ruby-mode (1 0)) (pcre2el (1 8))) "Minor mode for Behaviour and Test Driven" single ((:commit . "e805a81c3ea787f3c82dbb252c21d747be20bc7a") (:keywords "ruby" "unit" "test" "rspec" "tools") (:authors ("Roman Scherer" . "roman.scherer@gmx.de") ("Caspar Florian Ebeling" . "florian.ebeling@gmail.com")) (:maintainer "Roman Scherer" . "roman.scherer@burningswell.com") (:url . "https://github.com/ruby-test-mode/ruby-test-mode"))]) (ruby-tools . [(20151209 1615) nil "Collection of handy functions for ruby-mode." tar ((:commit . "6b97066b58a4f82eb2ecea6434a0a7e981aa4c18"))]) (rvm . [(20150402 1442) nil "Emacs integration for rvm" single ((:commit . "134497bc460990c71ab8fa75431156e62c17da2d") (:keywords "ruby" "rvm") (:authors ("Yves Senn" . "yves.senn@gmx.ch")) (:maintainer "Yves Senn" . "yves.senn@gmx.ch") (:url . "http://www.emacswiki.org/emacs/RvmEl"))]) (seeing-is-believing . [(20170214 1320) nil "minor mode for running the seeing-is-believing ruby gem" single ((:commit . "fbbe246c0fda87bb26227bb826eebadb418a220f") (:authors ("John Cinnamond")) (:maintainer "John Cinnamond"))]) (rake . [(20180212 1008) ((f (0 13 0)) (dash (1 5 0)) (cl-lib (0 5))) "Run rake commands" single ((:commit . "9c204334b03b4e899fadae6e59c20cf105404128") (:keywords "rake" "ruby") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:url . "https://github.com/asok/rake.el"))]) (reason-mode . [(20190710 1037) ((emacs (24 3))) "A major mode for editing ReasonML" tar ((:commit . "5e6205cfede8c10c6821dfd9f9757a9d8035ec04") (:keywords "languages" "ocaml") (:authors ("Mozilla")) (:maintainer "Mozilla") (:url . "https://github.com/reasonml-editor/reason-mode"))]) (sql-indent . [(1 4) ((cl-lib (0 5))) "Support for indenting code in SQL files." tar ((:url . "https://github.com/alex-hhh/emacs-sql-indent") (:maintainer "Alex Harsanyi" . "AlexHarsanyi@gmail.com") (:authors ("Alex Harsanyi" . "AlexHarsanyi@gmail.com")) (:keywords "languages" "sql"))]) (sqlup-mode . [(20170610 1537) nil "Upcase SQL words for you" single ((:commit . "3f9df9c88d6a7f9b1ae907e401cad8d3d7d63bbf") (:keywords "sql" "tools" "redis" "upcase") (:authors ("Aldric Giacomoni" . "trevoke@gmail.com")) (:maintainer "Aldric Giacomoni" . "trevoke@gmail.com") (:url . "https://github.com/trevoke/sqlup-mode.el"))]) (browse-at-remote . [(20190213 1929) ((f (0 17 2)) (s (1 9 0)) (cl-lib (0 5))) "Open github/gitlab/bitbucket/stash/gist/phab/sourcehut page from Emacs" single ((:commit . "1a9392e9d1fad4e1aafb25b68b4e6857fde8f564") (:keywords "github" "gitlab" "bitbucket" "gist" "stash" "phabricator" "sourcehut") (:authors ("Rustem Muslimov" . "r.muslimov@gmail.com")) (:maintainer "Rustem Muslimov" . "r.muslimov@gmail.com"))]) (diff-hl . [(20190707 2243) ((cl-lib (0 2)) (emacs (24 3))) "Highlight uncommitted changes using VC" tar ((:commit . "374b1d4b34876219218da7a539e7301259b56958") (:keywords "vc" "diff") (:authors ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:url . "https://github.com/dgutov/diff-hl"))]) (git-gutter . [(20161105 1356) ((emacs (24 3))) "Port of Sublime Text plugin GitGutter" single ((:commit . "00c05264af046b5ce248e5b0bc42f117d9c27a09") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-git-gutter"))]) (git-gutter-fringe . [(20170113 533) ((git-gutter (0 88)) (fringe-helper (0 1 1)) (cl-lib (0 5)) (emacs (24))) "Fringe version of git-gutter.el" single ((:commit . "16226caab44174301f1659f7bf8cc67a76153445") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-git-gutter-fringe"))]) (fringe-helper . [(20140620 2109) nil "helper functions for fringe bitmaps" single ((:commit . "ef4a9c023bae18ec1ddd7265f1f2d6d2e775efdd") (:keywords "lisp") (:authors ("Nikolaj Schumacher ")) (:maintainer "Nikolaj Schumacher ") (:url . "http://nschum.de/src/emacs/fringe-helper/"))]) (git-gutter+ . [(20151204 1723) ((git-commit (0)) (dash (0))) "Manage Git hunks straight from the buffer" single ((:commit . "b7726997806d9a2da9fe84ff00ecf21d62b6f975") (:keywords "git" "vc") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/nonsequitur/git-gutter-plus"))]) (git-gutter-fringe+ . [(20140729 1103) ((git-gutter+ (0 1)) (fringe-helper (1 0 1))) "Fringe version of git-gutter+.el" single ((:commit . "7a2f49d2455a3a872e90e5f7dd4e6b27f1d96cfc") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/nonsequitur/git-gutter-fringe-plus"))]) (ghub . [(20190806 959) ((emacs (25 1)) (dash (2 14 1)) (let-alist (1 0 5)) (treepy (0 1 1))) "Minuscule client libraries for Git forge APIs." tar ((:commit . "7d59937d7782d0062216130a4d059b45e8396f82"))]) (closql . [(20190731 1450) ((emacs (25 1)) (emacsql-sqlite (3 0 0))) "store EIEIO objects using EmacSQL" single ((:commit . "70b98dbae53611d10a461d9b4a6f71086910dcef") (:keywords "extensions") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/closql"))]) (emacsql-sqlite . [(20190727 1710) ((emacs (25 1)) (emacsql (2 0 0))) "EmacSQL back-end for SQLite" tar ((:commit . "a118b6c95af1306f0288a383d274b5dd93efbbda") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacsql"))]) (emacsql . [(20190625 1859) ((emacs (25 1))) "high-level SQL database front-end" tar ((:commit . "a118b6c95af1306f0288a383d274b5dd93efbbda") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacsql"))]) (treepy . [(20180724 656) ((emacs (25 1))) "Generic tree traversal tools" single ((:commit . "b40e6b09eb9be45da67b8c9e4990a5a0d7a2a09d") (:keywords "lisp" "maint" "tools") (:authors ("Daniel Barreto" . "daniel.barreto.n@gmail.com")) (:maintainer "Daniel Barreto" . "daniel.barreto.n@gmail.com") (:url . "https://github.com/volrath/treepy.el"))]) (forge . [(20190820 826) ((emacs (25 1)) (closql (1 0 0)) (dash (2 14 1)) (emacsql-sqlite (3 0 0)) (ghub (20190319)) (let-alist (1 0 5)) (magit (20190408)) (markdown-mode (2 3)) (transient (0 1 0))) "Access Git forges from Magit." tar ((:commit . "6c43971a78a08954c20992cb6b0e98a7e7295908"))]) (gist . [(20171128 406) ((emacs (24 1)) (gh (0 10 0))) "Emacs integration for gist.github.com" single ((:commit . "314fe6ab80fae35b95f0734eceb82f72813b6f41") (:keywords "tools") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:url . "https://github.com/defunkt/gist.el"))]) (github-clone . [(20160623 310) ((gh (0 7 2)) (magit (2 1 0)) (emacs (24 4))) "Fork and clone github repos" single ((:commit . "467b40ca60a6c26257466ebc43c74414df7f19cc") (:keywords "vc" "tools") (:authors ("Charles L.G. Comstock" . "dgtized@gmail.com")) (:maintainer "Charles L.G. Comstock" . "dgtized@gmail.com") (:url . "https://github.com/dgtized/github-clone.el"))]) (gh . [(20180308 2138) ((emacs (24 3)) (pcache (0 4 1)) (logito (0 1)) (marshal (0 6 3))) "A GitHub library for Emacs" tar ((:commit . "f029fc11f345ef04ab62ee91c38657e29c462fea"))]) (marshal . [(20180124 1239) ((eieio (1 4)) (json (1 3)) (ht (2 1))) "eieio extension for automatic (un)marshalling" single ((:commit . "f038689cbd5b3680b80b44edd0c7a63ca3038e26") (:keywords "eieio") (:authors ("Yann Hodique" . "hodiquey@vmware.com")) (:maintainer "Yann Hodique" . "hodiquey@vmware.com") (:url . "https://github.com/sigma/marshal.el"))]) (logito . [(20120225 2055) ((eieio (1 3))) "logging library for Emacs" single ((:commit . "824acb89d2cc18cb47281a4fbddd81ad244a2052") (:keywords "lisp" "tool") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com"))]) (github-search . [(20190624 436) ((magit (0 8 1)) (gh (1 0 0))) "Clone repositories by searching github" single ((:commit . "b73efaf19491010522b09db35bb0f1bad1620e63") (:keywords "github" "search" "clone" "api" "gh" "magit" "vc" "tools") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/github-search"))]) (p4 . [(20150721 1937) nil "Simple Perforce-Emacs Integration" single ((:commit . "eff047caa75dbe4965defca9d1212454cdb755d5") (:authors ("Gareth Rees" . "gdr@garethrees.org")) (:maintainer "Gareth Rees" . "gdr@garethrees.org") (:url . "https://github.com/gareth-rees/p4.el"))]) (evil-magit . [(20190620 153) ((evil (1 2 3)) (magit (2 6 0))) "evil-based key bindings for magit" single ((:commit . "6a32e4359cbd2803bafb7134cb6df312644ac986") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/evil-magit"))]) (fill-column-indicator . [(20171209 1924) nil "Graphically indicate the fill column" single ((:commit . "a284bb50789c97d7ef9021214260b3ce7cc220e3") (:keywords "convenience") (:authors ("Alp Aker" . "alp.tekin.aker@gmail.com")) (:maintainer "Alp Aker" . "alp.tekin.aker@gmail.com"))]) (gitattributes-mode . [(20180318 1956) nil "Major mode for editing .gitattributes files" single ((:commit . "33c6a116a5b298e20eb39ebb154a51c4dd37c06d") (:keywords "convenience" "vc" "git") (:authors ("Rüdiger Sonderfeld" . "ruediger@c-plusplus.net")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/git-modes"))]) (gitconfig-mode . [(20180318 1956) nil "Major mode for editing .gitconfig files" single ((:commit . "33c6a116a5b298e20eb39ebb154a51c4dd37c06d") (:keywords "convenience" "vc" "git") (:authors ("Sebastian Wiesner" . "lunaryorn@gmail.com")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/git-modes"))]) (gitignore-templates . [(20180327 1326) ((emacs (24 3))) "Access GitHub .gitignore templates" single ((:commit . "b0705b8de4cbdd631c64c4e0024d62ba4ad68052") (:keywords "tools") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/gitignore-templates.el"))]) (git-link . [(20190817 302) ((emacs (24 3))) "Get the GitHub/Bitbucket/GitLab URL for a buffer location" single ((:commit . "b5ff7671dbb912e723503984c70402fe3a773a62") (:keywords "git" "vc" "github" "bitbucket" "gitlab" "sourcehut" "convenience") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:url . "http://github.com/sshaw/git-link"))]) (git-messenger . [(20170102 440) ((emacs (24 3)) (popup (0 5 0))) "Pop up last commit information of current line" single ((:commit . "83815915eb8c1cb47443ff34bca3fecf7d2edf3a") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-git-messenger"))]) (git-timemachine . [(20190730 849) ((emacs (24 3)) (transient (0 1 0))) "Walk through git revisions of a file" single ((:commit . "391eb61050de321101e631fcf373fc70ec6e7700") (:keywords "vc") (:authors ("Peter Stiernström" . "peter@stiernstrom.se")) (:maintainer "Peter Stiernström" . "peter@stiernstrom.se") (:url . "https://gitlab.com/pidu/git-timemachine"))]) (helm-git-grep . [(20170614 1411) ((helm-core (2 2 0))) "helm for git grep, an incremental git-grep(1)" single ((:commit . "744cea07dba6e6a5effbdba83f1b786c78fd86d3") (:authors ("mechairoi")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-git-grep"))]) (gitignore-mode . [(20180318 1956) nil "Major mode for editing .gitignore files" single ((:commit . "33c6a116a5b298e20eb39ebb154a51c4dd37c06d") (:keywords "convenience" "vc" "git") (:authors ("Sebastian Wiesner" . "lunaryorn@gmail.com")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/git-modes"))]) (helm-gitignore . [(20170211 8) ((gitignore-mode (1 1 0)) (helm (1 7 0)) (request (0 1 0)) (cl-lib (0 5))) "Generate .gitignore files with gitignore.io." single ((:commit . "2a2e7da7855a6db0ab3bb6a6a087863d7abd4391") (:keywords "helm" "gitignore" "gitignore.io") (:authors ("Juan Placencia")) (:maintainer "Juan Placencia") (:url . "https://github.com/jupl/helm-gitignore"))]) (magit-gitflow . [(20170929 824) ((magit (2 1 0)) (magit-popup (2 2 0))) "gitflow extension for magit" single ((:commit . "cc41b561ec6eea947fe9a176349fb4f771ed865b") (:keywords "vc" "tools") (:authors ("Jan Tatarik" . "Jan.Tatarik@gmail.com")) (:maintainer "Jan Tatarik" . "Jan.Tatarik@gmail.com") (:url . "https://github.com/jtatarik/magit-gitflow"))]) (magit-svn . [(20190324 1459) ((emacs (24 4)) (magit (2 1 0))) "Git-Svn extension for Magit" single ((:commit . "f7dad9b0f6b81b23550ea5cca0f3219f184b746c") (:keywords "vc" "tools") (:authors ("Phil Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Phil Jackson" . "phil@shellarchive.co.uk"))]) (magit . [(20190819 1414) ((emacs (25 1)) (async (20180527)) (dash (20180910)) (git-commit (20181104)) (transient (20190528)) (with-editor (20181103))) "A Git porcelain inside Emacs." tar ((:commit . "546a9c33715f12a9b1101eca22b070004c9c6392") (:keywords "git" "tools" "vc"))]) (git-commit . [(20190717 29) ((emacs (25 1)) (dash (20180910)) (with-editor (20181103))) "Edit Git commit messages" single ((:commit . "546a9c33715f12a9b1101eca22b070004c9c6392") (:keywords "git" "tools" "vc") (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/magit"))]) (orgit . [(20190717 1526) ((emacs (25 1)) (dash (2 14 1)) (magit (2 90 0)) (org (9 3))) "support for Org links to Magit buffers" single ((:commit . "1e578f8cf97b07835f02858f05a094ae9a5e99bb") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/orgit"))]) (smeargle . [(20161212 2358) ((emacs (24 3))) "Highlighting region by last updated time" single ((:commit . "0665b1ff5109731898bc4a0ca6d939933b804777") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-smeargle"))]) (transient . [(20190812 1336) ((emacs (25 1)) (dash (2 15 0))) "Transient commands" tar ((:commit . "9fb3f797f10fd069c2bffa7a3ead746aa53d1a25") (:keywords "bindings") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/transient"))]) (afternoon-theme . [(20140104 1859) ((emacs (24 1))) "Dark color theme with a deep blue background" single ((:commit . "89b1d778a1f8b385775c122f2bd1c62f0fbf931a") (:keywords "themes") (:authors ("Ozan Sener" . "ozan@ozansener.com")) (:maintainer "Ozan Sener" . "ozan@ozansener.com") (:url . "http://github.com/osener/emacs-afternoon-theme"))]) (alect-themes . [(20190506 1440) ((emacs (24 0))) "Configurable light, dark and black themes for Emacs 24 or later" tar ((:commit . "da7305075d292cc1909bf26dc5634bc3cc8d2603") (:keywords "color" "theme") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/alect-themes"))]) (ample-theme . [(20180207 1745) nil "Calm Dark Theme for Emacs" tar ((:commit . "536966adf882446165a1f756830028faa792c7a9") (:keywords "theme" "dark") (:authors ("Jordon Biondo" . "jordonbiondo@gmail.com")) (:maintainer "Jordon Biondo" . "jordonbiondo@gmail.com") (:url . "https://github.com/jordonbiondo/ample-theme"))]) (ample-zen-theme . [(20150119 2154) nil "AmpleZen Theme for Emacs 24" single ((:commit . "b277bb7abd4b6624e8d59f02474b79af50a007bd") (:keywords "theme" "dark" "emacs 24") (:authors ("Michael Wall")) (:maintainer "Michael Wall") (:url . "https://github.com/mjwall/ample-zen"))]) (apropospriate-theme . [(20190724 1729) nil "A colorful, low-contrast, light & dark theme set for Emacs with a fun name." tar ((:commit . "c46432a5559630380abee9ead387eba2db28ad15") (:keywords "color" "theme") (:url . "https://github.com/waymondo/apropospriate-theme"))]) (anti-zenburn-theme . [(20180712 1838) nil "Low-contrast Zenburn-inverted theme" single ((:commit . "dbafbaa86be67c1d409873f57a5c0bbe1e7ca158") (:authors ("Andrey Kotlarski" . "m00naticus@gmail.com")) (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:url . "https://github.com/m00natic/anti-zenburn-theme"))]) (badwolf-theme . [(20161004 715) ((emacs (24))) "Bad Wolf color theme" single ((:commit . "ea01a3d9358e968f75e3ed15dec6a2a96ce3d9a1") (:keywords "themes") (:authors ("bkruczyk" . "bartlomiej.kruczyk@gmail.com")) (:maintainer "bkruczyk" . "bartlomiej.kruczyk@gmail.com") (:url . "https://github.com/bkruczyk/badwolf-emacs"))]) (birds-of-paradise-plus-theme . [(20130419 2129) nil "A brown/orange light-on-dark theme for Emacs 24 (deftheme)." single ((:commit . "bb9f9d4ef7f7872a388ec4eee1253069adcadb6f") (:keywords "themes") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:url . "https://github.com/jimeh/birds-of-paradise-plus-theme.el"))]) (bubbleberry-theme . [(20141017 944) ((emacs (24 1))) "A theme based on LightTable for Emacs24" single ((:commit . "22e9adf4586414024e4592972022ec297321b320") (:authors ("Jason Milkins" . "jasonm23@gmail.com") ("Gaurav Giri github.com/grvgr")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-bubbleberry-theme"))]) (busybee-theme . [(20170719 928) nil "port of vim's mustang theme" single ((:commit . "66b2315b030582d0ebee605cf455d386d8c30fcd") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/busybee-theme"))]) (cherry-blossom-theme . [(20150622 342) ((emacs (24 0))) "a soothing color theme for Emacs24." single ((:commit . "eea7653e00f35973857ee23b27bc2fae5e753e50") (:authors ("Ben Yelsey" . "byelsey1@gmail.com")) (:maintainer "Ben Yelsey" . "byelsey1@gmail.com") (:url . "https://github.com/inlinestyle/emacs-cherry-blossom-theme"))]) (chocolate-theme . [(20190818 756) ((emacs (24 1)) (autothemer (0 2))) "A dark chocolaty theme" single ((:commit . "7de46341adcc7a5eaafcddc0d3a9d63274f5e9c7") (:url . "http://github.com/SavchenkoValeriy/emacs-chocolate-theme"))]) (clues-theme . [(20161213 1127) ((emacs (24 0))) "an Emacs 24 theme which may well be fully awesome..." single ((:commit . "abd61f2b7f3e98de58ca26e6d1230e70c6406cc7") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/emacsfodder/emacs-clues-theme"))]) (color-theme-sanityinc-solarized . [(20190206 59) ((cl-lib (0 6))) "A version of Ethan Schoonover's Solarized themes" tar ((:commit . "54daf1e5a0fbee6682cade1f59171daf185239e3") (:keywords "faces" "themes") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "http://github.com/purcell/color-theme-sanityinc-solarized"))]) (color-theme-sanityinc-tomorrow . [(20190819 2324) nil "A version of Chris Kempson's \"tomorrow\" themes" tar ((:commit . "596c3fdc422cb2886b93e65596a478475475b0be") (:keywords "faces" "themes") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "http://github.com/purcell/color-theme-sanityinc-tomorrow"))]) (cyberpunk-theme . [(20190717 1509) nil "Cyberpunk Color Theme" single ((:commit . "9779fc4c9f89b14c8c8bb238dd4ed6428ed30ba9") (:keywords "color" "theme" "cyberpunk") (:authors ("Nicholas M. Van Horn" . "nvanhorn@protonmail.com")) (:maintainer "Nicholas M. Van Horn" . "nvanhorn@protonmail.com") (:url . "https://github.com/n3mo/cyberpunk-theme.el"))]) (dakrone-theme . [(20170801 1933) nil "dakrone's custom dark theme" single ((:commit . "232ad1be5f3572dcbdf528f1655109aa355a6937") (:keywords "color" "themes") (:authors ("Lee Hinman ")) (:maintainer "Lee Hinman ") (:url . "https://github.com/dakrone/dakrone-theme"))]) (darkburn-theme . [(20170423 1652) nil "A not-so-low contrast color theme for Emacs." single ((:commit . "0af794ff7fac19778ac8a7efb92455c6f6c2158f") (:authors ("Jonas Gorauskas" . "jgorauskas@gmail.com")) (:maintainer "Jonas Gorauskas" . "jgorauskas@gmail.com") (:url . "http://github.com/gorauskas/darkburn-theme"))]) (darkmine-theme . [(20160406 624) nil "Yet another emacs dark color theme." single ((:commit . "7f7e82ca03bcad52911fa41fb3e204e32d6ee63e") (:authors ("Pierre Lecocq" . "pierre.lecocq@gmail.com")) (:maintainer "Pierre Lecocq" . "pierre.lecocq@gmail.com") (:url . "https://github.com/pierre-lecocq/darkmine-theme"))]) (darkokai-theme . [(20190603 1919) nil "A darker variant on Monokai." single ((:commit . "a53815fbfb06604d7f51519c62cc11e507204a70") (:url . "http://github.com/sjrmanning/darkokai"))]) (darktooth-theme . [(20190412 142) ((autothemer (0 2))) "From the darkness... it watches" single ((:commit . "5cc7fbfb08d2f1a33b85eac92b6450407b915119") (:url . "http://github.com/emacsfodder/emacs-theme-darktooth"))]) (django-theme . [(20131022 902) nil "Custom face theme for Emacs" single ((:commit . "86c8142b3eb1addd94a43aa6f1d98dab06401af0") (:authors ("Andrzej Sliwa")) (:maintainer "Andrzej Sliwa") (:url . "http://github/anrzejsliwa/django-theme"))]) (doom-themes . [(20190819 1549) ((emacs (25 1)) (cl-lib (0 5))) "an opinionated pack of modern color-themes" tar ((:commit . "9dddab2091a5e087dc5de725142463abae1ab5ff") (:keywords "dark" "light" "blue" "atom" "one" "theme" "neotree" "icons" "faces" "nova") (:authors ("Henrik Lissner ")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-doom-theme"))]) (dracula-theme . [(20190107 2016) ((emacs (24))) "Dracula Theme" single ((:commit . "66e429f4d576346661ae3a111bafaa06febc1d94") (:authors ("film42")) (:maintainer "film42") (:url . "https://github.com/dracula/emacs"))]) (spacemacs-theme . [(20190820 816) nil "Color theme with a dark and light versions" tar ((:commit . "32ddc1a9b9f4f58ebe8410abc1124b7acf0f36b1") (:keywords "color" "theme") (:url . "https://github.com/nashamri/spacemacs-theme"))]) (ewal . [(20190820 1702) ((emacs (25))) "A pywal-based theme generator" tar ((:commit . "3ddb2be48892185dfdbf2753ee97572ddc5a83d7") (:keywords "faces") (:authors ("Uros Perisic")) (:maintainer "Uros Perisic") (:url . "https://gitlab.com/jjzmajic/ewal"))]) (ewal-spacemacs-themes . [(20190821 451) ((emacs (25)) (ewal (0 1)) (spacemacs-theme (0 1))) "An `ewal'-based theme" tar ((:commit . "5a34be048759549937f7c701ec529b0e2d1b5798") (:keywords "faces") (:authors ("Uros Perisic")) (:maintainer "Uros Perisic") (:url . "https://gitlab.com/jjzmajic/ewal"))]) (espresso-theme . [(20181025 826) nil "Espresso Tutti Colori port for Emacs" single ((:commit . "d2fa034eb833bf37cc6842017070725e0da9b046") (:authors ("Martin Kühl ")) (:maintainer "Martin Kühl ") (:url . "https://github.com/dgutov/espresso-theme"))]) (exotica-theme . [(20180212 2329) ((emacs (24))) "A dark theme with vibrant colors" single ((:commit . "ff3ef4f6fa38c93b99becad977c7810c990a4d2f") (:keywords "faces" "theme" "dark" "vibrant colors") (:authors ("Bharat Joshi" . "jbharat@outlook.com")) (:maintainer "Bharat Joshi" . "jbharat@outlook.com") (:url . "https://github.com/jbharat/exotica-theme"))]) (eziam-theme . [(20190720 1720) nil "A mostly monochrome theme, inspired by Tao and Leuven, with dark and light versions." tar ((:commit . "a0cafce1c49f3830fe96dacd49f4732b53166603"))]) (farmhouse-theme . [(20160713 2244) nil "Farmhouse Theme, Emacs edition" tar ((:commit . "7ddc1ff13b4a3d5466bd0d33ecb86100352e83a7") (:keywords "color" "theme") (:url . "https://github.com/mattly/emacs-farmhouse-theme"))]) (flatland-theme . [(20171113 1521) nil "A simple theme for Emacs based on the Flatland theme for Sublime Text" single ((:commit . "a98a6f19ad4dff0fa3fad1ea487b7d0ef634a19a") (:authors ("Greg Chapple" . "info@gregchapple.com")) (:maintainer "Greg Chapple" . "info@gregchapple.com") (:url . "http://github.com/gregchapple/flatland-emacs"))]) (flatui-theme . [(20160619 127) nil "A color theme for Emacs based on flatuicolors.com" single ((:commit . "9c15db5526c15c8dba55023f5698372b19c2a780") (:authors ("John Louis Del Rosario" . "john2x@gmail.com")) (:maintainer "John Louis Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/flatui-theme.el"))]) (gandalf-theme . [(20130809 947) nil "Gandalf color theme" single ((:commit . "4e472fc851431458537d458d09c1f5895e338536") (:keywords "color" "theme") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net"))]) (gotham-theme . [(20171013 1916) nil "A very dark Emacs color theme." single ((:commit . "5e97554d1f9639698faedb0660e63694be33bd84") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/gotham-theme"))]) (grandshell-theme . [(20180606 517) nil "Dark color theme for Emacs > 24 with intensive colors." tar ((:commit . "0ed8e4273607dd4fcaa742b4097259233b09eda6"))]) (gruber-darker-theme . [(20180529 712) nil "Gruber Darker color theme for Emacs 24." single ((:commit . "c7687ec0511941db1371dcd70b31061d74aa5668") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/rexim/gruber-darker-theme"))]) (gruvbox-theme . [(20190720 337) ((autothemer (0 2))) "A retro-groove colour theme for Emacs" tar ((:commit . "37548041b6c541b69ab6d18b53f7513781a1f2b3") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "http://github.com/greduan/emacs-theme-gruvbox"))]) (hc-zenburn-theme . [(20150928 1633) nil "An higher contrast version of the Zenburn theme." single ((:commit . "fd0024a5191cdce204d91c8f1db99ba31640f6e9") (:authors ("Nantas Nardelli" . "nantas.nardelli@gmail.com")) (:maintainer "Nantas Nardelli" . "nantas.nardelli@gmail.com") (:url . "https:github.com/edran/hc-zenburn-emacs"))]) (hemisu-theme . [(20130508 1844) nil "Hemisu for Emacs." tar ((:commit . "5c206561aa2c844ecdf3e3b672c3235e559ddd7f") (:authors ("Andrzej Sliwa")) (:maintainer "Andrzej Sliwa") (:url . "http://github/anrzejsliwa/django-theme"))]) (heroku-theme . [(20150523 219) nil "Heroku color theme" single ((:commit . "8083643fe92ec3a1c3eb82f1b8dc2236c9c9691d") (:authors ("Jonathan Chu" . "me@jonathanchu.is")) (:maintainer "Jonathan Chu" . "me@jonathanchu.is") (:url . "https://github.com/jonathanchu/color-theme-heroku"))]) (inkpot-theme . [(20190816 715) nil "port of vim's inkpot theme" single ((:commit . "54adc447d30e60b6e6c39220e8b36d93d63fecac") (:keywords "color" "theme") (:authors ("Sarah Iovan" . "sarah@hwaetageek.com") ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Sarah Iovan" . "sarah@hwaetageek.com") (:url . "https://github.com/ideasman42/emacs-inkpot-theme"))]) (ir-black-theme . [(20130303 755) nil "Port of ir-black theme" single ((:commit . "36e930d107604b5763c80294a6f92aaa02e6c272") (:keywords "faces") (:authors ("Jon-Michael Deldin" . "dev@jmdeldin.com")) (:maintainer "Jon-Michael Deldin" . "dev@jmdeldin.com"))]) (jazz-theme . [(20170411 1411) nil "A warm color theme for Emacs 24+." single ((:commit . "b1cb78a97cc4050f19d88a89e455c3e52d98240e") (:authors ("Roman Parykin" . "donderom@ymail.com")) (:maintainer "Roman Parykin" . "donderom@ymail.com") (:url . "https://github.com/donderom/jazz-theme"))]) (jbeans-theme . [(20180309 1625) ((emacs (24))) "Jbeans theme for GNU Emacs 24 (deftheme)" single ((:commit . "3caa95998d8492a2ca6c17971de499ca15609871") (:authors ("Adam Olsen" . "arolsen@gmail.com")) (:maintainer "Adam Olsen" . "arolsen@gmail.com") (:url . "https://github.com/synic/jbeans-emacs"))]) (autothemer . [(20180920 923) ((dash (2 10 0)) (emacs (24)) (cl-lib (0 5))) "Conveniently define themes." single ((:commit . "69488c71dfc182cf2e7be2d745037f230ade678e") (:authors ("Sebastian Sturm")) (:maintainer "Sebastian Sturm") (:url . "https://github.com/sebastiansturm/autothemer"))]) (kaolin-themes . [(20190812 1835) ((emacs (25 1)) (autothemer (0 2 2)) (cl-lib (0 6))) "A set of eye pleasing themes" tar ((:commit . "9bc8dc1b69e6d858a523b98603201f60a51825fa") (:keywords "dark" "light" "teal" "blue" "violet" "purple" "brown" "theme" "faces") (:authors ("Ogden Webb" . "ogdenwebb@gmail.com")) (:maintainer "Ogden Webb" . "ogdenwebb@gmail.com") (:url . "https://github.com/ogdenwebb/emacs-kaolin-themes"))]) (light-soap-theme . [(20150607 1445) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "76a787bd40c6b567ae68ced7f5d9f9f10725e00d"))]) (lush-theme . [(20180816 2200) ((emacs (24))) "A dark theme with lush colors" single ((:commit . "7cfc993709d712f75c51b505078608c9e1c11466") (:keywords "theme" "dark" "strong colors") (:authors ("Andre Richter" . "andre.o.richter@gmail.com")) (:maintainer "Andre Richter" . "andre.o.richter@gmail.com") (:url . "https://github.com/andre-richter/emacs-lush-theme"))]) (madhat2r-theme . [(20170203 30) ((emacs (24))) "dark color theme that is easy on the eyes" single ((:commit . "6b387f09de055cfcc15d74981cd4f32f8f9a7323") (:keywords "color" "theme") (:authors ("Micah Duke")) (:maintainer "Micah Duke") (:url . "https://github.com/madhat2r/madhat2r-theme"))]) (majapahit-theme . [(20160817 1848) nil "Color theme with a dark and light versions" tar ((:commit . "77c96df7619666b2102d90d452eeadf04adc89a6") (:keywords "color" "theme") (:url . "https://gitlab.com/franksn/majapahit-theme"))]) (material-theme . [(20171123 1840) ((emacs (24 1))) "A Theme based on the colors of the Google Material Design" tar ((:commit . "b66838d220ad380a16da1d8878936974b26f815d") (:keywords "themes") (:authors ("Christoph Paulik" . "cpaulik@gmail.com")) (:maintainer "Christoph Paulik" . "cpaulik@gmail.com") (:url . "http://github.com/cpaulik/emacs-material-theme"))]) (minimal-theme . [(20190113 2132) nil "A light/dark minimalistic Emacs 24 theme." tar ((:commit . "063b4d8ca33d55d04c341f0b2b777ec241a3e201") (:keywords "color" "theme" "minimal") (:authors ("Anler Hp ")) (:maintainer "Anler Hp ") (:url . "http://github.com/ikame/minimal-theme"))]) (moe-theme . [(20180617 200) nil "A colorful eye-candy theme. Moe, moe, kyun!" tar ((:commit . "6e086d855d6bb446bbd1090742815589a81a915f") (:url . "https://github.com/kuanyui/moe-theme.el"))]) (molokai-theme . [(20151016 1545) nil "molokai theme with Emacs theme engine" single ((:commit . "04a44f21184b6a26caae4f2c92db9019d883309c") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/alloy-d/color-theme-molokai"))]) (monokai-theme . [(20190801 1701) nil "A fruity color theme for Emacs." single ((:commit . "e407f51d34b0c30cfe9d815f80a0c3539b998b08") (:authors ("Kelvin Smith" . "oneKelvinSmith@gmail.com")) (:maintainer "Kelvin Smith" . "oneKelvinSmith@gmail.com") (:url . "http://github.com/oneKelvinSmith/monokai-emacs"))]) (monochrome-theme . [(20140326 1050) nil "A dark Emacs 24 theme for your focused hacking sessions" tar ((:commit . "bfca67fe7365310bc47ae9ca96c417caada54896") (:authors ("Xavier Noria" . "fxn@hashref.com")) (:maintainer "Xavier Noria" . "fxn@hashref.com"))]) (mustang-theme . [(20170719 946) nil "port of vim's mustang theme" single ((:commit . "dda6d04803f1c9b196b620ef564e7768fee15de2") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/mustang-theme"))]) (naquadah-theme . [(20190225 1427) nil "A theme based on Tango color set" single ((:commit . "430c3b7bd51922cb616b3f60301f4e2604816ed8"))]) (noctilux-theme . [(20161113 1442) ((emacs (24))) "Dark theme inspired by LightTable" single ((:commit . "a3265a1be7f4d73f44acce6d968ca6f7add1f2ca") (:authors ("Simon Manning" . "simon@ecksdee.org")) (:maintainer "Simon Manning" . "simon@ecksdee.org") (:url . "https://github.com/sjrmanning/noctilux-theme"))]) (obsidian-theme . [(20170719 948) nil "port of the eclipse obsidian theme" single ((:commit . "f45efb2ebe9942466c1db6abbe2d0e6847b785ea") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/obsidian-theme"))]) (occidental-theme . [(20130312 1958) nil "Custom theme for faces based on Adwaita" single ((:commit . "fd2db7256d4f78c43d99c3cddb1c39106d479816") (:authors ("William Stevenson" . "yhvh2000@gmail.com") ("Erik Timan" . "dev@timan.info")) (:maintainer "William Stevenson" . "yhvh2000@gmail.com") (:url . "http://github.com/olcai/occidental-theme"))]) (omtose-phellack-theme . [(20161111 2120) nil "A dark theme, with cold bluish touch." tar ((:commit . "66f99633e199e65bd28641626435e8e59246529a"))]) (oldlace-theme . [(20150705 1300) ((emacs (24))) "Emacs 24 theme with an 'oldlace' background." single ((:commit . "5c6f437203b0783b36a7aff4a578de4a0c8c4ee6") (:authors ("martin haesler")) (:maintainer "martin haesler"))]) (organic-green-theme . [(20180522 1620) nil "Low-contrast green color theme." single ((:commit . "200ac4a636eeb6faf1793d1937e62a343debc437"))]) (phoenix-dark-mono-theme . [(20170729 1406) nil "Monochromatic version of the Phoenix theme" single ((:commit . "a54f515d162148bcb38676980bc2316adb3d7b8b") (:authors ("J Irving" . "j@lollyshouse.ca")) (:maintainer "J Irving" . "j@lollyshouse.ca") (:url . "http://github.com/j0ni/phoenix-dark-mono"))]) (phoenix-dark-pink-theme . [(20190821 48) nil "Originally a port of the Sublime Text 2 theme" single ((:commit . "ddd98a45775be105984ec598384e68df3d3e8046") (:authors ("J Irving" . "j@lollyshouse.ca")) (:maintainer "J Irving" . "j@lollyshouse.ca") (:url . "http://github.com/j0ni/phoenix-dark-pink"))]) (planet-theme . [(20161031 217) ((emacs (24))) "A dark theme inspired by Gmail's 'Planets' theme of yore" single ((:commit . "b0a310ff36565fe22224c407cf59569986698a32") (:keywords "themes") (:authors ("Charlie McMackin" . "charlie.mac@gmail.com")) (:maintainer "Charlie McMackin" . "charlie.mac@gmail.com") (:url . "https://github.com/cmack/emacs-planet-theme"))]) (professional-theme . [(20150315 1100) nil "Emacs port of Vim's professional theme" single ((:commit . "0927d1474049a193f9f366bde5eb1887b9ba20ed") (:keywords "theme" "light" "professional") (:authors ("Juanjo Alvarez" . "juanjo@juanjoalvarez.net")) (:maintainer "Juanjo Alvarez" . "juanjo@juanjoalvarez.net") (:url . "https://github.com/juanjux/emacs-professional-theme"))]) (purple-haze-theme . [(20141015 229) ((emacs (24 0))) "an overtly purple color theme for Emacs24." single ((:commit . "3e245cbef7cd09e6b3ee124963e372a04e9a6485") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-purple-haze-theme"))]) (railscasts-theme . [(20150219 1525) nil "Railscasts color theme for GNU Emacs." single ((:commit . "1340c3f6c2717761cab95617cf8dcbd962b1095b") (:keywords "railscasts" "color" "theme") (:authors ("Oleg Shaldybin")) (:maintainer "Oleg Shaldybin") (:url . "https://github.com/mikenichols/railscasts-theme"))]) (rebecca-theme . [(20180324 821) ((emacs (24))) "Rebecca Purple Theme" single ((:commit . "9ac0c71c2858b76dc5499f62c7c7fb7f9e8f16bc") (:keywords "theme" "dark") (:authors ("vic" . "vborja@apache.org")) (:maintainer "vic" . "vborja@apache.org") (:url . "https://github.com/vic/rebecca-theme"))]) (reverse-theme . [(20141205 145) nil "Reverse theme for Emacs" single ((:commit . "8319d0d5342890a3530ffa4daafdb7c35feda1ca") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-reverse-theme"))]) (seti-theme . [(20190201 1848) nil "A dark colored theme, inspired by Seti Atom Theme" single ((:commit . "9d76db0b91d4f574dd96ac80fad41da35bffa109") (:keywords "themes") (:authors ("Vlad Piersec" . "vlad.piersec@gmail.com")) (:maintainer "Vlad Piersec" . "vlad.piersec@gmail.com") (:url . "https://github.com/caisah/seti-theme"))]) (smyx-theme . [(20141127 828) nil "smyx Color Theme" single ((:commit . "6263f6b401bbabaed388c8efcfc0be2e58c51401") (:keywords "color" "theme" "smyx") (:authors ("Uriel G Maldonado" . "uriel781@gmail.com")) (:maintainer "Uriel G Maldonado" . "uriel781@gmail.com"))]) (soft-charcoal-theme . [(20140420 1643) nil "Dark charcoal theme with soft colors" single ((:commit . "5607ab977fae6638e78b1495e02da8955c9ba19f") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-charcoal-theme"))]) (soft-morning-theme . [(20150918 2041) nil "Emacs24 theme with a light background." single ((:commit . "c0f9c70c97ef2be2a093cf839c4bfe27740a111c") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-morning-theme"))]) (soft-stone-theme . [(20140614 835) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "fb475514cfb02cf30ce358a61c48e46614344d48") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-stone-theme"))]) (solarized-theme . [(20190809 1202) ((emacs (24 1)) (cl-lib (0 5)) (dash (2 6 0))) "The Solarized color theme, ported to Emacs." tar ((:commit . "55cd77b61b6968048c61e13358ba487d217f24c0"))]) (soothe-theme . [(20141027 1441) ((emacs (24 1))) "a dark colorful theme for Emacs24." single ((:commit . "0786fe70c6c1b4ddcfb932fdc6862b9611cfc09b") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-soothe-theme"))]) (spacegray-theme . [(20150719 1931) ((emacs (24 1))) "A Hyperminimal UI Theme" single ((:commit . "7f70ee36297e5ccf9bc90b1f81472024f5a7a749") (:keywords "themes") (:authors ("Bruce Williams" . "brwcodes@gmail.com")) (:maintainer "Bruce Williams" . "brwcodes@gmail.com") (:url . "http://github.com/bruce/emacs-spacegray-theme"))]) (subatomic-theme . [(20190607 1022) nil "Low contrast bluish color theme" single ((:commit . "a13cdac97a6d0488b13bc36d4c2f4d4102ff6a31") (:keywords "color-theme" "blue" "low contrast") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:url . "https://github.com/cryon/subatomic"))]) (subatomic256-theme . [(20130621 210) nil "Fork of subatomic-theme for terminals." single ((:commit . "326177d6f99cd2b1d30df695e67ee3bc441cd96f") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:url . "https://github.com/cryon/subatomic256"))]) (sublime-themes . [(20170606 1844) nil "A collection of themes based on Sublime Text" tar ((:commit . "60ee40af82eb55b79d5ed4026f1911326311603f") (:keywords "faces") (:authors ("Owain Lewis" . "owain@owainlewis.com")) (:maintainer "Owain Lewis" . "owain@owainlewis.com"))]) (sunny-day-theme . [(20140413 2125) nil "Emacs24 theme with a light background." single ((:commit . "420e0a6eb33fcc9b75c2c9e88ab60a975d782a00") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/sunny-day-theme"))]) (tango-2-theme . [(20120312 2025) nil "Tango 2 color theme for GNU Emacs 24" single ((:commit . "64e44c98e41ebbe3b827d54280e3b9615787daaa") (:authors ("Nick Parker")) (:maintainer "Nick Parker"))]) (tango-plus-theme . [(20170214 1708) nil "A color theme based on the tango palette" single ((:commit . "8ba8901397e3e9f1d53110487bfa0effc65015e7") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/tmalsburg/tango-plus-theme"))]) (tangotango-theme . [(20170924 1509) nil "Tango Palette color theme for Emacs 24." single ((:commit . "e2f2ea9c35f06dfc43a29c91c14cf0cdb19f2144") (:keywords "tango" "palette" "color" "theme" "emacs") (:authors ("Julien Barnier")) (:maintainer "Julien Barnier") (:url . "https://github.com/juba/color-theme-tangotango"))]) (tao-theme . [(20190204 1104) nil "This package provides two parametrized uncoloured color themes for Emacs: tao-yin and tao-yang." tar ((:commit . "c5107fbe7e752f4e58c2d2147ff18a1ebb12937c"))]) (toxi-theme . [(20160424 2126) ((emacs (24))) "A dark color theme by toxi" single ((:commit . "b322fc7497a53f102e74f7994da96f2974171c9b") (:authors ("Karsten Schmidt" . "info@postspectacular.com")) (:maintainer "Karsten Schmidt" . "info@postspectacular.com") (:url . "http://bitbucket.org/postspectacular/toxi-theme/"))]) (twilight-anti-bright-theme . [(20160622 848) nil "A soothing Emacs 24 light-on-dark theme" single ((:commit . "523b95fcdbf4a6a6483af314ad05354a3d80f23f") (:keywords "themes") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:url . "https://github.com/jimeh/twilight-anti-bright-theme.el"))]) (twilight-bright-theme . [(20130605 843) nil "A Emacs 24 faces port of the TextMate theme" single ((:commit . "322157cb2f3bf7920ecd209dafc31bc1c7959f49") (:keywords "themes") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:url . "https://github.com/jimeh/twilight-bright-theme.el"))]) (twilight-theme . [(20120412 1303) nil "Twilight theme for GNU Emacs 24 (deftheme)" single ((:commit . "77c4741cb3dcf16e53d06d6c2ffdc660c40afb5b") (:authors ("Nick Parker" . "nickp@developernotes.com")) (:maintainer "Nick Parker" . "nickp@developernotes.com"))]) (ujelly-theme . [(20180214 1624) nil "Ujelly theme for GNU Emacs 24 (deftheme)" single ((:commit . "bf724ce7806a738d2043544061e5f9bbfc56e674") (:authors ("Mark Tran" . "mark.tran@gmail.com")) (:maintainer "Mark Tran" . "mark.tran@gmail.com") (:url . "http://github.com/marktran/color-theme-ujelly"))]) (underwater-theme . [(20131118 2) nil "A gentle, deep blue color theme" single ((:commit . "4eb9ef014f580adc135d91d1cd68d37a310640b6") (:keywords "faces") (:authors ("Jon-Michael Deldin" . "dev@jmdeldin.com")) (:maintainer "Jon-Michael Deldin" . "dev@jmdeldin.com"))]) (white-sand-theme . [(20151117 1648) ((emacs (24))) "Emacs theme with a light background." single ((:commit . "97621edd69267dd143760d94393db2c2558c9ea4") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))]) (zen-and-art-theme . [(20120622 1437) nil "zen and art color theme for GNU Emacs 24" single ((:commit . "a7226cbce0bca2501d69a620cb2aeabfc396c232") (:authors ("Nick Parker")) (:maintainer "Nick Parker"))]) (zenburn-theme . [(20190809 1324) nil "A low contrast color theme for Emacs." single ((:commit . "4db36d32207613340dfc6a48fcf8e57a60d97ba3") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "http://github.com/bbatsov/zenburn-emacs"))]) (nyan-mode . [(20170423 740) nil "Nyan Cat shows position in current buffer in mode-line." tar ((:commit . "a85ac925367ddc542827182a2d9f0133b421c41b") (:keywords "nyan" "cat" "lulz" "scrolling" "pop tart cat" "build something amazing") (:authors ("Jacek \"TeMPOraL\" Zlydach" . "temporal.pl@gmail.com")) (:maintainer "Jacek \"TeMPOraL\" Zlydach" . "temporal.pl@gmail.com") (:url . "https://github.com/TeMPOraL/nyan-mode/"))]) (color-identifiers-mode . [(20190805 1455) ((dash (2 5 0)) (emacs (24))) "Color identifiers based on their names" single ((:commit . "58fc8706a8f44e8df4678eec8ce15636fd4db758") (:keywords "faces" "languages") (:authors ("Ankur Dave" . "ankurdave@gmail.com")) (:maintainer "Ankur Dave" . "ankurdave@gmail.com") (:url . "https://github.com/ankurdave/color-identifiers-mode"))]) (rainbow-identifiers . [(20141102 1526) ((emacs (24))) "Highlight identifiers according to their names" single ((:commit . "19fbfded1baa98d12335f26f6d7b20e5ae44ce2e") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/rainbow-identifiers"))]) (rainbow-mode . [(1 0 1) nil "Colorize color names in buffers" single ((:url . "http://elpa.gnu.org/packages/rainbow-mode.html") (:keywords "faces") (:authors ("Julien Danjou" . "julien@danjou.info")) (:maintainer "Julien Danjou" . "julien@danjou.info"))]) (ucs-utils . [(20150826 1414) ((persistent-soft (0 8 8)) (pcache (0 2 3)) (list-utils (0 4 2))) "Utilities for Unicode characters" tar ((:commit . "cbfd42f822bf5717934fa2d92060e6e24a813433") (:keywords "i18n" "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/ucs-utils"))]) (font-utils . [(20150806 1751) ((persistent-soft (0 8 8)) (pcache (0 2 3))) "Utility functions for working with fonts" single ((:commit . "9192d3f8ee6a4e75f34c3fed10378674cc2b11d3") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/font-utils"))]) (unicode-fonts . [(20181001 1509) ((font-utils (0 7 8)) (ucs-utils (0 8 2)) (list-utils (0 4 2)) (persistent-soft (0 8 10)) (pcache (0 3 1))) "Configure Unicode fonts" single ((:commit . "7b88ae84e589f6c8b9386b2fb5a02ff4ccb91169") (:keywords "i18n" "faces" "frames" "wp" "interface") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/unicode-fonts"))]) (list-utils . [(20160414 1402) nil "List-manipulation utility functions" single ((:commit . "acf18aca1131a90f8d673974673e3c5d8fdc6a86") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/list-utils"))]) (pcache . [(20170105 2214) ((eieio (1 3))) "persistent caching for Emacs." single ((:commit . "1f8086077d770e524492e6fa59b07856e85a6fea") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com"))]) (persistent-soft . [(20150223 1853) ((pcache (0 3 1)) (list-utils (0 4 2))) "Persistent storage, returning nil on failure" single ((:commit . "a1e0ddf2a12a6f18cab565dee250f070384cbe02") (:keywords "data" "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/persistent-soft"))]) (mu4e-alert . [(20190418 558) ((alert (1 2)) (s (1 10 0)) (ht (2 0)) (emacs (24 3))) "Desktop notification for mu4e" single ((:commit . "91f0657c5b245a9de57aa38391221fb5d141d9bd") (:keywords "mail" "convenience") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:url . "https://github.com/iqbalansari/mu4e-alert"))]) (mu4e-maildirs-extension . [(20180606 812) ((dash (0 0 0))) "Show mu4e maildirs summary in mu4e-main-view" single ((:commit . "3ef4c48516be66e73d24fe764aadbcfc126b7964") (:authors ("Andreu Gil Pàmies" . "agpchil@gmail.com")) (:maintainer "Andreu Gil Pàmies" . "agpchil@gmail.com") (:url . "http://github.com/agpchil/mu4e-maildirs-extension"))]) (helm-mu . [(20190819 1311) ((helm (1 5 5))) "Helm sources for searching emails and contacts" single ((:commit . "481964fb26c59ea280a1ec7bce192d724ddf7d12") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/emacs-helm/helm-mu"))]) (persp-mode . [(20190511 1402) nil "windows/buffers sets shared among frames + save/load." single ((:commit . "e330e6240bbb82589077f30472b05b95d1ff430d") (:keywords "perspectives" "session" "workspace" "persistence" "windows" "buffers" "convenience") (:authors ("Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com")) (:maintainer "Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com") (:url . "https://github.com/Bad-ptr/persp-mode.el"))]) (counsel-notmuch . [(20181203 935) ((emacs (24)) (ivy (0 10 0)) (notmuch (0 21)) (s (1 12 0))) "Search emails in Notmuch asynchronously with Ivy" single ((:commit . "a4a1562935e4180c42524c51609d1283e9be0688") (:keywords "mail") (:authors ("Alexander Fu Xi" . "fuxialexander@gmail.com")) (:maintainer "Alexander Fu Xi" . "fuxialexander@gmail.com") (:url . "https://github.com/fuxialexander/counsel-notmuch"))]) (helm-notmuch . [(20190320 1048) ((helm (1 9 3)) (notmuch (0 21))) "Search emails with Notmuch and Helm" single ((:commit . "97a01497e079a7b6505987e9feba6b603bbec288") (:keywords "mail") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/emacs-helm/helm-notmuch"))]) (notmuch . [(20190525 1602) nil "run notmuch within emacs" tar ((:commit . "17806ecc955ce0375146ea1df51eae061a72bef8") (:url . "https://notmuchmail.org/"))]) (company-terraform . [(20190607 1037) ((emacs (24 4)) (company (0 8 12)) (terraform-mode (0 6))) "A company backend for terraform" tar ((:commit . "2d11a21fee2f298e48968e479ddcaeda4d736e12") (:keywords "abbrev" "convenience" "terraform" "company") (:authors ("RafaÅ‚ CieÅ›lak" . "rafalcieslak256@gmail.com")) (:maintainer "RafaÅ‚ CieÅ›lak" . "rafalcieslak256@gmail.com") (:url . "https://github.com/rafalcieslak/emacs-company-terraform"))]) (hcl-mode . [(20170107 827) ((emacs (24 3))) "Major mode for Hashicorp" single ((:commit . "0f2c5ec7e7bcf77c8548e8cac8721ea935ca1b5e") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-hcl-mode"))]) (terraform-mode . [(20170112 517) ((emacs (24 3)) (hcl-mode (0 3))) "Major mode for terraform configuration file" single ((:commit . "6973d1acaba2835dfdf174f5a5e27de6366002e1") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-terraform-mode"))]) (sailfish-scratchbox . [(20171202 1332) nil "Sailfish OS scratchbox inside the emacs." single ((:commit . "bb5ed0f0b0cd72f2eb1af065b7587ec81866b089") (:keywords "sb2" "mb2" "building" "scratchbox" "sailfish") (:authors ("V. V. Polevoy" . "fx@thefx.co")) (:maintainer "V. V. Polevoy" . "fx@thefx.co") (:url . "https://github.com/vityafx/sailfish-scratchbox.el"))]) (ranger . [(20190412 624) ((emacs (24 4))) "Make dired more like ranger" single ((:commit . "c3f349e52f5c50926dc0f285c97676934f50bc18") (:keywords "files" "convenience" "dired") (:authors ("Rich Alesi ")) (:maintainer "Rich Alesi ") (:url . "https://github.com/ralesi/ranger"))]) (pandoc-mode . [(20190711 2122) ((hydra (0 10 0)) (dash (2 10 0))) "Minor mode for interacting with Pandoc" tar ((:commit . "7b9a19d8777a21431a819281a14201bfdf1dfdc1") (:keywords "text" "pandoc") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (ox-pandoc . [(20180510 1338) ((org (8 2)) (emacs (24)) (dash (2 8)) (ht (2 0)) (cl-lib (0 5))) "org exporter for pandoc." single ((:commit . "aa37dc7e94213d4ebedb85c384c1ba35007da18e") (:keywords "tools") (:authors ("KAWABATA, Taichi" . "kawabata.taichi@gmail.com")) (:maintainer "KAWABATA, Taichi" . "kawabata.taichi@gmail.com") (:url . "https://github.com/kawabata/ox-pandoc"))]) (json-mode . [(20190123 422) ((json-reformat (0 0 5)) (json-snatcher (1 0 0))) "Major mode for editing JSON files." single ((:commit . "0e819e519ae17a2686e0881c4ca51fa873fa9b83") (:authors ("Josh Johnston")) (:maintainer "Josh Johnston") (:url . "https://github.com/joshwnj/json-mode"))]) (magit-popup . [(20190223 2234) ((emacs (24 4)) (async (1 9 2)) (dash (2 13 0))) "Define prefix-infix-suffix command combos" tar ((:commit . "4250c3a606011e3ff2477e3b5bbde2b493f3c85c") (:keywords "bindings") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/magit-popup"))]) (json-snatcher . [(20150512 347) ((emacs (24))) "Grabs the path to JSON values in a JSON file" single ((:commit . "c4cecc0a5051bd364373aa499c47a1bb7a5ac51c") (:authors ("Sterling Graham" . "sterlingrgraham@gmail.com")) (:maintainer "Sterling Graham" . "sterlingrgraham@gmail.com") (:url . "http://github.com/sterlingg/json-snatcher"))]) (json-reformat . [(20160212 853) nil "Reformatting tool for JSON" single ((:commit . "8eb6668ed447988aea06467ba8f42e1f2178246f") (:keywords "json") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:url . "https://github.com/gongo/json-reformat"))]) (docker . [(20190813 1431) ((emacs (24 5)) (dash (2 14 1)) (docker-tramp (0 1)) (magit-popup (2 12 4)) (s (1 12 0)) (tablist (0 70)) (json-mode (1 7 0))) "Emacs interface to Docker" tar ((:commit . "fe74a499ce3246fb9a7d72e6931864b94ce5261d") (:keywords "filename" "convenience") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:url . "https://github.com/Silex/docker.el"))]) (docker-tramp . [(20170207 325) ((emacs (24)) (cl-lib (0 5))) "TRAMP integration for docker containers" tar ((:commit . "8e2b671eff7a81af43b76d9dfcf94ddaa8333a23") (:keywords "docker" "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/docker-tramp.el"))]) (dockerfile-mode . [(20190505 1807) ((emacs (24)) (s (1 12))) "Major mode for editing Docker's Dockerfiles" single ((:commit . "ed73e82dcc636dad00d1a8c3b32a49136d25ee60") (:url . "https://github.com/spotify/dockerfile-mode"))]) (ycmd . [(20190416 807) ((emacs (24 4)) (dash (2 13 0)) (s (1 11 0)) (deferred (0 5 1)) (cl-lib (0 6 1)) (let-alist (1 0 5)) (request (0 3 0)) (request-deferred (0 3 0)) (pkg-info (0 6))) "emacs bindings to the ycmd completion server" tar ((:commit . "6f4f7384b82203cccf208e3ec09252eb079439f9") (:url . "https://github.com/abingham/emacs-ycmd"))]) (flycheck-ycmd . [(20181016 618) ((emacs (24)) (dash (2 13 0)) (flycheck (0 22)) (ycmd (1 2)) (let-alist (1 0 5))) "flycheck integration for ycmd" single ((:commit . "6f4f7384b82203cccf208e3ec09252eb079439f9") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/emacs-ycmd"))]) (cliphist . [(20181229 1411) ((emacs (24 3)) (ivy (0 9 0))) "Read data from clipboard managers at Linux and Mac" tar ((:commit . "232ab0b3f6d502de61ebe76681a6a04d4223b877") (:keywords "clipboard" "manager" "history") (:authors ("Chen Bin ")) (:maintainer "Chen Bin ") (:url . "http://github.com/redguardtoo/cliphist"))]) (levenshtein . [(20090830 1040) nil "Edit distance between two strings." single ((:commit . "070925197ebf6b704e6e00c4f2d2ec783f3df38c") (:keywords "lisp") (:authors ("Aaron S. Hawley ,") ("Art Taylor")) (:maintainer "Aaron S. Hawley ,"))]) (cmake-ide . [(20190731 1009) ((emacs (24 4)) (cl-lib (0 5)) (seq (1 11)) (levenshtein (0)) (s (1 11 0))) "Calls CMake to find out include paths and other compiler flags" single ((:commit . "e3aa1ded10c079337826b40586111df7114f6379") (:keywords "languages") (:authors ("Atila Neves" . "atila.neves@gmail.com")) (:maintainer "Atila Neves" . "atila.neves@gmail.com") (:url . "http://github.com/atilaneves/cmake-ide"))]) (cmake-mode . [(20190710 1319) ((emacs (24 1))) "major-mode for editing CMake sources" single ((:commit . "a04b852a7b1c8590ad35db5d09c99e73ebd5e464"))]) (helm-ctest . [(20180821 1005) ((s (1 9 0)) (dash (2 11 0)) (helm-core (1 7 4))) "Run ctest from within emacs" single ((:commit . "0c73689692a290f56080e95325c15362e90d529b") (:keywords "helm" "ctest") (:authors ("Dan LaManna" . "me@danlamanna.com")) (:maintainer "Dan LaManna" . "me@danlamanna.com"))]) (bm . [(20190807 1217) nil "Visible bookmarks in buffer." tar ((:commit . "8129428182e1b8a647d16fceb2d08cc0a2a5f3c7") (:keywords "bookmark" "highlight" "faces" "persistent") (:authors ("Jo Odland ")) (:maintainer "Jo Odland ") (:url . "https://github.com/joodland/bm"))]) (ivy-pass . [(20170812 1955) ((emacs (24)) (ivy (0 8 0)) (password-store (1 6 5))) "ivy interface for pass" single ((:commit . "5b523de1151f2109fdd6a8114d0af12eef83d3c5") (:keywords "pass" "password" "convenience" "data") (:authors ("ecraven")) (:maintainer "ecraven") (:url . "https://github.com/ecraven/ivy-pass/"))]) (auth-source-pass . [(20190813 1026) ((emacs (25))) "Integrate auth-source with password-store" single ((:commit . "847a1f54ed48856b4dfaaa184583ef2c84173edf") (:authors ("Damien Cassou" . "damien@cassou.me") ("Nicolas Petton" . "nicolas@petton.fr") ("Keith Amidon" . "camalot@picnicpark.org")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/auth-password-store"))]) (helm-pass . [(20190315 1335) ((emacs (25)) (helm (0)) (password-store (0)) (auth-source-pass (4 0 0))) "helm interface of pass, the standard Unix password manager" single ((:commit . "ed5798f2d83937575e8f23fde33323bca9e85131") (:authors ("J. Alexander Branham" . "branham@utexas.edu")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://github.com/emacs-helm/helm-pass"))]) (with-editor . [(20190715 2007) ((emacs (24 4)) (async (1 9))) "Use the Emacsclient as $EDITOR" tar ((:commit . "45c29f9bfb7f2df93426ce1571e2f4f41ed4e492") (:keywords "tools") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/with-editor"))]) (password-store . [(20190804 2004) ((emacs (25)) (f (0 11 0)) (s (1 9 0)) (with-editor (2 5 11))) "Password store (pass) support" single ((:commit . "e93e03705fb5b81f3af85f04c07ad0ee2190b6aa") (:keywords "tools" "pass" "password" "password-store") (:authors ("Svend Sorensen" . "svend@svends.net")) (:maintainer "Svend Sorensen" . "svend@svends.net") (:url . "https://www.passwordstore.org/"))]) (esh-help . [(20170830 411) ((dash (1 4 0))) "Add some help functions and support for Eshell" single ((:commit . "8a8a9d4d9852f8bd96da3b94e95ff57097ac8ec6") (:keywords "eshell" "extensions") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/esh-help/"))]) (eshell-prompt-extras . [(20181229 1418) nil "Display extra information for your eshell prompt." single ((:commit . "5a328e1b9112c7f31ce2da7cde340f96626546b6") (:keywords "eshell" "prompt") (:authors ("zwild" . "judezhao@outlook.com")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/zwild/eshell-prompt-extras"))]) (eshell-z . [(20170117 438) ((cl-lib (0 5))) "cd to frequent directory in eshell" single ((:commit . "c9334cbc1552234df3437f35d98e32f4d18446b8") (:keywords "convenience") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/eshell-z"))]) (multi-term . [(20190624 1147) nil "Managing multiple terminal buffers in Emacs." single ((:commit . "0804b11e52b960c80f5cd0712ee1e53ae70d83a4") (:keywords "term" "terminal" "multiple buffer") (:authors ("Andy Stewart" . "lazycat.manatee@gmail.com")) (:maintainer "Andy Stewart" . "lazycat.manatee@gmail.com") (:url . "http://www.emacswiki.org/emacs/download/multi-term.el"))]) (shell-pop . [(20170304 1416) ((emacs (24)) (cl-lib (0 5))) "helps you to use shell easily on Emacs. Only one key action to work." single ((:commit . "4a3a9d093ad1add792bba764c601aa28de302b34") (:keywords "shell" "terminal" "tools") (:authors ("Kazuo YAGI" . "kazuo.yagi@gmail.com")) (:maintainer "Kazuo YAGI" . "kazuo.yagi@gmail.com") (:url . "http://github.com/kyagi/shell-pop-el"))]) (xterm-color . [(20190816 941) ((cl-lib (0 5))) "ANSI & XTERM 256 color support" single ((:commit . "44e6df835bd4173ee4ccc7e29842e9dae76f2668") (:keywords "faces") (:authors ("xristos" . "xristos@sdf.lonestar.org")) (:maintainer "xristos" . "xristos@sdf.lonestar.org") (:url . "https://github.com/atomontage/xterm-color"))]) (vagrant . [(20170301 2206) nil "Manage a vagrant box from emacs" single ((:commit . "636ce2f9af32ea199170335a9cf1201b64873440") (:keywords "vagrant" "chef") (:authors ("Robert Crim" . "rob@servermilk.com")) (:maintainer "Robert Crim" . "rob@servermilk.com") (:url . "https://github.com/ottbot/vagrant.el"))]) (vagrant-tramp . [(20190816 1846) ((dash (2 12 0))) "Vagrant method for TRAMP" tar ((:commit . "47c6fdc07722934eacce9f91c47bb1ee7d46b86f") (:keywords "vagrant") (:authors ("Doug MacEachern" . "dougm@vmware.com") ("Ryan Prior " . "ryanprior@gmail.com")) (:maintainer "Doug MacEachern" . "dougm@vmware.com") (:url . "https://github.com/dougm/vagrant-tramp"))]) (systemd . [(20180629 2106) ((emacs (24 4))) "Major mode for editing systemd units" tar ((:commit . "401d71c2dd24e424216ae5e4275c830f2a9c6b0c") (:keywords "tools" "unix") (:authors ("Mark Oteiza" . "mvoteiza@udel.edu")) (:maintainer "Mark Oteiza" . "mvoteiza@udel.edu"))]) (lsp-ui . [(20190809 1907) ((emacs (25 1)) (dash (2 14)) (dash-functional (1 2 0)) (lsp-mode (6 0)) (markdown-mode (2 3))) "UI modules for lsp-mode" tar ((:commit . "1cfff2135ffbf7ac52d9c2ece3f2bd157ac51167") (:keywords "lsp") (:authors ("Sebastien Chapuis , Fangrui Song" . "i@maskray.me")) (:maintainer "Sebastien Chapuis , Fangrui Song" . "i@maskray.me") (:url . "https://github.com/emacs-lsp/lsp-ui"))]) (helm-lsp . [(20190423 548) ((emacs (25 1)) (dash (2 14 1)) (lsp-mode (5 0)) (helm (2 0))) "LSP helm integration" single ((:commit . "3a58ca4cfd94b9ab1e15e819d3b16ef568e8889b") (:keywords "languages" "debug") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:url . "https://github.com/yyoncho/helm-lsp"))]) (lsp-treemacs . [(20190817 1904) ((emacs (25 1)) (dash (2 14 1)) (dash-functional (2 14 1)) (f (0 20 0)) (ht (2 0)) (treemacs (2 5)) (lsp-mode (6 0))) "LSP treemacs" tar ((:commit . "a64fabbc7566a9043ac8a66006f61ff906cbcff5") (:keywords "languages") (:authors ("Ivan Yonchovski")) (:maintainer "Ivan Yonchovski") (:url . "https://github.com/emacs-lsp/lsp-treemacs"))]) (dotnet . [(20190415 1237) nil "Interact with dotnet CLI tool" single ((:commit . "932d776ed739d20d57dbd6ba49f61d1b450571fc") (:keywords ".net" "tools") (:authors ("Julien BLANCHARD" . "julien@sideburns.eu")) (:maintainer "Julien BLANCHARD" . "julien@sideburns.eu") (:url . "https://github.com/julienXX/dotnet.el"))]) (ansible . [(20190619 1255) ((s (1 9 0)) (f (0 16 2))) "Ansible minor mode" tar ((:commit . "2d35aa1280ace3cae404ea9e1231a8b26c7b9eb4") (:authors ("k1LoW (Kenichirou Oyama), ")) (:maintainer "k1LoW (Kenichirou Oyama), ") (:url . "http://101000lab.org"))]) (ansible-doc . [(20160924 824) ((emacs (24 3))) "Ansible documentation Minor Mode" single ((:commit . "86083a7bb2ed0468ca64e52076b06441a2f8e9e0") (:keywords "tools" "help") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn") (:url . "https://github.com/lunaryorn/ansible-doc.el"))]) (company-ansible . [(20190301 2111) ((emacs (24 4)) (company (0 8 12))) "A company back-end for ansible" tar ((:commit . "c31efced8a9b461de5982ed94c234fda3df96f10") (:keywords "ansible") (:authors ("Krzysztof Magosa" . "krzysztof@magosa.pl")) (:maintainer "Krzysztof Magosa" . "krzysztof@magosa.pl") (:url . "https://github.com/krzysztof-magosa/company-ansible"))]) (jinja2-mode . [(20141128 1007) nil "A major mode for jinja2" single ((:commit . "cfaa7bbe7bb290cc500440124ce89686f3e26f86") (:authors ("Florian Mounier aka paradoxxxzero")) (:maintainer "Florian Mounier aka paradoxxxzero"))]) (mmm-jinja2 . [(20170313 1420) ((mmm-mode (0 5 4))) "MMM submode class for Jinja2 Templates" single ((:commit . "c8cb763174fa2fb61b9a0e5e0ff8cb0210f8492f") (:authors ("Ben Hayden" . "hayden767@gmail.com")) (:maintainer "Ben Hayden" . "hayden767@gmail.com") (:url . "https://github.com/glynnforrest/mmm-jinja2"))]) (yaml-mode . [(20190625 1740) ((emacs (24 1))) "Major mode for editing YAML files" single ((:commit . "5b4a0db384f996554454b5642e4531c502421de8") (:keywords "data" "yaml") (:authors ("Yoshiki Kurihara" . "clouder@gmail.com") ("Marshall T. Vandegrift" . "llasram@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com"))]) (mmm-mode . [(0 5 7) ((cl-lib (0 2))) "Allow Multiple Major Modes in a buffer" tar ((:url . "https://github.com/purcell/mmm-mode") (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:authors ("Michael Abraham Shulman" . "viritrilbia@gmail.com")) (:keywords "convenience" "faces" "languages" "tools"))]) (salt-mode . [(20181225 1157) ((emacs (24 4)) (yaml-mode (0 0 12)) (mmm-mode (0 5 4)) (mmm-jinja2 (0 1))) "Major mode for Salt States" single ((:commit . "5ed02dabe0c5c58f51959a48b559f7fc5425ea2c") (:keywords "languages") (:authors ("Ben Hayden" . "hayden767@gmail.com")) (:maintainer "Glynn Forrest" . "me@glynnforrest.com") (:url . "https://github.com/glynnforrest/salt-mode"))]) (nginx-mode . [(20170612 437) nil "major mode for editing nginx config files" single ((:commit . "a2bab83c2eb233d57d76b236e7c141c2ccc97005") (:keywords "languages" "nginx") (:authors ("Andrew J Cosgriff" . "andrew@cosgriff.name")) (:maintainer "Andrew J Cosgriff" . "andrew@cosgriff.name"))]) (command-log-mode . [(20160413 447) nil "log keyboard commands to buffer" single ((:commit . "af600e6b4129c8115f464af576505ea8e789db27") (:keywords "help") (:authors ("Michael Weber" . "michaelw@foldr.org")) (:maintainer "Michael Weber" . "michaelw@foldr.org") (:url . "https://github.com/lewang/command-log-mode"))]) (rebox2 . [(20121113 1300) nil "Handling of comment boxes in various styles." single ((:commit . "00634eca420cc48657b81e40e599ff8548083985") (:authors ("François Pinard") ("Le Wang")) (:maintainer "Le Wang (lewang.emacs!!!gmayo.com remove exclamations, correct host, hint: google mail)") (:url . "https://github.com/lewang/rebox2"))]) (edit-server . [(20181016 1125) nil "server that responds to edit requests from Chrome" single ((:commit . "af46de40e2991b046f04856c18a6483badce38aa") (:authors ("Alex Bennée" . "alex@bennee.com")) (:maintainer "Alex Bennée" . "alex@bennee.com") (:url . "https://github.com/stsquad/emacs_chrome"))]) (ham-mode . [(20150811 1306) ((html-to-markdown (1 2)) (markdown-mode (2 0))) "Html As Markdown. Transparently edit an html file using markdown" single ((:commit . "3a141986a21c2aa6eefb428983352abb8b7907d2") (:keywords "convenience" "emulation" "wp") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/ham-mode"))]) (html-to-markdown . [(20151105 840) ((cl-lib (0 5))) "HTML to Markdown converter written in Emacs-lisp." single ((:commit . "60c5498c801be186478cf7c05be05b4430c4a144") (:keywords "tools" "wp" "languages") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/html-to-markdown"))]) (gmail-message-mode . [(20160627 1847) ((ham-mode (1 0))) "A major-mode for editing gmail messages using markdown syntax." single ((:commit . "ec36672a9dc93c09ebe2f77597b498d11883d008") (:keywords "mail" "convenience" "emulation") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/gmail-message-mode"))]) (flymd . [(20160617 1214) ((cl-lib (0 5))) "On the fly markdown preview" tar ((:commit . "84d5a68bcfed4a295952c33ffcd11e880978d9d7") (:keywords "markdown" "convenience") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:url . "https://github.com/mola-T/flymd"))]) (osx-location . [(20150613 917) nil "Watch and respond to changes in geographical location on OS X" tar ((:commit . "8bb3a94cc9f04b922d2d730fe08596cc6ee12bf2"))]) (rase . [(20120928 2045) nil "Run At Sun Event daemon" single ((:commit . "59b5f7e8102570b65040e8d55781c7ea28de7338") (:keywords "solar" "sunrise" "sunset" "midday" "midnight") (:authors ("Andrey Kotlarski" . "m00naticus@gmail.com")) (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:url . "https://github.com/m00natic/rase/"))]) (sunshine . [(20181029 1654) ((cl-lib (0 5))) "Provide weather and forecast information." single ((:commit . "8959dea03377e61aaca0124ac8d2703daaae6b9a") (:keywords "tools" "weather") (:authors ("Aaron Bieber" . "aaron@aaronbieber.com")) (:maintainer "Aaron Bieber" . "aaron@aaronbieber.com") (:url . "https://github.com/aaronbieber/sunshine.el"))]) (theme-changer . [(20171221 1927) nil "Sunrise/Sunset Theme Changer for Emacs" single ((:commit . "61945695a30d678e6a5d47cbe7c8aff59a8c30ea") (:keywords "color-theme" "deftheme" "solar" "sunrise" "sunset") (:authors ("Joshua B. Griffith" . "josh.griffith@gmail.com")) (:maintainer "Joshua B. Griffith" . "josh.griffith@gmail.com") (:url . "https://github.com/hadronzoo/theme-changer"))]) (transmission . [(20190211 246) ((emacs (24 4)) (let-alist (1 0 5))) "Interface to a Transmission session" single ((:commit . "7293beeb8a49cf6822abd16a9f4b9e4bef0a9296") (:keywords "comm" "tools") (:authors ("Mark Oteiza" . "mvoteiza@udel.edu")) (:maintainer "Mark Oteiza" . "mvoteiza@udel.edu"))]) (prodigy . [(20190714 1102) ((s (1 8 0)) (dash (2 4 0)) (f (0 14 0)) (emacs (24))) "Manage external services from within Emacs" single ((:commit . "0a12eec1f001a4eef16b2c0c524f02f2647a4ff1") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/prodigy.el"))]) (flycheck-ledger . [(20180819 321) ((flycheck (0 15))) "Flycheck integration for ledger files" single ((:commit . "8d7f52a4c7f80ca396ef0fc6c7d8e9f005778dfc") (:keywords "convenience" "languages" "tools") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (ledger-mode . [(20190811 2340) ((emacs (24 3))) "Helper code for use with the \"ledger\" command-line tool" tar ((:commit . "0114525803860b18a34624339825219bb6b8943e"))]) (evil-ledger . [(20180802 1612) ((emacs (24 4)) (evil (1 2 12)) (ledger-mode (0))) "Make `ledger-mode' more `evil'." single ((:commit . "7a9f9f5d39c42fffdba8004f8982642351f2b233") (:keywords "convenience" "evil" "languages" "ledger" "vim-emulation") (:authors ("Aaron Jacobs" . "atheriel@gmail.com")) (:maintainer "Aaron Jacobs" . "atheriel@gmail.com") (:url . "https://github.com/atheriel/evil-ledger"))]) (know-your-http-well . [(20160208 2304) nil "Look up the meaning of HTTP headers, methods, relations, status codes" tar ((:commit . "3cc5ab6d2764ab7aacb1b6e026abaccbeb6c37f2"))]) (company-restclient . [(20190426 1312) ((cl-lib (0 5)) (company (0 8 0)) (emacs (24)) (know-your-http-well (0 2 0)) (restclient (0 0 0))) "company-mode completion back-end for restclient-mode" single ((:commit . "e5a3ec54edb44776738c13e13e34c85b3085277b") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-restclient"))]) (ob-http . [(20180707 1448) ((s (1 9 0)) (cl-lib (0 5))) "http request in org-mode babel" tar ((:commit . "b1428ea2a63bcb510e7382a1bf5fe82b19c104a7") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-http"))]) (ob-restclient . [(20190626 1824) ((restclient (0))) "org-babel functions for restclient-mode" single ((:commit . "53376667eeddb1388fd6c6976f3222e7c8adcd46") (:keywords "literate programming" "reproducible research") (:authors ("Alf LervÃ¥g")) (:maintainer "Alf LervÃ¥g") (:url . "https://github.com/alf/ob-restclient.el"))]) (restclient . [(20190502 2214) nil "An interactive HTTP client for Emacs" single ((:commit . "422ee8d8b077dffe65706a0f027ed700b84746bc") (:keywords "http") (:authors ("Pavel Kurnosov" . "pashky@gmail.com")) (:maintainer "Pavel Kurnosov" . "pashky@gmail.com"))]) (restclient-helm . [(20170314 1554) ((restclient (0)) (helm (1 9 4))) "helm interface for restclient.el" single ((:commit . "422ee8d8b077dffe65706a0f027ed700b84746bc") (:keywords "http" "helm") (:authors ("Pavel Kurnosov" . "pashky@gmail.com")) (:maintainer "Pavel Kurnosov" . "pashky@gmail.com"))]) (ob-cfengine3 . [(20190520 1929) nil "Org Babel functions for CFEngine 3" single ((:commit . "4d4cd53ceaf8a756f48c02cb2e10476f3cda37c4") (:keywords "tools" "convenience") (:authors ("Nick Anderson" . "nick@cmdln.org")) (:maintainer "Nick Anderson" . "nick@cmdln.org") (:url . "https://github.com/nickanderson/ob-cfengine3"))]) (tern . [(20181108 722) ((json (1 2)) (cl-lib (0 5)) (emacs (24))) "Tern-powered JavaScript integration" single ((:commit . "9ddff4ca9bce7f46694b15c51799904ff41131b6") (:authors ("Marijn Haverbeke")) (:maintainer "Marijn Haverbeke") (:url . "http://ternjs.net/"))]) (company-tern . [(20161004 1847) ((company (0 8 0)) (tern (0 0 1)) (dash (2 8 0)) (dash-functional (2 8 0)) (s (1 9 0)) (cl-lib (0 5 0))) "Tern backend for company-mode" single ((:commit . "10ac058b065ae73c1f30e9fb7d969dd1a79387be") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/company-tern"))]) (bui . [(20181218 1830) ((emacs (24 3)) (dash (2 11 0))) "Buffer interface library" tar ((:commit . "508577a7225b3d07eaefa9444064410af2518675") (:keywords "tools") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/bui.el"))]) (tree-mode . [(20151104 1331) nil "A mode to manage tree widgets" single ((:commit . "b06078826d5875d74b0e7b7ac47b0d0917610534") (:keywords "help" "convenience" "widget") (:authors (nil . "wenbinye@163.com")) (:maintainer nil . "wenbinye@163.com"))]) (lsp-mode . [(20190821 848) ((emacs (25 1)) (dash (2 14 1)) (dash-functional (2 14 1)) (f (0 20 0)) (ht (2 0)) (spinner (1 7 3)) (markdown-mode (2 3))) "LSP mode" tar ((:commit . "91cf8d770ed222e2fc7f2c419ec45a24584887d7") (:keywords "languages") (:authors ("Vibhav Pant, Fangrui Song, Ivan Yonchovski")) (:maintainer "Vibhav Pant, Fangrui Song, Ivan Yonchovski") (:url . "https://github.com/emacs-lsp/lsp-mode"))]) (markdown-mode . [(20190802 2215) ((emacs (24 4)) (cl-lib (0 5))) "Major mode for Markdown-formatted text" single ((:commit . "f3c54e34cc5228001af36a5301883325319f21d4") (:keywords "markdown" "github flavored markdown" "itex") (:authors ("Jason R. Blevins" . "jblevins@xbeta.org")) (:maintainer "Jason R. Blevins" . "jblevins@xbeta.org") (:url . "https://jblevins.org/projects/markdown-mode/"))]) (dap-mode . [(20190819 902) ((emacs (25 1)) (dash (2 14 1)) (lsp-mode (6 0)) (dash-functional (1 2 0)) (tree-mode (1 1 1 1)) (bui (1 1 0)) (f (0 20 0)) (s (1 12 0))) "Debug Adapter Protocol mode" tar ((:commit . "7ce4df18c25decff70b48e42337c57994b97fb64") (:keywords "languages" "debug") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:url . "https://github.com/yyoncho/dap-mode"))]) (puppet-mode . [(20180813 1947) ((emacs (24 1)) (pkg-info (0 4))) "Major mode for Puppet manifests" single ((:commit . "7dee1b5a5debac6e56f9107492a413b6c0edb94d") (:keywords "languages") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com") ("Russ Allbery" . "rra@stanford.edu")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "https://github.com/voxpupuli/puppet-mode"))]) (fasd . [(20180606 505) nil "Emacs integration for the command-line productivity booster `fasd'" single ((:commit . "020c6a4b5fd1498a84ae142d2e32c7ff678fb029") (:keywords "cli" "bash" "zsh" "autojump") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:url . "https://framagit.org/steckerhalter/emacs-fasd"))]) (evil-tutor-ja . [(20160917 132) ((evil (1 0 9)) (evil-tutor (0 1))) "Japanese Vimtutor adapted to Evil and wrapped in a major-mode" tar ((:commit . "99af7d82e02ce3bcdfaff47c5c80b57327a7ea8d") (:keywords "convenience" "editing" "evil" "japanese") (:authors ("Kenji Miyazaki" . "kenjizmyzk@gmail.com")) (:maintainer "Kenji Miyazaki" . "kenjizmyzk@gmail.com") (:url . "https://github.com/kenjimyzk/evil-tutor-ja"))]) (migemo . [(20190112 516) ((cl-lib (0 5))) "Japanese incremental search through dynamic pattern expansion" single ((:commit . "f42832c8ac462ecbec9a16eb781194f876fba64a") (:authors ("Satoru Takabayashi" . "satoru-t@is.aist-nara.ac.jp")) (:maintainer "Satoru Takabayashi" . "satoru-t@is.aist-nara.ac.jp") (:url . "https://github.com/emacs-jp/migemo"))]) (avy-migemo . [(20180716 1455) ((emacs (24 4)) (avy (0 4 0)) (migemo (1 9))) "avy with migemo" tar ((:commit . "922a6dd82c0bfa316b0fbb56a9d4dd4ffa5707e7") (:keywords "avy" "migemo") (:authors ("momomo5717")) (:maintainer "momomo5717") (:url . "https://github.com/momomo5717/avy-migemo"))]) (cdb . [(20151205 1343) nil "constant database (cdb) reader for Emacs Lisp" single ((:commit . "ad61579af269291b4446f4bab0a58522cc454f1c") (:keywords "cdb") (:authors ("Yusuke Shinyama ")) (:maintainer "SKK Development Team" . "skk@ring.gr.jp"))]) (ccc . [(20151205 1343) nil "buffer local cursor color control library" single ((:commit . "ad61579af269291b4446f4bab0a58522cc454f1c") (:keywords "cursor") (:authors ("Masatake YAMATO" . "masata-y@is.aist-nara.ac.jp")) (:maintainer "SKK Development Team" . "skk@ring.gr.jp") (:url . "https://github.com/skk-dev/ddskk/blob/master/READMEs/README.ccc.org"))]) (ddskk . [(20190423 1234) ((ccc (1 43)) (cdb (20141201 754))) "Simple Kana to Kanji conversion program." tar ((:commit . "ad61579af269291b4446f4bab0a58522cc454f1c"))]) (japanese-holidays . [(20190317 1220) ((cl-lib (0 3))) "calendar functions for the Japanese calendar" single ((:commit . "45e70a6eaf4a555fadc58ab731d522a037a81997") (:keywords "calendar") (:authors ("Takashi Hattori" . "hattori@sfc.keio.ac.jp") ("Hiroya Murata" . "lapis-lazuli@pop06.odn.ne.jp")) (:maintainer "Takashi Hattori" . "hattori@sfc.keio.ac.jp") (:url . "https://github.com/emacs-jp/japanese-holidays"))]) (pangu-spacing . [(20190422 514) nil "Minor-mode to add space between Chinese and English characters." single ((:commit . "3a741c1b669c7194fb766b784c10d52a8de9b87f") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/pangu-spacing"))]) (pyim-basedict . [(20190719 1252) nil "The default pinyin dict of pyim" tar ((:commit . "d499104189a9462cb80f8efd9713e4064dc7093d") (:keywords "convenience" "chinese" "pinyin" "input-method" "complete") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/pyim-basedict"))]) (pyim . [(20190820 835) ((emacs (24 4)) (popup (0 1)) (async (1 6)) (pyim-basedict (0 1))) "A Chinese input method support quanpin, shuangpin, wubi and cangjie." tar ((:commit . "101413d54aa19713f15a5fa031c937df0714497d") (:keywords "convenience" "chinese" "pinyin" "input-method") (:authors ("Ye Wenbin , Feng Shu" . "tumashu@163.com")) (:maintainer "Ye Wenbin , Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/pyim"))]) (chinese-wbim . [(20190727 854) nil "Enable Wubi Input Method in Emacs." tar ((:commit . "5d496364b0b6bbaaf0f9b37e5a6d260d4994f260"))]) (fcitx . [(20190806 1923) nil "Make fcitx better in Emacs" single ((:commit . "12dc2638ddd15c8f6cfaecb20e1f428ab2bb5624") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/fcitx.el"))]) (find-by-pinyin-dired . [(20180210 218) ((pinyinlib (0 1 0))) "Find file by first PinYin character of Chinese Hanzi" single ((:commit . "3b4781148dddc84a701ad76c0934ed991ecd59d5") (:keywords "hanzi" "chinese" "dired" "find" "file" "pinyin") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/find-by-pinyin-dired"))]) (pinyinlib . [(20170827 2142) nil "Convert first letter of Pinyin to Simplified/Traditional Chinese characters" single ((:commit . "45f05d3dbb4fe957f7ab332ca6f94675848b6aa3") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (ace-pinyin . [(20190123 402) ((avy (0 2 0)) (pinyinlib (0 1 0))) "Jump to Chinese characters using avy or ace-jump-mode" single ((:commit . "4915b2413359d85002918e322dbc90c4984b4277") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/ace-pinyin"))]) (names . [(20180321 1155) ((emacs (24 1)) (cl-lib (0 5))) "Namespaces for emacs-lisp. Avoid name clobbering without hiding symbols." tar ((:commit . "d8baba5360e5253938a25d3e005455b6d2d86971") (:keywords "extensions" "lisp") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/names"))]) (chinese-word-at-point . [(20170811 941) ((cl-lib (0 5))) "Add `chinese-word' thing to `thing-at-point'" single ((:commit . "8223d7439e005555b86995a005b225ae042f0538") (:keywords "convenience" "chinese") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/chinese-word-at-point.el"))]) (youdao-dictionary . [(20180714 414) ((popup (0 5 0)) (pos-tip (0 4 6)) (chinese-word-at-point (0 2)) (names (0 5)) (emacs (24))) "Youdao Dictionary interface for Emacs" single ((:commit . "9496ea3ba8aa999db3dbde88d6aa37f3579d8dea") (:keywords "convenience" "chinese" "dictionary") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/youdao-dictionary.el"))]) (chinese-conv . [(20170807 2128) ((cl-lib (0 5))) "Conversion between Chinese Characters with opencc or cconv" single ((:commit . "b56815bbb163d642e97fa73093b5a7e87cc32574") (:authors ("gucong" . "gucong43216@gmail.com")) (:maintainer "gucong" . "gucong43216@gmail.com") (:url . "https://github.com/gucong/emacs-chinese-conv"))]) (evil-escape . [(20180910 1234) nil "No description available." single ((:commit . "f4e9116bfbaac8c9d210c17ad488e0982291245f"))]) (eyebrowse . [(20190322 933) ((dash (2 7 0)) (emacs (24 3 1))) "Easy window config switching" single ((:commit . "52e160997a1c4b1d463e8b9cc2ba3e27408c2a89") (:keywords "convenience") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/eyebrowse"))]) (neotree . [(20181121 2026) ((cl-lib (0 5))) "A tree plugin like NerdTree for Vim" tar ((:commit . "c2420a4b344a9337760981c451783f0ff9df8bbf") (:authors ("jaypei" . "jaypei97159@gmail.com")) (:maintainer "jaypei" . "jaypei97159@gmail.com") (:url . "https://github.com/jaypei/emacs-neotree"))]) (exec-path-from-shell . [(20190426 2227) nil "Get environment variables such as $PATH from the shell" single ((:commit . "3cfedb8791397ed50ee66bc0a7cbee5b9d78245c") (:keywords "unix" "environment") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/exec-path-from-shell"))]) (launchctl . [(20150518 1309) ((emacs (24 1))) "Interface to launchctl on Mac OS X." single ((:commit . "73f8f52a5aa9a0be9bdcf68c29ad0fa2b4a115a4") (:keywords "tools" "convenience") (:authors ("Peking Duck ")) (:maintainer "Peking Duck ") (:url . "http://github.com/pekingduck/launchctl-el"))]) (osx-dictionary . [(20171026 734) ((cl-lib (0 5))) "Interface for OSX Dictionary.app" tar ((:commit . "b16630ecf69f87ac873486d8b9c8c03e6c9ea7fa") (:keywords "mac" "dictionary") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/osx-dictionary.el"))]) (osx-trash . [(20160520 1300) ((emacs (24 1))) "System trash for OS X" tar ((:commit . "0f1dc052d0a750b8c75f14530a4897f5d4324b4e") (:keywords "files" "convenience" "tools" "unix") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/lunaryorn/osx-trash.el"))]) (osx-clipboard . [(20141012 717) nil "Use the OS X clipboard from terminal Emacs" single ((:commit . "e46dd31327a3f92f77b013b4c9b1e5fdd0e5c73d") (:authors ("Jon Oddie ")) (:maintainer "Jon Oddie ") (:url . "https://github.com/joddie/osx-clipboard-mode"))]) (reveal-in-osx-finder . [(20150802 1657) nil "Reveal file associated with buffer in OS X Finder" single ((:commit . "5710e5936e47139a610ec9a06899f72e77ddc7bc") (:keywords "os x" "finder") (:authors ("Kazuki YOSHIDA")) (:maintainer "Kazuki YOSHIDA") (:url . "https://github.com/kaz-yos/reveal-in-osx-finder"))]) (company-nixos-options . [(20160215 857) ((company (0 8 0)) (nixos-options (0 0 1)) (cl-lib (0 5 0))) "Company Backend for nixos-options" single ((:commit . "45c8d90748304c90e1503c9fa8db0443f3d4bd89") (:keywords "unix") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))]) (helm-nixos-options . [(20151013 2309) ((nixos-options (0 0 1)) (helm (1 5 6))) "Helm Interface for nixos-options" single ((:commit . "45c8d90748304c90e1503c9fa8db0443f3d4bd89") (:keywords "unix") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))]) (nix-mode . [(20190703 526) ((emacs (24 3))) "Major mode for editing .nix files" tar ((:commit . "ddf091708b9069f1fe0979a7be4e719445eed918") (:keywords "nix" "languages" "tools" "unix") (:maintainer "Matthew Bauer" . "mjbauer95@gmail.com") (:url . "https://github.com/NixOS/nix-mode"))]) (nixos-options . [(20160209 1841) ((emacs (24))) "Interface for browsing and completing NixOS options." single ((:commit . "45c8d90748304c90e1503c9fa8db0443f3d4bd89") (:keywords "unix") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))]) (selectric-mode . [(20170216 1111) nil "IBM Selectric mode for Emacs" tar ((:commit . "aed70015b29074b52a5d0c49b88b7a501d276dda") (:keywords "multimedia" "convenience" "typewriter" "selectric") (:authors ("Ricardo Bánffy" . "rbanffy@gmail.com")) (:maintainer "Ricardo Banffy" . "rbanffy@gmail.com") (:url . "https://github.com/rbanffy/selectric-mode"))]) (2048-game . [(20151026 1933) nil "play 2048 in Emacs" single ((:commit . "ea6c3bce8ac1c17dae5ac711ae4e931c0495e455") (:authors ("Zachary Kanfer" . "zkanfer@gmail.com")) (:maintainer "Zachary Kanfer" . "zkanfer@gmail.com") (:url . "https://bitbucket.org/zck/2048.el"))]) (pacmacs . [(20160131 832) ((emacs (24 4)) (dash (2 11 0)) (dash-functional (1 2 0)) (cl-lib (0 5)) (f (0 18 0))) "Pacman for Emacs" tar ((:commit . "d813e9c62c2540fe619234824fc60e128c786442") (:authors ("Codingteam" . "codingteam@conference.jabber.ru")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/codingteam/pacmacs.el"))]) (sudoku . [(20161111 706) ((emacs (24 4))) "Simple sudoku game, can download puzzles" single ((:commit . "77c11b5041b58fc943cf1668b44b40bae039cb5b") (:keywords "games") (:authors ("Zajcev Evgeny" . "zevlg@yandex.ru")) (:maintainer "Zajcev Evgeny" . "zevlg@yandex.ru"))]) (mmt . [(20190713 1347) ((emacs (24 1)) (cl-lib (0 3))) "Missing macro tools for Emacs Lisp" single ((:commit . "753f6dc888acbd932c4fbd7c73ff750381058561") (:keywords "macro" "emacs-lisp") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/mmt"))]) (typit . [(20190713 1336) ((emacs (24 4)) (f (0 18)) (mmt (0 1 1))) "Typing game similar to tests on 10 fast fingers" tar ((:commit . "2adb0e0df4689b5abaa89a71808ec7993ecfaf9b") (:keywords "games") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/typit"))]) (xkcd . [(20160419 1130) ((json (1 3))) "View xkcd from Emacs" single ((:commit . "66e928706fd660cfdab204c98a347b49c4267bdf") (:keywords "xkcd" "webcomic") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/vibhavp/emacs-xkcd"))]) (erc-image . [(20180522 1424) nil "Show received image urls in the ERC buffer" single ((:commit . "82fb3871f02e24b1e880770b9a3d187aab43d0f0") (:keywords "multimedia") (:authors ("Jon de Andrés Frías" . "jondeandres@gmail.com") ("Raimon Grau Cuscó" . "raimonster@gmail.com")) (:maintainer "Jon de Andrés Frías" . "jondeandres@gmail.com"))]) (erc-tweet . [(20150920 1258) nil "shows text of a tweet when an url is posted in erc buffers" single ((:commit . "91fed61e139fa788d66a7358f0d50acc896414b8") (:keywords "extensions") (:authors ("Raimon Grau" . "raimonster@gmail.com")) (:maintainer "Raimon Grau" . "raimonster@gmail.com"))]) (erc-yt . [(20150426 1249) ((dash (2 10 0))) "An erc module to display youtube links nicely" single ((:commit . "43e7d49325b17a3217a6ffb4a9daf75c5ff4e6f8") (:keywords "multimedia") (:authors ("William Stevenson" . "yhvh2000@gmail.com")) (:maintainer "William Stevenson" . "yhvh2000@gmail.com"))]) (rcirc-color . [(0 4 1) ((emacs (24 4))) "color nicks" single ((:url . "http://elpa.gnu.org/packages/rcirc-color.html") (:keywords "comm") (:authors ("Alex Schroeder" . "alex@gnu.org")) (:maintainer "Alex Schroeder" . "alex@gnu.org"))]) (rcirc-notify . [(20150219 2204) nil "libnotify popups" single ((:commit . "841a7b5a6cdb0c11a812df924d2c6a7d364fd455") (:keywords "lisp" "rcirc" "irc" "notify" "growl") (:authors ("Will Farrington, Alex Schroeder , Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk"))]) (rcirc-styles . [(20160207 250) ((cl-lib (0 5))) "support mIRC-style color and attribute codes" single ((:commit . "f313bf6a7470bed314b27c7a40558cb787d7bc67"))]) (srv . [(20180715 1959) ((emacs (24 3))) "perform SRV DNS requests" single ((:commit . "714387d5a5cf34d8d8cd96bdb1f9cb8ded823ff7") (:keywords "comm") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com") (:url . "https://github.com/legoscia/srv.el"))]) (fsm . [(0 2 1) ((emacs (24 1)) (cl-lib (0 5))) "state machine library" single ((:url . "http://elpa.gnu.org/packages/fsm.html") (:keywords "extensions") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Thomas Fitzsimmons" . "fitzsim@fitzsim.org"))]) (jabber . [(20180927 2325) ((fsm (0 2)) (srv (0 2))) "A Jabber client for Emacs." tar ((:commit . "fff33826f42e040dad7ef64ea312d85215d3b0a1"))]) (emojify . [(20190809 959) ((seq (1 11)) (ht (2 0)) (emacs (24 3))) "Display emojis in Emacs" tar ((:commit . "782ac307f37239e90c56810323db4263a6469219") (:keywords "multimedia" "convenience") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:url . "https://github.com/iqbalansari/emacs-emojify"))]) (circe . [(20190322 1242) ((cl-lib (0 5))) "Client for IRC in Emacs" tar ((:commit . "6ccd4b494cbae9d28091217654f052eaea321007") (:url . "https://github.com/jorgenschaefer/circe"))]) (oauth2 . [(0 11) nil "OAuth 2.0 Authorization Protocol" single ((:url . "http://elpa.gnu.org/packages/oauth2.html") (:keywords "comm") (:authors ("Julien Danjou" . "julien@danjou.info")) (:maintainer "Julien Danjou" . "julien@danjou.info"))]) (websocket . [(20190621 54) ((cl-lib (0 5))) "Emacs WebSocket client and server" single ((:commit . "d91a9aef5a3ec5af985e5185c3b237fdd24605e0") (:keywords "communication" "websocket" "server") (:authors ("Andrew Hyatt" . "ahyatt@gmail.com")) (:maintainer "Andrew Hyatt" . "ahyatt@gmail.com"))]) (slack . [(20190803 1406) ((websocket (1 8)) (request (0 2 0)) (oauth2 (0 10)) (circe (2 2)) (alert (1 2)) (emojify (0 2))) "Slack client for Emacs" tar ((:commit . "ea89ac4291532a136d02bb8852b5dc641622ab73") (:url . "https://github.com/yuya373/emacs-slack"))]) (erc-hl-nicks . [(20180415 1946) nil "ERC nick highlighter that ignores uniquifying chars when colorizing" single ((:commit . "756c4438a8245ccd3e389bf6c9850ee8453783ec") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/erc-hl-nicks"))]) (erc-social-graph . [(20150508 1204) nil "A social network graph module for ERC." single ((:commit . "e6ef3416a1c5064054bf054d9f0c1c7bf54a9cd0") (:keywords "erc" "graph") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/vibhavp/erc-social-graph"))]) (erc-terminal-notifier . [(20140115 1024) nil "OSX notifications via the terminal-notifier gem for Emacs ERC." single ((:commit . "a3dacb935845e4a20031212bbd82b2170f68d2a8") (:keywords "erc" "terminal-notifier" "nick") (:authors ("Julien Blanchard" . "julien@sideburns.eu")) (:maintainer "Julien Blanchard" . "julien@sideburns.eu") (:url . "http://github.com/julienXX/"))]) (erc-view-log . [(20140227 2039) nil "Major mode for viewing ERC logs" single ((:commit . "c5a25f0cbca84ed2e4f72068c02b66bd0ea3b266") (:keywords "erc" "viewer" "logs" "colors") (:authors ("Antoine Levitt") ("Thomas Riccardi" . "riccardi.thomas@gmail.com")) (:maintainer "Antoine Levitt") (:url . "http://github.com/Niluge-KiWi/erc-view-log/raw/master/erc-view-log.el"))]) (spotify . [(20181030 810) ((cl-lib (0 5))) "Control the spotify application from emacs" single ((:commit . "29577cf1188161f98b8358c149aaf47b2c137902") (:keywords "convenience") (:authors ("R.W. van 't Veer")) (:maintainer "R.W. van 't Veer") (:url . "https://github.com/remvee/spotify-el"))]) (multi . [(20131013 1544) ((emacs (24))) "Clojure-style multi-methods for emacs lisp" single ((:commit . "0987ab71692717ed457cb3984de184db9185806d") (:keywords "multimethod" "generic" "predicate" "dispatch") (:authors ("Christina Whyte" . "kurisu.whyte@gmail.com")) (:maintainer "Christina Whyte" . "kurisu.whyte@gmail.com") (:url . "http://github.com/kurisuwhyte/emacs-multi"))]) (helm-spotify-plus . [(20190807 2115) ((emacs (24 4)) (helm (2 0 0)) (multi (2 0 1))) "Control Spotify search and select music with Helm." single ((:commit . "e52233523917596dd3862e1151a027ce89a80a38") (:authors ("Wanderson Ferreira and Luis Moneda ")) (:maintainer "Wanderson Ferreira and Luis Moneda ") (:url . "https://github.com/wandersoncferreira/helm-spotify-plus"))]) (counsel-spotify . [(20190406 2025) ((emacs (25)) (ivy (0 9 0))) "Control Spotify search and select music with Ivy." single ((:commit . "f484e6efd3994704cfd16c87c298fbfa12d442cc") (:authors ("Lautaro García ")) (:maintainer "Lautaro García "))]) (copy-as-format . [(20190523 258) ((cl-lib (0 5))) "Copy buffer locations as GitHub/Slack/JIRA etc... formatted code" single ((:commit . "a0962b670e26b723ce304b14e3397da453aef84e") (:keywords "github" "slack" "jira" "hipchat" "gitlab" "bitbucket" "org-mode" "pod" "rst" "asciidoc" "tools" "convenience") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:url . "https://github.com/sshaw/copy-as-format"))]) (ietf-docs . [(20190420 851) nil "Fetch, Cache and Load IETF documents" single ((:commit . "ae157549eae5ec78dcbf215c2f48cb662b73abd0") (:keywords "ietf" "rfc") (:authors ("Christian E. Hopps" . "chopps@gmail.com")) (:maintainer "Christian E. Hopps" . "chopps@gmail.com") (:url . "https://github.com/choppsv1/ietf-docs"))]) (ox-rfc . [(20190429 1133) ((emacs (24 3)) (org (8 3))) "RFC Back-End for Org Export Engine" tar ((:commit . "4cac33c387bc10e32f18940298aa5095d060ed3e") (:keywords "org" "rfc" "wp" "xml") (:authors ("Christian Hopps" . "chopps@devhopps.com")) (:maintainer "Christian Hopps" . "chopps@devhopps.com") (:url . "https://github.com/choppsv1/org-rfc-export"))]) (evil-mc . [(20190321 1606) ((emacs (24 3)) (evil (1 2 13)) (cl-lib (0 5))) "Multiple cursors for evil-mode" tar ((:commit . "5205fe671803465149e578849bbbe803c23a8e4e") (:keywords "evil" "editing" "multiple-cursors" "vim" "evil-multiple-cursors" "evil-mc" "evil-mc") (:authors ("Gabriel Adomnicai" . "gabesoft@gmail.com")) (:maintainer "Gabriel Adomnicai" . "gabesoft@gmail.com") (:url . "https://github.com/gabesoft/evil-mc"))]) (multiple-cursors . [(20190820 749) ((cl-lib (0 5))) "Multiple cursors for Emacs." tar ((:commit . "b9b851a7670f4348f3a08b11ef12ed99676c8b84"))]) (auto-yasnippet . [(20190326 958) ((yasnippet (0 13 0))) "Quickly create disposable yasnippets" single ((:commit . "624b0d9711222073a2a3f2186e2605eb99fc83c9") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/auto-yasnippet"))]) (auto-complete . [(20170125 245) ((popup (0 5 0)) (cl-lib (0 5))) "Auto Completion for GNU Emacs" tar ((:commit . "2e83566ddfa758c69afe50b8a1c62a66f47471e3"))]) (ac-ispell . [(20151101 226) ((auto-complete (1 4)) (cl-lib (0 5))) "ispell completion source for auto-complete" single ((:commit . "22bace7387e9012002a6a444922f75f9913077b0") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-ispell"))]) (company-statistics . [(20170210 1933) ((emacs (24 3)) (company (0 8 5))) "Sort candidates using completion history" single ((:commit . "e62157d43b2c874d2edbd547c3bdfb05d0a7ae5c") (:keywords "abbrev" "convenience" "matching") (:authors ("Ingo Lohmar" . "i.lohmar@gmail.com")) (:maintainer "Ingo Lohmar" . "i.lohmar@gmail.com") (:url . "https://github.com/company-mode/company-statistics"))]) (fuzzy . [(20150730 337) nil "Fuzzy Matching" single ((:commit . "534d723ad2e06322ff8d9bd0ba4863d243f698e7") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (company . [(20190821 658) ((emacs (24 3))) "Modular text completion framework" tar ((:commit . "1120b56bd1154a17e4c0b950cbdba4c85be28e2a") (:keywords "abbrev" "convenience" "matching") (:authors ("Nikolaj Schumacher")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:url . "http://company-mode.github.io/"))]) (helm-company . [(20190812 1429) ((helm (1 5 9)) (company (0 6 13))) "Helm interface for company-mode" single ((:commit . "6eb5c2d730a60e394e005b47c1db018697094dde") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Daniel Ralston" . "Sodel-the-Vociferous@users.noreply.github.com") (:url . "https://github.com/Sodel-the-Vociferous/helm-company"))]) (helm-c-yasnippet . [(20170128 1542) ((helm (1 7 7)) (yasnippet (0 8 0)) (cl-lib (0 3))) "helm source for yasnippet.el" single ((:commit . "65ca732b510bfc31636708aebcfe4d2d845b59b0") (:keywords "convenience" "emulation") (:authors ("Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com")) (:maintainer "Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com"))]) (ivy-yasnippet . [(20181002 1655) ((emacs (24)) (ivy (0 10 0)) (yasnippet (0 12 2)) (dash (2 14 1)) (cl-lib (0))) "Preview yasnippets with ivy" single ((:commit . "32580b4fd23ebf9ca7dde96704f7d53df6e253cd") (:keywords "convenience") (:authors ("MichaÅ‚ Krzywkowski" . "k.michal@zoho.com")) (:maintainer "MichaÅ‚ Krzywkowski" . "k.michal@zoho.com") (:url . "https://github.com/mkcms/ivy-yasnippet"))]) (yasnippet-snippets . [(20190821 901) ((yasnippet (0 8 0))) "Collection of yasnippet snippets" tar ((:commit . "71ae4a665f0db13165f14687cf5828d4510ef557") (:keywords "snippets") (:authors ("Andrea Crotti" . "andrea.crotti.0@gmail.com")) (:maintainer "Andrea Crotti" . "andrea.crotti.0@gmail.com"))]) (counsel-projectile . [(20190817 102) ((counsel (0 12 0)) (projectile (2 0 0))) "Ivy integration for Projectile" single ((:commit . "fda7f0bad93a471fddf5fa01d6fdee5684e7f880") (:keywords "project" "convenience") (:authors ("Eric Danan")) (:maintainer "Eric Danan") (:url . "https://github.com/ericdanan/counsel-projectile"))]) (helm-make . [(20190729 1221) nil "Select a Makefile target with helm" single ((:commit . "6f3d9a0feed47c1d6a9b82baef2e2663ac496514") (:keywords "makefile") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/helm-make"))]) (ivy-hydra . [(20190731 1602) ((emacs (24 1)) (ivy (0 12 0)) (hydra (0 13 4))) "Additional key bindings for Ivy" single ((:commit . "824f8d767094ad48c047c811cbe764a0de96892c") (:keywords "convenience") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (ivy-rich . [(20190707 107) ((emacs (24 4)) (ivy (0 8 0))) "More friendly display transformer for ivy." single ((:commit . "e78fc4b9d467da338471f234393a1c791a6b0e6b") (:keywords "ivy") (:authors ("Yevgnen Koh" . "wherejoystarts@gmail.com")) (:maintainer "Yevgnen Koh" . "wherejoystarts@gmail.com"))]) (ivy-xref . [(20190611 1305) ((emacs (25 1)) (ivy (0 10 0))) "Ivy interface for xref results" single ((:commit . "1a35fc0f070388701b05b0a455cbe262e924d547") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/ivy-xref"))]) (smex . [(20151212 2209) ((emacs (24))) "M-x interface with Ido-style fuzzy matching." single ((:commit . "55aaebe3d793c2c990b39a302eb26c184281c42c") (:keywords "convenience" "usability") (:authors ("Cornelius Mika" . "cornelius.mika@gmail.com")) (:maintainer "Cornelius Mika" . "cornelius.mika@gmail.com") (:url . "http://github.com/nonsequitur/smex/"))]) (wgrep . [(20181229 40) nil "Writable grep buffer and apply the changes to files" single ((:commit . "379afd89ebd76f63842c8589127d66096a8bb595") (:keywords "grep" "edit" "extensions") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep.el"))]) (yasnippet . [(20190724 1204) ((cl-lib (0 5))) "Yet another snippet extension for Emacs" single ((:commit . "d91dd66f2aed9bbaef32813a68b105ea77e83890") (:keywords "convenience" "emulation") (:maintainer "Noam Postavsky" . "npostavs@gmail.com") (:url . "http://github.com/joaotavora/yasnippet"))]) (yatemplate . [(20180617 952) ((yasnippet (0 8 1)) (emacs (24 3))) "File templates with yasnippet" tar ((:commit . "4f4fca9f04f7088c98aa195cf33635a35a6055cb") (:keywords "files" "convenience") (:authors ("Wieland Hoffmann" . "themineo+yatemplate@gmail.com")) (:maintainer "Wieland Hoffmann" . "themineo+yatemplate@gmail.com") (:url . "https://github.com/mineo/yatemplate"))]) (ace-jump-helm-line . [(20160918 1836) ((avy (0 4 0)) (helm (1 6 3))) "Ace-jump to a candidate in helm window" single ((:commit . "1483055255df3f8ae349f7520f05b1e43ea3ed37") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/ace-jump-helm-line"))]) (helm-ag . [(20170209 1545) ((emacs (24 4)) (helm (2 0))) "the silver searcher with helm interface" single ((:commit . "2fc02c4ead29bf0db06fd70740cc7c364cb650ac") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-ag"))]) (helm-descbinds . [(20190501 935) ((helm (1 5))) "A convenient `describe-bindings' with `helm'" single ((:commit . "b72515982396b6e336ad7beb6767e95a80fca192") (:keywords "helm" "help") (:authors ("Taiki SUGAWARA" . "buzz.taiki@gmail.com")) (:maintainer "Taiki SUGAWARA" . "buzz.taiki@gmail.com") (:url . "https://github.com/emacs-helm/helm-descbinds"))]) (helm-flx . [(20180103 516) ((emacs (24 4)) (helm (1 7 9)) (flx (0 5))) "Sort helm candidates by flx score" single ((:commit . "6640fac5cb16bee73c95b8ed1248a4e5e113690e") (:keywords "convenience" "helm" "fuzzy" "flx") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:url . "https://github.com/PythonNut/helm-flx"))]) (helm-mode-manager . [(20151124 938) ((helm (1 5 3))) "Select and toggle major and minor modes with helm" single ((:commit . "5d9c3ca4f8205d07ff4e03c4c3e88f596751c1fc") (:authors ("istib")) (:maintainer "istib") (:url . "https://github.com/istib/helm-mode-manager"))]) (helm-projectile . [(20190731 1538) ((helm (1 9 9)) (projectile (0 14 0)) (cl-lib (0 3))) "Helm integration for Projectile" single ((:commit . "5328b74dddcee8d1913803ca8167868831a07463") (:keywords "project" "convenience") (:authors ("Bozhidar Batsov")) (:maintainer "Bozhidar Batsov") (:url . "https://github.com/bbatsov/helm-projectile"))]) (helm-swoop . [(20190814 1234) ((helm (3 2)) (emacs (24 4))) "Efficiently hopping squeezed lines powered by helm interface" single ((:commit . "2f6ed31fafa741bb845a58536c178b02aeb27cfd") (:keywords "helm" "swoop" "inner" "buffer" "search") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:url . "https://github.com/ShingoFukuyama/helm-swoop"))]) (helm-themes . [(20160918 545) ((helm-core (2 0)) (emacs (24 4))) "Color theme selection with helm interface" single ((:commit . "1160af42590b0d845a55e65e1e782d9e4027fd6e") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-themes"))]) (helm-xref . [(20190821 1252) ((emacs (25 1)) (helm (1 9 4))) "Helm interface for xref results" single ((:commit . "5290e2a05209b742d7efcd3e03b5f51ac1eab6ad") (:authors ("Fritz Stelzer" . "brotzeitmacher@gmail.com")) (:maintainer "Fritz Stelzer" . "brotzeitmacher@gmail.com") (:url . "https://github.com/brotzeit/helm-xref"))]) (winum . [(20181119 1705) ((cl-lib (0 5)) (dash (2 13 0))) "Navigate windows and frames using numbers." single ((:commit . "247df36c03d70b453e9b912d6e1b7065644f639d") (:keywords "convenience" "frames" "windows" "multi-screen") (:authors ("Thomas de Beauchêne" . "thomas.de.beauchene@gmail.com")) (:maintainer "Thomas de Beauchêne" . "thomas.de.beauchene@gmail.com") (:url . "http://github.com/deb0ch/winum.el"))]) (treemacs-evil . [(20190619 1516) ((evil (1 2 12)) (treemacs (0 0))) "Evil mode integration for treemacs" single ((:commit . "748b2a584e13b03e8adc51ab901d036d75038408") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))]) (treemacs . [(20190814 459) ((emacs (25 2)) (cl-lib (0 5)) (dash (2 11 0)) (s (1 10 0)) (f (0 11 0)) (ace-window (0 9 0)) (pfuture (1 7)) (hydra (0 13 2)) (ht (2 2))) "A tree style file explorer package" tar ((:commit . "748b2a584e13b03e8adc51ab901d036d75038408") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))]) (ht . [(20190611 2131) ((dash (2 12 0))) "The missing hash table library for Emacs" single ((:commit . "5650a8cd190badb49d28d21e72a2f55c9380de7b") (:keywords "hash table" "hash map" "hash") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (pfuture . [(20190505 1006) ((emacs (25 2))) "a simple wrapper around asynchronous processes" single ((:commit . "368254ee30692c709400db413c347e18e76a8a55") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/pfuture"))]) (ace-window . [(20190708 933) ((avy (0 2 0))) "Quickly switch windows." single ((:commit . "a5344925e399e1f015721cda6cf5db03c90ab87a") (:keywords "window" "location") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/ace-window"))]) (treemacs-projectile . [(20190619 1516) ((projectile (0 14 0)) (treemacs (0 0))) "Projectile integration for treemacs" single ((:commit . "748b2a584e13b03e8adc51ab901d036d75038408") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))]) (pos-tip . [(20150318 1513) nil "Show tooltip at point" single ((:commit . "051e08fec5cf30b7574bdf439f79fef7d42d689d") (:keywords "tooltip") (:authors ("S. Irie")) (:maintainer "S. Irie"))]) (flycheck . [(20190821 926) ((dash (2 12 1)) (pkg-info (0 4)) (let-alist (1 0 4)) (seq (1 11)) (emacs (24 3))) "On-the-fly syntax checking" tar ((:commit . "52ddbfc9429fdd8ae583672a1e4ebe3bff0bace6") (:keywords "convenience" "languages" "tools") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:url . "http://www.flycheck.org"))]) (flycheck-pos-tip . [(20180610 1615) ((emacs (24 1)) (flycheck (0 22)) (pos-tip (0 4 6))) "Display Flycheck errors in GUI tooltips" single ((:commit . "909113977d37739387c7f099d74a724cfe6efcec") (:keywords "tools" "convenience") (:authors ("Akiha Senda" . "senda.akiha@gmail.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-pos-tip"))]) (auto-dictionary . [(20150410 1610) nil "automatic dictionary switcher for flyspell" single ((:commit . "b364e08009fe0062cf0927d8a0582fad5a12b8e7") (:keywords "wp") (:authors ("Nikolaj Schumacher ")) (:maintainer "Nikolaj Schumacher ") (:url . "http://nschum.de/src/emacs/auto-dictionary/"))]) (flyspell-correct-ivy . [(20181205 1932) ((flyspell-correct (0 5 0)) (ivy (0 8 0))) "correcting words with flyspell via ivy interface" single ((:commit . "a0852074bab130a711ba6b4696a7cb8059dac8db") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-correct-helm . [(20181205 1932) ((flyspell-correct (0 5 0)) (helm (1 9 0))) "correcting words with flyspell via helm interface" single ((:commit . "a0852074bab130a711ba6b4696a7cb8059dac8db") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-correct . [(20190408 1010) nil "correcting words with flyspell via custom interface" tar ((:commit . "a0852074bab130a711ba6b4696a7cb8059dac8db") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-correct-popup . [(20181205 1932) ((flyspell-correct (0 5 0)) (popup (0 5 3))) "correcting words with flyspell via popup interface" single ((:commit . "a0852074bab130a711ba6b4696a7cb8059dac8db") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-popup . [(20170529 815) ((popup (0 5 0))) "Correcting words with Flyspell in popup menus" single ((:commit . "29311849bfd253b9b689bf331860b4c4d3bd4dde") (:keywords "convenience") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/flyspell-popup"))]) (highlight . [(20181002 1151) nil "Highlighting commands." single ((:commit . "ea733e17884aeae19172407e20559fc693fdd3a7") (:keywords "faces" "help" "local") (:authors ("Drew Adams")) (:maintainer nil . "Drew Adams (concat \"drew.adams\" \"@\" \"oracle\" \".com\")") (:url . "https://www.emacswiki.org/emacs/download/highlight.el"))]) (floobits . [(20180801 524) ((json (1 2)) (highlight (0))) "Floobits plugin for real-time collaborative editing" tar ((:commit . "489b294a7f30ecd2af2edc0823dead8102f27af6") (:keywords "comm" "tools") (:authors ("Matt Kaniaris") ("Geoff Greer")) (:maintainer "Matt Kaniaris") (:url . "http://github.com/Floobits/floobits-emacs"))]) (mwim . [(20181110 1900) nil "Switch between the beginning/end of line or code" single ((:commit . "b4f3edb4c0fb8f8b71cecbf8095c2c25a8ffbf85") (:keywords "convenience") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/mwim.el"))]) (unfill . [(20170723 146) nil "Unfill paragraphs or regions, and toggle between filled & unfilled" single ((:commit . "df0c4dee19a3874b11c7c7f04e8a2fba629fda9b") (:keywords "utilities") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/unfill"))]) (evil-org . [(20180323 2306) ((emacs (24 4)) (evil (1 0))) "evil keybindings for org-mode" tar ((:commit . "b6d652a9163d3430a9e0933a554bdbee5244bbf6") (:keywords "evil" "vim-emulation" "org-mode" "key-bindings" "presets") (:maintainer "Somelauw") (:url . "https://github.com/Somelauw/evil-org-mode.git"))]) (gnuplot . [(20141231 2137) nil "drive gnuplot from within emacs" tar ((:commit . "21f9046e3f5caad41b750b5c9cee02fa4fd20fb9") (:keywords "gnuplot" "plotting") (:authors ("Bruce Ravel" . "bruceravel1@gmail.com")) (:maintainer "Bruce Ravel" . "bruceravel1@gmail.com"))]) (helm-org . [(20190819 617) ((helm (3 3)) (emacs (24 4))) "Helm for org headlines and keywords completion" single ((:commit . "542dda7bc9a3b9dfb439e4f8a1e5f60cfb6cc256") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/emacs-helm/helm-org"))]) (helm-org-rifle . [(20190809 1831) ((emacs (24 4)) (dash (2 12)) (f (0 18 1)) (helm (1 9 4)) (s (1 10 0))) "Rifle through your Org files" single ((:commit . "dbda48031bad6fec1e130ee6e0d1a3bfea8ad8b8") (:keywords "hypermedia" "outlines") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/helm-org-rifle"))]) (org-brain . [(20190813 1155) ((emacs (25)) (org (9 2))) "Org-mode concept mapping" single ((:commit . "d54eb4373968c6392523117a9114d661d12d39ae") (:keywords "outlines" "hypermedia") (:authors ("Erik Sjöstrand" . "sjostrand.erik@gmail.com")) (:maintainer "Erik Sjöstrand" . "sjostrand.erik@gmail.com") (:url . "http://github.com/Kungsgeten/org-brain"))]) (org-journal . [(20190816 2036) ((emacs (25 1))) "a simple org-mode based journaling mode" single ((:commit . "eb5e6cc56bfef96997b3477403bbc30f320f59fa") (:authors ("Bastian Bechtold")) (:maintainer "Bastian Bechtold") (:url . "http://github.com/bastibe/org-journal"))]) (org-download . [(20190821 501) ((async (1 2))) "Image drag-and-drop for Emacs org-mode" single ((:commit . "8bc54b6c1a7ac70c4d871ba9e2313035465e18b1") (:keywords "images" "screenshots" "download") (:authors ("Oleh Krehel")) (:maintainer "Oleh Krehel") (:url . "https://github.com/abo-abo/org-download"))]) (org-jira . [(20190712 443) ((emacs (24 5)) (cl-lib (0 5)) (request (0 2 0)) (dash (2 14 1))) "Syncing between Jira and Org-mode." tar ((:commit . "d1d2ff6155c6259a066110ed13d1850143618f7b") (:keywords "ahungry" "jira" "org" "bug" "tracker") (:maintainer "Matthew Carter" . "m@ahungry.com") (:url . "https://github.com/ahungry/org-jira"))]) (org-mime . [(20190805 57) ((emacs (24 4)) (cl-lib (0 5))) "org html export for text/html MIME emails" single ((:commit . "4bd5d55ba9bca84ffd938b477c72d701cf3736df") (:keywords "mime" "mail" "email" "html") (:authors ("Eric Schulte")) (:maintainer "Chen Bin (redguardtoo)") (:url . "http://github.com/org-mime/org-mime"))]) (alert . [(20190816 2205) ((gntp (0 1)) (log4e (0 3 0)) (cl-lib (0 5))) "Growl-style notification system for Emacs" single ((:commit . "95a735e6947b0d09dbf9b9a944a21e5f5c1e6ee1") (:keywords "notification" "emacs" "message") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:url . "https://github.com/jwiegley/alert"))]) (log4e . [(20170401 1304) nil "provide logging framework for elisp" single ((:commit . "c69424e407be0d9d0e54b427d8b18b1ac5a607e2") (:keywords "log") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/log4e"))]) (gntp . [(20141025 250) nil "Growl Notification Protocol for Emacs" single ((:commit . "767571135e2c0985944017dc59b0be79af222ef5") (:authors ("Engelke Eschner" . "tekai@gmx.li")) (:maintainer "Engelke Eschner" . "tekai@gmx.li"))]) (org-pomodoro . [(20190530 1445) ((alert (0 5 10)) (cl-lib (0 5))) "Pomodoro implementation for org-mode." tar ((:commit . "aa07c11318f91219336197e62c47bc7a3d090479") (:authors ("Arthur Leonard Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Leonard Andersen" . "leoc.git@gmail.com") (:url . "https://github.com/lolownia/org-pomodoro"))]) (org-present . [(20180303 2330) ((org (7))) "Minimalist presentation minor-mode for Emacs org-mode." single ((:commit . "d13acd70eff6a1608bc991920232146a0de76b21") (:authors ("Ric Lister")) (:maintainer "Ric Lister") (:url . "https://github.com/rlister/org-present"))]) (org-cliplink . [(20190608 2134) ((emacs (24 4))) "insert org-mode links from the clipboard" tar ((:commit . "82402cae7e118d67de7328417fd018a18f95fac2") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/rexim/org-cliplink"))]) (org-category-capture . [(20180601 242) ((org (9 0 0)) (emacs (24))) "Contextualy capture of org-mode TODOs." single ((:commit . "de37d0094791ab1146276904f3a37eba699e0b60") (:keywords "org-mode" "todo" "tools" "outlines") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/org-projectile"))]) (org-projectile . [(20190130 1439) ((projectile (0 11 0)) (dash (2 10 0)) (emacs (24)) (s (1 9 0)) (org-category-capture (0 0 0))) "Repository todo management for org-mode" single ((:commit . "de37d0094791ab1146276904f3a37eba699e0b60") (:keywords "org-mode" "projectile" "todo" "tools" "outlines") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/org-projectile"))]) (ox-epub . [(20181101 1854) ((emacs (24 3)) (org (9))) "Export org mode projects to EPUB" single ((:commit . "c9629ef4b4bc40d51afefd8c0bb2c683931e6409") (:keywords "hypermedia") (:authors ("Mark Meyer" . "mark@ofosos.org")) (:maintainer "Mark Meyer" . "mark@ofosos.org") (:url . "http://github.com/ofosos/org-epub"))]) (ox-twbs . [(20161103 2016) nil "Bootstrap compatible HTML Back-End for Org" single ((:commit . "2414e6b1de7deb6dd2ae79a7be633fdccb9c2f28") (:keywords "org" "html" "publish" "twitter" "bootstrap") (:authors ("Carsten Dominik ") ("Jambunathan K ") ("Brandon van Beekum ")) (:maintainer "Carsten Dominik ") (:url . "https://github.com/marsmining/ox-twbs"))]) (ox-gfm . [(20170628 2102) nil "Github Flavored Markdown Back-End for Org Export Engine" single ((:commit . "99f93011b069e02b37c9660b8fcb45dab086a07f") (:keywords "org" "wp" "markdown" "github") (:authors ("Lars Tveito")) (:maintainer "Lars Tveito"))]) (htmlize . [(20180923 1829) nil "Convert buffer text and decorations to HTML." single ((:commit . "8db0aa6aab77475a732b7363f0d57bd3933c18fd") (:keywords "hypermedia" "extensions") (:authors ("Hrvoje Niksic" . "hniksic@gmail.com")) (:maintainer "Hrvoje Niksic" . "hniksic@gmail.com"))]) (org-re-reveal . [(20190821 919) ((emacs (24 4)) (org (8 3)) (htmlize (1 34))) "Org export to reveal.js presentations" tar ((:commit . "5c5b087449eb47c5b98aca64def88a1857f0d48d") (:keywords "tools" "outlines" "hypermedia" "slideshow" "presentation" "oer") (:url . "https://gitlab.com/oer/org-re-reveal"))]) (ox-hugo . [(20190802 1755) ((emacs (24 4)) (org (9 0))) "Hugo Markdown Back-End for Org Export Engine" tar ((:commit . "470a708152c4a17eca80c49e042d4eeb57645539") (:keywords "org" "markdown" "docs") (:url . "https://ox-hugo.scripter.co"))]) (ox-jira . [(20171001 916) ((org (8 3))) "JIRA Backend for Org Export Engine" single ((:commit . "db2ec528f46c9e611624ba28611c440a99bff255") (:keywords "outlines" "hypermedia" "wp") (:authors ("Stig Brautaset" . "stig@brautaset.org")) (:maintainer "Stig Brautaset" . "stig@brautaset.org") (:url . "https://github.com/stig/ox-jira.el"))]) (dash-functional . [(20180107 1618) ((dash (2 0 0)) (emacs (24))) "Collection of useful combinators for Emacs Lisp" single ((:commit . "11907f4592ff1813536366d54245d3ecf6b99198") (:keywords "lisp" "functions" "combinators"))]) (request-deferred . [(20181129 317) ((deferred (0 3 1)) (request (0 2 0))) "Wrap request.el by deferred" single ((:commit . "000719521e7a1f065f78ea5ffe787d949a5abc5e") (:authors ("Takafumi Arakaki ")) (:maintainer "Takafumi Arakaki ") (:url . "https://github.com/tkf/emacs-request"))]) (deferred . [(20170901 1330) ((emacs (24 4))) "Simple asynchronous functions for emacs lisp" single ((:commit . "2239671d94b38d92e9b28d4e12fd79814cfb9c16") (:keywords "deferred" "async") (:authors ("SAKURAI Masashi ")) (:maintainer "SAKURAI Masashi ") (:url . "https://github.com/kiwanami/emacs-deferred"))]) (org-trello . [(20190304 900) ((request-deferred (0 2 0)) (deferred (0 4 0)) (s (1 11 0)) (dash-functional (2 12 1)) (dash (2 12 1))) "Minor mode to synchronize org-mode buffer and trello board" tar ((:commit . "94539558343ff109030e20ebba6a282af41a5eb9"))]) (org-sticky-header . [(20190406 2313) ((emacs (24 4)) (org (8 3 5))) "Show off-screen Org heading at top of window" single ((:commit . "32c13a56a78a4de239010031fea4b9583bac2512") (:keywords "hypermedia" "outlines" "org") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/org-sticky-header"))]) (projectile . [(20190626 1315) ((emacs (25 1)) (pkg-info (0 4))) "Manage and navigate projects in Emacs easily" single ((:commit . "71a01f409a319d57eb3832e93e8a412fbc9d7a65") (:keywords "project" "convenience") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "https://github.com/bbatsov/projectile"))]) (pkg-info . [(20150517 1143) ((epl (0 8))) "Information about packages" single ((:commit . "76ba7415480687d05a4353b27fea2ae02b8d9d61") (:keywords "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/lunaryorn/pkg-info.el"))]) (epl . [(20180205 2049) ((cl-lib (0 3))) "Emacs Package Library" single ((:commit . "78ab7a85c08222cd15582a298a364774e3282ce6") (:keywords "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/cask/epl"))]) (ibuffer-projectile . [(20181202 352) ((projectile (0 11 0)) (emacs (24))) "Group ibuffer's list by projectile root" single ((:commit . "76496214144687cee0b5139be2e61b1e400cac87") (:keywords "convenience") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "http://github.com/purcell/ibuffer-projectile"))]) (tablist . [(20190414 643) ((emacs (24 3))) "Extended tabulated-list-mode" tar ((:commit . "8079801527da1f596bc942162026328d7bdf6ad9") (:keywords "extensions" "lisp") (:authors ("Andreas Politz" . "politza@fh-trier.de")) (:maintainer "Andreas Politz" . "politza@fh-trier.de"))]) (pdf-tools . [(20190701 202) ((emacs (24 3)) (tablist (1 0)) (let-alist (1 0 4))) "Support library for PDF documents." tar ((:commit . "db7de3901ae0e55f6ab8cf9baec257f706c3d16e") (:keywords "files" "multimedia") (:authors ("Andreas Politz" . "politza@fh-trier.de")) (:maintainer "Andreas Politz" . "politza@fh-trier.de"))]) (spray . [(20160304 2220) nil "a speed reading mode" single ((:commit . "00638bc916227f2f961013543d10e85a43a32e29") (:keywords "convenience") (:authors ("Ian Kelling" . "ian@iankelling.org")) (:maintainer "Ian Kelling" . "ian@iankelling.org") (:url . "https://github.com/ian-kelling/spray"))]) (ace-jump-mode . [(20140616 815) nil "a quick cursor location minor mode for emacs" single ((:commit . "8351e2df4fbbeb2a4003f2fb39f46d33803f3dac") (:keywords "motion" "location" "cursor") (:authors ("winterTTr" . "winterTTr@gmail.com")) (:maintainer "winterTTr" . "winterTTr@gmail.com") (:url . "https://github.com/winterTTr/ace-jump-mode/"))]) (noflet . [(20141102 1454) nil "locally override functions" single ((:commit . "7ae84dc3257637af7334101456dafe1759c6b68a") (:keywords "lisp") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "https://github.com/nicferrier/emacs-noflet"))]) (popwin . [(20150315 1300) nil "Popup Window Manager." single ((:commit . "95dea14c60019d6cccf9a3b33e0dec4e1f22c304") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (elfeed-goodies . [(20190128 1631) ((popwin (1 0 0)) (powerline (2 2)) (elfeed (2 0 0)) (cl-lib (0 5)) (noflet (0 0 10)) (ace-jump-mode (2 0))) "Elfeed goodies" tar ((:commit . "95b4ea632fbd5960927952ec8f3394eb88da4752") (:authors ("Gergely Nagy")) (:maintainer "Gergely Nagy") (:url . "https://github.com/algernon/elfeed-goodies"))]) (org . [(20190819) nil "Outline-based notes management and organizer" tar nil]) (elfeed-org . [(20181015 1100) ((elfeed (1 1 1)) (org (8 2 7)) (dash (2 10 0)) (s (1 9 0)) (cl-lib (0 5))) "Configure elfeed with one or more org-mode files" single ((:commit . "77b6bbf222487809813de260447d31c4c59902c9") (:keywords "news") (:authors ("Remy Honig" . "remyhonig@gmail.com")) (:maintainer "Remy Honig" . "remyhonig@gmail.com") (:url . "https://github.com/remyhonig/elfeed-org"))]) (elfeed . [(20190809 1358) ((emacs (24 3))) "an Emacs Atom/RSS feed reader" tar ((:commit . "87433438e10d851d57d76bea4403cbde936647e9"))]) (simple-httpd . [(20190110 1505) ((cl-lib (0 3))) "pure elisp HTTP server" single ((:commit . "08535d0fad6a32fdc03d725ec74e10a754bb9c7a") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacs-http-server"))]) (elfeed-web . [(20180829 1716) ((simple-httpd (1 4 3)) (elfeed (1 4 0)) (emacs (24 1))) "web interface to Elfeed" tar ((:commit . "87433438e10d851d57d76bea4403cbde936647e9"))]) (dash-at-point . [(20180710 1356) nil "Search the word at point with Dash" single ((:commit . "4d795a23a8428c421d5107f1b005c9d8e0d1816c") (:authors ("Shinji Tanaka" . "shinji.tanaka@gmail.com")) (:maintainer "Shinji Tanaka" . "shinji.tanaka@gmail.com") (:url . "https://github.com/stanaka/dash-at-point"))]) (helm-dash . [(20190527 1118) ((emacs (24 4)) (dash-docs (1 4 0)) (helm (1 9 2)) (cl-lib (0 5))) "Offline documentation browser for +150 APIs using Dash docsets." single ((:commit . "6c76c794fec95586028633f24773451812af5df4") (:keywords "docs") (:authors ("Raimon Grau" . "raimonster@gmail.com") ("Toni Reina " . "areina0@gmail.com") ("Bryan Gilbert" . "bryan@bryan.sh")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:url . "https://github.com/dash-docs-el/helm-dash"))]) (counsel . [(20190821 1027) ((emacs (24 3)) (swiper (0 12 0))) "Various completion functions using Ivy" single ((:commit . "824f8d767094ad48c047c811cbe764a0de96892c") (:keywords "convenience" "matching" "tools") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (dash-docs . [(20190516 1702) ((emacs (24 4)) (cl-lib (0 5)) (async (1 9 3))) "Offline documentation browser using Dash docsets." single ((:commit . "111fd9b97001f1ad887b45e5308a14ddd68ce70a") (:keywords "docs") (:authors ("Raimon Grau" . "raimonster@gmail.com") ("Toni Reina " . "areina0@gmail.com") ("Bryan Gilbert" . "bryan@bryan.sh")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:url . "http://github.com/areina/helm-dash"))]) (swiper . [(20190801 1110) ((emacs (24 1)) (ivy (0 12 0))) "Isearch with an overview. Oh, man!" single ((:commit . "824f8d767094ad48c047c811cbe764a0de96892c") (:keywords "matching") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (counsel-dash . [(20190510 708) ((emacs (24 4)) (dash-docs (1 4 0)) (counsel (0 8 0)) (cl-lib (0 5))) "Browse dash docsets using Ivy" single ((:commit . "5856b8766956428c183a2df911a05f845d014041") (:keywords "dash" "ivy" "counsel") (:authors ("Nathan Kot" . "nk@nathankot.com")) (:maintainer "Nathan Kot" . "nk@nathankot.com") (:url . "https://github.com/nathankot/counsel-dash"))]) (zeal-at-point . [(20180131 2354) nil "Search the word at point with Zeal" single ((:commit . "0fc3263f44e95acd3e9d91057677621ce4d297ee") (:authors ("Jinzhu" . "wosmvp@gmail.com")) (:maintainer "Jinzhu" . "wosmvp@gmail.com") (:url . "https://github.com/jinzhu/zeal-at-point"))]) (esxml . [(20171129 807) nil "Library for working with xml via esxml and sxml" tar ((:commit . "5548ceba17deae0c3c6d0092672edc4de3c75ce3"))]) (nov . [(20190818 2002) ((dash (2 12 0)) (esxml (0 3 3)) (emacs (24 4))) "Featureful EPUB reader mode" single ((:commit . "5184fbb1f3b3540be58a28f6dd469ff212ccc9bd") (:keywords "hypermedia" "multimedia" "epub") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:url . "https://github.com/wasamasa/nov.el"))]) (deft . [(20181226 1534) nil "quickly browse, filter, and edit plain text notes" single ((:commit . "f54e8a65a7e75a029657364055420374df45656d") (:keywords "plain text" "notes" "simplenote" "notational velocity") (:authors ("Jason R. Blevins" . "jrblevin@xbeta.org")) (:maintainer "Jason R. Blevins" . "jrblevin@xbeta.org") (:url . "https://jblevins.org/projects/deft/"))]) (aggressive-indent . [(20190218 2331) ((emacs (24 1)) (cl-lib (0 5))) "Minor mode to aggressively keep your code always indented" single ((:commit . "3803f24020ef0a656dc5345713c4964073aec9a8") (:keywords "indent" "lisp" "maint" "tools") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/aggressive-indent-mode"))]) (bracketed-paste . [(20160407 2348) ((emacs (24 3))) "bracketed paste mode support within emacs -nw" single ((:commit . "843ce3bbb63d560face889e13a57a2f7543957d5") (:keywords "terminals") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net"))]) (clean-aindent-mode . [(20171017 2043) nil "Simple indent and unindent, trims indent white-space" single ((:commit . "a97bcae8f43a9ff64e95473e4ef0d8bafe829211") (:keywords "indentation" "whitespace" "backspace") (:authors ("peter marinov" . "efravia@gmail.com")) (:maintainer "peter marinov" . "efravia@gmail.com") (:url . "https://github.com/pmarinov/clean-aindent-mode"))]) (editorconfig . [(20190703 336) ((cl-lib (0 5)) (emacs (24))) "EditorConfig Emacs Plugin" tar ((:commit . "f24f651245344f5f97c348246ce035843419b322") (:authors ("EditorConfig Team" . "editorconfig@googlegroups.com")) (:maintainer "EditorConfig Team" . "editorconfig@googlegroups.com") (:url . "https://github.com/editorconfig/editorconfig-emacs#readme"))]) (expand-region . [(20190416 538) nil "Increase selected region by semantic units." tar ((:commit . "1c31447730443d98f90f65dfcb752f347d46ad1b"))]) (hungry-delete . [(20170412 102) nil "hungry delete minor mode" single ((:commit . "0434458d3f6b2b585f332271feaa054bf4ec96d7") (:authors ("Nathaniel Flath" . "flat0103@gmail.com")) (:maintainer "Nathaniel Flath" . "flat0103@gmail.com") (:url . "http://github.com/nflath/hungry-delete"))]) (link-hint . [(20190721 1844) ((avy (0 4 0)) (emacs (24 1)) (cl-lib (0 5))) "Use avy to open, copy, etc. visible links." single ((:commit . "4db4e6fb82bfffd00f540e3a489013f6a8173871") (:keywords "convenience" "url" "avy" "link" "links" "hyperlink") (:authors ("Fox Kiester" . "noct@posteo.net")) (:maintainer "Fox Kiester" . "noct@posteo.net") (:url . "https://github.com/noctuid/link-hint.el"))]) (lorem-ipsum . [(20190819 2042) nil "Insert dummy pseudo Latin text." single ((:commit . "da75c155da327c7a7aedb80f5cfe409984787049") (:keywords "tools" "language" "convenience") (:authors ("Jean-Philippe Theberge" . "jphil21@sourceforge.net")) (:maintainer "Joe Schafer" . "joe@jschaf.com"))]) (move-text . [(20170909 330) nil "Move current line or region with M-up or M-down." single ((:commit . "7cbc941a9150468609010a93c429117da2523903") (:keywords "edit") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/emacsfodder/move-text"))]) (origami . [(20180101 1553) ((s (1 9 0)) (dash (2 5 0)) (emacs (24)) (cl-lib (0 5))) "Flexible text folding" tar ((:commit . "1f38085c8f9af7842765ed63f7d6dfe4dab59366") (:keywords "folding") (:authors ("Greg Sexton" . "gregsexton@gmail.com")) (:maintainer "Greg Sexton" . "gregsexton@gmail.com") (:url . "https://github.com/gregsexton/origami.el"))]) (password-generator . [(20150222 2040) nil "Password generator for humans. Good, Bad, Phonetic passwords included." single ((:commit . "904cdb591a04305ba882ce19e1d117f5fa60f7d3") (:authors ("Zargener" . "zargener@gmail.com")) (:maintainer "Zargener" . "zargener@gmail.com") (:url . "http://github.com/zargener/emacs-password-genarator"))]) (string-inflection . [(20180827 1301) nil "underscore -> UPCASE -> CamelCase -> lowerCamelCase conversion of names" single ((:commit . "e9a50855a4c718592c28a5a892f164ecf46e39a8") (:keywords "elisp") (:authors ("akicho8" . "akicho8@gmail.com")) (:maintainer "akicho8" . "akicho8@gmail.com"))]) (uuidgen . [(20140918 2301) nil "Provides various UUID generating functions" single ((:commit . "7eb96415484c3854a3f383d1a3e10b87ae674e22") (:keywords "extensions" "lisp" "tools") (:authors ("Kan-Ru Chen" . "koster@debian.org")) (:maintainer "Kan-Ru Chen" . "koster@debian.org"))]) (ws-butler . [(20170111 2334) nil "Unobtrusively remove trailing whitespace." single ((:commit . "52321b99be69aa1b661da7743c4421a30d8b6bcb") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/ws-butler"))]) (flx . [(20151030 1812) ((cl-lib (0 3))) "fuzzy matching with good sorting" single ((:commit . "46040d0b096a0340d91235561f27a959a61d0fef") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/flx"))]) (flx-ido . [(20180117 1519) ((flx (0 1)) (cl-lib (0 3))) "flx integration for ido" single ((:commit . "46040d0b096a0340d91235561f27a959a61d0fef") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/flx"))]) (ido-vertical-mode . [(20180618 2101) nil "Makes ido-mode display vertically." single ((:commit . "16c4c1a112796ee0bcf401ea39d3e2643a89feaf") (:keywords "convenience") (:authors ("Steven Degutis")) (:maintainer "Christopher Reichert" . "creichert07@gmail.com") (:url . "https://github.com/creichert/ido-vertical-mode.el"))]) (avy . [(20190630 1538) ((emacs (24 1)) (cl-lib (0 5))) "Jump to arbitrary positions in visible text and select text quickly." single ((:commit . "66886e265cf41c6061dc70440eb5b61fad8f48e0") (:keywords "point" "location") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/avy"))]) (ace-link . [(20190716 920) ((avy (0 4 0))) "Quickly follow links" single ((:commit . "9b6d02564650e963ce05d124f83ced17e0027d7f") (:keywords "convenience" "links" "avy") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/ace-link"))]) (centered-cursor-mode . [(20190306 1006) nil "cursor stays vertically centered" single ((:commit . "90e6d68a74d134f67c32d0621d64db90703c46eb") (:keywords "convenience") (:authors ("André Riemann" . "andre.riemann@web.de")) (:maintainer "André Riemann" . "andre.riemann@web.de") (:url . "https://github.com/andre-r/centered-cursor-mode.el"))]) (open-junk-file . [(20161210 1114) nil "Open a junk (memo) file to try-and-error" single ((:commit . "558bec7372b0fed4c4cb6074ab906535fae615bd") (:keywords "convenience" "tools") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/open-junk-file.el"))]) (hydra . [(20190821 939) ((cl-lib (0 5)) (lv (0))) "Make bindings that stick around." tar ((:commit . "435c55e9f75a8cf3ae6a4ba0c7725e3dc4e5963f") (:keywords "bindings") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/hydra"))]) (spinner . [(1 7 3) nil "Add spinners and progress-bars to the mode-line for ongoing operations" single ((:keywords "processes" "mode-line") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/spinner.el"))]) (seq . [(2 20) nil "Sequence manipulation functions" tar ((:maintainer nil . "emacs-devel@gnu.org") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:keywords "sequences") (:url . "http://elpa.gnu.org/packages/seq.html"))]) (lv . [(20190821 947) nil "Other echo area" single ((:commit . "435c55e9f75a8cf3ae6a4ba0c7725e3dc4e5963f") (:authors ("Oleh Krehel")) (:maintainer "Oleh Krehel"))]) (paradox . [(20190624 41) ((emacs (24 4)) (seq (1 7)) (let-alist (1 0 3)) (spinner (1 7 3)) (hydra (0 13 2))) "A modern Packages Menu. Colored, with package ratings, and customizable." tar ((:commit . "1b9e4b198e0a02773b52f6fe4fd03a82340c6cbc") (:keywords "package" "packages") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/paradox"))]) (restart-emacs . [(20180601 1031) nil "Restart emacs from within emacs" single ((:commit . "9aa90d3df9e08bc420e1c9845ee3ff568e911bd9") (:keywords "convenience") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:url . "https://github.com/iqbalansari/restart-emacs"))]) (smooth-scrolling . [(20161002 1949) nil "Make emacs scroll smoothly" single ((:commit . "2462c13640aa4c75ab3ddad443fedc29acf68f84") (:keywords "convenience") (:authors ("Adam Spiers" . "emacs-ss@adamspiers.org") ("Jeremy Bondeson" . "jbondeson@gmail.com") ("Ryan C. Thompson" . "rct+github@thompsonclan.org")) (:maintainer "Adam Spiers" . "emacs-ss@adamspiers.org") (:url . "http://github.com/aspiers/smooth-scrolling/"))]) (symbol-overlay . [(20190608 442) ((emacs (24 3))) "Highlight symbols with keymap-enabled overlays" single ((:commit . "e40a7c407f24158c45eaa5f54ed41f5e416a51dc") (:keywords "faces" "matching") (:authors ("wolray" . "wolray@foxmail.com")) (:maintainer "wolray" . "wolray@foxmail.com") (:url . "https://github.com/wolray/symbol-overlay/"))]) (helm . [(20190821 735) ((emacs (24 4)) (async (1 9 3)) (popup (0 5 3)) (helm-core (3 0))) "Helm is an Emacs incremental and narrowing framework" tar ((:commit . "a38316808f4f5c2b4c4b6b909ce6e6544a9c4ffb") (:url . "https://emacs-helm.github.io/helm/"))]) (helm-core . [(20190820 1142) ((emacs (24 4)) (async (1 9 3))) "Development files for Helm" tar ((:commit . "a38316808f4f5c2b4c4b6b909ce6e6544a9c4ffb") (:url . "https://emacs-helm.github.io/helm/"))]) (async . [(20190503 656) nil "Asynchronous processing in Emacs" tar ((:commit . "bd68cc1ab1ac6af890e250bdaa12ffb1cb9649be") (:keywords "async") (:url . "https://github.com/jwiegley/emacs-async"))]) (helm-purpose . [(20170114 1636) ((emacs (24)) (helm (1 9 2)) (window-purpose (1 4))) "Helm Interface for Purpose" single ((:commit . "9ff4c21c1e9ebc7afb851b738f815df7343bb287") (:authors ("Bar Magal (2016)")) (:maintainer "Bar Magal (2016)") (:url . "https://github.com/bmag/helm-purpose"))]) (window-purpose . [(20190628 1827) ((emacs (24 4)) (let-alist (1 0 3)) (imenu-list (0 1))) "Purpose-based window management for Emacs" tar ((:commit . "f6421966761ad911fe8861aba2b110c5dd60d1ea") (:keywords "frames") (:authors ("Bar Magal")) (:maintainer "Bar Magal") (:url . "https://github.com/bmag/emacs-purpose"))]) (ivy . [(20190821 1017) ((emacs (24 1))) "Incremental Vertical completYon" tar ((:commit . "824f8d767094ad48c047c811cbe764a0de96892c") (:keywords "matching") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (imenu-list . [(20190115 2130) ((cl-lib (0 5))) "Show imenu entries in a separate buffer" single ((:commit . "46008738f8fef578a763c308cf6695e5b4d4aa77") (:authors ("Bar Magal (2015)")) (:maintainer "Bar Magal (2015)") (:url . "https://github.com/bmag/imenu-list"))]) (let-alist . [(1 0 6) ((emacs (24 1))) "Easily let-bind values of an assoc-list by their names" single ((:url . "http://elpa.gnu.org/packages/let-alist.html") (:keywords "extensions" "lisp") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com"))]) (ivy-purpose . [(20160724 1003) ((emacs (24)) (ivy (0 8)) (window-purpose (1 5))) "Ivy Interface for Purpose" single ((:commit . "0495f2f3aed64d7e0028125e76a9a68f8fc4107e") (:authors ("Bar Magal (2016)")) (:maintainer "Bar Magal (2016)") (:url . "https://github.com/bmag/ivy-purpose"))]) (define-word . [(20190506 1525) ((emacs (24 3))) "display the definition of word at point." single ((:commit . "11bfee628aee082a9a3a2fd5f083cbdb05d5d00a") (:keywords "dictionary" "convenience") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/define-word"))]) (google-translate . [(20190620 1416) nil "Emacs interface to Google Translate." tar ((:commit . "dc118de511c433750d4c98b9dd67350118c04fd6"))]) (org-plus-contrib . [(20190819) nil "Outline-based notes management and organizer" tar nil]) (org-bullets . [(20190802 927) nil "Show bullets in org-mode as UTF-8 characters" single ((:commit . "c19b13be00df8d8dc596e4f1aef4a094b08ac801") (:authors ("sabof")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacsorphanage/org-bullets"))]) (toc-org . [(20190603 803) nil "add table of contents to org-mode files (formerly, org-toc)" single ((:commit . "2539b4be401d006e2752f6ad3b88e696889a7fc8") (:keywords "org-mode" "org-toc" "toc-org" "org" "toc" "table" "of" "contents") (:authors ("Sergei Nosov ")) (:maintainer "Sergei Nosov ") (:url . "https://github.com/snosov1/toc-org"))]) (hl-anything . [(20160422 1708) ((emacs (24 3))) "Highlight symbols, selections, enclosing parens and more." tar ((:commit . "8696bc55a8cba408f0fc83a907a9ec529d79e558") (:authors ("boyw165")) (:maintainer "boyw165"))]) (column-enforce-mode . [(20171030 1900) nil "Highlight text that extends beyond a column" single ((:commit . "2341a2b6a33d4b8b74c35062ec9cfe1bffd61944") (:authors ("Jordon Biondo")) (:maintainer "Jordon Biondo") (:url . "www.github.com/jordonbiondo/column-enforce-mode"))]) (highlight-indentation . [(20181204 839) nil "Minor modes for highlighting indentation" single ((:commit . "d03803f2c06749c430443a3d24e039cbafc9c58f") (:authors ("Anton Johansson" . "anton.johansson@gmail.com")) (:maintainer "Anton Johansson" . "anton.johansson@gmail.com") (:url . "https://github.com/antonj/Highlight-Indentation-for-Emacs"))]) (parent-mode . [(20150824 2300) nil "get major mode's parent modes" single ((:commit . "db692cf08deff2f0e973e6e86e26662b44813d1b") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/parent-mode"))]) (highlight-numbers . [(20181013 1744) ((emacs (24)) (parent-mode (2 0))) "Highlight numbers in source code" single ((:commit . "8b4744c7f46c72b1d3d599d4fb75ef8183dee307") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/highlight-numbers"))]) (highlight-parentheses . [(20180704 1102) nil "highlight surrounding parentheses" single ((:commit . "f0bd58c8dadd2db703b7bfd09e911b5fda05b3df") (:keywords "faces" "matching") (:authors ("Nikolaj Schumacher ")) (:maintainer "Tassilo Horn" . "tsdh@gnu.org") (:url . "https://github.com/tsdh/highlight-parentheses.el"))]) (indent-guide . [(20170221 1127) nil "show vertical lines to guide indentation" single ((:commit . "d64f43011c72068e008621e620009ec592b35913") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (rainbow-delimiters . [(20170929 1132) nil "Highlight brackets according to their depth" single ((:commit . "e561cff4abf97d00d9b2b5f10256d417182e2772") (:keywords "faces" "convenience" "lisp" "tools") (:authors ("Jeremy Rayman" . "opensource@jeremyrayman.com") ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/rainbow-delimiters"))]) (volatile-highlights . [(20160612 155) nil "Minor mode for visual feedback on some operations." single ((:commit . "9a20091f0ce7fc0a6b3e641a6a46d5f3ac4d8392") (:keywords "emulations" "convenience" "wp") (:authors ("K-talo Miyazaki ")) (:maintainer "K-talo Miyazaki ") (:url . "http://www.emacswiki.org/emacs/download/volatile-highlights.el"))]) (visual-fill-column . [(20190422 2154) ((emacs (24 3))) "fill-column for visual-line-mode" single ((:commit . "772d4b25ba19f57409cd03524be0f5bfdc2e8da1") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (writeroom-mode . [(20190406 2135) ((emacs (24 1)) (visual-fill-column (1 9))) "Minor mode for distraction-free writing" tar ((:commit . "ebe522ba5a0367cf82ed03ffeb63fe597b84f4a1") (:keywords "text") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (hl-todo . [(20190807 1831) ((emacs (25))) "highlight TODO and similar keywords" single ((:commit . "be57dbc5a4667e4a60b8249b53fa176db1019c8e") (:keywords "convenience") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/hl-todo"))]) (page-break-lines . [(20190519 2238) ((emacs (24 4))) "Display ^L page breaks as tidy horizontal lines" single ((:commit . "6f19d894bda6a981c10a58df5e23419f4d2ba353") (:keywords "convenience" "faces") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/page-break-lines"))]) (evil-anzu . [(20170124 718) ((evil (1 0 0)) (anzu (0 46))) "anzu for evil-mode" single ((:commit . "9bca6ca14d865e7e005bc02a28a09b4ae74facc9") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com") ("Fredrik Bergroth" . "fbergroth@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-evil-anzu"))]) (evil-args . [(20180908 2157) ((evil (1 0 8))) "Motions and text objects for delimited arguments in Evil." single ((:commit . "758ad5ae54ad34202064fec192c88151c08cb387") (:keywords "evil" "vim-emulation") (:authors ("Connor Smith" . "wconnorsmith@gmail.com")) (:maintainer "Connor Smith" . "wconnorsmith@gmail.com") (:url . "http://github.com/wcsmith/evil-args"))]) (evil-ediff . [(20170724 1923) ((evil (1 2 3))) "Make ediff a little evil" single ((:commit . "50d26cb0654fca8f8fd7227410e5cbf0b8f681cf") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/evil-ediff"))]) (evil-exchange . [(20170511 259) ((evil (1 2 8)) (cl-lib (0 3))) "Exchange text more easily within Evil" single ((:commit . "47691537815150715e64e6f6ec79be7746c96120") (:keywords "evil" "plugin") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:url . "http://github.com/Dewdrops/evil-exchange"))]) (evil-goggles . [(20181123 1946) ((emacs (24 4)) (evil (1 0 0))) "Add a visual hint to evil operations" single ((:commit . "78454a7e8bd609edf0d93cb0a7f9ed576dd33546") (:keywords "emulations" "evil" "vim" "visual") (:authors ("edkolev" . "evgenysw@gmail.com")) (:maintainer "edkolev" . "evgenysw@gmail.com") (:url . "http://github.com/edkolev/evil-goggles"))]) (iedit . [(20190419 803) nil "Edit multiple regions in the same way simultaneously." tar ((:commit . "e2c100cdd67b7d82835d281ac2cd1bf4f374bc8f") (:keywords "occurrence" "region" "simultaneous" "refactoring") (:authors ("Victor Ren" . "victorhge@gmail.com")) (:maintainer "Victor Ren" . "victorhge@gmail.com") (:url . "https://www.emacswiki.org/emacs/Iedit"))]) (evil-iedit-state . [(20180607 558) ((evil (1 0 9)) (iedit (0 97))) "Evil states to interface iedit mode." single ((:commit . "f75cff4ecbd5beaa9ca64a6c157c4105f078daec") (:keywords "convenience" "editing" "evil" "iedit" "mnemonic") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/evil-iedit-state"))]) (evil-indent-plus . [(20151109 1906) ((evil (0)) (cl-lib (0 5))) "Evil textobjects based on indentation" single ((:commit . "0c7501e6efed661242c3a20e0a6c79a6455c2c40") (:keywords "convenience" "evil") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:url . "http://github.com/TheBB/evil-indent-plus"))]) (evil-lion . [(20170811 614) ((emacs (24 3)) (evil (1 0 0))) "Evil align operator, port of vim-lion" single ((:commit . "6b03593f5dd6e7c9ca02207f9a73615cf94c93ab") (:keywords "emulations" "evil" "vim") (:authors ("edkolev" . "evgenysw@gmail.com")) (:maintainer "edkolev" . "evgenysw@gmail.com") (:url . "http://github.com/edkolev/evil-lion"))]) (smartparens . [(20190728 2037) ((dash (2 13 0)) (cl-lib (0 3))) "Automatic insertion, wrapping and paredit-like navigation with user defined pairs." tar ((:commit . "7080e7fba9f478c2e5d4c18a325c3a5d60f6be76"))]) (bind-map . [(20161207 1511) ((emacs (24 3))) "Bind personal keymaps in multiple locations" single ((:commit . "bf4181e3a41463684adfffc6c5c305b30480e30f") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/emacs-bind-map"))]) (evil-lisp-state . [(20160404 248) ((evil (1 0 9)) (bind-map (0)) (smartparens (1 6 1))) "An evil state to edit Lisp code" single ((:commit . "3c65fecd9917a41eaf6460f22187e2323821f3ce") (:keywords "convenience" "editing" "evil" "smartparens" "lisp" "mnemonic") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/evil-lisp-state"))]) (evil-nerd-commenter . [(20190801 148) ((emacs (24 4))) "Comment/uncomment lines efficiently. Like Nerd Commenter in Vim" tar ((:commit . "7132693a4cc684dff232839fed45a8a54d832646") (:keywords "commenter" "vim" "line" "evil") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/evil-nerd-commenter"))]) (evil-numbers . [(20140606 1251) nil "increment/decrement numbers like in vim" single ((:commit . "6ea1c8c3a9b37bed63d48f1128e9a4910e68187e") (:keywords "numbers" "increment" "decrement" "octal" "hex" "binary") (:authors ("Michael Markert" . "markert.michael@googlemail.com")) (:maintainer "Michael Markert" . "markert.michael@googlemail.com") (:url . "http://github.com/cofi/evil-numbers"))]) (evil-textobj-line . [(20150729 1522) ((evil (1 0 0))) "evil textobj line" single ((:commit . "3d401b6831bdbeec967ec8e64177a8950251e812") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-evil-textobj-line"))]) (evil-tutor . [(20150103 650) ((evil (1 0 9))) "Vimtutor adapted to Evil and wrapped in a major-mode" tar ((:commit . "4e124cd3911dc0d1b6817ad2c9e59b4753638f28") (:keywords "convenience" "editing" "evil") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/evil-tutor"))]) (evil-visual-mark-mode . [(20190116 1557) ((evil (1 0 9)) (dash (2 10))) "Display evil marks on buffer" single ((:commit . "ac5997971972a9251f140b5542d82790ca4a43b4") (:keywords "evil") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com"))]) (evil-visualstar . [(20160223 48) ((evil (0))) "Starts a * or # search from the visual selection" single ((:commit . "06c053d8f7381f91c53311b1234872ca96ced752") (:keywords "evil" "vim" "visualstar") (:authors ("Bailey Ling")) (:maintainer "Bailey Ling") (:url . "https://github.com/bling/evil-visualstar"))]) (linum-relative . [(20180124 1047) nil "display relative line number in emacs." single ((:commit . "c74a6981b688a5e1e6b8e0809363963ff558ce4d") (:keywords "converience") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/linum-relative"))]) (anzu . [(20190303 1701) ((emacs (24 3))) "Show number of matches in mode-line while searching" single ((:commit . "592f8ee6d0b1bc543943b36a30063c2d1aac4b22") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-anzu"))]) (shrink-path . [(20190208 1335) ((emacs (24)) (s (1 6 1)) (dash (1 8 0)) (f (0 10 0))) "fish-style path" single ((:commit . "c14882c8599aec79a6e8ef2d06454254bb3e1e41") (:authors ("Benjamin Andresen")) (:maintainer "Benjamin Andresen") (:url . "https://gitlab.com/bennya/shrink-path.el"))]) (doom-modeline . [(20190820 1749) ((emacs (25 1)) (all-the-icons (1 0 0)) (shrink-path (0 2 0)) (dash (2 11 0))) "A minimal and modern mode-line" tar ((:commit . "442e1ada1832928679fb3e5eb09b63c842853575") (:keywords "faces" "mode-line") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:url . "https://github.com/seagle0128/doom-modeline"))]) (fancy-battery . [(20150101 1204) ((emacs (24 1))) "Fancy battery display" single ((:commit . "9b88ae77a01aa3edc529840338bcb2db7f445822") (:keywords "convenience" "tools" "hardware") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/lunaryorn/fancy-battery.el"))]) (spaceline . [(20181223 2024) ((emacs (24 4)) (cl-lib (0 5)) (powerline (2 3)) (dash (2 11 0)) (s (1 10 0))) "Modeline configuration library for powerline" tar ((:commit . "ae45a819ea7ae52febb4d7d82170af44dff10f19") (:keywords "mode-line" "powerline" "spacemacs") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:url . "https://github.com/TheBB/spaceline"))]) (all-the-icons . [(20190320 1809) ((emacs (24 3)) (memoize (1 0 1))) "A library for inserting Developer icons" tar ((:commit . "f996fafa5b2ea072d0ad1df9cd98acc75820f530") (:keywords "convenient" "lisp") (:authors ("Dominic Charlesworth" . "dgc336@gmail.com")) (:maintainer "Dominic Charlesworth" . "dgc336@gmail.com") (:url . "https://github.com/domtronn/all-the-icons.el"))]) (memoize . [(20180614 1930) nil "Memoization functions" single ((:commit . "9a561268ffb550b257a08710489a95cd087998b6") (:authors ("Christopher Wellons" . "mosquitopsu@gmail.com")) (:maintainer "Christopher Wellons" . "mosquitopsu@gmail.com") (:url . "https://github.com/skeeto/emacs-memoize"))]) (powerline . [(20190323 213) ((cl-lib (0 2))) "Rewrite of Powerline" tar ((:commit . "6ef4a06c3c583045accbc957b6f449b7c0c57cd8") (:keywords "mode-line") (:authors ("Donald Ephraim Curtis" . "dcurtis@milkbox.net")) (:maintainer "Donald Ephraim Curtis" . "dcurtis@milkbox.net") (:url . "http://github.com/milkypostman/powerline/"))]) (spaceline-all-the-icons . [(20190325 1602) ((emacs (24 4)) (all-the-icons (2 6 0)) (spaceline (2 0 0)) (memoize (1 0 1))) "A Spaceline theme using All The Icons" tar ((:commit . "5afd48c10f1bd42d9b9648c5e64596b72f3e9042") (:keywords "convenience" "lisp" "tools") (:authors ("Dominic Charlesworth" . "dgc336@gmail.com")) (:maintainer "Dominic Charlesworth" . "dgc336@gmail.com") (:url . "https://github.com/domtronn/spaceline-all-the-icons.el"))]) (symon . [(20170224 833) nil "tiny graphical system monitor" single ((:commit . "8dd8b6df49b03cd7d31b85aedbe9dd08fb922335") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (devdocs . [(20170731 850) nil "Launch DevDocs search" single ((:commit . "a2d51e824f0cc48a9dd611cc740bc8b86143e611") (:authors ("Chunyang Xu" . "xuchunyang.me@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang.me@gmail.com") (:url . "https://github.com/xuchunyang/DevDocs.el"))]) (popup . [(20160709 1429) ((cl-lib (0 5))) "Visual Popup User Interface" single ((:commit . "80829dd46381754639fb764da11c67235fe63282") (:keywords "lisp") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (f . [(20190109 906) ((s (1 7 0)) (dash (2 2 0))) "Modern API for working with files and directories" single ((:commit . "8191672377816a1975414cc1f116fd3b94b30bd0") (:keywords "files" "directories") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/f.el"))]) (dash . [(20190814 2006) nil "A modern list library for Emacs" single ((:commit . "11907f4592ff1813536366d54245d3ecf6b99198") (:keywords "lists") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (s . [(20180406 808) nil "The long lost Emacs string manipulation library." single ((:commit . "03410e6a7a2b11e47e1fea3b7d9899c7df26435e") (:keywords "strings") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (dumb-jump . [(20190804 533) ((emacs (24 3)) (f (0 20 0)) (s (1 11 0)) (dash (2 9 0)) (popup (0 5 3))) "jump to definition for multiple languages without configuration." single ((:commit . "7ffa63cdc8481158a2dbfe4acc6719ebe7fff056") (:keywords "programming") (:authors ("jack angers")) (:maintainer "jack angers"))]) (request . [(20190819 1735) ((emacs (24 4))) "Compatible layer for URL request in Emacs" single ((:commit . "000719521e7a1f065f78ea5ffe787d949a5abc5e") (:authors ("Takafumi Arakaki ")) (:maintainer "Takafumi Arakaki ") (:url . "https://github.com/tkf/emacs-request"))]) (evil-snipe . [(20180731 1731) ((emacs (24 4)) (evil (1 2 12)) (cl-lib (0 5))) "emulate vim-sneak & vim-seek" single ((:commit . "8dd076cc56eb9b04494e4e303b86a959b048350b") (:keywords "emulation" "vim" "evil" "sneak" "seek") (:authors ("Henrik Lissner ")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/evil-snipe"))]) (evil . [(20190729 704) ((emacs (24 1)) (undo-tree (0 6 3)) (goto-chg (1 6)) (cl-lib (0 5))) "Extensible Vi layer for Emacs." tar ((:commit . "874beba2cb243c325eca08fb7badff567f3c9494"))]) (cl-lib . [(0 6 1) nil "Forward cl-lib compatibility library for Emacs<24.3" single ((:url . "http://elpa.gnu.org/packages/cl-lib.html") (:authors ("Stefan Monnier" . "monnier@iro.umontreal.ca")) (:maintainer "Stefan Monnier" . "monnier@iro.umontreal.ca"))]) (goto-chg . [(20190110 2114) ((undo-tree (0 1 3))) "goto last change" single ((:commit . "1829a13026c597e358f716d2c7793202458120b5") (:keywords "convenience" "matching") (:authors ("David Andersson ")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/emacs-evil/goto-chg"))]) (undo-tree . [(0 6 5) nil "Treat undo history as a tree" single ((:keywords "convenience" "files" "undo" "redo" "history" "tree") (:authors ("Toby Cubitt" . "toby-undo-tree@dr-qubit.org")) (:maintainer "Toby Cubitt" . "toby-undo-tree@dr-qubit.org") (:url . "http://www.dr-qubit.org/emacs.php"))]) (evil-commentary . [(20170413 1451) ((evil (1 0 0))) "Comment stuff out. A port of vim-commentary." tar ((:commit . "395f91014b69844b81660c155f42eb9b1b3d199d") (:keywords "evil" "comment" "commentary" "evil-commentary") (:authors ("Quang Linh LE" . "linktohack@gmail.com")) (:maintainer "Quang Linh LE" . "linktohack@gmail.com") (:url . "http://github.com/linktohack/evil-commentary"))]) (vim-empty-lines-mode . [(20150111 426) ((emacs (23))) "Vim-like empty line indicator at end of files." single ((:commit . "d4a5034ca8ea0c962ad6e92c86c0fa2a74d2964b") (:keywords "emulations") (:authors ("Jonne Mickelin" . "jonne@ljhms.com")) (:maintainer "Jonne Mickelin" . "jonne@ljhms.com") (:url . "https://github.com/jmickelin/vim-empty-lines-mode"))])) \ No newline at end of file diff --git a/packages/arduino-mode-20180509.36.tar b/packages/arduino-mode-20180509.36.tar index 4b59456..1ebe301 100644 Binary files a/packages/arduino-mode-20180509.36.tar and b/packages/arduino-mode-20180509.36.tar differ diff --git a/packages/async-20180527.1730.tar b/packages/async-20190503.656.tar similarity index 93% rename from packages/async-20180527.1730.tar rename to packages/async-20190503.656.tar index d4e8681..6347fef 100644 Binary files a/packages/async-20180527.1730.tar and b/packages/async-20190503.656.tar differ diff --git a/packages/attrap-20190805.1829.el b/packages/attrap-20190805.1829.el new file mode 100644 index 0000000..653dc51 --- /dev/null +++ b/packages/attrap-20190805.1829.el @@ -0,0 +1,398 @@ +;;; attrap.el --- ATtempt To Repair At Point -*- lexical-binding: t -*- + +;; Copyright (c) 2018 Jean-Philippe Bernardy + + +;; Author: Jean-Philippe Bernardy +;; Maintainer: Jean-Philippe Bernardy +;; URL: https://github.com/jyp/attrap +;; Package-Version: 20190805.1829 +;; Created: February 2018 +;; Keywords: programming, tools +;; Package-Requires: ((dash "2.12.0") (emacs "25.1") (f "0.19.0") (flycheck "0.30") (s "1.11.0")) +;; Version: 0.1 + +;; 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 file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Attrap! provides a command to attempt to fix the flycheck error at point. +;; +;; Users: Invoke the command `attrap-attrap' when point is on a +;; flycheck or flymake error, and check the results. (If several +;; fixes apply you will be asked which one to apply.) Attrap! +;; currently comes with builtin fixers for haskell (GHC messages) and +;; elisp. +;; +;; Configuration: `attrap-flymake-backends-alist' is an alist from +;; flymake backend to attrap fixer. `attrap-flycheck-checkers-alist' +;; is an alist from flycheck checker symbol to attrap fixer. All the +;; See below for the definition of a fixer. +;; +;; A fixer is a element is a side-effect-free function mapping an +;; error message MSG to a list of options. An option is a cons of a +;; description and a repair. (Thus a list of options is an alist.) +;; The repair is a function of no argument which is meant to apply one +;; fix suggested by MSG in the current buffer, at point. The +;; description is meant to be a summarized user-facing s-expr which +;; describes the repair. This description can be used for example for +;; selecting the best repair. An option can be conveniently defined +;; using `attrap-option'. A singleton option list can be conveniently +;; defined using `attrap-one-option'. + + +;;; Code: +(require 'dash) +(require 's) +(require 'flycheck) + +(defcustom attrap-flycheck-checkers-alist '((haskell-dante . attrap-ghc-fixer) + (emacs-lisp . attrap-elisp-fixer)) + "An alist from flycheck checker symbol to attrap fixer." + :type '(alist :key-type symbol :value-type function) + :group 'attrap) + +(defcustom attrap-flymake-backends-alist + '((dante-flymake . attrap-ghc-fixer) + (elisp-flymake-byte-compile . attrap-elisp-fixer) + (elisp-flymake-checkdoc . attrap-elisp-fixer)) + "An alist from flymake backend to attrap fixer." + :type '(alist :key-type symbol :value-type function) + :group 'attrap) + +(defun attrap-select-and-apply-option (options) + "Ask the user which of OPTIONS is best, then apply it." + (when (not options) (error "No fixer applies to the issue at point")) + (let* ((named-options (--map (cons (format "%s" (car it)) (cdr it)) options)) + (selected-fix (if (eq 1 (length options)) + (car options) + (assoc (completing-read "repair using: " + named-options + nil + t) + named-options)))) + (message "Applied %s" (car selected-fix)) + (save-excursion + (funcall (cdr selected-fix))))) + +;;;###autoload +(defun attrap-flymake (pos) + "Attempt to repair the flymake error at POS." + (interactive "d") + (let ((diags (flymake-diagnostics pos))) + (when (not diags) (error "No flymake diagnostic at point")) + (attrap-select-and-apply-option + (-non-nil (--mapcat (let ((fixer (alist-get (flymake-diagnostic-backend it) + attrap-flymake-backends-alist))) + (when fixer (funcall fixer + (flymake-diagnostic-text it) + (flymake-diagnostic-beg it) + (flymake-diagnostic-end it)))) + diags))))) + + +;;;###autoload +(defun attrap-flycheck (pos) + "Attempt to repair the flycheck error at POS." + (interactive "d") + (let ((messages (-filter + #'car + (--map (list (flycheck-error-message + (overlay-get it 'flycheck-error)) + (overlay-start it) + (overlay-end it)) + (flycheck-overlays-at pos)))) + (checker (flycheck-get-checker-for-buffer))) + (when (not messages) (error "No flycheck message at point")) + (when (not checker) (error "No flycheck-checker for current buffer")) + (let ((fixers (-map #'cdr (--filter (eq (car it) checker) attrap-flycheck-checkers-alist)))) + (when (not fixers) (error "No fixers for flycheck-checker %s" checker)) + (attrap-select-and-apply-option + (-non-nil (-mapcat + (lambda (msg) (-mapcat + (lambda (fixer) (apply fixer msg)) + fixers)) + messages)))))) + +;;;###autoload +(defun attrap-attrap (pos) + "Attempt to repair the error at POS." + (interactive "d") + (cond + ((bound-and-true-p flymake-mode) (attrap-flymake pos)) + ((bound-and-true-p flycheck-mode) (attrap-flycheck pos)) + (t (error "Expecting flymake or flycheck to be active")))) + +(defcustom attrap-haskell-extensions + '("AllowAmbiguousTypes" + "BangPatterns" + "ConstraintKinds" + "DataKinds" + "DefaultSignatures" + "DeriveAnyClass" + "DeriveFoldable" + "DeriveFunctor" + "DeriveGeneric" + "DeriveTraversable" + "EmptyCase" + "EmptyDataDecls" + "EmptyDataDeriving" + "ExplicitNamespaces" + "FlexibleContexts" + "FlexibleInstances" + "FunctionalDependencies" + "GADTs" + "GeneralizedNewtypeDeriving" + "InstanceSigs" + "KindSignatures" + "MultiParamTypeClasses" + "NamedFieldPuns" + "ParallelListComp" + "PartialTypeSignatures" + "PatternSynonyms" + "PolyKinds" + "RankNTypes" + "RecordWildCards" + "ScopedTypeVariables" + "StandaloneDeriving" + "TemplateHaskell" + "TransformListComp" + "TupleSections" + "TypeApplications" + "TypeFamilies" + "TypeInType" + "TypeOperators" + "TypeSynonymInstances" + "UndecidableSuperClasses" + "UndecidableInstances" + "ViewPatterns") + "Language extensions that Attrap can use to fix errors." + :type '(repeat string) + :group 'attrap) + +(defmacro attrap-option (description &rest body) + "Create an attrap option with DESCRIPTION and BODY." + (declare (indent 1)) + `(let ((saved-match-data (match-data))) + (cons ,description + (lambda () + (set-match-data saved-match-data 'evaporate) + ,@body)))) + +(defmacro attrap-one-option (description &rest body) + "Create an attrap option list with a single element of DESCRIPTION and BODY." + (declare (indent 1)) + `(list (attrap-option ,description ,@body))) + +(defmacro attrap-alternatives (&rest clauses) + "Append all succeeding clauses. +Each clause looks like (CONDITION BODY...). CONDITION is evaluated +and, if the value is non-nil, this clause succeeds: +then the expressions in BODY are evaluated and the last one's +value is a list which is appended to the result of `attrap-alternatives'. +usage: (attrap-alternatives CLAUSES...)" + `(append ,@(mapcar (lambda (c) `(when ,(car c) ,@(cdr c))) clauses))) + +(defun attrap-elisp-fixer (msg _beg _end) + "An `attrap' fixer for any elisp warning given as MSG." + (attrap-alternatives + ((string-match "Name emacs should appear capitalized as Emacs" msg) + (attrap-one-option 'capitalize-emacs + (let ((case-fold-search nil)) + (re-search-forward "emacs" (line-end-position)) + (replace-match "Emacs" nil t nil 0)))) + ((string-match "White space found at end of line" msg) + (attrap-one-option 'delete-trailing-space + (end-of-line) + (delete-region (point) (progn (skip-chars-backward "\t ") (point))))) + ((string-match "There should be two spaces after a period" msg) + (attrap-one-option 'add-space + (beginning-of-line) + (re-search-forward "\\(\\.\\) [^ ]" (line-end-position)) + (replace-match ". " nil t nil 1))) + ((string-match "might as well have a documentation" msg) + (attrap-one-option 'add-empty-doc + (beginning-of-line) + (insert " \"\"\n"))) + ((string-match "The footer should be: " msg) + (let ((footer (s-replace "\\n" "\n" (substring msg (match-end 0))))) + (attrap-one-option 'add-footer + (end-of-line) + (insert (concat "\n" footer))))) + ((string-match "First line is not a complete sentence" msg) + (attrap-one-option 'merge-lines + (end-of-line) + (delete-char 1))) + ((string-match "First sentence should end with punctuation" msg) + (attrap-one-option 'add-punctuation + (end-of-line) + (backward-char) + (insert "."))))) + +(defun attrap-ghc-fixer (msg pos _end) + "An `attrap' fixer for any GHC error or warning given as MSG and reported between POS and END." + (let ((normalized-msg (s-collapse-whitespace msg))) + (cond + ((string-match "Redundant constraints?: (?\\([^,)\n]*\\)" msg) + (attrap-one-option 'delete-reduntant-constraint + (let ((constraint (match-string 1 msg))) + (search-forward constraint) ; find type sig + (delete-region (match-beginning 0) (match-end 0)) + (when (looking-at "[ \t]*,") + (delete-region (point) (search-forward ","))) + (when (looking-at "[ \t]*=>") + (delete-region (point) (search-forward "=>")))))) + ((string-match "The type signature for ‘\\(.*\\)’[ \t\n]*lacks an accompanying binding" msg) + (attrap-one-option 'add-binding + (beginning-of-line) + (forward-line) + (insert (concat (match-string 1 msg) " = _\n")))) + ((string-match "add (\\(.*\\)) to the context of[\n ]*the type signature for:[ \n]*\\([^ ]*\\) ::" msg) + (attrap-one-option 'add-constraint-to-context + (let ((missing-constraint (match-string 1 msg)) + (function-name (match-string 2 msg))) + (search-backward-regexp (concat (regexp-quote function-name) "[ \t]*::[ \t]*" )) ; find type sig + (goto-char (match-end 0)) + (when (looking-at "forall\\|∀") ; skip quantifiers + (search-forward ".")) + (skip-chars-forward "\n\t ") ; skip spaces + (insert (concat missing-constraint " => "))))) + ((string-match "Unticked promoted constructor: ‘\\(.*\\)’" msg) + (let ((constructor (match-string 1 msg))) + (attrap-one-option 'tick-promoted-constructor + (goto-char pos) + ;; when the constructor is infix, flycheck reports the wrong position. + (search-forward constructor) + (backward-char (length constructor)) + (insert "'")))) + ((string-match "Patterns not matched:" msg) + (attrap-one-option 'add-missing-patterns + (let ((patterns (mapcar #'string-trim (split-string (substring msg (match-end 0)) "\n" t " ")))) ;; patterns to match + (if (string-match "In an equation for ‘\\(.*\\)’:" msg) + (let ((function-name (match-string 1 msg))) + (end-of-line) + (dolist (pattern patterns) + (insert (concat "\n" function-name " " pattern " = _")))) + (end-of-line) ;; assuming that the case expression is on multiple lines and that "of" is at the end of the line + (dolist (pattern patterns) + (insert "\n ") ;; fixme: guess how much indent is needed. + (insert (concat pattern " -> _"))))))) + ((string-match "A do-notation statement discarded a result of type" msg) + (attrap-one-option 'explicitly-discard-result + (goto-char pos) + (insert "_ <- "))) + ((string-match "\\(Failed to load interface for\\|Could not find module\\) ‘\\(.*\\)’\n[ ]*Perhaps you meant[ \n]*\\([^ ]*\\)" msg) + (attrap-one-option 'rename-module-import + (let ((replacement (match-string 3 msg))) + ;; ^^ delete-region may garble the matches + (search-forward (match-string 2 msg)) + (delete-region (match-beginning 0) (point)) + (insert replacement)))) + ((string-match "Unsupported extension: \\(.*\\)\n[ ]*Perhaps you meant ‘\\([^‘]*\\)’" msg) + (attrap-one-option 'rename-extension + (let ((replacement (match-string 2 msg))) + ;; ^^ delete-region may garble the matches + (goto-char pos) + (search-forward (match-string 1 msg)) + (delete-region (match-beginning 0) (point)) + (insert replacement)))) + ((string-match "Perhaps you want to add ‘\\(.*\\)’ to the import list[\n\t ]+in the import of[ \n\t]*‘.*’[\n\t ]+([^:]*:\\([0-9]*\\):[0-9]*-\\([0-9]*\\))" msg) + (attrap-one-option 'add-to-import-list + (let ((missing (match-string 1 msg)) + (line (string-to-number (match-string 2 msg))) + (end-col (string-to-number (match-string 3 msg)))) + (goto-char (point-min)) + (forward-line (1- line)) + (move-to-column (1- end-col)) + (skip-chars-backward " \t") + (unless (looking-back "(" (- (point) 2)) (insert ",")) + (insert missing)))) + ;; Not in scope: data constructor ‘SimpleBroadcast’ + ;; Perhaps you meant ‘SimpleBroadCast’ (imported from TypedFlow.Types) + ;; Not in scope: ‘BackCore.argmax’ + ;; Perhaps you meant one of these: + ;; ‘BackCore.argMax’ (imported from TensorFlow.GenOps.Core), + ;; ‘BackCore.argMax'’ (imported from TensorFlow.GenOps.Core), + ;; ‘BackCore.max’ (imported from TensorFlow.GenOps.Core) + ((string-match (s-join "\\|" + '("Data constructor not in scope:[ \n\t]*\\(?1:[^ \n]*\\)" + "Variable not in scope:[ \n\t]*\\(?1:[^ \n]*\\)" + "not in scope: data constructor ‘\\(?1:[^’]*\\)’" + "not in scope: type constructor or class ‘\\(?1:[^’]*\\)’" + "Not in scope: ‘\\(?1:[^’]*\\)’" + )) ; in patterns + msg) + (let* ((delete (match-string 1 msg)) + (delete-has-paren (eq ?\( (elt delete 0))) + (delete-no-paren (if delete-has-paren (substring delete 1 (1- (length delete))) delete)) + (replacements (s-match-strings-all "‘\\([^’]*\\)’ (\\([^)]*\\))" msg))) + (--map (attrap-option (list 'replace delete-no-paren (nth 1 it) (nth 2 it)) + (goto-char pos) + (let ((case-fold-search nil)) + (search-forward delete-no-paren (+ (length delete) pos)) + (replace-match (nth 1 it) t))) + replacements))) + ((string-match "It could refer to either" msg) ;; ambiguous identifier + (let ((replacements (--map (nth 1 it) (s-match-strings-all "‘\\([^‘]*\\)’," msg)))) + (--map (attrap-option (list 'rename it) + (apply #'delete-region (dante-ident-pos-at-point)) + (insert it)) + replacements))) + ((string-match "\\(Top-level binding\\|Pattern synonym\\) with no type signature:[\n ]*" msg) + (attrap-one-option 'add-signature + (beginning-of-line) + (insert (concat (substring msg (match-end 0)) "\n")))) + ((string-match "Defined but not used" msg) + (attrap-one-option 'add-underscore + (goto-char pos) + (insert "_"))) + ((string-match "Unused quantified type variable ‘\\(.*\\)’" msg) + (attrap-one-option 'delete-type-variable + ;; note there can be a kind annotation, not just a variable. + (delete-region (point) (+ (point) (- (match-end 1) (match-beginning 1)))))) + ;; Module ‘TensorFlow.GenOps.Core’ does not export ‘argmax’. + + ((string-match "The import of ‘\\(.*\\)’ from module ‘[^’]*’ is redundant\\|Module ‘.*’ does not export ‘\\(.*\\)’" normalized-msg) + (attrap-one-option 'delete-import + (let ((redundant (or (match-string 1 normalized-msg) (match-string 2 normalized-msg)))) + (dolist (r (s-split ", " redundant t)) + (save-excursion + ;; todo check for operators + ;; toto search for full words + (search-forward r) + (replace-match "") + (when (looking-at "(..)") (delete-char 4)) + (when (looking-at ",") (delete-char 1))))))) + ((string-match "The import of ‘[^’]*’ is redundant" msg) + (attrap-one-option 'delete-module-import + (beginning-of-line) + (delete-region (point) (progn (next-logical-line) (point))))) + ((string-match "Found type wildcard ‘\\(.*\\)’[ \t\n]*standing for ‘\\([^’]*\\)’" msg) + (attrap-one-option 'explicit-type-wildcard + (let ((wildcard (match-string 1 msg)) + (type-expr (match-string 2 msg))) + (goto-char pos) + (search-forward wildcard) + (replace-match (concat "(" type-expr ")") t)))) + ((--any? (s-matches? it msg) attrap-haskell-extensions) + (--map (attrap-option (list 'use-extension it) + (goto-char 1) + (insert (concat "{-# LANGUAGE " it " #-}\n"))) + (--filter (s-matches? it msg) attrap-haskell-extensions)))))) + +(provide 'attrap) +;;; attrap.el ends here + diff --git a/packages/auctex-12.1.1.tar b/packages/auctex-12.1.2.tar similarity index 95% rename from packages/auctex-12.1.1.tar rename to packages/auctex-12.1.2.tar index def0eb6..1ac4bc6 100644 Binary files a/packages/auctex-12.1.1.tar and b/packages/auctex-12.1.2.tar differ diff --git a/packages/auth-source-pass-20181106.1348.el b/packages/auth-source-pass-20181106.1348.el deleted file mode 100644 index ac6c337..0000000 --- a/packages/auth-source-pass-20181106.1348.el +++ /dev/null @@ -1,261 +0,0 @@ -;;; auth-source-pass.el --- Integrate auth-source with password-store -*- lexical-binding: t -*- - -;; Copyright (C) 2015, 2017-2018 Free Software Foundation, Inc. - -;; Author: Damien Cassou , -;; Nicolas Petton -;; Version: 4.0.2 -;; Package-Version: 20181106.1348 -;; Package-Requires: ((emacs "25")) -;; Url: https://github.com/DamienCassou/auth-password-store -;; Created: 07 Jun 2015 - -;; This file is part of GNU Emacs. - -;; GNU Emacs 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. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . - -;;; Commentary: - -;; Integrates password-store (http://passwordstore.org/) within -;; auth-source. - -;;; Code: - -(require 'seq) -(eval-when-compile (require 'subr-x)) -(eval-when-compile - (require 'cl-lib)) -(require 'auth-source) -(require 'url-parse) - -(cl-defun auth-source-pass-search (&rest spec - &key backend type host user port - &allow-other-keys) - "Given a property list SPEC, return search matches from the :backend. -See `auth-source-search' for details on SPEC." - (cl-assert (or (null type) (eq type (oref backend type))) - t "Invalid password-store search: %s %s") - (when (consp host) - (warn "auth-source-pass ignores all but first host in spec.") - ;; Take the first non-nil item of the list of hosts - (setq host (seq-find #'identity host))) - (cond ((eq host t) - (warn "auth-source-pass does not handle host wildcards.") - nil) - ((null host) - ;; Do not build a result, as none will match when HOST is nil - nil) - (t - (when-let ((result (auth-source-pass--build-result host port user))) - (list result))))) - -(defun auth-source-pass--build-result (host port user) - "Build auth-source-pass entry matching HOST, PORT and USER." - (let ((entry (auth-source-pass--find-match host user port))) - (when entry - (let ((retval (list - :host host - :port (or (auth-source-pass-get "port" entry) port) - :user (or (auth-source-pass-get "user" entry) user) - :secret (lambda () (auth-source-pass-get 'secret entry))))) - (auth-source-pass--do-debug "return %s as final result (plus hidden password)" - (seq-subseq retval 0 -2)) ;; remove password - retval)))) - -;;;###autoload -(defun auth-source-pass-enable () - "Enable auth-source-password-store." - ;; To add password-store to the list of sources, evaluate the following: - (add-to-list 'auth-sources 'password-store) - ;; clear the cache (required after each change to #'auth-source-pass-search) - (auth-source-forget-all-cached)) - -(defvar auth-source-pass-backend - (auth-source-backend - (when (<= emacs-major-version 25) "password-store") - :source "." ;; not used - :type 'password-store - :search-function #'auth-source-pass-search) - "Auth-source backend for password-store.") - -(defun auth-source-pass-backend-parse (entry) - "Create a password-store auth-source backend from ENTRY." - (when (eq entry 'password-store) - (auth-source-backend-parse-parameters entry auth-source-pass-backend))) - -(if (boundp 'auth-source-backend-parser-functions) - (add-hook 'auth-source-backend-parser-functions #'auth-source-pass-backend-parse) - (advice-add 'auth-source-backend-parse :before-until #'auth-source-pass-backend-parse)) - - -;;;###autoload -(defun auth-source-pass-get (key entry) - "Return the value associated to KEY in the password-store entry ENTRY. - -ENTRY is the name of a password-store entry. -The key used to retrieve the password is the symbol `secret'. - -The convention used as the format for a password-store file is -the following (see http://www.passwordstore.org/#organization): - -secret -key1: value1 -key2: value2" - (let ((data (auth-source-pass-parse-entry entry))) - (or (cdr (assoc key data)) - (and (string= key "user") - (cdr (assoc "username" data)))))) - -(defun auth-source-pass--read-entry (entry) - "Return a string with the file content of ENTRY." - (with-temp-buffer - (insert-file-contents (expand-file-name - (format "%s.gpg" entry) - "~/.password-store")) - (buffer-substring-no-properties (point-min) (point-max)))) - -(defun auth-source-pass-parse-entry (entry) - "Return an alist of the data associated with ENTRY. - -ENTRY is the name of a password-store entry." - (let ((file-contents (ignore-errors (auth-source-pass--read-entry entry)))) - (and file-contents - (cons `(secret . ,(auth-source-pass--parse-secret file-contents)) - (auth-source-pass--parse-data file-contents))))) - -(defun auth-source-pass--parse-secret (contents) - "Parse the password-store data in the string CONTENTS and return its secret. -The secret is the first line of CONTENTS." - (car (split-string contents "\\\n" t))) - -(defun auth-source-pass--parse-data (contents) - "Parse the password-store data in the string CONTENTS and return an alist. -CONTENTS is the contents of a password-store formatted file." - (let ((lines (split-string contents "\\\n" t "\\\s"))) - (seq-remove #'null - (mapcar (lambda (line) - (let ((pair (mapcar (lambda (s) (string-trim s)) - (split-string line ":")))) - (when (> (length pair) 1) - (cons (car pair) - (mapconcat #'identity (cdr pair) ":"))))) - (cdr lines))))) - -(defun auth-source-pass--do-debug (&rest msg) - "Call `auth-source-do-debug` with MSG and a prefix." - (apply #'auth-source-do-debug - (cons (concat "auth-source-pass: " (car msg)) - (cdr msg)))) - -(defun auth-source-pass--select-one-entry (entries user) - "Select one entry from ENTRIES by searching for a field matching USER." - (let ((number (length entries)) - (entry-with-user - (and user - (seq-find (lambda (entry) - (string-equal (auth-source-pass-get "user" entry) user)) - entries)))) - (auth-source-pass--do-debug "found %s matches: %s" number - (mapconcat #'identity entries ", ")) - (if entry-with-user - (progn - (auth-source-pass--do-debug "return %s as it contains matching user field" - entry-with-user) - entry-with-user) - (auth-source-pass--do-debug "return %s as it is the first one" (car entries)) - (car entries)))) - -(defun auth-source-pass--entry-valid-p (entry) - "Return t iff ENTRY can be opened. -Also displays a warning if not. This function is slow, don't call it too -often." - (if (auth-source-pass-parse-entry entry) - t - (auth-source-pass--do-debug "entry '%s' is not valid" entry) - nil)) - -;; TODO: add tests for that when `assess-with-filesystem' is included -;; in Emacs -(defun auth-source-pass-entries () - "Return a list of all password store entries." - (let ((store-dir (expand-file-name "~/.password-store/"))) - (mapcar - (lambda (file) (file-name-sans-extension (file-relative-name file store-dir))) - (directory-files-recursively store-dir "\.gpg$")))) - -(defun auth-source-pass--find-all-by-entry-name (entryname user) - "Search the store for all entries either matching ENTRYNAME/USER or ENTRYNAME. -Only return valid entries as of `auth-source-pass--entry-valid-p'." - (seq-filter (lambda (entry) - (and - (or - (let ((components-host-user - (member entryname (split-string entry "/")))) - (and (= (length components-host-user) 2) - (string-equal user (cadr components-host-user)))) - (string-equal entryname (file-name-nondirectory entry))) - (auth-source-pass--entry-valid-p entry))) - (auth-source-pass-entries))) - -(defun auth-source-pass--find-one-by-entry-name (entryname user) - "Search the store for an entry matching ENTRYNAME. -If USER is non nil, give precedence to entries containing a user field -matching USER." - (auth-source-pass--do-debug "searching for '%s' in entry names (user: %s)" - entryname - user) - (let ((matching-entries (auth-source-pass--find-all-by-entry-name entryname user))) - (pcase (length matching-entries) - (0 (auth-source-pass--do-debug "no match found") - nil) - (1 (auth-source-pass--do-debug "found 1 match: %s" (car matching-entries)) - (car matching-entries)) - (_ (auth-source-pass--select-one-entry matching-entries user))))) - -(defun auth-source-pass--find-match (host user port) - "Return a password-store entry name matching HOST, USER and PORT. - -Disambiguate between user provided inside HOST (e.g., user@server.com) and -inside USER by giving priority to USER. Same for PORT." - (let* ((url (url-generic-parse-url (if (string-match-p ".*://" host) - host - (format "https://%s" host))))) - (auth-source-pass--find-match-unambiguous - (or (url-host url) host) - (or user (url-user url)) - ;; url-port returns 443 (because of the https:// above) by default - (or port (number-to-string (url-port url)))))) - -(defun auth-source-pass--find-match-unambiguous (hostname user port) - "Return a password-store entry name matching HOSTNAME, USER and PORT. -If many matches are found, return the first one. If no match is found, -return nil. - -HOSTNAME should not contain any username or port number." - (or - (and user port (auth-source-pass--find-one-by-entry-name (format "%s@%s:%s" user hostname port) user)) - (and user (auth-source-pass--find-one-by-entry-name (format "%s@%s" user hostname) user)) - (and port (auth-source-pass--find-one-by-entry-name (format "%s:%s" hostname port) nil)) - (auth-source-pass--find-one-by-entry-name hostname user) - ;; if that didn't work, remove subdomain: foo.bar.com -> bar.com - (let ((components (split-string hostname "\\."))) - (when (= (length components) 3) - ;; start from scratch - (auth-source-pass--find-match-unambiguous - (mapconcat 'identity (cdr components) ".") - user - port))))) - -(provide 'auth-source-pass) -;;; auth-source-pass.el ends here diff --git a/packages/auth-source-pass-20190813.1026.el b/packages/auth-source-pass-20190813.1026.el new file mode 100644 index 0000000..e4da433 --- /dev/null +++ b/packages/auth-source-pass-20190813.1026.el @@ -0,0 +1,322 @@ +;;; auth-source-pass.el --- Integrate auth-source with password-store -*- lexical-binding: t -*- + +;; Copyright (C) 2015, 2017-2019 Free Software Foundation, Inc. + +;; Author: Damien Cassou , +;; Nicolas Petton +;; Keith Amidon +;; Version: 5.0.0 +;; Package-Version: 20190813.1026 +;; Package-Requires: ((emacs "25")) +;; Url: https://github.com/DamienCassou/auth-password-store +;; Created: 07 Jun 2015 + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Integrates password-store (http://passwordstore.org/) within +;; auth-source. + +;;; Code: + +(require 'seq) +(eval-when-compile (require 'subr-x)) +(eval-when-compile + (require 'cl-lib)) +(require 'auth-source) +(require 'url-parse) + +(defgroup auth-source-pass nil + "password-store integration within auth-source." + :prefix "auth-source-pass-" + :group 'auth-source + :version "27.1") + +(defcustom auth-source-pass-filename (or (getenv "PASSWORD_STORE_DIR") "~/.password-store") + "Filename of the password-store folder." + :type 'directory + :version "27.1") + +(defcustom auth-source-pass-port-separator ":" + "Separator string between host and port in entry filename." + :type 'string + :version "27.1") + +(cl-defun auth-source-pass-search (&rest spec + &key backend type host user port + &allow-other-keys) + "Given a property list SPEC, return search matches from the :backend. +See `auth-source-search' for details on SPEC. + +HOST can be a string or a list of strings, but USER and PORT are expected +to be a string only." + (cl-assert (or (null type) (eq type (oref backend type))) + t "Invalid password-store search: %s %s") + (cond ((eq host t) + (warn "auth-source-pass does not handle host wildcards.") + nil) + ((null host) + ;; Do not build a result, as none will match when HOST is nil + nil) + (t + (when-let ((result (auth-source-pass--build-result host port user))) + (list result))))) + +(defun auth-source-pass--build-result (hosts port user) + "Build auth-source-pass entry matching HOSTS, PORT and USER. + +HOSTS can be a string or a list of strings." + (let ((entry-data (auth-source-pass--find-match hosts user port))) + (when entry-data + (let ((retval (list + :host (auth-source-pass--get-attr "host" entry-data) + :port (or (auth-source-pass--get-attr "port" entry-data) port) + :user (or (auth-source-pass--get-attr "user" entry-data) user) + :secret (lambda () (auth-source-pass--get-attr 'secret entry-data))))) + (auth-source-pass--do-debug "return %s as final result (plus hidden password)" + (seq-subseq retval 0 -2)) ;; remove password + retval)))) + +;;;###autoload +(defun auth-source-pass-enable () + "Enable auth-source-password-store." + ;; To add password-store to the list of sources, evaluate the following: + (add-to-list 'auth-sources 'password-store) + ;; clear the cache (required after each change to #'auth-source-pass-search) + (auth-source-forget-all-cached)) + +(defvar auth-source-pass-backend + (auth-source-backend + (when (<= emacs-major-version 25) "password-store") + :source "." ;; not used + :type 'password-store + :search-function #'auth-source-pass-search) + "Auth-source backend for password-store.") + +(defun auth-source-pass-backend-parse (entry) + "Create a password-store auth-source backend from ENTRY." + (when (eq entry 'password-store) + (auth-source-backend-parse-parameters entry auth-source-pass-backend))) + +(if (boundp 'auth-source-backend-parser-functions) + (add-hook 'auth-source-backend-parser-functions #'auth-source-pass-backend-parse) + (advice-add 'auth-source-backend-parse :before-until #'auth-source-pass-backend-parse)) + + +;;;###autoload +(defun auth-source-pass-get (key entry) + "Return the value associated to KEY in the password-store entry ENTRY. + +ENTRY is the name of a password-store entry. +The key used to retrieve the password is the symbol `secret'. + +The convention used as the format for a password-store file is +the following (see http://www.passwordstore.org/#organization): + +secret +key1: value1 +key2: value2" + (let ((data (auth-source-pass-parse-entry entry))) + (auth-source-pass--get-attr key data))) + +(defun auth-source-pass--get-attr (key entry-data) + "Return value associated with KEY in an ENTRY-DATA. + +ENTRY-DATA is the data from a parsed password-store entry. +The key used to retrieve the password is the symbol `secret'. + +See `auth-source-pass-get'." + (or (cdr (assoc key entry-data)) + (and (string= key "user") + (cdr (assoc "username" entry-data))))) + +(defun auth-source-pass--read-entry (entry) + "Return a string with the file content of ENTRY." + (with-temp-buffer + (insert-file-contents (expand-file-name + (format "%s.gpg" entry) + auth-source-pass-filename)) + (buffer-substring-no-properties (point-min) (point-max)))) + +(defun auth-source-pass-parse-entry (entry) + "Return an alist of the data associated with ENTRY. + +ENTRY is the name of a password-store entry." + (let ((file-contents (ignore-errors (auth-source-pass--read-entry entry)))) + (and file-contents + (cons `(secret . ,(auth-source-pass--parse-secret file-contents)) + (auth-source-pass--parse-data file-contents))))) + +(defun auth-source-pass--parse-secret (contents) + "Parse the password-store data in the string CONTENTS and return its secret. +The secret is the first line of CONTENTS." + (car (split-string contents "\n" t))) + +(defun auth-source-pass--parse-data (contents) + "Parse the password-store data in the string CONTENTS and return an alist. +CONTENTS is the contents of a password-store formatted file." + (let ((lines (split-string contents "\n" t "[ \t]+"))) + (seq-remove #'null + (mapcar (lambda (line) + (let ((pair (mapcar (lambda (s) (string-trim s)) + (split-string line ":")))) + (when (> (length pair) 1) + (cons (car pair) + (mapconcat #'identity (cdr pair) ":"))))) + (cdr lines))))) + +(defun auth-source-pass--do-debug (&rest msg) + "Call `auth-source-do-debug` with MSG and a prefix." + (apply #'auth-source-do-debug + (cons (concat "auth-source-pass: " (car msg)) + (cdr msg)))) + +;; TODO: add tests for that when `assess-with-filesystem' is included +;; in Emacs +(defun auth-source-pass-entries () + "Return a list of all password store entries." + (let ((store-dir (expand-file-name auth-source-pass-filename))) + (mapcar + (lambda (file) (file-name-sans-extension (file-relative-name file store-dir))) + (directory-files-recursively store-dir "\\.gpg$")))) + +(defun auth-source-pass--find-match (hosts user port) + "Return password-store entry data matching HOSTS, USER and PORT. + +Disambiguate between user provided inside HOSTS (e.g., user@server.com) and +inside USER by giving priority to USER. Same for PORT. +HOSTS can be a string or a list of strings." + (seq-some (lambda (host) + (let ((entry (apply #'auth-source-pass--find-match-unambiguous + (auth-source-pass--disambiguate host user port)))) + (if (or (null entry) (assoc "host" entry)) + entry + (cons (cons "host" host) entry)))) + (if (listp hosts) + hosts + (list hosts)))) + +(defun auth-source-pass--disambiguate (host &optional user port) + "Return (HOST USER PORT) after disambiguation. +Disambiguate between having user provided inside HOST (e.g., +user@server.com) and inside USER by giving priority to USER. +Same for PORT." + (let* ((url (url-generic-parse-url (if (string-match-p ".*://" host) + host + (format "https://%s" host))))) + (list + (or (url-host url) host) + (or user (url-user url)) + ;; url-port returns 443 (because of the https:// above) by default + (or port (number-to-string (url-port url)))))) + +(defun auth-source-pass--find-match-unambiguous (hostname user port) + "Return password-store entry data matching HOSTNAME, USER and PORT. +If many matches are found, return the first one. If no match is found, +return nil. + +HOSTNAME should not contain any username or port number." + (let ((all-entries (auth-source-pass-entries)) + (suffixes (auth-source-pass--generate-entry-suffixes hostname user port))) + (auth-source-pass--do-debug "searching for entries matching hostname=%S, user=%S, port=%S" + hostname (or user "") (or port "")) + (auth-source-pass--do-debug "corresponding suffixes to search for: %S" suffixes) + (catch 'auth-source-pass-break + (dolist (suffix suffixes) + (let* ((matching-entries (auth-source-pass--entries-matching-suffix suffix all-entries)) + (best-entry-data (auth-source-pass--select-from-entries matching-entries user))) + (pcase (length matching-entries) + (0 (auth-source-pass--do-debug "found no entries matching %S" suffix)) + (1 (auth-source-pass--do-debug "found 1 entry matching %S: %S" + suffix + (car matching-entries))) + (_ (auth-source-pass--do-debug "found %s entries matching %S: %S" + (length matching-entries) + suffix + matching-entries))) + (when best-entry-data + (throw 'auth-source-pass-break best-entry-data))))))) + +(defun auth-source-pass--select-from-entries (entries user) + "Return best matching password-store entry data from ENTRIES. + +If USER is non nil, give precedence to entries containing a user field +matching USER." + (let (fallback) + (catch 'auth-source-pass-break + (dolist (entry entries fallback) + (let ((entry-data (auth-source-pass-parse-entry entry))) + (when (and entry-data (not fallback)) + (setq fallback entry-data) + (when (or (not user) (equal (auth-source-pass--get-attr "user" entry-data) user)) + (throw 'auth-source-pass-break entry-data)))))))) + +(defun auth-source-pass--entries-matching-suffix (suffix entries) + "Return entries matching SUFFIX. +If ENTRIES is nil, use the result of calling `auth-source-pass-entries' instead." + (cl-remove-if-not + (lambda (entry) (string-match-p + (format "\\(^\\|/\\)%s$" (regexp-quote suffix)) + entry)) + (or entries (auth-source-pass-entries)))) + +(defun auth-source-pass--generate-entry-suffixes (hostname user port) + "Return a list of possible entry path suffixes in the password-store. + +Based on the supported pathname patterns for HOSTNAME, USER, & +PORT, return a list of possible suffixes for matching entries in +the password-store." + (let ((domains (auth-source-pass--domains (split-string hostname "\\.")))) + (seq-mapcat (lambda (n) + (auth-source-pass--name-port-user-suffixes n user port)) + domains))) + +(defun auth-source-pass--domains (name-components) + "Return a list of possible domain names matching the hostname. + +This function takes a list of NAME-COMPONENTS, the strings +separated by periods in the hostname, and returns a list of full +domain names containing the trailing sequences of those +components, from longest to shortest." + (cl-maplist (lambda (components) (mapconcat #'identity components ".")) + name-components)) + +(defun auth-source-pass--name-port-user-suffixes (name user port) + "Return a list of possible path suffixes for NAME, USER, & PORT. + +The resulting list is ordered from most specifc to least +specific, with paths matching all of NAME, USER, & PORT first, +then NAME & USER, then NAME & PORT, then just NAME." + (seq-mapcat + #'identity + (list + (when (and user port) + (list + (format "%s@%s%s%s" user name auth-source-pass-port-separator port) + (format "%s%s%s/%s" name auth-source-pass-port-separator port user))) + (when user + (list + (format "%s@%s" user name) + (format "%s/%s" name user))) + (when port + (list + (format "%s%s%s" name auth-source-pass-port-separator port))) + (list + (format "%s" name))))) + +(provide 'auth-source-pass) +;;; auth-source-pass.el ends here diff --git a/packages/auto-compile-20180321.1507.el b/packages/auto-compile-20181230.2216.el similarity index 94% rename from packages/auto-compile-20180321.1507.el rename to packages/auto-compile-20181230.2216.el index 9f481f4..bdee9fd 100644 --- a/packages/auto-compile-20180321.1507.el +++ b/packages/auto-compile-20181230.2216.el @@ -5,9 +5,9 @@ ;; Author: Jonas Bernoulli ;; Homepage: https://github.com/emacscollective/auto-compile ;; Keywords: compile, convenience, lisp -;; Package-Version: 20180321.1507 +;; Package-Version: 20181230.2216 -;; Package-Requires: ((emacs "24.3") (packed "2.0.0")) +;; Package-Requires: ((emacs "25.1") (packed "3.0.0")) ;; This file is not part of GNU Emacs. @@ -466,9 +466,9 @@ pretend the byte code file exists.") (defvar auto-compile-file-buffer nil) (defvar-local auto-compile-warnings 0) -(defadvice byte-compile-log-warning - (before auto-compile-count-warnings activate) - ;; (STRING &optional FILL LEVEL) +(define-advice byte-compile-log-warning + (:before (_string &optional _fill _level) auto-compile) + "Increment local value of `auto-compile-warnings'." (when auto-compile-file-buffer (with-current-buffer auto-compile-file-buffer (cl-incf auto-compile-warnings)))) @@ -584,25 +584,25 @@ pretend the byte code file exists.") (when auto-compile-ding (ding))) -(defadvice save-buffers-kill-emacs - (around auto-compile-dont-mark-failed-modified disable) - "Set `auto-compile-mark-failed-modified' to nil when killing Emacs. +(define-advice save-buffers-kill-emacs + (:around (fn &optional arg) auto-compile) + "Bind `auto-compile-mark-failed-modified' to nil when killing Emacs. If the regular value of this variable is non-nil the user might still be asked whether she wants to save modified buffers, which she actually did already safe. This advice ensures she at least is only asked once about each such file." (let ((auto-compile-mark-failed-modified nil)) - ad-do-it)) + (funcall fn arg))) -(defadvice save-buffers-kill-terminal - (around auto-compile-dont-mark-failed-modified disable) - "Set `auto-compile-mark-failed-modified' to nil when killing Emacs. +(define-advice save-buffers-kill-terminal + (:around (fn &optional arg) auto-compile) + "Bind `auto-compile-mark-failed-modified' to nil when killing Emacs. If the regular value of this variable is non-nil the user might still be asked whether she wants to save modified buffers, which she actually did already safe. This advice ensures she at least is only asked once about each such file." (let ((auto-compile-mark-failed-modified nil)) - ad-do-it)) + (funcall fn arg))) ;; REDEFINE autoload-save-buffers defined in autoload.el ;; - verify buffers are still live before killing them @@ -731,35 +731,30 @@ byte code file would be loaded instead. Also see the related `auto-compile-on-save-mode'." :lighter auto-compile-on-load-mode-lighter :group 'auto-compile - :global t - (cond (auto-compile-on-load-mode - (ad-enable-advice 'load 'before 'auto-compile-on-load) - (ad-enable-advice 'require 'before 'auto-compile-on-load) - (ad-activate 'load) - (ad-activate 'require)) - (t - (ad-disable-advice 'load 'before 'auto-compile-on-load) - (ad-disable-advice 'require 'before 'auto-compile-on-load)))) + :global t) (defvar auto-compile-on-load-mode-lighter "" "Mode lighter for Auto-Compile-On-Load Mode.") -(defadvice load (before auto-compile-on-load disable) - ;; (file &optional noerror nomessage nosuffix must-suffix) +(define-advice load + (:before (file &optional _noerror _nomessage nosuffix _must-suffix) + auto-compile) "Before loading the library recompile it if it needs recompilation. -It needs recompilation if it is newer than the byte-compile -destination. Without this advice the outdated byte-compiled -file would get loaded." - (auto-compile-on-load file nosuffix)) - -(defadvice require (before auto-compile-on-load disable) - ;; (feature &optional FILENAME NOERROR) +If `auto-compile-on-load-mode' isn't enabled, then do nothing. +It needs recompilation if it is newer than the byte-code file. +Without this advice the outdated source file would get loaded." + (when auto-compile-on-load-mode + (auto-compile-on-load file nosuffix))) + +(define-advice require + (:before (feature &optional filename _noerror) auto-compile) "Before loading the library recompile it if it needs recompilation. -It needs recompilation if it is newer than the byte-compile -destination. Without this advice the outdated byte-compiled -file would get loaded." - (unless (featurep feature) - (auto-compile-on-load (or filename (symbol-name feature))))) +If `auto-compile-on-load-mode' isn't enabled, then do nothing. +It needs recompilation if it is newer than the byte-code file. +Without this advice the outdated source file would get loaded." + (when auto-compile-on-load-mode + (unless (featurep feature) + (auto-compile-on-load (or filename (symbol-name feature)))))) (defvar auto-compile--loading nil) diff --git a/packages/auto-complete-20170125.245.tar b/packages/auto-complete-20170125.245.tar index 1fb22ef..188315a 100644 Binary files a/packages/auto-complete-20170125.245.tar and b/packages/auto-complete-20170125.245.tar differ diff --git a/packages/auto-complete-rst-20140225.944.tar b/packages/auto-complete-rst-20140225.944.tar index 49216d2..1f71c1a 100644 Binary files a/packages/auto-complete-rst-20140225.944.tar and b/packages/auto-complete-rst-20140225.944.tar differ diff --git a/packages/auto-yasnippet-20180503.1908.el b/packages/auto-yasnippet-20190326.958.el similarity index 93% rename from packages/auto-yasnippet-20180503.1908.el rename to packages/auto-yasnippet-20190326.958.el index ebef8ea..aee1030 100644 --- a/packages/auto-yasnippet-20180503.1908.el +++ b/packages/auto-yasnippet-20190326.958.el @@ -2,9 +2,9 @@ ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/auto-yasnippet -;; Package-Version: 20180503.1908 +;; Package-Version: 20190326.958 ;; Version: 0.3 -;; Package-Requires: ((yasnippet "0.8.0")) +;; Package-Requires: ((yasnippet "0.13.0")) ;; This file is not part of GNU Emacs @@ -202,6 +202,7 @@ menu.add_item(spamspamspam, \"spamspamspam\")" (delete-region beg end) (when aya-create-with-newline (delete-char 1)) (setq aya-current line) + (yas-minor-mode 1) (yas-expand-snippet line))))) (defun aya--parse (str) @@ -233,19 +234,25 @@ menu.add_item(spamspamspam, \"spamspamspam\")" (nreverse res))) ;;;###autoload -(defun aya-create () - "Works on either the current line, or, if `mark-active', the current region. -Removes `aya-marker' prefixes, -writes the corresponding snippet to `aya-current', -with words prefixed by `aya-marker' as fields, and mirrors properly set up." +(defun aya-create (&optional beg end) + "Create a snippet from the text between BEG and END. +When the bounds are not given, use either the current region or line. + +Remove `aya-marker' prefixes, write the corresponding snippet to +`aya-current', with words prefixed by `aya-marker' as fields, and +mirrors properly set up." (interactive) (unless (aya-create-one-line) - (let* ((beg (if (region-active-p) - (region-beginning) - (line-beginning-position))) - (end (if (region-active-p) - (region-end) - (line-end-position))) + (let* ((beg (cond (beg) + ((region-active-p) + (region-beginning)) + (t + (line-beginning-position)))) + (end (cond (end) + ((region-active-p) + (region-end)) + (t + (line-end-position)))) (str (buffer-substring-no-properties beg end)) (case-fold-search nil) (res (aya--parse str))) @@ -326,14 +333,13 @@ move to the next field. Call `open-line' if nothing else applies." ((progn (unless yas-global-mode (yas-global-mode 1)) - (yas--snippets-at-point)) + (yas-active-snippets)) (yas-next-field-or-maybe-expand)) ((ignore-errors (setq aya-invokation-point (point)) (setq aya-invokation-buffer (current-buffer)) (setq aya-tab-position (- (point) (line-beginning-position))) - (let ((yas-fallback-behavior 'return-nil)) - (yas-expand)))) + (yas-expand))) ((and (fboundp 'tiny-expand) (funcall 'tiny-expand))) (t diff --git a/packages/avy-20181009.1648.el b/packages/avy-20190630.1538.el similarity index 90% rename from packages/avy-20181009.1648.el rename to packages/avy-20190630.1538.el index be6a9b5..4267393 100644 --- a/packages/avy-20181009.1648.el +++ b/packages/avy-20190630.1538.el @@ -1,11 +1,11 @@ ;;; avy.el --- Jump to arbitrary positions in visible text and select text quickly. -*- lexical-binding: t -*- -;; Copyright (C) 2015 Free Software Foundation, Inc. +;; Copyright (C) 2015-2019 Free Software Foundation, Inc. ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/avy -;; Package-Version: 20181009.1648 -;; Version: 0.4.0 +;; Package-Version: 20190630.1538 +;; Version: 0.5.0 ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5")) ;; Keywords: point, location @@ -456,13 +456,28 @@ KEYS is the path from the root of `avy-tree' to LEAF." (throw 'done 'restart)) ((memq char '(27 ?\C-g)) ;; exit silently - (throw 'done 'exit)) + (throw 'done 'abort)) + ((eq char ??) + (avy-show-dispatch-help) + (throw 'done 'restart)) ((mouse-event-p char) (signal 'user-error (list "Mouse event not handled" char))) (t - (signal 'user-error (list "No such candidate" - (if (characterp char) (string char) char))) - (throw 'done nil))))) + (message "No such candidate: %s, hit `C-g' to quit." + (if (characterp char) (string char) char)))))) + +(defun avy-show-dispatch-help () + "Display action shortucts in echo area." + (let ((len (length "avy-action-"))) + (message "%s" (mapconcat + (lambda (x) + (format "%s: %s" + (propertize + (char-to-string (car x)) + 'face 'aw-key-face) + (substring (symbol-name (cdr x)) len))) + avy-dispatch-alist + " ")))) (defvar avy-handler-function 'avy-handler-default "A function to call for a bad `read-key' in `avy-read'.") @@ -481,7 +496,7 @@ Return nil if not a mouse event." (t (selected-window))))) (defun avy-read (tree display-fn cleanup-fn) - "Select a leaf from TREE using consecutive `read-char'. + "Select a leaf from TREE using consecutive `read-key'. DISPLAY-FN should take CHAR and LEAF and signify that LEAFs associated with CHAR will be selected if CHAR is pressed. This is @@ -504,13 +519,14 @@ multiple DISPLAY-FN invocations." (funcall cleanup-fn) (if (setq window (avy-mouse-event-window char)) (throw 'done (cons char window)) - ;; Ensure avy-current-path stores the full path prior to - ;; exit so other packages can utilize its value. - (setq avy-current-path - (concat avy-current-path (string (avy--key-to-char char)))) (if (setq branch (assoc char tree)) - (if (eq (car (setq tree (cdr branch))) 'leaf) - (throw 'done (cdr tree))) + (progn + ;; Ensure avy-current-path stores the full path prior to + ;; exit so other packages can utilize its value. + (setq avy-current-path + (concat avy-current-path (string (avy--key-to-char char)))) + (if (eq (car (setq tree (cdr branch))) 'leaf) + (throw 'done (cdr tree)))) (funcall avy-handler-function char))))))) (defun avy-read-de-bruijn (lst keys) @@ -651,7 +667,9 @@ Set `avy-style' according to COMMMAND as well." (setf (symbol-function 'avy-resume) (lambda () (interactive) - ,@body)) + ,@(if (eq command 'avy-goto-char-timer) + (cdr body) + body))) ,@body)) (defun avy-action-goto (pt) @@ -734,6 +752,11 @@ Set `avy-style' according to COMMMAND as well." (declare-function flyspell-correct-word-before-point "flyspell") +(defcustom avy-flyspell-correct-function #'flyspell-correct-word-before-point + "Function called to correct word by `avy-action-ispell' when +`flyspell-mode' is enabled." + :type 'function) + (defun avy-action-ispell (pt) "Auto correct word at PT." (save-excursion @@ -744,7 +767,7 @@ Set `avy-style' according to COMMMAND as well." (line-beginning-position) (line-end-position))) ((bound-and-true-p flyspell-mode) - (flyspell-correct-word-before-point)) + (funcall avy-flyspell-correct-function)) ((looking-at-p "\\b") (ispell-word)) (t @@ -753,7 +776,20 @@ Set `avy-style' according to COMMMAND as well." (when (looking-at-p "\\b") (ispell-word))))))) -(defun avy--process-1 (candidates overlay-fn) +(defvar avy-pre-action #'avy-pre-action-default + "Function to call before `avy-action' is called.") + +(defun avy-pre-action-default (res) + (avy-push-mark) + (when (and (consp res) + (windowp (cdr res))) + (let* ((window (cdr res)) + (frame (window-frame window))) + (unless (equal frame (selected-frame)) + (select-frame-set-input-focus frame)) + (select-window window)))) + +(defun avy--process-1 (candidates overlay-fn &optional cleanup-fn) (let ((len (length candidates))) (cond ((= len 0) nil) @@ -773,42 +809,79 @@ Set `avy-style' according to COMMMAND as well." (t (avy-read (avy-tree candidates avy-keys) overlay-fn - #'avy--remove-leading-chars)))) + (or cleanup-fn #'avy--remove-leading-chars))))) (avy--done)))))) -(defun avy--process (candidates overlay-fn) +(defvar avy-last-candidates nil + "Store the last candidate list.") + +(defun avy--last-candidates-cycle (advancer) + (let* ((avy-last-candidates + (cl-remove-if-not + (lambda (x) (equal (cdr x) (selected-window))) + avy-last-candidates)) + (min-dist + (apply #'min + (mapcar (lambda (x) (abs (- (caar x) (point)))) avy-last-candidates))) + (pos + (cl-position-if + (lambda (x) + (= (- (caar x) (point)) min-dist)) + avy-last-candidates))) + (funcall advancer pos avy-last-candidates))) + +(defun avy-prev () + "Go to the previous candidate of the last `avy-read'." + (interactive) + (avy--last-candidates-cycle + (lambda (pos lst) + (when (> pos 0) + (goto-char (caar (nth (1- pos) lst))))))) + +(defun avy-next () + "Go to the next candidate of the last `avy-read'." + (interactive) + (avy--last-candidates-cycle + (lambda (pos lst) + (when (< pos (1- (length lst))) + (goto-char (caar (nth (1+ pos) lst))))))) + +(defun avy-process (candidates &optional overlay-fn cleanup-fn) "Select one of CANDIDATES using `avy-read'. -Use OVERLAY-FN to visualize the decision overlay." +Use OVERLAY-FN to visualize the decision overlay. +CLEANUP-FN should take no arguments and remove the effects of +multiple OVERLAY-FN invocations." + (setq overlay-fn (or overlay-fn (avy--style-fn avy-style))) + (setq cleanup-fn (or cleanup-fn #'avy--remove-leading-chars)) (unless (and (consp (car candidates)) (windowp (cdar candidates))) (setq candidates (mapcar (lambda (x) (cons x (selected-window))) candidates))) + (setq avy-last-candidates (copy-sequence candidates)) (let ((original-cands (copy-sequence candidates)) - (res (avy--process-1 candidates overlay-fn))) + (res (avy--process-1 candidates overlay-fn cleanup-fn))) (cond ((null res) (message "zero candidates") t) ((eq res 'restart) - (avy--process original-cands overlay-fn)) + (avy-process original-cands overlay-fn cleanup-fn)) ;; ignore exit from `avy-handler-function' ((eq res 'exit)) + ((eq res 'abort) + nil) (t - (avy-push-mark) - (when (and (consp res) - (windowp (cdr res))) - (let* ((window (cdr res)) - (frame (window-frame window))) - (unless (equal frame (selected-frame)) - (select-frame-set-input-focus frame)) - (select-window window)) - (setq res (car res))) - + (funcall avy-pre-action res) + (setq res (car res)) (funcall (or avy-action 'avy-action-goto) (if (consp res) (car res) - res)))))) + res)) + res)))) + +(define-obsolete-function-alias 'avy--process 'avy-process + "0.4.0") (defvar avy--overlays-back nil "Hold overlays for when `avy-background' is t.") @@ -833,18 +906,24 @@ Use OVERLAY-FN to visualize the decision overlay." (setq avy--overlays-back nil) (avy--remove-leading-chars)) +(defun avy--visible-p (s) + (let ((invisible (get-char-property s 'invisible))) + (or (null invisible) + (eq t buffer-invisibility-spec) + (null (assoc invisible buffer-invisibility-spec))))) + (defun avy--next-visible-point () "Return the next closest point without 'invisible property." (let ((s (point))) (while (and (not (= (point-max) (setq s (next-char-property-change s)))) - (get-char-property s 'invisible))) + (not (avy--visible-p s)))) s)) (defun avy--next-invisible-point () "Return the next closest point with 'invisible property." (let ((s (point))) (while (and (not (= (point-max) (setq s (next-char-property-change s)))) - (not (get-char-property s 'invisible)))) + (avy--visible-p s))) s)) (defun avy--find-visible-regions (rbeg rend) @@ -879,7 +958,7 @@ When GROUP is non-nil, (BEG . END) should delimit that regex group." (save-excursion (goto-char (car pair)) (while (re-search-forward regex (cdr pair) t) - (unless (get-char-property (1- (point)) 'invisible) + (when (avy--visible-p (1- (point))) (when (or (null pred) (funcall pred)) (push (cons (cons (match-beginning group) @@ -1026,7 +1105,7 @@ LEAF is normally ((BEG . END) . WND)." (wnd (cdr leaf)) end) (dotimes (i len) - (set-text-properties (- len i 1) (- len i) + (set-text-properties i (1+ i) `(face ,(nth i avy-lead-faces)) str)) (when (eq avy-style 'de-bruijn) @@ -1152,21 +1231,36 @@ exist." (post #'avy--overlay-post) (de-bruijn #'avy--overlay-at-full) (words #'avy--overlay-at-full) + (ignore #'ignore) (t (error "Unexpected style %S" style)))) -(defun avy--generic-jump (regex window-flip style &optional beg end) +(cl-defun avy-jump (regex &key window-flip beg end action pred) + "Jump to REGEX. +The window scope is determined by `avy-all-windows'. +When WINDOW-FLIP is non-nil, do the opposite of `avy-all-windows'. +BEG and END narrow the scope where candidates are searched. +ACTION is a function that takes point position as an argument. +When PRED is non-nil, it's a filter for matching point positions." + (setq avy-action (or action avy-action)) + (let ((avy-all-windows + (if window-flip + (not avy-all-windows) + avy-all-windows))) + (avy-process + (avy--regex-candidates regex beg end pred)))) + +(defun avy--generic-jump (regex window-flip &optional beg end) "Jump to REGEX. The window scope is determined by `avy-all-windows'. When WINDOW-FLIP is non-nil, do the opposite of `avy-all-windows'. -STYLE determines the leading char overlay style. BEG and END narrow the scope where candidates are searched." + (declare (obsolete avy-jump "0.4.0")) (let ((avy-all-windows (if window-flip (not avy-all-windows) avy-all-windows))) - (avy--process - (avy--regex-candidates regex beg end) - (avy--style-fn style)))) + (avy-process + (avy--regex-candidates regex beg end)))) ;;* Commands ;;;###autoload @@ -1176,24 +1270,21 @@ The window scope is determined by `avy-all-windows' (ARG negates it)." (interactive (list (read-char "char: " t) current-prefix-arg)) (avy-with avy-goto-char - (avy--generic-jump + (avy-jump (if (= 13 char) "\n" (regexp-quote (string char))) - arg - avy-style))) + :window-flip arg))) ;;;###autoload (defun avy-goto-char-in-line (char) "Jump to the currently visible CHAR in the current line." (interactive (list (read-char "char: " t))) (avy-with avy-goto-char - (avy--generic-jump + (avy-jump (regexp-quote (string char)) - avy-all-windows - avy-style - (line-beginning-position) - (line-end-position)))) + :beg (line-beginning-position) + :end (line-end-position)))) ;;;###autoload (defun avy-goto-char-2 (char1 char2 &optional arg beg end) @@ -1210,11 +1301,11 @@ BEG and END narrow the scope where candidates are searched." (when (eq char2 ? ) (setq char2 ?\n)) (avy-with avy-goto-char-2 - (avy--generic-jump + (avy-jump (regexp-quote (string char1 char2)) - arg - avy-style - beg end))) + :window-flip arg + :beg beg + :end end))) ;;;###autoload (defun avy-goto-char-2-above (char1 char2 &optional arg) @@ -1252,11 +1343,10 @@ When ARG is non-nil, do the opposite of `avy-all-windows'." (interactive) (avy-with avy-isearch (let ((avy-background nil)) - (avy--process + (avy-process (avy--regex-candidates (if isearch-regexp isearch-string - (regexp-quote isearch-string))) - (avy--style-fn avy-style)) + (regexp-quote isearch-string)))) (isearch-done)))) ;;;###autoload @@ -1267,7 +1357,10 @@ When ARG is non-nil, do the opposite of `avy-all-windows'. BEG and END narrow the scope where candidates are searched." (interactive "P") (avy-with avy-goto-word-0 - (avy--generic-jump avy-goto-word-0-regexp arg avy-style beg end))) + (avy-jump avy-goto-word-0-regexp + :window-flip arg + :beg beg + :end end))) (defun avy-goto-word-0-above (arg) "Jump to a word start between window start and point. @@ -1307,7 +1400,10 @@ When SYMBOL is non-nil, jump to symbol start instead of word start." (concat (if symbol "\\_<" "\\b") str))))) - (avy--generic-jump regex arg avy-style beg end)))) + (avy-jump regex + :window-flip arg + :beg beg + :end end)))) ;;;###autoload (defun avy-goto-word-1-above (char &optional arg) @@ -1404,7 +1500,7 @@ BEG and END narrow the scope where candidates are searched." (while (> (point) ws) (when (or (null predicate) (and predicate (funcall predicate))) - (unless (get-char-property (point) 'invisible) + (unless (not (avy--visible-p (point))) (push (cons (point) (selected-window)) window-cands))) (subword-backward)) (and (= (point) ws) @@ -1413,7 +1509,7 @@ BEG and END narrow the scope where candidates are searched." (not (get-char-property (point) 'invisible)) (push (cons (point) (selected-window)) window-cands))) (setq candidates (nconc candidates window-cands)))))) - (avy--process candidates (avy--style-fn avy-style))))) + (avy-process candidates)))) ;;;###autoload (defun avy-goto-subword-1 (char &optional arg) @@ -1458,8 +1554,8 @@ When BOTTOM-UP is non-nil, display avy candidates from top to bottom" (narrow-to-region ws (or end (window-end (selected-window) t))) (goto-char (point-min)) (while (< (point) (point-max)) - (unless (get-char-property - (max (1- (point)) ws) 'invisible) + (when (member (get-char-property + (max (1- (point)) ws) 'invisible) '(nil org-link)) (push (cons (if (eq avy-style 'post) (line-end-position) @@ -1566,13 +1662,14 @@ The window scope is determined by `avy-all-windows'. When ARG is non-nil, do the opposite of `avy-all-windows'. BEG and END narrow the scope where candidates are searched. When BOTTOM-UP is non-nil, display avy candidates from top to bottom" - (let ((avy-action #'identity)) - (avy--process - (avy--line-cands arg beg end bottom-up) - (if avy-linum-mode - (progn (message "Goto line:") - 'ignore) - (avy--style-fn avy-style))))) + (setq avy-action (or avy-action #'identity)) + (let ((avy-style (if avy-linum-mode + (progn + (message "Goto line:") + 'ignore) + avy-style))) + (avy-process + (avy--line-cands arg beg end bottom-up)))) ;;;###autoload (defun avy-goto-line (&optional arg) @@ -1608,7 +1705,7 @@ Otherwise, forward to `goto-line' with ARG." (forward-line (1- (string-to-number line)))) (throw 'done 'exit)))))) (r (avy--line (eq arg 4)))) - (unless (eq r t) + (when (and (not (eq r t)) (eq avy-action #'identity)) (avy-action-goto r)))))) ;;;###autoload @@ -1889,11 +1986,10 @@ newline." (defun avy--read-candidates (&optional re-builder) "Read as many chars as possible and return their occurrences. At least one char must be read, and then repeatedly one next char -may be read if it is entered before `avy-timeout-seconds'. Any -key defined in `avy-del-last-char-by' (by default `C-h' and `DEL') -deletes the last char entered, and `RET' exits with the -currently read string immediately instead of waiting for another -char for `avy-timeout-seconds'. +may be read if it is entered before `avy-timeout-seconds'. DEL +deletes the last char entered, and RET exits with the currently +read string immediately instead of waiting for another char for +`avy-timeout-seconds'. The format of the result is the same as that of `avy--regex-candidates'. This function obeys `avy-all-windows' setting. RE-BUILDER is a function that takes a string and returns a regex. @@ -1905,6 +2001,8 @@ Otherwise, the whole regex is highlighted." char break overlays regex) (unwind-protect (progn + (avy--make-backgrounds + (avy-window-list)) (while (and (not break) (setq char (read-char (format "%d char%s: " @@ -1948,7 +2046,7 @@ Otherwise, the whole regex is highlighted." (goto-char (car pair)) (setq regex (funcall re-builder str)) (while (re-search-forward regex (cdr pair) t) - (unless (get-char-property (1- (point)) 'invisible) + (unless (not (avy--visible-p (1- (point)))) (let* ((idx (if (= (length (match-data)) 4) 1 0)) (ov (make-overlay (match-beginning idx) (match-end idx)))) @@ -1966,7 +2064,10 @@ Otherwise, the whole regex is highlighted." (overlay-get ov 'window))) overlays))) (dolist (ov overlays) - (delete-overlay ov))))) + (delete-overlay ov)) + (avy--done)))) + +(defvar avy--old-cands nil) ;;;###autoload (defun avy-goto-char-timer (&optional arg) @@ -1977,16 +2078,16 @@ The window scope is determined by `avy-all-windows' (ARG negates it)." (not avy-all-windows) avy-all-windows))) (avy-with avy-goto-char-timer - (avy--process - (avy--read-candidates) - (avy--style-fn avy-style))))) + (setq avy--old-cands (avy--read-candidates)) + (avy-process avy--old-cands)))) (defun avy-push-mark () "Store the current point and window." - (ring-insert avy-ring - (cons (point) (selected-window))) - (unless (region-active-p) - (push-mark))) + (let ((inhibit-message t)) + (ring-insert avy-ring + (cons (point) (selected-window))) + (unless (region-active-p) + (push-mark)))) (defun avy-pop-mark () "Jump back to the last location of `avy-push-mark'." @@ -2010,22 +2111,30 @@ The window scope is determined by `avy-all-windows' (ARG negates it)." (defvar org-reverse-note-order) (declare-function org-refile "org") (declare-function org-back-to-heading "org") +(declare-function org-reveal "org") + +(defvar org-after-refile-insert-hook) (defun avy-org-refile-as-child () "Refile current heading as first child of heading selected with `avy.'" ;; Inspired by `org-teleport': http://kitchingroup.cheme.cmu.edu/blog/2016/03/18/Org-teleport-headlines/ (interactive) - (let ((rfloc (save-excursion - (let* ((org-reverse-note-order t) - (pos (avy-with avy-goto-line - (avy--generic-jump (rx bol (1+ "*") (1+ space)) - nil avy-style) - (point))) - (filename (buffer-file-name (or (buffer-base-buffer (current-buffer)) - (current-buffer))))) - (list nil filename nil pos))))) - ;; org-refile must be called outside of the excursion - (org-refile nil nil rfloc))) + (let* ((org-reverse-note-order t) + (marker (save-excursion + (avy-with avy-goto-line + (unless (eq 't (avy-jump (rx bol (1+ "*") (1+ space)))) + ;; `avy-jump' returns t when aborted with C-g. + (point-marker))))) + (filename (buffer-file-name (or (buffer-base-buffer (marker-buffer marker)) + (marker-buffer marker)))) + (rfloc (list nil filename nil marker)) + ;; Ensure the refiled heading is visible. + (org-after-refile-insert-hook (if (member 'org-reveal org-after-refile-insert-hook) + org-after-refile-insert-hook + (cons #'org-reveal org-after-refile-insert-hook)))) + (when marker + ;; Only attempt refile if avy session was not aborted. + (org-refile nil nil rfloc)))) (defun avy-org-goto-heading-timer (&optional arg) "Read one or many characters and jump to matching Org headings. @@ -2035,11 +2144,10 @@ The window scope is determined by `avy-all-windows' (ARG negates it)." (not avy-all-windows) avy-all-windows))) (avy-with avy-goto-char-timer - (avy--process + (avy-process (avy--read-candidates (lambda (input) - (format "^\\*+ .*\\(%s\\)" input))) - (avy--style-fn avy-style)) + (format "^\\*+ .*\\(%s\\)" input)))) (org-back-to-heading)))) (provide 'avy) diff --git a/packages/avy-migemo-20180716.1455.tar b/packages/avy-migemo-20180716.1455.tar index ceedc45..bd80a0c 100644 Binary files a/packages/avy-migemo-20180716.1455.tar and b/packages/avy-migemo-20180716.1455.tar differ diff --git a/packages/biblio-20161014.2304.tar b/packages/biblio-20190624.1408.tar similarity index 82% rename from packages/biblio-20161014.2304.tar rename to packages/biblio-20190624.1408.tar index e34bd06..83ceebc 100644 Binary files a/packages/biblio-20161014.2304.tar and b/packages/biblio-20190624.1408.tar differ diff --git a/packages/biblio-core-20160901.1815.el b/packages/biblio-core-20190624.1408.el similarity index 97% rename from packages/biblio-core-20160901.1815.el rename to packages/biblio-core-20190624.1408.el index 94d1753..a5a2304 100644 --- a/packages/biblio-core-20160901.1815.el +++ b/packages/biblio-core-20190624.1408.el @@ -4,7 +4,7 @@ ;; Author: Clément Pit-Claudel ;; Version: 0.2 -;; Package-Version: 20160901.1815 +;; Package-Version: 20190624.1408 ;; Package-Requires: ((emacs "24.3") (let-alist "1.0.4") (seq "1.11") (dash "2.12.1")) ;; Keywords: bib, tex, convenience, hypermedia ;; URL: http://github.com/cpitclaudel/biblio.el @@ -113,7 +113,7 @@ DIALECT is `BibTeX' or `biblatex'. AUTOKEY: see `biblio-format-bibtex'." (bibtex-clean-entry autokey))) (defun biblio--cleanup-bibtex (autokey) - "Default balue of `biblio-cleanup-bibtex-function'. + "Default value of `biblio-cleanup-bibtex-function'. AUTOKEY: See biblio-format-bibtex." (save-excursion (when (search-forward "@data{" nil t) @@ -144,7 +144,7 @@ With non-nil AUTOKEY, automatically generate a key for BIBTEX." (funcall biblio-cleanup-bibtex-function autokey)) (if (fboundp 'font-lock-ensure) (font-lock-ensure) (with-no-warnings (font-lock-fontify-buffer))) - (buffer-string))) + (buffer-substring-no-properties (point-min) (point-max)))) (defun biblio--beginning-of-response-body () "Move point to beginning of response body." @@ -190,7 +190,7 @@ server's response is current at the time of the call, and killed after the call returns. Call CLEANUP-FUNCTION before checking for errors. If the request returns one of the errors in ALLOWED-ERRORS, CALLBACK is instead called with one argument, the -list of alowed errors that occured instead of a buffer. If the +list of allowed errors that occurred instead of a buffer. If the request returns another error, an exception is raised." (lambda (events) (let ((target-buffer (current-buffer))) @@ -386,7 +386,7 @@ Uses .url, and .doi as a fallback." (user-error "This record does not contain a direct URL (try arXiv or HAL)"))) (defun biblio--selection-next () - "Move to next seach result." + "Move to next search result." (interactive) (biblio--selection-move #'end-of-line #'re-search-forward)) @@ -396,7 +396,7 @@ Uses .url, and .doi as a fallback." (biblio--selection-move #'ignore #'re-search-forward)) (defun biblio--selection-previous () - "Move to previous seach result." + "Move to previous search result." (interactive) (biblio--selection-move #'beginning-of-line #'re-search-backward)) @@ -626,10 +626,11 @@ NEWLINE is non-nil, add a newline before the main text." (if authors (biblio-join-1 ", " authors) "(no authors)"))) -(defun biblio--prepare-title (title) - "Cleanup TITLE for presentation to the user." - (or (biblio--nonempty-string-p (biblio--cleanup-field title)) - "(no title)")) +(defun biblio--prepare-title (title &optional year) + "Cleanup TITLE and add YEAR for presentation to the user." + (concat (or (biblio--nonempty-string-p (biblio--cleanup-field title)) + "(no title)") + (if year (format " [%s]" year) ""))) (defun biblio--browse-url (button) "Open web browser on page pointed to by BUTTON." @@ -658,9 +659,10 @@ This command expects ITEM to be a single alist, in the following format: (type . \"Type of document (journal paper, proceedings, report, …)\") (category . \"Category of this document (aka primary topic)\") (publisher . \"Publisher of this document\") - (references . \"Identifier(s) of this document (DOI, DPLB id, Handle, …)\") + (references . \"Identifier(s) of this document (DOI, DBLP id, Handle, …)\") (open-access-status . \"Open access status of this document\") (url . \"Relevant URL\") + (year . \"Publication year as a string, if available\") (direct-url . \"Direct URL of paper (typically PDF)\")) Each of `container', `type', `category', `publisher', @@ -673,7 +675,7 @@ provide examples of how to build such a result." (biblio--with-text-property 'biblio-metadata item (let-alist item (biblio-with-fontification 'font-lock-function-name-face - (biblio-insert-with-prefix "> " (biblio--prepare-title .title))) + (biblio-insert-with-prefix "> " (biblio--prepare-title .title .year))) (insert "\n") (biblio-with-fontification 'font-lock-doc-face (biblio-insert-with-prefix " " (biblio--prepare-authors .authors))) diff --git a/packages/blacken-20190521.841.el b/packages/blacken-20190521.841.el new file mode 100644 index 0000000..382c9c3 --- /dev/null +++ b/packages/blacken-20190521.841.el @@ -0,0 +1,159 @@ +;;; blacken.el --- Reformat python buffers using the "black" formatter + +;; Copyright (C) 2018-2019 Artem Malyshev + +;; Author: Artem Malyshev +;; Homepage: https://github.com/proofit404/blacken +;; Version: 0.0.1 +;; Package-Version: 20190521.841 +;; Package-Requires: ((emacs "25.2")) + +;; 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 file 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 . + +;;; Commentary: +;; +;; Blacken uses black to format a Python buffer. It can be called +;; explicitly on a certain buffer, but more conveniently, a minor-mode +;; 'blacken-mode' is provided that turns on automatically running +;; black on a buffer before saving. +;; +;; Installation: +;; +;; Add blacken.el to your load-path. +;; +;; To automatically format all Python buffers before saving, add the +;; function blacken-mode to python-mode-hook: +;; +;; (add-hook 'python-mode-hook 'blacken-mode) +;; +;;; Code: + +(require 'cl-lib) + +(defgroup blacken nil + "Reformat Python code with \"black\"." + :group 'python) + +(defcustom blacken-executable "black" + "Name of the executable to run." + :type 'string) + +(defcustom blacken-line-length nil + "Line length to enforce. + +It must be an integer, nil or `fill'. +If `fill', the `fill-column' variable value is used." + :type '(choice :tag "Line Length Limit" + (const :tag "Use default" nil) + (const :tag "Use fill-column" fill) + (integer :tag "Line Length")) + :safe 'integerp) + +(defcustom blacken-allow-py36 nil + "Allow using Python 3.6-only syntax on all input files." + :type 'boolean + :safe 'booleanp) + +(defcustom blacken-skip-string-normalization nil + "Don't normalize string quotes or prefixes." + :type 'boolean + :safe 'booleanp) + +(defcustom blacken-fast-unsafe nil + "Skips temporary sanity checks." + :type 'boolean + :safe 'booleanp) + +(defun blacken-call-bin (input-buffer output-buffer error-buffer) + "Call process black. + +Send INPUT-BUFFER content to the process stdin. Saving the +output to OUTPUT-BUFFER. Saving process stderr to ERROR-BUFFER. +Return black process the exit code." + (with-current-buffer input-buffer + (let ((process (make-process :name "blacken" + :command `(,blacken-executable ,@(blacken-call-args)) + :buffer output-buffer + :stderr error-buffer + :noquery t + :sentinel (lambda (process event))))) + (set-process-query-on-exit-flag (get-buffer-process error-buffer) nil) + (set-process-sentinel (get-buffer-process error-buffer) (lambda (process event))) + (save-restriction + (widen) + (process-send-region process (point-min) (point-max))) + (process-send-eof process) + (accept-process-output process nil nil t) + (while (process-live-p process) + (accept-process-output process nil nil t)) + (process-exit-status process)))) + +(defun blacken-call-args () + "Build black process call arguments." + (append + (when blacken-line-length + (list "--line-length" + (number-to-string (cl-case blacken-line-length + ('fill fill-column) + (t blacken-line-length))))) + (when blacken-allow-py36 + (list "--py36")) + (when blacken-fast-unsafe + (list "--fast")) + (when blacken-skip-string-normalization + (list "--skip-string-normalization")) + (when (string-match "\.pyi$" (buffer-file-name (current-buffer))) + (list "--pyi")) + '("-"))) + +;;;###autoload +(defun blacken-buffer (&optional display) + "Try to blacken the current buffer. + +Show black output, if black exit abnormally and DISPLAY is t." + (interactive (list t)) + (let* ((original-buffer (current-buffer)) + (original-point (point)) + (original-window-pos (window-start)) + (tmpbuf (get-buffer-create "*blacken*")) + (errbuf (get-buffer-create "*blacken-error*"))) + ;; This buffer can be left after previous black invocation. It + ;; can contain error message of the previous run. + (dolist (buf (list tmpbuf errbuf)) + (with-current-buffer buf + (erase-buffer))) + (condition-case err + (if (not (zerop (blacken-call-bin original-buffer tmpbuf errbuf))) + (error "Black failed, see %s buffer for details" (buffer-name errbuf)) + (unless (eq (compare-buffer-substrings tmpbuf nil nil original-buffer nil nil) 0) + (with-current-buffer tmpbuf + (copy-to-buffer original-buffer (point-min) (point-max))) + (goto-char original-point) + (set-window-start (selected-window) original-window-pos)) + (mapc 'kill-buffer (list tmpbuf errbuf))) + (error (message "%s" (error-message-string err)) + (when display + (pop-to-buffer errbuf)))))) + +;;;###autoload +(define-minor-mode blacken-mode + "Automatically run black before saving." + :lighter " Black" + (if blacken-mode + (add-hook 'before-save-hook 'blacken-buffer nil t) + (remove-hook 'before-save-hook 'blacken-buffer t))) + +(provide 'blacken) + +;;; blacken.el ends here diff --git a/packages/bm-20181012.1631.tar b/packages/bm-20190807.1217.tar similarity index 95% rename from packages/bm-20181012.1631.tar rename to packages/bm-20190807.1217.tar index 0e9b486..1226cb6 100644 Binary files a/packages/bm-20181012.1631.tar and b/packages/bm-20190807.1217.tar differ diff --git a/packages/browse-at-remote-20180622.631.el b/packages/browse-at-remote-20190213.1929.el similarity index 85% rename from packages/browse-at-remote-20180622.631.el rename to packages/browse-at-remote-20190213.1929.el index 32d53d0..67e4e4d 100644 --- a/packages/browse-at-remote-20180622.631.el +++ b/packages/browse-at-remote-20190213.1929.el @@ -1,11 +1,11 @@ -;;; browse-at-remote.el --- Open github/gitlab/bitbucket/stash page from Emacs -*- lexical-binding:t -*- +;;; browse-at-remote.el --- Open github/gitlab/bitbucket/stash/gist/phab/sourcehut page from Emacs -*- lexical-binding:t -*- -;; Copyright © 2015-2016 Rustem Muslimov +;; Copyright © 2015-2018 Rustem Muslimov ;; ;; Author: Rustem Muslimov -;; Version: 0.10.0 -;; Package-Version: 20180622.631 -;; Keywords: github, gitlab, bitbucket, convenience +;; Version: 0.13.0 +;; Package-Version: 20190213.1929 +;; Keywords: github, gitlab, bitbucket, gist, stash, phabricator, sourcehut ;; Package-Requires: ((f "0.17.2") (s "1.9.0") (cl-lib "0.5")) ;; This program is free software: you can redistribute it and/or modify @@ -46,7 +46,9 @@ '(("bitbucket.org" ."bitbucket") ("github.com" . "github") ("gitlab.com" . "gitlab") - ("git.savannah.gnu.org" . "gnu")) + ("git.savannah.gnu.org" . "gnu") + ("gist.github.com" . "gist") + ("git.sr.ht" . "sourcehut")) "Alist of domain patterns to remote types." :type '(alist :key-type (string :tag "Domain") @@ -55,7 +57,10 @@ (const :tag "GitLab" "gitlab") (const :tag "Bitbucket" "bitbucket") (const :tag "Stash/Bitbucket Server" "stash") - (const :tag "git.savannah.gnu.org" "gnu"))) + (const :tag "git.savannah.gnu.org" "gnu") + (const :tag "Phabricator" "phabricator") + (const :tag "gist.github.com" "gist") + (const :tag "sourcehut" "sourcehut"))) :group 'browse-at-remote) (defcustom browse-at-remote-prefer-symbolic t @@ -247,6 +252,24 @@ If HEAD is detached, return nil." "Commit URL formatted for bitbucket" (format "%s/commits/%s" repo-url commithash)) +(defun browse-at-remote--format-region-url-as-gist (repo-url location filename &optional linestart lineend) + "URL formatted for gist." + (concat + (format "%s#file-%s" repo-url + (replace-regexp-in-string "[^a-z0-9_]+" "-" filename)) + (cond + ((and linestart lineend) (format "-L%d-L%d" linestart lineend)) + (linestart (format "-L%d" linestart)) + (t "")))) + +(defun browse-at-remote--format-commit-url-as-gist (repo-url commithash) + "Commit URL formatted for gist" + (cond + ((equal commithash "master") + repo-url) + (t + (format "%s/%s" repo-url commithash)))) + (defun browse-at-remote--fix-repo-url-stash (repo-url) "Inserts 'projects' and 'repos' in #repo-url" (let* ((reversed-url (reverse (split-string repo-url "/"))) @@ -269,6 +292,19 @@ If HEAD is detached, return nil." "Commit URL formatted for stash" (format "%s/commits/%s" (browse-at-remote--fix-repo-url-stash repo-url) commithash)) +(defun browse-at-remote--format-region-url-as-phabricator (repo-url location filename &optional linestart lineend) + "URL formatted for Phabricator" + (let* ((lines (cond + (lineend (format "\$%d-%d" linestart lineend)) + (linestart (format "\$%d" linestart)) + (t "")))) + (format "%s/browse/%s/%s%s" repo-url location filename lines))) + +(defun browse-at-remote--format-commit-url-as-phabricator (repo-url commithash) + "Commit URL formatted for Phabricator" + (message repo-url) + (format "%s/%s%s" (replace-regexp-in-string "\/source/.*" "" repo-url) (read-string "Please input the callsign for this repository:") commithash)) + (defun browse-at-remote--format-region-url-as-gitlab (repo-url location filename &optional linestart lineend) "URL formatted for gitlab. The only difference from github is format of region: L1-2 instead of L1-L2" @@ -278,11 +314,23 @@ The only difference from github is format of region: L1-2 instead of L1-L2" (linestart (format "%s/blob/%s/%s#L%d" repo-url location filename linestart)) (t (format "%s/tree/%s/%s" repo-url location filename)))) +(defun browse-at-remote--format-region-url-as-sourcehut (repo-url location filename &optional linestart lineend) + "URL formatted for sourcehut." + (cond + ((and linestart lineend) + (format "%s/tree/%s/%s#L%d-%d" repo-url location filename linestart lineend)) + (linestart (format "%s/tree/%s/%s#L%d" repo-url location filename linestart)) + (t (format "%s/tree/%s/%s" repo-url location filename)))) + (defun browse-at-remote--format-commit-url-as-gitlab (repo-url commithash) "Commit URL formatted for gitlab. Currently the same as for github." (format "%s/commit/%s" repo-url commithash)) +(defun browse-at-remote--format-commit-url-as-sourcehut (repo-url commithash) + "Commit URL formatted for sourcehut." + (format "%s/commit/%s" repo-url commithash)) + (defun browse-at-remote--commit-url (commithash) "Return the URL to browse COMMITHASH." (let* ((remote (car (browse-at-remote--remote-ref))) @@ -339,10 +387,13 @@ Currently the same as for github." ;; magit-commit-mode and magit-revision-mode ((or (eq major-mode 'magit-commit-mode) (eq major-mode 'magit-revision-mode)) (save-excursion + ;; Search for the SHA1 on the first line. (goto-char (point-min)) (let* ((first-line (buffer-substring-no-properties (line-beginning-position) (line-end-position))) - (commithash (car (s-split " " first-line)))) + (commithash (cl-loop for word in (s-split " " first-line) + when (eq 40 (length word)) + return word))) (browse-at-remote--commit-url commithash)))) ;; log-view-mode diff --git a/packages/bui-20181218.1830.tar b/packages/bui-20181218.1830.tar new file mode 100644 index 0000000..28ad37b Binary files /dev/null and b/packages/bui-20181218.1830.tar differ diff --git a/packages/bundler-20160815.915.el b/packages/bundler-20190701.1013.el similarity index 98% rename from packages/bundler-20160815.915.el rename to packages/bundler-20190701.1013.el index 02d8736..a328bb0 100644 --- a/packages/bundler-20160815.915.el +++ b/packages/bundler-20190701.1013.el @@ -4,7 +4,7 @@ ;; Author: Tobias Svensson ;; URL: http://github.com/endofunky/bundler.el -;; Package-Version: 20160815.915 +;; Package-Version: 20190701.1013 ;; Keywords: bundler ruby ;; Created: 31 Dec 2011 ;; Version: 1.1.1 @@ -183,7 +183,7 @@ found." (t (concat remote (replace-regexp-in-string - "Resolving dependencies...\\|\n" "" + "Resolving dependencies...\\|The dependency .* will be unused by .*$\\|\n" "" bundler-stdout) "/"))))) diff --git a/packages/caml-20181011.1328.tar b/packages/caml-20190413.1205.tar similarity index 93% rename from packages/caml-20181011.1328.tar rename to packages/caml-20190413.1205.tar index 3aaaabc..b3b91eb 100644 Binary files a/packages/caml-20181011.1328.tar and b/packages/caml-20190413.1205.tar differ diff --git a/packages/cargo-20181112.722.tar b/packages/cargo-20190816.1046.tar similarity index 88% rename from packages/cargo-20181112.722.tar rename to packages/cargo-20190816.1046.tar index adf9cd6..6977ead 100644 Binary files a/packages/cargo-20181112.722.tar and b/packages/cargo-20190816.1046.tar differ diff --git a/packages/ccls-20181106.546.tar b/packages/ccls-20190720.935.tar similarity index 84% rename from packages/ccls-20181106.546.tar rename to packages/ccls-20190720.935.tar index 31832cd..a1f8de8 100644 Binary files a/packages/ccls-20181106.546.tar and b/packages/ccls-20190720.935.tar differ diff --git a/packages/centered-cursor-mode-20180112.1555.el b/packages/centered-cursor-mode-20190306.1006.el similarity index 91% rename from packages/centered-cursor-mode-20180112.1555.el rename to packages/centered-cursor-mode-20190306.1006.el index 1b194e8..528a3e7 100644 --- a/packages/centered-cursor-mode-20180112.1555.el +++ b/packages/centered-cursor-mode-20190306.1006.el @@ -6,12 +6,12 @@ ;; Maintainer: André Riemann ;; Created: 2007-09-14 ;; Keywords: convenience -;; Package-Version: 20180112.1555 +;; Package-Version: 20190306.1006 ;; URL: https://github.com/andre-r/centered-cursor-mode.el -;; Compatibility: tested with GNU Emacs 23.0, 24, 26 -;; Version: 0.5.7 -;; Last-Updated: 2018-01-12 +;; Compatibility: tested with GNU Emacs 24, 26, 27 +;; Version: 0.5.11 +;; Last-Updated: 2019-03-06 ;; 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 @@ -57,6 +57,16 @@ ;; - more bugs? ;;; Change Log: +;; 2019-03-06 kqr +;; * more customisable way to inhibit recentering after a command: +;; new defcustom ccm-inhibit-centering-when +;; * new ignored command evil-mouse-drag-region +;; 2019-02-24 Gollum999 +;; * Fix aggressive centering while dragging mouse (selecting text doesn't scroll) +;; 2019-02-05 andre-r +;; * tip from MATTHIAS Andreas +;; - replaced forward-line with next-line in ccm-scroll-up and ccm-scroll-down; +;; scrolled too far in visual-line-mode ;; 2018-01-12 andre-r ;; * #3: Centering does not take line-height into account ;; - added new function for calculating visible lines @@ -133,10 +143,11 @@ If you want a different animation speed." :type 'number) (defcustom ccm-ignored-commands '(mouse-drag-region - mouse-set-region + mouse-set-region mouse-set-point widget-button-click - scroll-bar-toolkit-scroll) + scroll-bar-toolkit-scroll + evil-mouse-drag-region) "After these commands recentering is ignored. This is to prevent unintentional jumping (especially when mouse clicking). Following commands (except the ignored ones) will @@ -146,6 +157,14 @@ jumping to the center." :tag "Ignored commands" :type '(repeat (symbol :tag "Command"))) +(defcustom ccm-inhibit-centering-when '(ccm-ignored-command-p + ccm-mouse-drag-movement-p) + "A list of functions which are allowed to inhibit recentering. +If any of these return t, recentering is canceled." + :group 'centered-cursor + :tag "Inhibit centering when" + :type '(repeat (symbol :tag "Function"))) + ;;;###autoload (defun ccm-visible-text-lines () "Visible text lines" @@ -232,6 +251,8 @@ This command exists, because mwheel-scroll caused strange behaviour with automatic recentering." ;; (interactive (list last-input-event)) (interactive "e") + (when (region-active-p) + (deactivate-mark)) (let* ((mods (delq 'click (delq 'double (delq 'triple (event-modifiers event))))) (amt (assoc mods mouse-wheel-scroll-amount))) ;;(message "%S" mods) @@ -262,7 +283,7 @@ a fixed position the movement appears as page up." (interactive "P") (let ((amt (or arg (- (ccm-visible-text-lines) next-screen-context-lines)))) - (forward-line (- amt)))) + (next-line (- amt)))) (defun ccm-scroll-up (&optional arg) "Replaces `scroll-up' to be consistent with `ccm-scroll-down'. @@ -272,7 +293,7 @@ the movement appears as page up." (interactive "P") (let ((amt (or arg (- (ccm-visible-text-lines) next-screen-context-lines)))) - (forward-line amt))) + (next-line amt))) (defun ccm-vpos-down (arg) @@ -315,9 +336,17 @@ the center. Just the variable ccm-vpos is set." (setq ccm-vpos (* (eval ccm-vpos-init) ccm-vpos-inverted)))) +(defun ccm-ignored-command-p () + "Check if the last command was one listed in CCM-IGNORED-COMMANDS." + (member this-command ccm-ignored-commands)) + +(defun ccm-mouse-drag-movement-p () + "Check if the last input event corresponded to a mouse drag event." + (mouse-movement-p last-command-event)) + (defun ccm-position-cursor () "Do the actual recentering at the position `ccm-vpos'." - (unless (member this-command ccm-ignored-commands) + (unless (seq-some #'funcall ccm-inhibit-centering-when) (unless ccm-vpos (ccm-vpos-recenter)) (unless (minibufferp (current-buffer)) diff --git a/packages/chinese-wbim-20150624.350.tar b/packages/chinese-wbim-20190727.854.tar similarity index 99% rename from packages/chinese-wbim-20150624.350.tar rename to packages/chinese-wbim-20190727.854.tar index fb661a8..64ab73f 100644 Binary files a/packages/chinese-wbim-20150624.350.tar and b/packages/chinese-wbim-20190727.854.tar differ diff --git a/packages/chocolate-theme-20190818.756.el b/packages/chocolate-theme-20190818.756.el new file mode 100644 index 0000000..f180de0 --- /dev/null +++ b/packages/chocolate-theme-20190818.756.el @@ -0,0 +1,1660 @@ +;;; chocolate-theme.el --- A dark chocolaty theme -*- lexical-binding: t; -*- + +;; Copyright (c) 2018-2019 Valeriy Savchenko (GNU/GPL Licence) + +;; Authors: Valeriy Savchenko +;; URL: http://github.com/SavchenkoValeriy/emacs-chocolate-theme +;; Package-Version: 20190818.756 +;; Version: 0.2.0 +;; Package-Requires: ((emacs "24.1") (autothemer "0.2")) + +;;; Commentary: +;; Poor doggies can't experience it because of two reasons + +;;; Code: +(require 'autothemer) + +(autothemer-deftheme + chocolate "Poor doggies can't experience it because of two reasons" + + ((((class color) (min-colors #xFFFFFF))) ;; color column 1 GUI/24bit + + (chocolate-mono-1 "#BFAAAE") + (chocolate-mono-2 "#968185") + (chocolate-mono-3 "#705B5F") + (chocolate-hue-1 "#56B5C2") + (chocolate-hue-1-2 "#7CEFFF") + (chocolate-hue-1-3 "#6ED6E5") + (chocolate-hue-1-4 "#54BCCA") + (chocolate-hue-1-5 "#45AFBD") + (chocolate-hue-2 "#EAEAFE") + (chocolate-hue-3 "#DC672C") + (chocolate-hue-4 "#C7AE9D") + (chocolate-hue-4-2 "#937F73") + (chocolate-hue-5 "#DF6B75") + (chocolate-hue-5-2 "#BE5046") + (chocolate-hue-5-3 "#D2646E") + (chocolate-hue-5-4 "#C55D67") + (chocolate-hue-5-5 "#B85660") + (chocolate-hue-5-6 "#AB5059") + (chocolate-hue-6 "#D19965") + (chocolate-hue-6-2 "#E4BF7A") + (chocolate-hue-6-3 "#AA8768") + (chocolate-hue-7 "#FFC15E") + (chocolate-hue-7-2 "#FFC05B") + (chocolate-hue-7-3 "#FBBD5A") + (chocolate-hue-7-4 "#EDB254") + (chocolate-hue-7-5 "#E0A84F") + (chocolate-hue-8 "#C77497") + (chocolate-hue-8-2 "#BB6D8E") + (chocolate-hue-8-3 "#AF6685") + (chocolate-hue-8-4 "#975873") + (chocolate-hue-8-5 "#8B516A") + (chocolate-hue-9 "#56E39F") + (chocolate-hue-9-2 "#50D595") + (chocolate-hue-9-3 "#4BC88C") + (chocolate-hue-9-4 "#46BB83") + (chocolate-hue-9-5 "#41AE7A") + (chocolate-syntax-light "#4B393E") + (chocolate-syntax-bg-light "#3E2F33") + (chocolate-syntax-bg "#33272A") + (chocolate-syntax-bg-dark "#261D1F") + (chocolate-syntax-accent "#F88425") + (chocolate-syntax-renamed "#329fff") + (chocolate-syntax-added "#43d089") + (chocolate-syntax-modified "#e0c184") + (chocolate-syntax-removed "#e05151") + (chocolate-darker-green "#292D29") + (chocolate-dark-green "#2A382F") + (chocolate-darker-red "#4B2729") + (chocolate-dark-red "#632E2F") + (chocolate-darker-yellow "#483B31") + (chocolate-dark-yellow "#594A3B")) + + ((default (:foreground chocolate-hue-4 :background chocolate-syntax-bg)) + (cursor (:background chocolate-hue-4)) + (link (:foreground chocolate-hue-1 :underline t)) + (link-visited (:foreground chocolate-hue-1 :underline nil)) + (mode-line (:foreground chocolate-hue-6 :background chocolate-syntax-light :box nil)) + (mode-line-inactive (:foreground chocolate-hue-6-3 :background chocolate-syntax-bg-light :box nil)) + (fringe (:background chocolate-syntax-bg)) + (linum (:foreground chocolate-hue-4-2)) + (region (:background chocolate-syntax-light :distant-foreground chocolate-hue-4)) + (secondary-selection (:background chocolate-syntax-light)) + (hl-line (:background chocolate-syntax-bg-light)) + + ;; Built-in syntax + (font-lock-builtin-face (:foreground chocolate-syntax-accent)) + (font-lock-constant-face (:foreground chocolate-hue-6)) + (font-lock-comment-face (:foreground chocolate-mono-3)) + (font-lock-function-name-face (:weight 'bold :foreground chocolate-hue-1)) + (font-lock-keyword-face (:foreground chocolate-hue-3)) + (font-lock-string-face (:foreground chocolate-hue-6-2)) + (font-lock-variable-name-face (:foreground chocolate-hue-5)) + (font-lock-type-face (:foreground chocolate-hue-1)) + (font-lock-warning-face (:foreground chocolate-hue-5-2 :bold t)) + + ;; MODE SUPPORT: rainbow-delimiters + (rainbow-delimiters-depth-1-face (:foreground chocolate-hue-1)) + (rainbow-delimiters-depth-2-face (:foreground chocolate-hue-2)) + (rainbow-delimiters-depth-3-face (:foreground chocolate-hue-3)) + (rainbow-delimiters-depth-4-face (:foreground chocolate-hue-4)) + (rainbow-delimiters-depth-5-face (:foreground chocolate-hue-5)) + (rainbow-delimiters-depth-6-face (:foreground chocolate-hue-6)) + (rainbow-delimiters-depth-7-face (:foreground chocolate-hue-1)) + (rainbow-delimiters-depth-8-face (:foreground chocolate-hue-2)) + (rainbow-delimiters-depth-9-face (:foreground chocolate-hue-3)) + (rainbow-delimiters-depth-10-face (:foreground chocolate-hue-4)) + (rainbow-delimiters-depth-11-face (:foreground chocolate-hue-5)) + (rainbow-delimiters-depth-12-face (:foreground chocolate-hue-6)) + (rainbow-delimiters-unmatched-face (:foreground chocolate-hue-4 nil)) + + (cquery-sem-variable-face-0 (:foreground chocolate-hue-5)) + (cquery-sem-variable-face-1 (:foreground chocolate-hue-5-3)) + (cquery-sem-variable-face-2 (:foreground chocolate-hue-5-4)) + (cquery-sem-variable-face-3 (:foreground chocolate-hue-5-5)) + (cquery-sem-variable-face-4 (:foreground chocolate-hue-5-6)) + (cquery-sem-variable-face-5 (:foreground chocolate-hue-5)) + (cquery-sem-variable-face-6 (:foreground chocolate-hue-5-3)) + (cquery-sem-variable-face-7 (:foreground chocolate-hue-5-4)) + (cquery-sem-variable-face-8 (:foreground chocolate-hue-5-5)) + (cquery-sem-variable-face-9 (:foreground chocolate-hue-5-6)) + + (cquery-sem-type-face-0 (:foreground chocolate-hue-1)) + (cquery-sem-type-face-1 (:foreground chocolate-hue-1-2)) + (cquery-sem-type-face-2 (:foreground chocolate-hue-1-3)) + (cquery-sem-type-face-3 (:foreground chocolate-hue-1-4)) + (cquery-sem-type-face-4 (:foreground chocolate-hue-1-5)) + (cquery-sem-type-face-5 (:foreground chocolate-hue-1)) + (cquery-sem-type-face-6 (:foreground chocolate-hue-1-2)) + (cquery-sem-type-face-7 (:foreground chocolate-hue-1-3)) + (cquery-sem-type-face-8 (:foreground chocolate-hue-1-4)) + (cquery-sem-type-face-9 (:foreground chocolate-hue-1-5)) + + (cquery-sem-function-face-0 (:foreground chocolate-hue-7)) + (cquery-sem-function-face-1 (:foreground chocolate-hue-7-2)) + (cquery-sem-function-face-2 (:foreground chocolate-hue-7-3)) + (cquery-sem-function-face-3 (:foreground chocolate-hue-7-4)) + (cquery-sem-function-face-4 (:foreground chocolate-hue-7-5)) + (cquery-sem-function-face-5 (:foreground chocolate-hue-7)) + (cquery-sem-function-face-6 (:foreground chocolate-hue-7-2)) + (cquery-sem-function-face-7 (:foreground chocolate-hue-7-3)) + (cquery-sem-function-face-8 (:foreground chocolate-hue-7-4)) + (cquery-sem-function-face-9 (:foreground chocolate-hue-7-5)) + + (cquery-sem-namespace-face-0 (:foreground chocolate-hue-8)) + (cquery-sem-namespace-face-1 (:foreground chocolate-hue-8-2)) + (cquery-sem-namespace-face-2 (:foreground chocolate-hue-8-3)) + (cquery-sem-namespace-face-3 (:foreground chocolate-hue-8-4)) + (cquery-sem-namespace-face-4 (:foreground chocolate-hue-8-5)) + (cquery-sem-namespace-face-5 (:foreground chocolate-hue-8)) + (cquery-sem-namespace-face-6 (:foreground chocolate-hue-8-2)) + (cquery-sem-namespace-face-7 (:foreground chocolate-hue-8-3)) + (cquery-sem-namespace-face-8 (:foreground chocolate-hue-8-4)) + (cquery-sem-namespace-face-9 (:foreground chocolate-hue-8-5)) + + (cquery-sem-parameter-face-0 (:foreground chocolate-hue-9)) + (cquery-sem-parameter-face-1 (:foreground chocolate-hue-9-2)) + (cquery-sem-parameter-face-2 (:foreground chocolate-hue-9-3)) + (cquery-sem-parameter-face-3 (:foreground chocolate-hue-9-4)) + (cquery-sem-parameter-face-4 (:foreground chocolate-hue-9-5)) + (cquery-sem-parameter-face-5 (:foreground chocolate-hue-9)) + (cquery-sem-parameter-face-6 (:foreground chocolate-hue-9-2)) + (cquery-sem-parameter-face-7 (:foreground chocolate-hue-9-3)) + (cquery-sem-parameter-face-8 (:foreground chocolate-hue-9-4)) + (cquery-sem-parameter-face-9 (:foreground chocolate-hue-9-5)) + + (lsp-face-highlight-textual (:background chocolate-syntax-light)) + + ;; MODE SUPPORT: ivy + (ivy-prompt-match (:inherit 'ivy-current-match)) + (ivy-highlight-face (:inherit 'highlight)) + (ivy-action (:inherit 'font-lock-builtin-face)) + (ivy-virtual (:foreground chocolate-mono-1)) + (ivy-remote (:foreground chocolate-syntax-renamed)) + (ivy-modified-buffer (:inherit 'default)) + (ivy-subdir (:inherit 'dired-directory)) + (ivy-match-required-face (:foreground chocolate-syntax-accent :inherit 'minibuffer-prompt)) + (ivy-confirm-face (:foreground chocolate-syntax-bg-dark :inherit 'minibuffer-prompt)) + (ivy-minibuffer-match-face-4 (:foreground chocolate-hue-6-2 :inherit 'ivy-minibuffer-match-face-1)) + (ivy-minibuffer-match-face-3 (:foreground chocolate-syntax-added :inherit 'ivy-minibuffer-match-face-1)) + (ivy-minibuffer-match-face-2 (:foreground chocolate-hue-6 :inherit 'ivy-minibuffer-match-face-1)) + (ivy-minibuffer-match-face-1 (:weight 'bold :foreground chocolate-mono-3 :background chocolate-syntax-bg-dark)) + (ivy-minibuffer-match-highlight (:inherit 'highlight)) + (ivy-current-match (:weight 'bold :background chocolate-mono-3)) + (ivy-cursor (:foreground chocolate-hue-2 :background chocolate-syntax-bg-dark)) + + ;; MODE support: js2 + (js2-function-param (:foreground chocolate-hue-1)) + (js2-external-variable (:weight 'bold :foreground chocolate-hue-7)) + (js2-function-call (:foreground chocolate-hue-6)) + + ;; MODE support: display-line-numbers + (line-number (:foreground chocolate-mono-3)) + (line-number-current-line (:foreground chocolate-mono-2 :weight 'bold)) + + ;; MODE support: ediff + (ediff-current-diff-A (:background chocolate-darker-red)) + (ediff-current-diff-Ancestor (:inherit 'ediff-current-diff-A)) + (ediff-current-diff-B (:background chocolate-darker-green)) + (ediff-current-diff-C (:background chocolate-darker-yellow)) + (ediff-even-diff-A (:background chocolate-syntax-bg-light)) + (ediff-even-diff-Ancestor (:inherit 'ediff-even-diff-A)) + (ediff-even-diff-B (:background chocolate-syntax-bg-light)) + (ediff-even-diff-C (:background chocolate-syntax-bg-light)) + (ediff-fine-diff-A (:background chocolate-dark-red)) + (ediff-fine-diff-Ancestor (:inherit 'ediff-fine-diff-A)) + (ediff-fine-diff-B (:background chocolate-dark-green)) + (ediff-fine-diff-C (:background chocolate-dark-yellow)) + (ediff-odd-diff-A (:inherut 'ediff-even-diff-A)) + (ediff-odd-diff-Ancestor (:inherit 'ediff-odd-diff-A)) + (ediff-odd-diff-B (:inherit 'ediff-even-diff-B)) + (ediff-odd-diff-C (:inherit 'ediff-even-diff-C)) + + ;; MODE SUPPORT: org + (org-table (:foreground chocolate-hue-1-5)) + (org-date (:foreground chocolate-hue-1-3)) + (org-done (:foreground chocolate-hue-9)) + (org-agenda-done (:foreground chocolate-hue-9)) + (org-headline-done (:foreground chocolate-hue-5-3)) + (org-formula (:foreground chocolate-syntax-accent)) + (org-document-title (:foreground chocolate-hue-1)) + (org-document-info (:foreground chocolate-hue-1)) + (org-agenda-structure (:foreground chocolate-hue-1-5)) + (org-scheduled (:foreground chocolate-hue-9)) + (org-scheduled-today (:foreground chocolate-hue-9)) + (org-agenda-dimmed-todo-face (:foreground chocolate-mono-3)) + (org-scheduled-previously (:foreground chocolate-syntax-accent)) + (org-agenda-restriction-lock (:background chocolate-syntax-bg-dark)) + (org-time-grid (:foreground chocolate-hue-7)) + + ;; MODE SUPPORT: popup + (popup-face (:foreground chocolate-hue-4 + :background chocolate-syntax-light)) + (popup-menu-mouse-face (:foreground chocolate-hue-4 + :background chocolate-hue-1)) + (popup-menu-selection-face (:foreground chocolate-hue-4 + :background chocolate-hue-1)) + (popup-tip-face (:foreground chocolate-hue-4 + :background chocolate-syntax-bg-dark)) + ;; Use tip colors for the pos-tip color vars (see below) + + ;; MODE SUPPORT: powerline + (powerline-active1 (:background chocolate-syntax-light :foreground chocolate-hue-4 :inherit 'mode-line)) + (powerline-active2 (:background chocolate-syntax-bg)) + (powerline-inactive1 (:background chocolate-syntax-bg-dark :inherit 'mode-line-inactive)) + (powerline-inactive2 (:background chocolate-syntax-bg-dark :inherit 'mode-line-inactive)) + (spaceline-highlight-face (:background chocolate-hue-6 :foreground chocolate-syntax-bg-dark)) + + ;; MODE SUPPORT: centaur tabs + (centaur-tabs-default (:background chocolate-syntax-bg-dark :foreground chocolate-hue-4)) + (centaur-tabs-selected (:background chocolate-syntax-bg :foreground chocolate-hue-4 :weight 'bold)) + (centaur-tabs-unselected (:background chocolate-syntax-bg-dark :foreground chocolate-mono-3 :weight 'light)) + (centaur-tabs-selected-modified (:background chocolate-syntax-bg :foreground chocolate-hue-6 :weight 'bold)) + (centaur-tabs-unselected-modified (:background chocolate-syntax-bg-dark :foreground chocolate-hue-6-3 :weight 'light)) + (centaur-tabs-active-bar-face (:background chocolate-hue-7)) + (centaur-tabs-modified-marker-selected (:inherit 'centaur-tabs-selected-modified :foreground chocolate-hue-6-2)) + (centaur-tabs-modified-marker-unselected (:inherit 'centaur-tabs-unselected-modified)) + + ;; MODE SUPPORT: latex + (font-latex-sectioning-5-face (:foreground chocolate-hue-6-2)) + (font-latex-italic-face (:foreground chocolate-hue-9-5 :inherit 'italic)) + (font-latex-bold-face (:foreground chocolate-hue-7 :inherit 'bold)) + + (ffap + (:inherit 'highlight)) + (epa-field-body + (:slant 'italic :foreground chocolate-hue-1)) + (epa-field-name + (:weight 'bold :foreground chocolate-hue-2)) + (epa-mark + (:weight 'bold :foreground chocolate-syntax-accent)) + (epa-string + (:foreground chocolate-hue-2)) + (epa-validity-disabled + (:slant 'italic :inverse-video t)) + (epa-validity-low + (:slant 'italic)) + (epa-validity-medium + (:slant 'italic :foreground chocolate-hue-2)) + (epa-validity-high + (:weight 'bold :foreground chocolate-hue-2)) + (helm-bookmark-addressbook + (:foreground chocolate-syntax-removed)) + (helm-bookmark-directory + (:inherit 'helm-ff-directory)) + (helm-bookmark-file-not-found + (:foreground chocolate-mono-2)) + (helm-bookmark-file + (:foreground chocolate-syntax-renamed)) + (helm-bookmark-man + (:foreground chocolate-mono-3)) + (helm-bookmark-gnus + (:foreground chocolate-hue-2)) + (helm-bookmark-w3m + (:foreground chocolate-syntax-accent)) + (helm-bookmark-info + (:foreground chocolate-syntax-added)) + (bookmark-menu-heading + (:inherit 'font-lock-type-face)) + (bookmark-menu-bookmark + (:weight 'bold)) + (eshell-prompt + (:foreground chocolate-mono-1)) + (eshell-ls-clutter + (:foreground chocolate-hue-5)) + (eshell-ls-product + (:foreground chocolate-hue-6)) + (eshell-ls-backup + (:foreground chocolate-hue-6-2)) + (eshell-ls-archive + (:foreground chocolate-mono-1)) + (eshell-ls-missing + (:foreground chocolate-hue-5)) + (eshell-ls-special + (:foreground chocolate-mono-1)) + (eshell-ls-unreadable + (:foreground chocolate-mono-3)) + (eshell-ls-readonly + (:foreground chocolate-hue-6)) + (eshell-ls-executable + (:foreground chocolate-syntax-added)) + (eshell-ls-symlink + (:foreground chocolate-syntax-renamed)) + (eshell-ls-directory + (:foreground chocolate-hue-1)) + (nlinum-current-line + (:weight 'bold :foreground chocolate-hue-1)) + (aw-mode-line-face + (:inherit 'mode-line-buffer-id)) + (aw-background-face + (:foreground chocolate-mono-3)) + (aw-leading-char-face + (:foreground chocolate-syntax-accent)) + (avy-goto-char-timer-face + (:inherit 'highlight)) + (avy-background-face + (:foreground chocolate-mono-3)) + (avy-lead-face + (:foreground chocolate-syntax-bg-dark :background chocolate-hue-1)) + (avy-lead-face-2 + (:inherit 'avy-lead-face)) + (avy-lead-face-1 + (:inherit 'avy-lead-face)) + (avy-lead-face-0 + (:inherit 'avy-lead-face)) + (helm-M-x-key + (:underline t :foreground chocolate-syntax-accent)) + (helm-lisp-completion-info + (:foreground chocolate-syntax-accent)) + (helm-lisp-show-completion + (:background chocolate-syntax-light)) + (whitespace-space-after-tab + (:foreground chocolate-hue-5-2 :background chocolate-syntax-accent)) + (whitespace-empty + (:background chocolate-syntax-bg)) + (whitespace-big-indent + (:foreground chocolate-hue-5-2 :background chocolate-syntax-accent)) + (whitespace-indentation + (:foreground chocolate-hue-5 :background chocolate-hue-6-2)) + (whitespace-space-before-tab + (:foreground chocolate-hue-5-2 :background chocolate-syntax-accent)) + (whitespace-line + (:weight 'bold :foreground chocolate-hue-5 :background chocolate-syntax-bg-dark)) + (whitespace-trailing + (:inherit 'trailing-whitespace)) + (whitespace-newline + (:foreground chocolate-syntax-light)) + (whitespace-tab + (:foreground chocolate-syntax-light)) + (whitespace-hspace + (:foreground chocolate-mono-1 :background chocolate-syntax-light)) + (whitespace-space + (:foreground chocolate-syntax-light)) + (custom-group-subtitle + (:weight 'bold)) + (custom-group-tag + (:height 1.2 :weight 'bold :foreground chocolate-hue-2 :inherit 'variable-pitch)) + (custom-group-tag-1 + (:height 1.2 :weight 'bold :foreground chocolate-syntax-modified :inherit 'variable-pitch)) + (custom-face-tag + (:inherit 'custom-variable-tag)) + (custom-visibility + (:height 0.8 :inherit 'link)) + (custom-variable-button + (:weight 'bold :underline t)) + (custom-variable-tag + (:weight 'bold :foreground chocolate-hue-2)) + (custom-comment-tag + (:foreground chocolate-mono-1)) + (custom-comment + (:background chocolate-mono-3)) + (custom-link + (:inherit 'link)) + (custom-state + (:foreground chocolate-syntax-added)) + (custom-documentation nil) + (custom-button-pressed-unraised + (:foreground chocolate-hue-2 :inherit 'custom-button-unraised)) + (custom-button-pressed + (:box + (:line-width 2 :style 'pressed-button) + :foreground chocolate-syntax-bg-dark :background chocolate-hue-2)) + (custom-button-unraised + (:inherit 'underline)) + (custom-button-mouse + (:box + (:line-width 2 :style 'released-button) + :foreground chocolate-syntax-bg-dark :background chocolate-hue-2)) + (custom-button + (:box + (:line-width 2 :style 'released-button) + :foreground chocolate-syntax-bg-dark :background chocolate-hue-2)) + (custom-saved + (:underline t)) + (custom-themed + (:foreground chocolate-hue-2 :background chocolate-syntax-renamed)) + (custom-changed + (:foreground chocolate-hue-2 :background chocolate-syntax-renamed)) + (custom-set + (:foreground chocolate-syntax-renamed :background chocolate-hue-2)) + (custom-modified + (:foreground chocolate-hue-2 :background chocolate-syntax-renamed)) + (custom-rogue + (:foreground chocolate-syntax-modified :background chocolate-syntax-bg-dark)) + (custom-invalid + (:foreground chocolate-syntax-accent :background chocolate-syntax-accent)) + (memrise-session-keybinding + (:weight 'bold)) + (memrise-session-literal-translation + (:inherit 'memrise-dashboard-description)) + (memrise-session-keyword + (:weight 'bold)) + (memrise-session-thing + (:height 270)) + (memrise-dashboard-description + (:height 125 :inherit 'font-lock-comment-face)) + (memrise-dashboard-difficult + (:foreground chocolate-syntax-accent)) + (memrise-dashboard-review + (:foreground chocolate-syntax-renamed)) + (memrise-dashboard-all + (:inherit 'memrise-dashboard-learned)) + (memrise-dashboard-learned + (:foreground chocolate-mono-3)) + (memrise-dashboard-name + (:inherit 'font-lock-keyword-face)) + (paradox-description-face-multiline + (:inherit 'font-lock-doc-face)) + (paradox-description-face + (:inherit 'default)) + (paradox-download-face + (:inherit 'font-lock-keyword-face)) + (paradox-starred-face + (:inherit 'font-lock-variable-name-face)) + (paradox-star-face + (:inherit 'font-lock-string-face)) + (paradox-archive-face + (:inherit 'paradox-comment-face)) + (paradox-homepage-button-face + (:underline t :inherit 'font-lock-comment-face)) + (paradox-name-face + (:inherit 'link)) + (paradox-mode-line-face + (:weight 'normal :inherit + ('font-lock-keyword-face 'mode-line-buffer-id))) + (paradox-commit-tag-face + (:box 1 :foreground chocolate-hue-3 :background chocolate-hue-2)) + (paradox-highlight-face + (:weight 'bold :inherit 'font-lock-variable-name-face)) + (paradox-comment-face + (:foreground chocolate-mono-2)) + (emms-metaplaylist-mode-current-face + (:foreground chocolate-hue-3)) + (emms-metaplaylist-mode-face + (:foreground chocolate-mono-1)) + (emms-browser-track-face + (:height 1.0 :foreground chocolate-mono-1)) + (emms-browser-album-face + (:height 1.1 :foreground chocolate-mono-1)) + (emms-browser-performer-face + (:height 1.3 :foreground chocolate-mono-1)) + (emms-browser-composer-face + (:height 1.3 :foreground chocolate-mono-1)) + (emms-browser-artist-face + (:height 1.3 :foreground chocolate-mono-1)) + (emms-browser-year/genre-face + (:height 1.5 :foreground chocolate-mono-1)) + (emms-stream-url-face + (:foreground chocolate-mono-1)) + (emms-stream-name-face + (:weight 'bold)) + (emms-playlist-selected-face + (:foreground chocolate-hue-1)) + (emms-playlist-track-face + (:foreground chocolate-mono-2)) + (writegood-duplicates-face + (:underline + (:style 'wave :color chocolate-hue-5))) + (writegood-passive-voice-face + (:underline + (:style 'wave :color chocolate-syntax-renamed))) + (writegood-weasels-face + (:underline + (:style 'wave :color chocolate-syntax-accent))) + (haskell-quasi-quote-face + (:inherit 'font-lock-string-face)) + (haskell-definition-face + (:inherit 'font-lock-function-name-face)) + (flymake-warnline + (:underline + (:style 'wave :color chocolate-hue-6) + :background chocolate-syntax-bg)) + (flymake-errline + (:underline + (:style 'wave :color chocolate-hue-5) + :background chocolate-syntax-bg)) + (jedi:highlight-function-argument + (:inherit 'bold)) + (epc:face-title + (:weight 'bold :foreground chocolate-hue-5)) + (ctbl:face-continue-bar + (:background chocolate-syntax-light)) + (ctbl:face-cell-select + (:background chocolate-syntax-renamed)) + (ctbl:face-row-select + (:background chocolate-syntax-bg-dark)) + (ido-incomplete-regexp + (:inherit 'font-lock-warning-face)) + (ido-indicator + (:foreground chocolate-hue-5 :background chocolate-syntax-bg)) + (ido-virtual + (:foreground chocolate-mono-3)) + (ido-subdir + (:foreground chocolate-mono-1)) + (ido-only-match + (:foreground chocolate-syntax-added)) + (ido-first-match + (:foreground chocolate-hue-6)) + (ac-selection-face + (:inherit 'popup-menu-selection-face)) + (ac-candidate-mouse-face + (:inherit 'popup-menu-mouse-face)) + (ac-candidate-face + (:inherit 'popup-face)) + (ac-completion-face + (:underline t :foreground chocolate-mono-1)) + (c-annotation-face + (:inherit 'font-lock-constant-face)) + (company-template-field + (:inherit 'match)) + (flycheck-error-list-highlight + (:inherit 'highlight)) + (flycheck-error-list-checker-name + (:inherit 'font-lock-function-name-face)) + (flycheck-error-list-id-with-explainer + (:box + (:style 'released-button) + :inherit 'flycheck-error-list-id)) + (flycheck-error-list-id + (:inherit 'font-lock-type-face)) + (flycheck-error-list-filename + (:inherit 'font-lock-variable-name-face)) + (flycheck-error-list-column-number + (:inherit 'font-lock-constant-face)) + (flycheck-error-list-line-number + (:inherit 'font-lock-constant-face)) + (flycheck-error-list-info + (:inherit 'success)) + (flycheck-error-list-warning + (:inherit 'warning)) + (flycheck-error-list-error + (:inherit 'error)) + (flycheck-fringe-info + (:inherit 'success)) + (flycheck-fringe-warning + (:inherit 'warning)) + (flycheck-fringe-error + (:inherit 'error)) + (flycheck-info + (:underline + (:style 'wave :color chocolate-syntax-added))) + (flycheck-warning + (:underline + (:style 'wave :color chocolate-hue-6-2))) + (flycheck-error + (:underline + (:style 'wave :color chocolate-hue-5))) + (term-color-white + (:foreground chocolate-hue-2 :background chocolate-hue-2)) + (term-color-cyan + (:foreground chocolate-syntax-renamed :background chocolate-syntax-renamed)) + (term-color-magenta + (:foreground chocolate-mono-1 :background chocolate-mono-1)) + (term-color-blue + (:foreground chocolate-hue-1 :background chocolate-hue-1)) + (term-color-yellow + (:foreground chocolate-hue-6-2 :background chocolate-hue-6-2)) + (term-color-green + (:foreground chocolate-syntax-added :background chocolate-syntax-added)) + (term-color-red + (:foreground chocolate-hue-5 :background chocolate-hue-5)) + (term-color-black + (:foreground chocolate-syntax-bg-dark :background chocolate-syntax-bg-dark)) + (term-underline + (:underline t)) + (term-bold + (:inherit 'bold)) + (term + (:inherit 'default)) + (popup-menu-summary-face + (:inherit 'popup-summary-face)) + (popup-menu-face + (:inherit 'popup-face)) + (popup-isearch-match + (:background chocolate-hue-1 :inherit 'default)) + (popup-scroll-bar-background-face + (:background chocolate-mono-1)) + (popup-scroll-bar-foreground-face + (:background chocolate-syntax-bg-dark)) + (popup-summary-face + (:foreground chocolate-mono-3 :inherit 'popup-face)) + (helm-history-remote + (:foreground chocolate-hue-5)) + (helm-history-deleted + (:inherit 'helm-ff-invalid-symlink)) + (helm-ff-dirs + (:inherit 'font-lock-function-name-face)) + (helm-ff-file + (:foreground chocolate-mono-1)) + (helm-ff-invalid-symlink + (:foreground chocolate-syntax-bg-dark :background chocolate-syntax-accent)) + (helm-ff-symlink + (:inherit 'font-lock-comment-face)) + (helm-ff-dotted-symlink-directory + (:foreground chocolate-syntax-accent :background chocolate-mono-3)) + (helm-ff-dotted-directory + (:foreground chocolate-syntax-light)) + (helm-ff-directory + (:foreground chocolate-hue-2)) + (helm-ff-executable + (:foreground chocolate-hue-2 :inherit 'italic)) + (helm-ff-prefix + (:foreground chocolate-hue-1)) + (helm-non-file-buffer + (:inherit 'italic)) + (helm-buffer-archive + (:foreground chocolate-syntax-accent)) + (helm-buffer-file + (:inherit 'font-lock-builtin-face)) + (helm-buffer-directory + (:foreground chocolate-syntax-bg-dark :background chocolate-hue-2)) + (helm-buffer-process + (:foreground chocolate-hue-3)) + (helm-buffer-size + (:foreground chocolate-hue-4)) + (helm-buffer-modified + (:inherit 'font-lock-comment-face)) + (helm-buffer-not-saved + (:foreground chocolate-hue-5)) + (helm-buffer-saved-out + (:foreground chocolate-syntax-accent :background chocolate-syntax-bg-dark)) + (helm-etags-file + (:underline t :foreground chocolate-hue-4-2)) + (helm-locate-finish + (:foreground chocolate-syntax-added)) + (helm-grep-cmd-line + (:inherit 'font-lock-type-face)) + (helm-grep-finish + (:foreground chocolate-syntax-added)) + (helm-grep-lineno + (:foreground chocolate-mono-3)) + (helm-grep-file + (:foreground chocolate-mono-1)) + (helm-grep-match + (:foreground chocolate-hue-1)) + (helm-resume-need-update + (:background chocolate-syntax-accent)) + (helm-moccur-buffer + (:underline t :foreground chocolate-hue-1)) + (helm-match-item + (:inherit 'isearch)) + (helm-selection-line + (:inherit 'highlight)) + (helm-helper + (:inherit 'helm-header)) + (helm-header-line-left-margin + (:foreground chocolate-syntax-bg-dark :background chocolate-syntax-accent)) + (helm-match + (:underline t :foreground chocolate-hue-1)) + (helm-prefarg + (:foreground chocolate-syntax-added)) + (helm-action + (:underline t)) + (helm-separator + (:foreground chocolate-syntax-accent)) + (helm-selection + (:background chocolate-mono-3 :inherit 'bold)) + (helm-candidate-number-suspended + (:inverse-video t :inherit 'helm-candidate-number)) + (helm-candidate-number + (:foreground chocolate-syntax-bg-dark :background chocolate-syntax-accent)) + (helm-header + (:inherit 'header-line)) + (helm-visible-mark + (:inherit + ('bold 'highlight))) + (helm-source-header + (:foreground chocolate-mono-3 :background chocolate-syntax-bg)) + (compilation-column-number + (:inherit 'font-lock-doc-face)) + (compilation-line-number + (:inherit 'font-lock-keyword-face)) + (compilation-mode-line-exit + (:weight 'bold :foreground chocolate-syntax-bg-dark :inherit 'compilation-info)) + (compilation-mode-line-run + (:inherit 'compilation-warning)) + (compilation-mode-line-fail + (:weight 'bold :foreground chocolate-syntax-accent :inherit 'compilation-error)) + (compilation-info + (:inherit 'success)) + (compilation-warning + (:inherit 'warning)) + (compilation-error + (:inherit 'error)) + (rainbow-delimiters-mismatched-face + (:inherit 'rainbow-delimiters-unmatched-face)) + (rainbow-delimiters-base-face nil) + (yas--field-debug-face nil) + (yas-field-highlight-face + (:inherit 'match)) + (magithub-edit-title + (:inherit 'markdown-header-face-1)) + (magithub-deleted-thing + (:background chocolate-syntax-bg-dark :inherit 'magit-section-highlight)) + (magithub-notification-reason + (:inherit 'magit-dimmed)) + (magithub-label + (:box 1)) + (magithub-ci-unknown + (:inherit 'magit-signature-untrusted)) + (magithub-ci-failure + (:inherit 'error)) + (magithub-ci-success + (:inherit 'success)) + (magithub-ci-pending + (:inherit 'magit-signature-untrusted)) + (magithub-ci-error + (:inherit 'magit-signature-untrusted)) + (magithub-ci-no-status + (:inherit 'magit-dimmed)) + (magithub-user + (:inherit 'magit-log-author)) + (magithub-issue-title-with-note + (:inherit + ('git-commit-summary))) + (magithub-issue-title-edit + (:inherit + ('git-commit-summary))) + (magithub-issue-number + (:inherit 'magit-dimmed)) + (magithub-issue-title nil) + (magithub-repo + (:inherit 'magit-branch-remote)) + (widget-button-pressed + (:foreground chocolate-syntax-accent)) + (widget-inactive + (:inherit 'shadow)) + (widget-single-line-field + (:background chocolate-mono-3)) + (widget-field + (:background chocolate-mono-3)) + (widget-button + (:weight 'bold)) + (widget-documentation + (:foreground chocolate-syntax-added)) + (markdown-header-face-6 + (:inherit 'markdown-header-face)) + (markdown-header-face-5 + (:inherit 'markdown-header-face)) + (markdown-header-face-4 + (:inherit 'markdown-header-face)) + (markdown-header-face-3 + (:inherit 'markdown-header-face)) + (markdown-header-face-2 + (:inherit 'markdown-header-face)) + (markdown-header-face-1 + (:inherit 'markdown-header-face)) + (markdown-header-face + (:foreground chocolate-hue-5 :inherit 'bold)) + (markdown-html-entity-face + (:inherit 'font-lock-variable-name-face)) + (markdown-html-attr-value-face + (:inherit 'font-lock-string-face)) + (markdown-html-attr-name-face + (:inherit 'font-lock-variable-name-face)) + (markdown-html-tag-delimiter-face + (:inherit 'markdown-markup-face)) + (markdown-html-tag-name-face + (:inherit 'font-lock-type-face)) + (markdown-hr-face + (:inherit 'markdown-markup-face)) + (markdown-highlight-face + (:inherit 'highlight)) + (markdown-gfm-checkbox-face + (:inherit 'font-lock-builtin-face)) + (markdown-metadata-value-face + (:inherit 'font-lock-string-face)) + (markdown-metadata-key-face + (:foreground chocolate-hue-5)) + (markdown-math-face + (:inherit 'font-lock-string-face)) + (markdown-comment-face + (:inherit 'font-lock-comment-face)) + (markdown-line-break-face + (:underline t :inherit 'font-lock-constant-face)) + (markdown-link-title-face + (:inherit 'font-lock-comment-face)) + (markdown-plain-url-face + (:inherit 'markdown-link-face)) + (markdown-url-face + (:weight 'normal :foreground chocolate-mono-1)) + (markdown-footnote-text-face + (:inherit 'font-lock-comment-face)) + (markdown-footnote-marker-face + (:inherit 'markdown-markup-face)) + (markdown-reference-face + (:inherit 'markdown-markup-face)) + (markdown-missing-link-face + (:inherit 'font-lock-warning-face)) + (markdown-link-face + (:foreground chocolate-hue-1 :inherit 'bold)) + (markdown-language-info-face + (:inherit 'font-lock-string-face)) + (markdown-language-keyword-face + (:inherit 'font-lock-type-face)) + (markdown-table-face + (:inherit + ('markdown-code-face))) + (markdown-pre-face + (:foreground chocolate-syntax-added)) + (markdown-inline-code-face + (:inherit + ('markdown-code-face 'markdown-pre-face))) + (markdown-code-face + (:background chocolate-syntax-bg)) + (markdown-blockquote-face + (:foreground chocolate-mono-2 :inherit 'italic)) + (markdown-list-face + (:foreground chocolate-hue-5)) + (markdown-header-delimiter-face + (:inherit 'markdown-header-face)) + (markdown-header-rule-face + (:inherit 'markdown-markup-face)) + (markdown-markup-face + (:foreground chocolate-mono-1)) + (markdown-strike-through-face + (:strike-through t)) + (markdown-bold-face + (:foreground chocolate-hue-6 :inherit 'bold)) + (markdown-italic-face + (:foreground chocolate-mono-1 :inherit 'italic)) + (outline-8 + (:inherit 'font-lock-string-face)) + (outline-7 + (:inherit 'font-lock-builtin-face)) + (outline-6 + (:inherit 'font-lock-constant-face)) + (outline-5 + (:inherit 'font-lock-type-face)) + (outline-4 + (:inherit 'font-lock-comment-face)) + (outline-3 + (:inherit 'font-lock-keyword-face)) + (outline-2 + (:inherit 'font-lock-variable-name-face)) + (outline-1 + (:inherit 'font-lock-function-name-face)) + (magit-blame-date + (:foreground chocolate-hue-5)) + (magit-blame-name + (:inherit 'magit-blame-heading)) + (magit-blame-hash + (:inherit 'magit-blame-heading)) + (magit-blame-summary + (:inherit 'magit-blame-heading)) + (magit-blame-heading + (:foreground chocolate-hue-6 :background chocolate-syntax-bg)) + (magit-bisect-bad + (:foreground chocolate-hue-5)) + (magit-bisect-skip + (:foreground chocolate-hue-6)) + (magit-bisect-good + (:foreground chocolate-syntax-added)) + (magit-sequence-exec + (:inherit 'magit-hash)) + (magit-sequence-onto + (:inherit 'magit-sequence-done)) + (magit-sequence-done + (:inherit 'magit-hash)) + (magit-sequence-drop + (:foreground chocolate-hue-5)) + (magit-sequence-head + (:foreground chocolate-hue-1)) + (magit-sequence-part + (:foreground chocolate-hue-6)) + (magit-sequence-stop + (:foreground chocolate-syntax-added)) + (magit-sequence-pick + (:inherit 'default)) + (magit-filename + (:foreground chocolate-mono-1)) + (magit-cherry-equivalent + (:foreground chocolate-mono-1)) + (magit-cherry-unmatched + (:foreground chocolate-syntax-renamed)) + (magit-signature-error + (:inherit 'error)) + (magit-signature-revoked + (:foreground chocolate-mono-1)) + (magit-signature-expired-key + (:inherit 'magit-signature-expired)) + (magit-signature-expired + (:foreground chocolate-hue-6)) + (magit-signature-untrusted + (:foreground chocolate-syntax-renamed)) + (magit-signature-bad + (:inherit 'error)) + (magit-signature-good + (:inherit 'success)) + (magit-keyword + (:inherit 'font-lock-string-face)) + (magit-refname-wip + (:inherit 'magit-refname)) + (magit-refname-stash + (:inherit 'magit-refname)) + (magit-refname + (:foreground chocolate-mono-3)) + (magit-head + (:inherit 'magit-branch-local)) + (magit-branch-current + (:foreground chocolate-hue-1)) + (magit-branch-local + (:foreground chocolate-syntax-renamed)) + (magit-branch-remote-head + (:box 1 :inherit 'magit-branch-remote)) + (magit-branch-remote + (:foreground chocolate-syntax-added)) + (magit-tag + (:foreground chocolate-hue-6-2)) + (magit-hash + (:foreground chocolate-mono-3)) + (magit-dimmed + (:foreground chocolate-mono-3)) + (magit-header-line-key + (:inherit 'magit-popup-key)) + (magit-header-line + (:weight 'bold :box + (:line-width 3 :color chocolate-mono-3) + :foreground chocolate-hue-2 :background chocolate-mono-3)) + (magit-reflog-other + (:foreground chocolate-syntax-renamed)) + (magit-reflog-remote + (:foreground chocolate-syntax-renamed)) + (magit-reflog-cherry-pick + (:foreground chocolate-syntax-added)) + (magit-reflog-rebase + (:foreground chocolate-mono-1)) + (magit-reflog-reset + (:inherit 'error)) + (magit-reflog-checkout + (:foreground chocolate-hue-1)) + (magit-reflog-merge + (:foreground chocolate-syntax-added)) + (magit-reflog-amend + (:foreground chocolate-mono-1)) + (magit-reflog-commit + (:foreground chocolate-syntax-added)) + (magit-header-line-log-select + (:inherit 'bold)) + (magit-log-date + (:foreground chocolate-hue-1)) + (magit-log-author + (:foreground chocolate-hue-6)) + (magit-log-graph + (:foreground chocolate-mono-3)) + (magit-diffstat-removed + (:foreground chocolate-syntax-removed)) + (magit-diffstat-added + (:foreground chocolate-syntax-added)) + (magit-diff-whitespace-warning + (:inherit 'trailing-whitespace)) + (magit-diff-context-highlight + (:foreground chocolate-mono-1 :background chocolate-syntax-bg)) + (magit-diff-their-highlight + (:inherit 'magit-diff-added-highlight)) + (magit-diff-base-highlight + (:weight 'bold :foreground chocolate-hue-6 :background chocolate-syntax-light)) + (magit-diff-our-highlight + (:inherit 'magit-diff-removed-highlight)) + (magit-diff-removed-highlight + (:weight 'bold :foreground chocolate-syntax-removed :background chocolate-syntax-bg)) + (magit-diff-added-highlight + (:weight 'bold :foreground chocolate-syntax-added :background chocolate-syntax-light)) + (magit-diff-context + (:foreground chocolate-mono-3 :background chocolate-syntax-bg)) + (magit-diff-their + (:inherit 'magit-diff-added)) + (magit-diff-base + (:foreground chocolate-hue-5-2 :background chocolate-syntax-bg)) + (magit-diff-our + (:inherit 'magit-diff-removed)) + (magit-diff-removed + (:foreground chocolate-hue-5-2 :background chocolate-syntax-bg)) + (magit-diff-added + (:foreground chocolate-hue-9-5 :background chocolate-syntax-bg)) + (magit-diff-conflict-heading + (:inherit 'magit-diff-hunk-heading)) + (magit-diff-lines-boundary + (:inherit 'magit-diff-lines-heading)) + (magit-diff-lines-heading + (:foreground chocolate-hue-6-2 :background chocolate-hue-5)) + (magit-diff-hunk-region + (:inherit 'bold)) + (magit-diff-hunk-heading-selection + (:foreground chocolate-hue-6 :inherit 'magit-diff-hunk-heading-highlight)) + (magit-diff-hunk-heading-highlight + (:weight 'bold :foreground chocolate-syntax-bg :background chocolate-mono-1)) + (magit-diff-hunk-heading + (:foreground chocolate-syntax-bg :background chocolate-syntax-light)) + (magit-diff-file-heading-selection + (:weight 'bold :foreground chocolate-mono-1 :background chocolate-mono-3)) + (magit-diff-file-heading-highlight + (:inherit + ('magit-section-highlight))) + (magit-diff-file-heading + (:weight 'bold :foreground chocolate-mono-1)) + (smerge-refined-added + (:background chocolate-syntax-bg-dark :inherit 'smerge-refined-change)) + (smerge-refined-removed + (:background chocolate-hue-5-2 :inherit 'smerge-refined-change)) + (smerge-refined-changed nil) + (smerge-markers + (:background chocolate-syntax-light)) + (smerge-base + (:background chocolate-hue-4-2)) + (smerge-other + (:background chocolate-syntax-bg)) + (smerge-mine + (:background chocolate-syntax-light)) + (diff-refine-added + (:inverse-video t :inherit 'diff-added)) + (diff-refine-removed + (:inverse-video t :inherit 'diff-removed)) + (diff-refine-changed + (:inverse-video t :inherit 'diff-changed)) + (diff-nonexistent + (:inherit 'diff-file-header)) + (diff-context + (:foreground chocolate-hue-2)) + (diff-function + (:inherit 'diff-header)) + (diff-indicator-changed + (:inherit 'diff-changed)) + (diff-indicator-added + (:inherit 'diff-added)) + (diff-indicator-removed + (:inherit 'diff-removed)) + (diff-changed + (:foreground chocolate-mono-1)) + (diff-added + (:foreground chocolate-syntax-added :inherit 'hl-line)) + (diff-removed + (:foreground chocolate-hue-5 :background chocolate-syntax-bg)) + (diff-hunk-header + (:foreground chocolate-mono-1)) + (diff-index + (:inherit 'diff-file-header)) + (diff-file-header + (:foreground chocolate-hue-1)) + (diff-header + (:foreground chocolate-syntax-renamed)) + (magit-mode-line-process-error + (:inherit 'error)) + (magit-mode-line-process + (:inherit 'mode-line-emphasis)) + (magit-process-ng + (:inherit 'error)) + (magit-process-ok + (:inherit 'success)) + (git-commit-comment-action + (:inherit 'bold)) + (git-commit-comment-file + (:inherit 'git-commit-pseudo-header)) + (git-commit-comment-heading + (:inherit 'git-commit-known-pseudo-header)) + (git-commit-comment-detached + (:inherit 'git-commit-comment-branch-local)) + (git-commit-comment-branch-remote + (:inherit 'font-lock-variable-name-face)) + (git-commit-comment-branch-local + (:inherit 'font-lock-variable-name-face)) + (git-commit-known-pseudo-header + (:inherit 'font-lock-keyword-face)) + (git-commit-pseudo-header + (:inherit 'font-lock-string-face)) + (git-commit-note + (:inherit 'font-lock-string-face)) + (git-commit-nonempty-second-line + (:inherit 'font-lock-warning-face)) + (git-commit-overlong-summary + (:inherit 'font-lock-warning-face)) + (git-commit-summary + (:inherit 'font-lock-type-face)) + (magit-section-heading-selection + (:weight 'bold :foreground chocolate-hue-6)) + (magit-section-secondary-heading + (:weight 'bold :foreground chocolate-mono-1)) + (magit-section-heading + (:weight 'bold :foreground chocolate-hue-1)) + (magit-section-highlight + (:background chocolate-syntax-bg-light)) + (magit-popup-option-value + (:inherit 'font-lock-string-face)) + (magit-popup-disabled-argument + (:inherit 'shadow)) + (magit-popup-argument + (:inherit 'font-lock-warning-face)) + (magit-popup-key + (:inherit 'font-lock-builtin-face)) + (magit-popup-heading + (:inherit 'font-lock-keyword-face)) + (log-edit-unknown-header + (:inherit 'font-lock-comment-face)) + (log-edit-header + (:inherit 'font-lock-keyword-face)) + (log-edit-summary + (:inherit 'font-lock-function-name-face)) + (message-mml + (:foreground chocolate-syntax-added)) + (message-cited-text + (:foreground chocolate-mono-1)) + (message-separator + (:foreground chocolate-hue-2)) + (message-header-xheader + (:foreground chocolate-syntax-renamed)) + (message-header-name + (:foreground chocolate-syntax-added)) + (message-header-other + (:foreground chocolate-hue-5)) + (message-header-newsgroups + (:weight 'bold :slant 'italic :foreground chocolate-syntax-accent)) + (message-header-subject + (:foreground chocolate-hue-6)) + (message-header-cc + (:weight 'bold :foreground chocolate-syntax-added)) + (message-header-to + (:weight 'bold :foreground chocolate-hue-6-2)) + (dired-ignored + (:foreground chocolate-mono-3)) + (dired-symlink + (:inherit 'font-lock-keyword-face)) + (dired-directory + (:foreground chocolate-mono-1)) + (dired-perm-write + (:inherit 'font-lock-comment-delimiter-face)) + (dired-warning + (:inherit 'font-lock-warning-face)) + (dired-flagged + (:inherit 'error)) + (dired-marked + (:inherit 'warning)) + (dired-mark + (:inherit 'font-lock-constant-face)) + (dired-header + (:inherit 'font-lock-type-face)) + (mm-command-output + (:foreground chocolate-syntax-bg-dark)) + (change-log-acknowledgment + (:inherit 'font-lock-comment-face)) + (change-log-function + (:inherit 'font-lock-variable-name-face)) + (change-log-conditionals + (:inherit 'font-lock-variable-name-face)) + (change-log-list + (:inherit 'font-lock-keyword-face)) + (change-log-file + (:inherit 'font-lock-function-name-face)) + (change-log-email + (:inherit 'font-lock-variable-name-face)) + (change-log-name + (:inherit 'font-lock-constant-face)) + (change-log-date + (:inherit 'font-lock-string-face)) + (comint-highlight-prompt + (:inherit 'minibuffer-prompt)) + (comint-highlight-input + (:weight 'bold)) + (company-echo-common + (:foreground chocolate-hue-3)) + (company-echo nil) + (company-preview-search + (:inherit 'company-tooltip-search)) + (company-preview-common + (:foreground chocolate-mono-1 :background chocolate-syntax-bg)) + (company-preview + (:foreground chocolate-hue-1)) + (company-scrollbar-bg + (:inherit 'tooltip)) + (company-scrollbar-fg + (:background chocolate-hue-1)) + (company-tooltip-annotation-selection + (:inherit 'company-tooltip-annotation)) + (company-tooltip-annotation + (:foreground chocolate-mono-1)) + (company-tooltip-common-selection + (:inherit 'company-tooltip-common)) + (company-tooltip-common + (:foreground chocolate-hue-1)) + (company-tooltip-mouse + (:foreground chocolate-syntax-bg :background chocolate-mono-1)) + (company-tooltip-search-selection + (:inherit 'highlight)) + (company-tooltip-search + (:foreground chocolate-syntax-bg :background chocolate-hue-1)) + (company-tooltip-selection + (:background chocolate-mono-3)) + (company-tooltip + (:inherit 'tooltip)) + (hydra-face-teal + (:weight 'bold :foreground chocolate-hue-1)) + (hydra-face-pink + (:weight 'bold :foreground chocolate-mono-1)) + (hydra-face-amaranth + (:weight 'bold :foreground chocolate-mono-1)) + (hydra-face-blue + (:weight 'bold :foreground chocolate-hue-1)) + (hydra-face-red + (:weight 'bold :foreground chocolate-hue-5)) + (lv-separator + (:background chocolate-syntax-light)) + (origami-fold-replacement-face + (:inherit + ('quote 'font-lock-comment-face))) + (origami-fold-fringe-face nil) + (origami-fold-header-face + (:box + (:line-width 1 :color chocolate-hue-1) + :background chocolate-hue-1)) + (mc/region-face + (:inherit 'region)) + (mc/cursor-bar-face + (:height 1 :background chocolate-hue-1)) + (mc/cursor-face + (:inherit 'cursor)) + (rectangle-preview + (:inherit 'region)) + (highlight-leading-spaces + (:inherit 'font-lock-comment-face)) + (spaceline-all-the-icons-sunset-face + (:foreground chocolate-syntax-accent :inherit 'powerline-active2)) + (spaceline-all-the-icons-sunrise-face + (:foreground chocolate-hue-6-2 :inherit 'powerline-active2)) + (spaceline-all-the-icons-info-face + (:foreground chocolate-syntax-renamed)) + (spaceline-python-venv + (:foreground chocolate-hue-2)) + (spaceline-flycheck-info + (:foreground chocolate-hue-2)) + (spaceline-flycheck-warning + (:foreground chocolate-syntax-modified)) + (spaceline-flycheck-error + (:foreground chocolate-hue-5)) + (spaceline-read-only + (:foreground chocolate-syntax-light :background chocolate-mono-1 :inherit + ('quote 'mode-line))) + (spaceline-modified + (:foreground chocolate-syntax-light :background chocolate-hue-1 :inherit + ('quote 'mode-line))) + (spaceline-unmodified + (:foreground chocolate-syntax-light :background chocolate-syntax-accent :inherit + ('quote 'mode-line))) + (spaceline-evil-motion + (:foreground chocolate-syntax-light :background chocolate-mono-1 :inherit + ('quote 'mode-line))) + (spaceline-evil-visual + (:foreground chocolate-syntax-light :background chocolate-mono-1 :inherit + ('quote 'mode-line))) + (spaceline-evil-replace + (:foreground chocolate-syntax-light :background chocolate-hue-3 :inherit + ('quote 'mode-line))) + (spaceline-evil-emacs + (:foreground chocolate-syntax-light :background chocolate-hue-1 :inherit + ('quote 'mode-line))) + (spaceline-evil-insert + (:foreground chocolate-syntax-light :background chocolate-syntax-added :inherit + ('quote 'mode-line))) + (spaceline-evil-normal + (:foreground chocolate-syntax-light :background chocolate-syntax-accent :inherit + ('quote 'mode-line))) + (mode-line-buffer-id-inactive + (:inherit 'mode-line-buffer-id)) + (powerline-inactive0 + (:inherit 'mode-line-inactive)) + (powerline-active0 + (:inherit 'mode-line)) + (doom-modeline-error + (:foreground chocolate-syntax-bg-dark :background chocolate-hue-5-2)) + (all-the-icons-dsilver + (:foreground chocolate-mono-2)) + (all-the-icons-lsilver + (:foreground chocolate-mono-1)) + (all-the-icons-silver + (:foreground chocolate-mono-3)) + (all-the-icons-dpink + (:foreground chocolate-mono-2)) + (all-the-icons-lpink + (:foreground chocolate-syntax-modified)) + (all-the-icons-pink + (:foreground chocolate-mono-1)) + (all-the-icons-dcyan + (:foreground chocolate-mono-3)) + (all-the-icons-lcyan + (:foreground chocolate-hue-2)) + (all-the-icons-cyan-alt + (:foreground chocolate-hue-1)) + (all-the-icons-cyan + (:foreground chocolate-hue-1)) + (all-the-icons-dorange + (:foreground chocolate-hue-5-2)) + (all-the-icons-lorange + (:foreground chocolate-syntax-accent)) + (all-the-icons-orange + (:foreground chocolate-hue-3)) + (all-the-icons-dpurple + (:foreground chocolate-mono-3)) + (all-the-icons-lpurple + (:foreground chocolate-mono-1)) + (all-the-icons-purple + (:foreground chocolate-mono-2)) + (all-the-icons-dmaroon + (:foreground chocolate-mono-3)) + (all-the-icons-lmaroon + (:foreground chocolate-hue-6)) + (all-the-icons-maroon + (:foreground chocolate-hue-5-2)) + (all-the-icons-dblue + (:foreground chocolate-mono-3)) + (all-the-icons-lblue + (:foreground chocolate-hue-2)) + (all-the-icons-blue-alt + (:foreground chocolate-hue-1)) + (all-the-icons-blue + (:foreground chocolate-hue-1)) + (all-the-icons-dyellow + (:foreground chocolate-hue-6-3)) + (all-the-icons-lyellow + (:foreground chocolate-hue-6-2)) + (all-the-icons-yellow + (:foreground chocolate-hue-6-2)) + (all-the-icons-dgreen + (:foreground chocolate-mono-3)) + (all-the-icons-lgreen + (:foreground chocolate-hue-6-2)) + (all-the-icons-green + (:foreground chocolate-hue-4-2)) + (all-the-icons-red-alt + (:foreground chocolate-hue-5-2)) + (all-the-icons-dred + (:foreground chocolate-syntax-light)) + (all-the-icons-lred + (:foreground chocolate-syntax-removed)) + (all-the-icons-red + (:foreground chocolate-hue-5-2)) + (w3m-haddock-heading-face + (:inherit 'highlight)) + + ;; MODE SUPPORT: haskell + (haskell-hole-face + (:underline + (:style 'wave :color chocolate-hue-1))) + (haskell-warning-face + (:underline + (:style 'wave :color chocolate-syntax-accent))) + (haskell-error-face + (:underline + (:style 'wave :color chocolate-hue-3))) + (haskell-interactive-face-garbage + (:inherit 'font-lock-string-face)) + (haskell-interactive-face-result + (:inherit 'font-lock-string-face)) + (haskell-interactive-face-compile-warning + (:inherit 'compilation-warning)) + (haskell-interactive-face-compile-error + (:inherit 'compilation-error)) + (haskell-interactive-face-prompt2 + (:inherit 'font-lock-keyword-face)) + (haskell-interactive-face-prompt + (:inherit 'font-lock-function-name-face)) + (haskell-literate-comment-face + (:inherit 'font-lock-doc-face)) + (haskell-liquid-haskell-annotation-face + (:inherit 'haskell-pragma-face)) + (haskell-pragma-face + (:inherit 'font-lock-preprocessor-face)) + (haskell-operator-face + (:inherit 'font-lock-variable-name-face)) + (haskell-type-face (:foreground chocolate-hue-6)) + (haskell-constructor-face (:foreground chocolate-hue-6-2)) + (haskell-keyword-face + (:inherit 'font-lock-keyword-face)) + (haskell-debug-muted-face + (:foreground chocolate-mono-2)) + (haskell-debug-heading-face + (:inherit + ('quote 'font-lock-keyword-face))) + (haskell-debug-keybinding-face + (:weight 'bold :inherit + ('quote 'font-lock-type-face))) + (haskell-debug-newline-face + (:weight 'bold :background chocolate-hue-2)) + (haskell-debug-trace-number-face + (:weight 'bold :background chocolate-hue-2)) + (haskell-debug-warning-face + (:inherit + ('quote 'compilation-warning))) + (Info-quoted + (:inherit 'fixed-pitch-serif)) + (info-index-match + (:inherit 'match)) + (info-header-node + (:inherit 'info-node)) + (info-header-xref + (:inherit 'info-xref)) + (info-xref-visited + (:inherit + ('link-visited 'info-xref))) + (info-xref + (:inherit 'link)) + (info-menu-star + (:foreground chocolate-syntax-accent)) + (info-menu-header + (:weight 'bold :inherit 'variable-pitch)) + (info-title-4 + (:weight 'bold :inherit 'variable-pitch)) + (info-title-3 + (:height 1.2 :inherit 'info-title-4)) + (info-title-2 + (:height 1.2 :inherit 'info-title-3)) + (info-title-1 + (:height 1.2 :inherit 'info-title-2)) + (info-node + (:weight 'bold :slant 'italic :foreground chocolate-hue-2)) + (package-status-avail-obso + (:inherit 'package-status-incompat)) + (package-status-incompat + (:inherit 'font-lock-comment-face)) + (package-status-unsigned + (:inherit 'font-lock-warning-face)) + (package-status-dependency + (:inherit 'package-status-installed)) + (package-status-installed + (:inherit 'font-lock-comment-face)) + (package-status-disabled + (:inherit 'font-lock-warning-face)) + (package-status-held + (:inherit 'font-lock-constant-face)) + (package-status-new + (:inherit + ('bold 'package-status-available))) + (package-status-available + (:inherit 'default)) + (package-status-external + (:inherit 'package-status-built-in)) + (package-status-built-in + (:inherit 'font-lock-builtin-face)) + (package-description + (:inherit 'default)) + (package-name + (:inherit 'link)) + (package-help-section-name + (:inherit + ('bold 'font-lock-function-name-face))) + (tooltip + (:foreground chocolate-mono-1 :background chocolate-syntax-bg-light)) + (eldoc-highlight-function-argument + (:inherit 'bold)) + (vc-edited-state + (:inherit 'vc-state-base)) + (vc-missing-state + (:inherit 'vc-state-base)) + (vc-removed-state + (:inherit 'vc-state-base)) + (vc-conflict-state + (:inherit 'vc-state-base)) + (vc-locally-added-state + (:inherit 'vc-state-base)) + (vc-locked-state + (:inherit 'vc-state-base)) + (vc-needs-update-state + (:inherit 'vc-state-base)) + (vc-up-to-date-state + (:inherit 'vc-state-base)) + (vc-state-base nil) + (ns-working-text-face + (:underline t)) + (buffer-menu-buffer + (:weight 'bold)) + (match + (:weight 'bold :foreground chocolate-syntax-added :background chocolate-syntax-bg-dark)) + (query-replace + (:inherit 'isearch)) + (file-name-shadow + (:inherit 'shadow)) + (lazy-highlight + (:weight 'bold :foreground chocolate-hue-2 :background chocolate-mono-3)) + (isearch-fail + (:background chocolate-syntax-bg-dark)) + (isearch + (:weight 'bold :foreground chocolate-syntax-bg-dark :background chocolate-hue-1)) + (font-lock-regexp-grouping-construct + (:foreground chocolate-mono-1 :inherit 'bold)) + (font-lock-regexp-grouping-backslash + (:foreground chocolate-mono-1 :inherit 'bold)) + (font-lock-preprocessor-face + (:foreground chocolate-mono-1 :inherit 'bold)) + (font-lock-negation-char-face + (:foreground chocolate-mono-1 :inherit 'bold)) + (font-lock-doc-face + (:foreground chocolate-mono-2 :inherit 'font-lock-comment-face)) + (font-lock-comment-delimiter-face + (:inherit 'font-lock-comment-face)) + (next-error + (:inherit 'region)) + (completions-common-part nil) + (completions-first-difference + (:inherit 'bold)) + (completions-annotations + (:inherit 'italic)) + (button + (:inherit 'link)) + (show-paren-mismatch + (:weight 'bold :foreground chocolate-syntax-bg-dark :background chocolate-hue-5)) + (show-paren-match + (:weight 'bold :foreground chocolate-hue-5 :background chocolate-syntax-bg-dark)) + (tty-menu-selected-face + (:background chocolate-syntax-accent)) + (tty-menu-disabled-face + (:foreground chocolate-hue-2 :background chocolate-syntax-renamed)) + (tty-menu-enabled-face + (:weight 'bold :foreground chocolate-syntax-accent :background chocolate-syntax-renamed)) + (success + (:foreground chocolate-syntax-added)) + (warning + (:foreground chocolate-hue-6-2)) + (error + (:foreground chocolate-hue-5)) + (glyphless-char + (:height 0.6)) + (help-argument-name + (:inherit 'italic)) + (menu + (:inverse-video t)) + (tool-bar + (:box + (:line-width 1 :style 'released-button) + :foreground chocolate-syntax-bg-dark :background chocolate-mono-1)) + (mouse nil) + (border nil) + (scroll-bar nil) + (minibuffer-prompt + (:foreground chocolate-hue-1)) + (window-divider-last-pixel + (:inherit 'window-divider)) + (window-divider-first-pixel + (:inherit 'window-divider)) + (window-divider + (:inherit 'vertical-border)) + (vertical-border + (:foreground chocolate-syntax-bg-dark :background chocolate-syntax-bg-dark)) + (header-line + (:inherit 'mode-line)) + (mode-line-buffer-id + (:weight 'bold :foreground chocolate-mono-1)) + (mode-line-emphasis + (:foreground chocolate-hue-1)) + (mode-line-highlight + (:inherit 'highlight)) + (nobreak-space + (:underline t :inherit 'escape-glyph)) + (escape-glyph + (:foreground chocolate-syntax-renamed)) + (trailing-whitespace + (:background chocolate-hue-5)) + (highlight + (:foreground chocolate-syntax-bg-dark :background chocolate-hue-1)) + (shadow + (:foreground chocolate-mono-3)) + (variable-pitch + (:family "Sans Serif")) + (fixed-pitch-serif + (:family "Monospace Serif")) + (fixed-pitch + (:family "Monospace")) + (underline + (:underline t)) + (bold-italic + (:inherit + ('bold 'italic))) + (italic + (:slant 'italic)) + (bold + (:weight 'bold)) + (helm-ag-edit-deleted-line + (:strike-through t :inherit 'font-lock-comment-face)) + (swiper-line-face + (:foreground chocolate-syntax-bg-dark :background chocolate-hue-1)) + (swiper-match-face-4 + (:weight 'bold :foreground chocolate-syntax-bg-dark :background chocolate-syntax-added)) + (swiper-match-face-3 + (:weight 'bold :foreground chocolate-syntax-bg-dark :background chocolate-mono-1)) + (swiper-match-face-2 + (:weight 'bold :foreground chocolate-syntax-bg-dark :background chocolate-hue-6)) + (swiper-match-face-1 + (:foreground chocolate-mono-3 :background chocolate-syntax-bg-dark)) + (git-gutter-fr+-deleted + (:foreground chocolate-syntax-removed :background chocolate-syntax-removed :inherit 'git-gutter+-deleted)) + (git-gutter-fr+-added + (:foreground chocolate-syntax-added :background chocolate-syntax-added :inherit 'git-gutter+-added)) + (git-gutter-fr+-modified + (:foreground chocolate-syntax-modified :background chocolate-syntax-modified :inherit 'git-gutter+-modified)) + (git-gutter+-commit-header-face + (:inherit 'font-lock-comment-face)) + (git-gutter+-unchanged + (:background chocolate-syntax-accent)) + (git-gutter+-deleted + (:foreground chocolate-hue-5)) + (git-gutter+-added + (:foreground chocolate-syntax-added)) + (git-gutter+-modified + (:foreground chocolate-hue-6-2)) + (git-gutter+-separator + (:weight 'bold :foreground chocolate-syntax-renamed)) + (pulse-highlight-face + (:background chocolate-hue-6-3)) + (pulse-highlight-start-face + (:background chocolate-hue-6-3)) + (which-func + (:foreground chocolate-hue-1)) + )) + + +;;;###autoload +(and load-file-name + (add-to-list 'custom-theme-load-path + (file-name-as-directory + (file-name-directory load-file-name)))) + +(provide-theme 'chocolate) + +;;; chocolate-theme.el ends here diff --git a/packages/cider-20181110.1413.tar b/packages/cider-20190821.1002.tar similarity index 90% rename from packages/cider-20181110.1413.tar rename to packages/cider-20190821.1002.tar index bfdfa9e..8b9a924 100644 Binary files a/packages/cider-20181110.1413.tar and b/packages/cider-20190821.1002.tar differ diff --git a/packages/cider-eval-sexp-fu-20160907.800.el b/packages/cider-eval-sexp-fu-20190311.2152.el similarity index 91% rename from packages/cider-eval-sexp-fu-20160907.800.el rename to packages/cider-eval-sexp-fu-20190311.2152.el index 5a5318e..aa201db 100644 --- a/packages/cider-eval-sexp-fu-20160907.800.el +++ b/packages/cider-eval-sexp-fu-20190311.2152.el @@ -5,10 +5,10 @@ ;; Author: Sylvain Benner ;; Keywords: languages, clojure, cider -;; Package-Version: 20160907.800 +;; Package-Version: 20190311.2152 ;; Created: 20 Mar 2015 -;; Version: 1.1 -;; Package-Requires: ((emacs "24") (highlight "0") (eval-sexp-fu "0.4.0")) +;; Version: 1.2 +;; Package-Requires: ((emacs "24") (eval-sexp-fu "0.5.0")) ;; This file is not part of GNU Emacs. @@ -33,7 +33,6 @@ ;;; Code: -(require 'highlight) (require 'eval-sexp-fu) (defun cider-esf--bounds-of-last-sexp () @@ -54,7 +53,7 @@ area is identical to that which is evaluated." (eval-sexp-fu-flash (cider-esf--bounds-of-last-sexp))) (define-eval-sexp-fu-flash-command cider-eval-defun-at-point (eval-sexp-fu-flash (let ((bounds (cider-defun-at-point 'bounds))) - (cons (first bounds) (second bounds))))) + (cons (car bounds) (cadr bounds))))) ;; Defines: ;; `eval-sexp-fu-cider-sexp-inner-list', diff --git a/packages/circe-20180525.1231.tar b/packages/circe-20190322.1242.tar similarity index 98% rename from packages/circe-20180525.1231.tar rename to packages/circe-20190322.1242.tar index 915cef6..9d2e6a2 100644 Binary files a/packages/circe-20180525.1231.tar and b/packages/circe-20190322.1242.tar differ diff --git a/packages/cl-generic-0.3.el b/packages/cl-generic-0.3.el deleted file mode 100644 index 0e7e1e4..0000000 --- a/packages/cl-generic-0.3.el +++ /dev/null @@ -1,156 +0,0 @@ -;;; cl-generic.el --- Forward cl-generic compatibility for Emacs<25 - -;; Copyright (C) 2015, 2016 Free Software Foundation, Inc - -;; Author: Stefan Monnier -;; vcomment: Emacs-25's version is 1.0 so this has to stay below. -;; Version: 0.3 - -;; 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 . - -;;; Commentary: - -;; This is a forward compatibility package, which provides (a subset of) the -;; features of the cl-generic package introduced in Emacs-25, for use on -;; previous emacsen. - -;; Make sure this is installed *late* in your `load-path`, i.e. after Emacs's -;; built-in .../lisp/emacs-lisp directory, so that if/when you upgrade to -;; Emacs≥25, the built-in version of the file will take precedence, otherwise -;; you could get into trouble (although we try to hack our way around the -;; problem in case it happens). - -;; AFAIK, the main incompatibilities between cl-generic and EIEIO's defmethod -;; are: -;; - EIEIO does not support multiple dispatch. We ignore this difference here -;; and rely on EIEIO to detect and signal the problem. -;; - EIEIO only supports primary, :before, and :after qualifiers. We ignore -;; this difference here and rely on EIEIO to detect and signal the problem. -;; - EIEIO does not support specializers other than classes. We ignore this -;; difference here and rely on EIEIO to detect and signal the problem. -;; - EIEIO uses :static instead of (subclass ) and :static methods match -;; both class arguments as well as object argument of that class. Here we -;; turn (subclass ) into a :static qualifier and ignore the semantic -;; difference, hoping noone will notice. -;; - EIEIO's defgeneric does not reset the function. We ignore this difference -;; and hope for the best. -;; - EIEIO uses `call-next-method' and `next-method-p' while cl-defmethod uses -;; `cl-next-method-p' and `cl-call-next-method' (simple matter of renaming). -;; We handle that by renaming the calls in the `cl-defmethod' macro. -;; - The errors signaled are slightly different. We make -;; cl-no-applicable-method into a "parent" error of no-method-definition, -;; which should cover the usual cases. -;; - EIEIO's no-next-method and no-applicable-method have different calling -;; conventions from cl-generic's. We don't try to handle this, so just -;; refrain from trying to call (or add methods to) `cl-no-next-method' or -;; `cl-no-applicable-method'. -;; - EIEIO's `call-next-method' and `next-method-p' have dynamic scope whereas -;; cl-generic's `cl-next-method-p' and `cl-call-next-method' are lexically -;; scoped. The cl-defmethod here handles the common subset between the two. - -;;; Code: - -;; We need to handle the situation where this package is used with an Emacs -;; that comes with a real cl-generic (i.e. ≥25.1). - -;; First line of defense: try to make sure the built-in cl-lib comes earlier in -;; load-path so we never get loaded: -;;;###autoload (let ((d (file-name-directory #$))) -;;;###autoload (when (member d load-path) -;;;###autoload (setq load-path (append (remove d load-path) (list d))))) - -(require 'cl-lib nil 'noerror) - -;; In Emacs≥25, cl-lib autoloads cl-defmethod and friends. - -(unless (fboundp 'cl-defmethod) - (require 'eieio) - (require 'cl) ;For `labels'. - - (defalias 'cl-defgeneric 'defgeneric) - - ;; Compatibility with code which tries to catch - ;; `cl-no-applicable-method' errors. - (push 'cl-no-applicable-method (get 'no-method-definition 'error-conditions)) - - (defalias 'cl-generic-apply #'apply) - - (defmacro cl-defmethod (name args &rest body) - (let ((qualifiers nil)) - (while (not (listp args)) - (push args qualifiers) - (setq args (pop body))) - (let ((docstring (if (and (stringp (car body)) (cdr body)) (pop body)))) - ;; Backward compatibility for `no-next-method' and - ;; `no-applicable-method', which have slightly different calling - ;; convention than their cl-generic counterpart. - (pcase name - (`cl-no-next-method - (setq name 'no-next-method) - (setq args (cddr args))) - (`cl-no-applicable-method - (setq name 'no-applicable-method) - (setq args `(,(nth 1 args) ,(nth 0 args) - ,(make-symbol "_ignore") . ,(nthcdr 2 args))))) - (let ((arg1 (car args))) - (when (eq (car-safe (car (cdr-safe arg1))) 'subclass) - ;; There's no exact equivalent to `subclass', but :static - ;; provides a superset which should work just as well in practice. - (push :static qualifiers) - (setf (cadr arg1) (cadr (cadr arg1))))) - - `(defmethod ,name ,@qualifiers ,args - ,@(if docstring (list docstring)) - ;; We could just alias `cl-call-next-method' to `call-next-method', - ;; and that would work, but then files compiled with this cl-generic - ;; wouldn't work in Emacs-25 any more. - ;; Also we fallback on `labels' if `cl-flet' is not available - ;; (ELPA's cl-lib emulation doesn't provide cl-flet). - ;; We don't always use `labels' because that generates warnings - ;; in newer Emacsen where `cl-flet' is available. - ,@(if qualifiers - ;; Must be :before or :after, so can't call next-method. - body - `((,(if (fboundp 'cl-flet) 'cl-flet 'labels) - ((cl-call-next-method (&rest args) - (apply #'call-next-method args)) - (cl-next-method-p () (next-method-p))) - ,@body)))))))) - -;;;; ChangeLog: - -;; 2016-07-12 Stefan Monnier -;; -;; * cl-generic/cl-generic.el (cl-defmethod): Improve compatibility -;; -;; More specifically, map cl-no-applicable-method to no-applicable-method. -;; (cl-generic-apply): New function. -;; -;; 2015-02-18 Stefan Monnier -;; -;; * cl-generic/cl-generic.el (cl-defmethod): Use cl-flet if available. -;; -;; 2015-02-03 Stefan Monnier -;; -;; * packages/cl-generic/cl-generic.el (cl-defmethod): Fix handling of -;; subclass. -;; -;; 2015-02-03 Stefan Monnier -;; -;; * packages/cl-generic: Add new package -;; - - -(provide 'cl-generic) -;;; cl-generic.el ends here diff --git a/packages/cliphist-20181229.1411.tar b/packages/cliphist-20181229.1411.tar new file mode 100644 index 0000000..404e8a9 Binary files /dev/null and b/packages/cliphist-20181229.1411.tar differ diff --git a/packages/clj-refactor-20180826.2149.tar b/packages/clj-refactor-20190618.716.tar similarity index 97% rename from packages/clj-refactor-20180826.2149.tar rename to packages/clj-refactor-20190618.716.tar index abde173..fb6d349 100644 Binary files a/packages/clj-refactor-20180826.2149.tar and b/packages/clj-refactor-20190618.716.tar differ diff --git a/packages/clojure-cheatsheet-20180201.804.el b/packages/clojure-cheatsheet-20180201.804.el deleted file mode 100644 index 15fc0c7..0000000 --- a/packages/clojure-cheatsheet-20180201.804.el +++ /dev/null @@ -1,638 +0,0 @@ -;;; clojure-cheatsheet.el --- The Clojure Cheatsheet for Emacs - -;; Copyright 2013-2016 Kris Jenkins - -;; Author: Kris Jenkins -;; Maintainer: Kris Jenkins -;; Keywords: clojure cider cheatsheet helm -;; Package-Version: 20180201.804 -;; URL: https://github.com/clojure-emacs/clojure-cheatsheet -;; Created: 7th August 2013 -;; Version: 0.4.0 -;; Package-Requires: ((helm "1.7.7") (cider "0.9.0")) ;; TODO Helm core? - -;; This file is not part of GNU Emacs. - -;;; Commentary: - -;; A quick reference system for Clojure. Fast, searchable & available offline. - -;;; License: - -;; 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 GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Code: - -(require 'helm) -(require 'helm-multi-match) -(require 'cider-interaction) -(require 'cl-lib) - -(warn "This package is now deprecated as its functionality was fully integrated into CIDER and helm-cider") - -(defconst clojure-cheatsheet-hierarchy - '(("Primitives" - ("Numbers" - ("Arithmetic" - (clojure.core + - * / quot rem mod dec inc max min)) - ("Compare" - (clojure.core = == not= < > <= >= compare)) - ("Bitwise" - (clojure.core bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor unsigned-bit-shift-right)) - ("Cast" - (clojure.core byte short long int float double bigdec bigint biginteger num rationalize)) - ("Test" - (clojure.core nil? some? identical? zero? pos? neg? even? odd?)) - ("Random" - (clojure.core rand rand-int)) - ("BigDecimal" - (clojure.core with-precision)) - ("Ratios" - (clojure.core numerator denominator ratio?)) - ("Arbitrary Precision Arithmetic" - (clojure.core +\' -\' *\' inc\' dec\')) - ("Unchecked" - (clojure.core *unchecked-math* - unchecked-add - unchecked-add-int - unchecked-byte - unchecked-char - unchecked-dec - unchecked-dec-int - unchecked-divide-int - unchecked-double - unchecked-float - unchecked-inc - unchecked-inc-int - unchecked-int - unchecked-long - unchecked-multiply - unchecked-multiply-int - unchecked-negate - unchecked-negate-int - unchecked-remainder-int - unchecked-short - unchecked-subtract - unchecked-subtract-int))) - - ("Strings" - ("Create" - (clojure.core str format)) - ("Use" - (clojure.core count get subs compare) - (clojure.string join escape split split-lines replace replace-first reverse re-quote-replacement index-of last-index-of starts-with? ends-with? includes?)) - ("Regex" - (:url "Java's Regex Syntax" "http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html") - (clojure.core re-find re-seq re-matches re-pattern re-matcher re-groups) - (clojure.string replace replace-first re-quote-replacement)) - ("Letters" - (clojure.string capitalize lower-case upper-case)) - ("Trim" - (clojure.string trim trim-newline triml trimr)) - ("Test" - (clojure.core char char? string?) - (clojure.string blank?))) - - ("Other" - ("Characters" - (clojure.core char char-name-string char-escape-string)) - ("Keywords" - (clojure.core keyword keyword? find-keyword)) - ("Symbols" - (clojure.core symbol symbol? gensym)) - ("Data Readers" - (clojure.core *data-readers* default-data-readers *default-data-reader-fn*)))) - - ("Collections" - ("Generic Ops" - (clojure.core count empty not-empty into conj)) - ("Tree Walking" - (clojure.walk walk prewalk prewalk-demo prewalk-replace postwalk postwalk-demo postwalk-replace keywordize-keys stringify-keys)) - ("Content tests" - (clojure.core distinct? empty? every? not-every? some not-any?)) - ("Capabilities" - (clojure.core sequential? associative? sorted? counted? reversible?)) - ("Type tests" - (clojure.core type class coll? list? vector? set? map? seq? - number? integer? float? decimal? class? rational? ratio? - chunked-seq? reduced? special-symbol? record?)) - ("Lists" - ("Create" - (clojure.core list list*)) - ("Examine" - (clojure.core first nth peek)) - ("'Change'" - (clojure.core cons conj rest pop))) - - ("Vectors" - ("Create" - (clojure.core vec vector vector-of)) - ("Examine" - (clojure.core get peek)) - - ("'Change'" - (clojure.core assoc pop subvec replace conj rseq)) - ("Ops" - (clojure.core mapv filterv reduce-kv))) - - ("Sets" - ("Create" - (clojure.core set hash-set sorted-set sorted-set-by)) - ("Examine" - (clojure.core get contains?)) - ("'Change'" - (clojure.core conj disj)) - ("Relational Algebra" - (clojure.set join select project union difference intersection)) - ("Get map" - (clojure.set index rename-keys rename map-invert)) - ("Test" - (clojure.set subset? superset?))) - - ("Maps" - ("Create" - (clojure.core hash-map array-map zipmap sorted-map sorted-map-by bean frequencies group-by)) - ("Examine" - (clojure.core get get-in contains? find keys vals map-entry?)) - ("'Change'" - (clojure.core assoc assoc-in dissoc merge merge-with select-keys update update-in)) - ("Entry" - (clojure.core key val)) - ("Sorted Maps" - (clojure.core rseq subseq rsubseq))) - - ("Hashes" - (clojure.core hash hash-ordered-coll hash-unordered-coll mix-collection-hash)) - - ("Volatiles" - (clojure.core volatile! volatile? vreset! vswap!))) - - ("Functions" - ("Create" - (clojure.core fn defn defn- definline identity constantly comp complement partial juxt memfn memoize fnil every-pred some-fn trampoline)) - ("Call" - (clojure.core -> ->> some-> some->> as-> cond-> cond->>)) - ("Test" - (clojure.core fn? ifn?))) - - ("Transducers" - ("Create" - (clojure.core cat dedupe distinct drop drop-while filter interpose keep keep-indexed map map-indexed mapcat partition-all partition-by random-sample remove replace take take-nth take-while)) - ("Call" - (clojure.core ->Eduction eduction into sequence transduce completing run!)) - ("Early Termination" - (clojure.core deref reduced reduced? ensure-reduced unreduced))) - - ("Other" - ("XML" - (clojure.core xml-seq) - (clojure.xml parse)) - ("REPL" - (clojure.core *1 *2 *3 *e *print-dup* *print-length* *print-level* *print-meta* *print-readably*)) - ("EDN" - (clojure.edn read read-string)) - ("Compiling Code & Class Generation" - (:url "Documentation" "http://clojure.org/compilation") - (clojure.core *compile-files* *compile-path* *file* *warn-on-reflection* compile gen-class gen-interface loaded-libs test)) - ("Misc" - (clojure.core eval force name *clojure-version* clojure-version *command-line-args*)) - ("Pretty Printing" - (clojure.pprint pprint print-table pp *print-right-margin*)) - ("Browser / Shell" - (clojure.java.browse browse-url) - (clojure.java.shell sh with-sh-dir with-sh-env))) - - ("Vars & Global Environment" - (:url "Documentation" "http://clojure.org/vars") - ("Def Variants" - (:special def) - (clojure.core defn defn- definline defmacro defmethod defmulti defonce defrecord)) - ("Interned Vars" - (:special var) - (clojure.core declare intern binding find-var)) - ("Var Objects" - (clojure.core with-local-vars var-get var-set alter-var-root var?)) - ("Var Validators" - (clojure.core set-validator! get-validator))) - - ("Reader Conditionals" - (clojure.core reader-conditional reader-conditional? tagged-literal tagged-literal?)) - - ("Abstractions" - ("Protocols" - (:url "Documentation" "http://clojure.org/protocols") - (clojure.core defprotocol extend extend-type extend-protocol reify extends? satisfies? extenders)) - ("Records & Types" - (:url "Documentation" "http://clojure.org/datatypes") - (clojure.core defrecord deftype)) - ("Multimethods" - (:url "Documentation" "http://clojure.org/multimethods") - ("Define" - (clojure.core defmulti defmethod)) - ("Dispatch" - (clojure.core get-method methods)) - ("Remove" - (clojure.core remove-method remove-all-methods)) - ("Prefer" - (clojure.core prefer-method prefers)) - ("Relation" - (clojure.core derive isa? parents ancestors descendants make-hierarchy)))) - - ("Macros" - (:url "Documentation" "http://clojure.org/macros") - ("Create" - (clojure.core defmacro definline)) - ("Debug" - (clojure.core macroexpand-1 macroexpand) - (clojure.walk macroexpand-all)) - ("Branch" - (clojure.core and or when when-not when-let when-first if-not if-let cond condp case)) - ("Loop" - (clojure.core for doseq dotimes while)) - ("Arrange" - (clojure.core .. doto ->)) - ("Scope" - (clojure.core binding locking time) - (clojure.core with-in-str with-local-vars with-open with-out-str with-precision with-redefs with-redefs-fn)) - ("Lazy" - (clojure.core lazy-cat lazy-seq delay delay?)) - ("Doc." - (clojure.core assert comment) - (clojure.repl doc dir dir-fn source-fn))) - - ("Java Interop" - (:url "Documentation" "http://clojure.org/java_interop") - ("General" - (:special new set!) - (clojure.core .. doto bean comparator enumeration-seq import iterator-seq memfn definterface supers bases)) - ("Cast" - (clojure.core boolean byte short char int long float double bigdec bigint num cast biginteger)) - ("Java Arrays" - ("Create" - (clojure.core boolean-array byte-array double-array char-array float-array int-array long-array make-array object-array short-array to-array)) - ("Manipulate" - (clojure.core aclone aget aset alength amap areduce aset-int aset-long aset-short aset-boolean aset-byte aset-char aset-double aset-float)) - ("Cast" - (clojure.core booleans bytes chars doubles floats ints longs shorts))) - ("Exceptions" - (:special throw try catch finally) - (clojure.core ex-info ex-data Throwable->map) - (clojure.repl pst))) - - ("Namespaces" - (:url "Documentation" "http://clojure.org/namespaces") - ("Current" - (clojure.core *ns*)) - ("Create Switch" - (clojure.core ns in-ns create-ns)) - ("Add" - (clojure.core alias import intern refer refer-clojure)) - ("Find" - (clojure.core all-ns find-ns)) - ("Examine" - (clojure.core ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers)) - ("From symbol" - (clojure.core resolve namespace ns-resolve the-ns)) - ("Remove" - (clojure.core ns-unalias ns-unmap remove-ns))) - ("Loading" - ("Load libs" - (clojure.core require use import refer)) - ("List Loaded" - (clojure.core loaded-libs)) - ("Load Misc" - (clojure.core load load-file load-reader load-string))) - - ("Concurrency" - (:url "Documentation" "http://clojure.org/atoms") - ("Atoms" - (clojure.core atom swap! reset! compare-and-set!)) - ("Futures" - (clojure.core future future-call future-cancel future-cancelled? future-done? future?)) - ("Threads" - (clojure.core bound-fn bound-fn* get-thread-bindings pop-thread-bindings push-thread-bindings)) - - ("Misc" - (clojure.core locking pcalls pvalues pmap seque promise deliver)) - - ("Refs & Transactions" - (:url "Documentation" "http://clojure.org/refs") - ("Create" - (clojure.core ref)) - ("Examine" - (clojure.core deref)) - ("Transaction" - (clojure.core sync dosync io!)) - ("In Transaction" - (clojure.core ensure ref-set alter commute)) - ("Validators" - (clojure.core get-validator set-validator!)) - ("History" - (clojure.core ref-history-count ref-max-history ref-min-history))) - - ("Agents & Asynchronous Actions" - (:url "Documentation" "http://clojure.org/agents") - ("Create" - (clojure.core agent)) - ("Examine" - (clojure.core agent-error)) - ("Change State" - (clojure.core send send-off restart-agent send-via set-agent-send-executor! set-agent-send-off-executor!)) - ("Block Waiting" - (clojure.core await await-for)) - ("Ref Validators" - (clojure.core get-validator set-validator!)) - ("Watchers" - (clojure.core add-watch remove-watch)) - ("Thread Handling" - (clojure.core shutdown-agents)) - ("Error" - (clojure.core error-handler set-error-handler! error-mode set-error-mode!)) - ("Misc" - (clojure.core *agent* release-pending-sends)))) - - ("Sequences" - ("Creating a Lazy Seq" - ("From Collection" - (clojure.core seq sequence keys vals rseq subseq rsubseq)) - ("From Producer Fn" - (clojure.core lazy-seq repeatedly iterate)) - ("From Constant" - (clojure.core repeat range)) - ("From Other" - (clojure.core file-seq line-seq resultset-seq re-seq tree-seq xml-seq iterator-seq enumeration-seq)) - ("From Seq" - (clojure.core keep keep-indexed))) - - ("Seq in, Seq out" - ("Get shorter" - (clojure.core distinct dedupe filter remove for)) - ("Get longer" - (clojure.core cons conj concat lazy-cat mapcat cycle interleave interpose))) - ("Tail-items" - (clojure.core rest nthrest fnext nnext drop drop-while take-last for)) - ("Head-items" - (clojure.core take take-nth take-while butlast drop-last for)) - ("'Change'" - (clojure.core conj concat distinct flatten group-by partition partition-all partition-by split-at split-with filter remove replace shuffle random-sample)) - ("Rearrange" - (clojure.core reverse sort sort-by compare)) - ("Process items" - (clojure.core map pmap map-indexed mapcat for replace seque)) - - ("Using a Seq" - ("Extract item" - (clojure.core first second last rest next ffirst nfirst fnext nnext nth nthnext rand-nth when-first max-key min-key)) - ("Construct coll" - (clojure.core zipmap into reduce reductions set vec into-array to-array-2d)) - ("Pass to fn" - (clojure.core apply)) - ("Search" - (clojure.core some filter)) - ("Force evaluation" - (clojure.core doseq dorun doall)) - ("Check for forced" - (clojure.core realized?)))) - - ("Zippers" - ("Create" - (clojure.zip zipper seq-zip vector-zip xml-zip)) - ("Get loc" - (clojure.zip up down left right leftmost rightmost)) - ("Get seq" - (clojure.zip lefts rights path children)) - ("'Change'" - (clojure.zip make-node replace edit insert-child insert-left insert-right append-child remove)) - ("Move" - (clojure.zip next prev)) - ("XML" - (clojure.data.zip.xml attr attr= seq-test tag= text text= xml-> xml1->)) - ("Misc" - (clojure.zip root node branch? end?))) - - ("Documentation" - ("REPL" - (clojure.repl doc find-doc apropos source pst) - (clojure.java.javadoc javadoc))) - - ("Transients" - (:url "Documentation" "http://clojure.org/transients") - ("Create") - (clojure.core transient persistent!) - ("Change") - (clojure.core conj! pop! assoc! dissoc! disj!)) - ("Misc" - ("Compare" - (clojure.core = == identical? not= not compare) - (clojure.data diff)) - ("Test" - (clojure.core true? false? nil? instance?))) - - ("IO" - ("To/from ..." - (clojure.core spit slurp)) - ("To *out*" - (clojure.core pr prn print printf println newline) - (clojure.pprint print-table)) - ("To writer" - (clojure.pprint pprint cl-format)) - ("To string" - (clojure.core format with-out-str pr-str prn-str print-str println-str)) - ("From *in*" - (clojure.core read-line read)) - ("From reader" - (clojure.core line-seq read)) - ("From string" - (clojure.core read-string with-in-str)) - ("Open" - (clojure.core with-open) - (clojure.java.io reader writer input-stream output-stream)) - ("Interop" - (clojure.java.io make-writer make-reader make-output-stream make-input-stream)) - ("Misc" - (clojure.core flush file-seq *in* *out* *err*) - (clojure.java.io file copy delete-file resource as-file as-url as-relative-path make-parents))) - - ("Metadata" - (clojure.core meta with-meta alter-meta! reset-meta! vary-meta)) - - ("Special Forms" - (:url "Documentation" "http://clojure.org/special_forms") - (:special def if do quote var recur throw try monitor-enter monitor-exit) - (clojure.core fn loop) - ("Binding / Destructuring" - (clojure.core let fn letfn defn defmacro loop for doseq if-let if-some when-let when-some))) - ("Async" - ("Main" - (clojure.core.async go go-loop ! >!! chan put! take take! close! timeout offer! poll! promise-chan)) - ("Choice" - (clojure.core.async alt! alt!! alts! alts!! do-alts)) - ("Buffering" - (clojure.core.async buffer dropping-buffer sliding-buffer unblocking-buffer?)) - ("Pipelines" - (clojure.core.async pipeline pipeline-async pipeline-blocking)) - ("Threading" - (clojure.core.async thread thread-call)) - - ("Mixing" - (clojure.core.async admix solo-mode mix unmix unmix-all toggle merge pipe unique)) - ("Multiples" - (clojure.core.async mult tap untap untap-all)) - ("Publish/Subscribe" - (clojure.core.async pub sub unsub unsub-all)) - ("Higher Order" - (clojure.core.async filter< filter> map map< map> mapcat< mapcat> partition partition-by reduce remove< remove> split)) - ("Pre-Populate" - (clojure.core.async into onto-chan to-chan))) - ("Unit Tests" - ("Defining" - (clojure.test deftest deftest- testing is are)) - ("Running" - (clojure.test run-tests run-all-tests test-vars)) - ("Fixtures" - (clojure.test use-fixtures join-fixtures compose-fixtures)))) - "A data structure designed for the maintainer's convenience, which we -transform into the format that helm requires. - -It's a tree, where the head of each list determines the context of the rest of the list. -The head may be: - - A string, in which case it's a (sub)heading for the rest of the items. - A symbol, in which case it's the Clojure namespace of the symbols that follow it. - The keyword :special, in which case it's a Clojure special form - a symbol with no - Any other keyword, in which case it's a typed item that will be passed - through and handled in `clojure-cheatsheet/item-to-helm-source'. - -Note that some many Clojure symbols appear in more than once. This is -entirely intentional. For instance, `map` belongs in the sections on -collections and transducers.") - -;;; We could just make dash.el a dependency, but I'm not sure it's worth it for one utility macro. -(defmacro clojure-cheatsheet/->> (&rest body) - (let ((result (pop body))) - (dolist (form body result) - (setq result (append (if (sequencep form) - form - (list form)) - (list result)))))) - -(defun clojure-cheatsheet/treewalk (before after node) - "Walk a tree. -Invoke BEFORE before the walk, and AFTER after it, on each NODE." - (clojure-cheatsheet/->> node - (funcall before) - ((lambda (new-node) - (if (listp new-node) - (mapcar (lambda (child) - (clojure-cheatsheet/treewalk before after child)) - new-node) - new-node))) - (funcall after))) - -(defun clojure-cheatsheet/symbol-qualifier (namespace symbol) - "Given a (Clojure) NAMESPACE and a SYMBOL, fully-qualify that symbol." - (intern (format "%s/%s" namespace symbol))) - -(defun clojure-cheatsheet/string-qualifier (head subnode) - (cond - ((keywordp (car subnode)) (list head subnode)) - ((symbolp (car subnode)) (cons head subnode)) - ((stringp (car subnode)) (cons (format "%s : %s" head (car subnode)) - (cdr subnode))) - (t (mapcar (apply-partially 'clojure-cheatsheet/string-qualifier head) subnode)))) - -(defun clojure-cheatsheet/propagate-headings (node) - (clojure-cheatsheet/treewalk - #'identity - (lambda (item) - (if (listp item) - (cl-destructuring-bind (head &rest tail) item - (cond ((equal :special head) tail) - ((keywordp head) item) - ((symbolp head) (mapcar (apply-partially #'clojure-cheatsheet/symbol-qualifier head) tail)) - ((stringp head) (mapcar (apply-partially #'clojure-cheatsheet/string-qualifier head) tail)) - (t item))) - item)) - node)) - -(defun clojure-cheatsheet/flatten (node) - "Flatten NODE, which is a tree structure, into a list of its leaves." - (cond - ((not (listp node)) node) - ((keywordp (car node)) node) - ((listp (car node)) (apply 'append (mapcar 'clojure-cheatsheet/flatten node))) - (t (list (mapcar 'clojure-cheatsheet/flatten node))))) - -(defun clojure-cheatsheet/group-by-head (data) - "Group the DATA, which should be a list of lists, by the head of each list." - (let ((result '())) - (dolist (item data result) - (let* ((head (car item)) - (tail (cdr item)) - (current (cdr (assoc head result)))) - (if current - (setf (cdr (assoc head result)) - (append current tail)) - (setq result (append result (list item)))))))) - -(defun clojure-cheatsheet/lookup-doc (symbol) - (if (cider-connected-p) - (cider-doc-lookup symbol) - (user-error "CIDER not connected!"))) - -(defun clojure-cheatsheet/lookup-src (symbol) - (if (cider-connected-p) - (cider-find-var nil symbol) - (user-error "CIDER not connected!"))) - -(defun clojure-cheatsheet/item-to-helm-source (item) - "Turn ITEM, which will be (\"HEADING\" candidates...), into a helm-source." - (cl-destructuring-bind (heading &rest entries) item - `((name . ,heading) - (candidates ,@(mapcar (lambda (item) - (if (and (listp item) - (keywordp (car item))) - (cl-destructuring-bind (kind title value) item - (cons title - (list kind value))) - item)) - entries)) - (match . ((lambda (candidate) - (helm-mm-3-match (format "%s %s" candidate ,heading))))) - (action-transformer (lambda (action-list current-selection) - (if (and (listp current-selection) - (eq (car current-selection) :url)) - '(("Browse" . (lambda (item) - (helm-browse-url (cadr item))))) - '(("Lookup Docs" . clojure-cheatsheet/lookup-doc) - ("Lookup Source" . clojure-cheatsheet/lookup-src)))))))) - -(defvar helm-source-clojure-cheatsheet - (clojure-cheatsheet/->> clojure-cheatsheet-hierarchy - clojure-cheatsheet/propagate-headings - clojure-cheatsheet/flatten - clojure-cheatsheet/group-by-head - (mapcar 'clojure-cheatsheet/item-to-helm-source))) - -;;;###autoload -(defun clojure-cheatsheet () - "Use helm to show a Clojure cheatsheet." - (interactive) - (helm :sources helm-source-clojure-cheatsheet)) - -(provide 'clojure-cheatsheet) - -;;; clojure-cheatsheet.el ends here diff --git a/packages/clojure-mode-20181024.2224.el b/packages/clojure-mode-20190725.654.el similarity index 90% rename from packages/clojure-mode-20181024.2224.el rename to packages/clojure-mode-20190725.654.el index 5f71f3e..5c8faad 100644 --- a/packages/clojure-mode-20181024.2224.el +++ b/packages/clojure-mode-20190725.654.el @@ -1,7 +1,7 @@ ;;; clojure-mode.el --- Major mode for Clojure code -*- lexical-binding: t; -*- -;; Copyright © 2007-2018 Jeffrey Chu, Lennart Staflin, Phil Hagelberg -;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba +;; Copyright © 2007-2019 Jeffrey Chu, Lennart Staflin, Phil Hagelberg +;; Copyright © 2013-2019 Bozhidar Batsov, Artur Malabarba ;; ;; Authors: Jeffrey Chu ;; Lennart Staflin @@ -9,9 +9,9 @@ ;; Bozhidar Batsov ;; Artur Malabarba ;; URL: http://github.com/clojure-emacs/clojure-mode -;; Package-Version: 20181024.2224 +;; Package-Version: 20190725.654 ;; Keywords: languages clojure clojurescript lisp -;; Version: 5.10.0-snapshot +;; Version: 5.11.0 ;; Package-Requires: ((emacs "25.1")) ;; This file is not part of GNU Emacs. @@ -70,6 +70,8 @@ (require 'newcomment) (require 'align) (require 'subr-x) +(require 'lisp-mnt) +(require 'project) (declare-function lisp-fill-paragraph "lisp-mode" (&optional justify)) @@ -80,7 +82,9 @@ :link '(url-link :tag "GitHub" "https://github.com/clojure-emacs/clojure-mode") :link '(emacs-commentary-link :tag "Commentary" "clojure-mode")) -(defconst clojure-mode-version "5.8.2" +(defconst clojure-mode-version + (eval-when-compile + (lm-version (or load-file-name buffer-file-name))) "The current version of `clojure-mode'.") (defface clojure-keyword-face @@ -93,7 +97,7 @@ "Face used to font-lock Clojure character literals." :package-version '(clojure-mode . "3.0.0")) -(defcustom clojure-indent-style :always-align +(defcustom clojure-indent-style 'always-align "Indentation style to use for function forms and macro forms. There are two cases of interest configured by this variable. @@ -111,7 +115,7 @@ already use special indentation rules. The possible values for this variable are keywords indicating how to indent function forms. - `:always-align' - Follow the same rules as `lisp-mode'. All + `always-align' - Follow the same rules as `lisp-mode'. All args are vertically aligned with the first arg in case (A), and vertically aligned with the function name in case (B). For instance: @@ -121,30 +125,27 @@ to indent function forms. merge some-coll) - `:always-indent' - All args are indented like a macro body. + `always-indent' - All args are indented like a macro body. (reduce merge some-coll) (reduce merge some-coll) - `:align-arguments' - Case (A) is indented like `lisp', and + `align-arguments' - Case (A) is indented like `lisp', and case (B) is indented like a macro body. (reduce merge some-coll) (reduce merge some-coll)" - :safe #'keywordp - :type '(choice (const :tag "Same as `lisp-mode'" :always-align) - (const :tag "Indent like a macro body" :always-indent) + :safe #'symbolp + :type '(choice (const :tag "Same as `lisp-mode'" 'always-align) + (const :tag "Indent like a macro body" 'always-indent) (const :tag "Indent like a macro body unless first arg is on the same line" - :align-arguments)) + 'align-arguments)) :package-version '(clojure-mode . "5.2.0")) -(define-obsolete-variable-alias 'clojure-defun-style-default-indent - 'clojure-indent-style "5.2.0") - (defcustom clojure-use-backtracking-indent t "When non-nil, enable context sensitive indentation." :type 'boolean @@ -180,11 +181,12 @@ For example, \[ is allowed in :db/id[:db.part/user]." (cl-every 'characterp value)))) (defcustom clojure-build-tool-files - '("project.clj" ; Leiningen - "build.boot" ; Boot - "build.gradle" ; Gradle - "deps.edn" ; Clojure CLI (a.k.a. tools.deps) - "shadow-cljs.edn" ; shadow-cljs + '("project.clj" ; Leiningen + "build.boot" ; Boot + "build.gradle" ; Gradle + "build.gradle.kts" ; Gradle + "deps.edn" ; Clojure CLI (a.k.a. tools.deps) + "shadow-cljs.edn" ; shadow-cljs ) "A list of files, which identify a Clojure project's root. Out-of-the box `clojure-mode' understands lein, boot, gradle, @@ -216,8 +218,6 @@ Out-of-the box `clojure-mode' understands lein, boot, gradle, (define-key map (kbd "f") #'clojure-thread-first-all) (define-key map (kbd "C-l") #'clojure-thread-last-all) (define-key map (kbd "l") #'clojure-thread-last-all) - (define-key map (kbd "C-a") #'clojure-unwind-all) - (define-key map (kbd "a") #'clojure-unwind-all) (define-key map (kbd "C-p") #'clojure-cycle-privacy) (define-key map (kbd "p") #'clojure-cycle-privacy) (define-key map (kbd "C-(") #'clojure-convert-collection-to-list) @@ -240,10 +240,13 @@ Out-of-the box `clojure-mode' understands lein, boot, gradle, (define-key map (kbd "n h") #'clojure-insert-ns-form-at-point) (define-key map (kbd "n u") #'clojure-update-ns) (define-key map (kbd "n s") #'clojure-sort-ns) + (define-key map (kbd "n r") #'clojure-rename-ns-alias) (define-key map (kbd "s i") #'clojure-introduce-let) (define-key map (kbd "s m") #'clojure-move-to-let) (define-key map (kbd "s f") #'clojure-let-forward-slurp-sexp) (define-key map (kbd "s b") #'clojure-let-backward-slurp-sexp) + (define-key map (kbd "C-a") #'clojure-add-arity) + (define-key map (kbd "a") #'clojure-add-arity) map) "Keymap for Clojure refactoring commands.") (fset 'clojure-refactor-map clojure-refactor-map) @@ -262,11 +265,13 @@ Out-of-the box `clojure-mode' understands lein, boot, gradle, ["Cycle if, if-not" clojure-cycle-if] ["Cycle when, when-not" clojure-cycle-when] ["Cycle not" clojure-cycle-not] + ["Add function arity" clojure-add-arity] ("ns forms" ["Insert ns form at the top" clojure-insert-ns-form] ["Insert ns form here" clojure-insert-ns-form-at-point] ["Update ns form" clojure-update-ns] - ["Sort ns form" clojure-sort-ns]) + ["Sort ns form" clojure-sort-ns] + ["Rename ns alias" clojure-rename-ns-alias]) ("Convert collection" ["Convert to list" clojure-convert-collection-to-list] ["Convert to quoted list" clojure-convert-collection-to-quoted-list] @@ -395,7 +400,7 @@ The command will prompt you to select one of the available sections." (let ((section-url (concat clojure-reference-base-url (cdr (assoc section clojure-reference-sections))))) (browse-url section-url))))) -(defconst clojure-cheatsheet-url "http://clojure.org/api/cheatsheet" +(defconst clojure-cheatsheet-url "https://clojure.org/api/cheatsheet" "The URL of the official Clojure cheatsheet.") (defun clojure-view-cheatsheet () @@ -470,22 +475,15 @@ ENDP and DELIMITER." t) (= orig-point (match-end 0))))))))) -(declare-function paredit-open-curly "ext:paredit") -(declare-function paredit-close-curly "ext:paredit") +(declare-function paredit-open-curly "ext:paredit" t t) +(declare-function paredit-close-curly "ext:paredit" t t) (declare-function paredit-convolute-sexp "ext:paredit") -(defun clojure--replace-let-bindings-and-indent (orig-fun &rest args) - "Advise ORIG-FUN to replace let bindings. - -Sexps are replace by their bound name if a let form was -convoluted. - -ORIG-FUN should be `paredit-convolute-sexp'. - -ARGS are passed to ORIG-FUN, as with all advice." +(defun clojure--replace-let-bindings-and-indent () + "Replace let bindings and indent." (save-excursion (backward-sexp) - (when (looking-back clojure--let-regexp) + (when (looking-back clojure--let-regexp nil) (clojure--replace-sexps-with-bindings-and-indent)))) (defun clojure-paredit-setup (&optional keymap) @@ -553,9 +551,16 @@ replacement for `cljr-expand-let`." (clojure-font-lock-setup) (add-hook 'paredit-mode-hook #'clojure-paredit-setup) ;; `electric-layout-post-self-insert-function' prevents indentation in strings - ;; and comments, force indentation in docstrings: + ;; and comments, force indentation of non-inlined docstrings: (add-hook 'electric-indent-functions - (lambda (_char) (if (clojure-in-docstring-p) 'do-indent))) + (lambda (_char) (if (and (clojure-in-docstring-p) + ;; make sure we're not dealing with an inline docstring + ;; e.g. (def foo "inline docstring" bar) + (save-excursion + (beginning-of-line-text) + (eq (get-text-property (point) 'face) + 'font-lock-doc-face))) + 'do-indent))) ;; integration with project.el (add-hook 'project-find-functions #'clojure-current-project)) @@ -786,7 +791,7 @@ any number of matches of `clojure--sym-forbidden-rest-chars'.")) "[ \r\n\t]*" ;; Possibly type or metadata "\\(?:#?^\\(?:{[^}]*}\\|\\sw+\\)[ \r\n\t]*\\)*" - "\\(\\sw+\\)?") + (concat "\\(" clojure--sym-regexp "\\)?")) (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t)) ;; (fn name? args ...) @@ -848,7 +853,8 @@ any number of matches of `clojure--sym-forbidden-rest-chars'.")) "\\>") 0 font-lock-builtin-face) ;; Dynamic variables - *something* or @*something* - ("\\(?:\\<\\|/\\)@?\\(\\*[a-z-]*\\*\\)\\>" 1 font-lock-variable-name-face) + (,(concat "\\(?:\\<\\|/\\)@?\\(\\*" clojure--sym-regexp "\\*\\)\\>") + 1 font-lock-variable-name-face) ;; Global constants - nil, true, false (,(concat "\\<" @@ -861,8 +867,8 @@ any number of matches of `clojure--sym-forbidden-rest-chars'.")) ;; namespace definitions: (ns foo.bar) (,(concat "(\\[ \r\n\t]*" - ;; Possibly metadata - "\\(?:\\^?{[^}]+}[ \r\n\t]*\\)*" + ;; Possibly metadata, shorthand and/or longhand + "\\(?:\\^?\\(?:{[^}]+}\\|:[^ \r\n\t]+[ \r\n\t]\\)[ \r\n\t]*\\)*" ;; namespace "\\(" clojure--sym-regexp "\\)") (1 font-lock-type-face)) @@ -909,6 +915,10 @@ any number of matches of `clojure--sym-forbidden-rest-chars'.")) (,(rx "`" (group-n 1 (optional "#'") (+ (or (syntax symbol) (syntax word)))) "`") (1 'font-lock-constant-face prepend)) + ;; Highlight [[var]] comments + (,(rx "[[" (group-n 1 (optional "#'") + (+ (or (syntax symbol) (syntax word)))) "]]") + (1 'font-lock-constant-face prepend)) ;; Highlight escaped characters in strings. (clojure-font-lock-escaped-chars 0 'bold prepend) ;; Highlight grouping constructs in regular expressions @@ -955,7 +965,13 @@ highlighted region)." (setq docelt (1- docelt))))) (and (zerop docelt) (<= (point) startpos) (progn (forward-comment (point-max)) t) - (= (point) (nth 8 state))))) + (= (point) (nth 8 state)))) + ;; In a def, at last position is not a docstring + (not (and (string= "def" firstsym) + (save-excursion + (goto-char startpos) + (goto-char (+ startpos (length (sexp-at-point)) 2)) + (looking-at "[ \r\n\t]*\)"))))) font-lock-doc-face font-lock-string-face)))) font-lock-comment-face)) @@ -1115,7 +1131,9 @@ will align the values like this: :safe #'listp :type '(repeat string)) -(defcustom clojure-align-cond-forms '("condp" "cond" "cond->" "cond->>" "case" "are") +(defcustom clojure-align-cond-forms '("condp" "cond" "cond->" "cond->>" "case" "are" + "clojure.core/condp" "clojure.core/cond" "clojure.core/cond->" + "clojure.core/cond->>" "clojure.core/case" "clojure.test/are") "List of strings identifying cond-like forms." :package-version '(clojure-mode . "5.1") :safe #'listp @@ -1305,7 +1323,10 @@ symbol properties." 'clojure-indent-function) (get (intern-soft (match-string 1 function-name)) 'clojure-backtracking-indent))) - (when (string-match (rx (or "let" "when" "while") (syntax symbol)) + ;; indent symbols starting with if, when, ... + ;; such as if-let, when-let, ... + ;; like if, when, ... + (when (string-match (rx string-start (or "if" "when" "let" "while") (syntax symbol)) function-name) (clojure--get-indent-method (substring (match-string 0 function-name) 0 -1))))) @@ -1365,6 +1386,10 @@ spec." (let ((function (thing-at-point 'symbol))) (clojure--get-indent-method function)))) +(defun clojure--keyword-to-symbol (keyword) + "Convert KEYWORD to symbol." + (intern (substring (symbol-name keyword) 1))) + (defun clojure--normal-indent (last-sexp indent-mode) "Return the normal indentation column for a sexp. Point should be after the open paren of the _enclosing_ sexp, and @@ -1390,19 +1415,22 @@ accepted by `clojure-indent-style'." ;; Here we have reached the start of the enclosing sexp (point is now at ;; the function name), so the behaviour depends on INDENT-MODE and on ;; whether there's also an argument on this line (case A or B). - (let ((case-a ; The meaning of case-a is explained in `clojure-indent-style'. + (let ((indent-mode (if (keywordp indent-mode) + ;; needed for backwards compatibility + ;; as before clojure-mode 5.10 indent-mode was a keyword + (clojure--keyword-to-symbol indent-mode) + indent-mode)) + (case-a ; The meaning of case-a is explained in `clojure-indent-style'. (and last-sexp-start (< last-sexp-start (line-end-position))))) (cond - ;; For compatibility with the old `clojure-defun-style-default-indent', any - ;; value other than these 3 is equivalent to `always-body'. - ((not (memq indent-mode '(:always-align :align-arguments nil))) + ((eq indent-mode 'always-indent) (+ (current-column) lisp-body-indent -1)) ;; There's an arg after the function name, so align with it. (case-a (goto-char last-sexp-start) (current-column)) ;; Not same line. - ((eq indent-mode :align-arguments) + ((eq indent-mode 'align-arguments) (+ (current-column) lisp-body-indent -1)) ;; Finally, just align with the function name. (t (current-column))))))) @@ -1474,7 +1502,7 @@ This function also returns nil meaning don't specify the indentation." (+ lisp-body-indent containing-form-column)) ;; Further non-special args, align with the arg above. ((> pos (1+ method)) - (clojure--normal-indent last-sexp :always-align)) + (clojure--normal-indent last-sexp 'always-align)) ;; Special arg. Rigidly indent with a large indentation. (t (+ (* 2 lisp-body-indent) containing-form-column))))) @@ -1488,7 +1516,7 @@ This function also returns nil meaning don't specify the indentation." (cond ;; Preserve useful alignment of :require (and friends) in `ns' forms. ((and function (string-match "^:" function)) - (clojure--normal-indent last-sexp :always-align)) + (clojure--normal-indent last-sexp 'always-align)) ;; This should be identical to the :defn above. ((and function (string-match "\\`\\(?:\\S +/\\)?\\(def[a-z]*\\|with-\\)" @@ -1550,6 +1578,7 @@ work). To set it from Lisp code, use (when-not 1) (when-first 1) (do 0) + (delay 0) (future 0) (comment 0) (doto 1) @@ -1718,6 +1747,10 @@ Return nil if not inside a project." (when (> (length choices) 0) (car (sort choices #'file-in-directory-p))))) +;; project.el integration +(cl-defmethod project-roots ((project (head clojure))) + (list (cdr project))) + (defun clojure-project-relative-path (path) "Denormalize PATH by making it relative to the project root." (file-relative-name path (clojure-project-dir))) @@ -1864,6 +1897,19 @@ the cached value will be updated automatically." (defvar-local clojure-cached-ns nil "A buffer ns cache used to speed up ns-related operations.") +(defun clojure--find-ns-in-direction (direction) + "Return the nearest namespace in a specific DIRECTION. +DIRECTION is `forward' or `backward'." + (let ((candidate) + (fn (if (eq direction 'forward) + #'search-forward-regexp + #'search-backward-regexp))) + (while (and (not candidate) + (funcall fn clojure-namespace-name-regex nil t)) + (unless (or (clojure--in-string-p) (clojure--in-comment-p)) + (setq candidate (match-string-no-properties 4)))) + candidate)) + (defun clojure-find-ns () "Return the namespace of the current Clojure buffer. Return the namespace closest to point and above it. If there are @@ -1879,12 +1925,8 @@ The results will be cached if `clojure-cache-ns' is set to t." ;; Move to top-level to avoid searching from inside ns (ignore-errors (while t (up-list nil t t))) - ;; The closest ns form above point. - (when (or (re-search-backward clojure-namespace-name-regex nil t) - ;; Or any form at all. - (and (goto-char (point-min)) - (re-search-forward clojure-namespace-name-regex nil t))) - (match-string-no-properties 4)))))) + (or (clojure--find-ns-in-direction 'backward) + (clojure--find-ns-in-direction 'forward)))))) (setq clojure-cached-ns ns) ns))) @@ -1934,7 +1976,7 @@ Returns a list pair, e.g. (\"defn\" \"abc\") or (\"deftest\" \"some-test\")." \"Non-logical\" sexp are ^metadata and #reader.macros." (comment-normalize-vars) (comment-forward (point-max)) - (looking-at-p "\\^\\|#[[:alpha:]]")) + (looking-at-p "\\^\\|#:?:?[[:alpha:]]")) (defun clojure-forward-logical-sexp (&optional n) "Move forward N logical sexps. @@ -2032,9 +2074,8 @@ many times." (condition-case nil (save-match-data (let ((original-position (point)) - clojure-comment-start clojure-comment-end) + clojure-comment-end) (beginning-of-defun) - (setq clojure-comment-start (point)) (end-of-defun) (setq clojure-comment-end (point)) (beginning-of-defun) @@ -2089,8 +2130,7 @@ list of (fn args) to pass to `apply''" Point must be between the opening paren and the ->> symbol." (forward-sexp) (save-excursion - (let ((beg (point)) - (contents (clojure-delete-and-extract-sexp))) + (let ((contents (clojure-delete-and-extract-sexp))) (when (looking-at " *\n") (join-line 'following)) (clojure--ensure-parens-around-function-names) @@ -2162,10 +2202,12 @@ before fixing whitespace." (delete-trailing-whitespace (car sexp) (cdr sexp))))) ;;;###autoload -(defun clojure-unwind () - "Unwind thread at point or above point by one level. -Return nil if there are no more levels to unwind." - (interactive) +(defun clojure-unwind (&optional n) + "Unwind thread at point or above point by N levels. +With universal argument \\[universal-argument], fully unwind thread." + (interactive "P") + (setq n (cond ((equal n '(4)) 999) + (n) (1))) (save-excursion (let ((limit (save-excursion (beginning-of-defun) @@ -2174,23 +2216,24 @@ Return nil if there are no more levels to unwind." (when (looking-at "(") (forward-char 1) (forward-sexp 1))) - (search-backward-regexp "([^-]*->" limit) - (if (clojure--nothing-more-to-unwind) - (progn (clojure--pop-out-of-threading) - (clojure--fix-sexp-whitespace) - nil) - (down-list) - (prog1 (cond - ((looking-at "[^-]*->\\_>") (clojure--unwind-first)) - ((looking-at "[^-]*->>\\_>") (clojure--unwind-last))) - (clojure--fix-sexp-whitespace 'move-out)) - t)))) + (while (> n 0) + (search-backward-regexp "([^-]*->" limit) + (if (clojure--nothing-more-to-unwind) + (progn (clojure--pop-out-of-threading) + (clojure--fix-sexp-whitespace) + (setq n 0)) ;; break out of loop + (down-list) + (cond + ((looking-at "[^-]*->\\_>") (clojure--unwind-first)) + ((looking-at "[^-]*->>\\_>") (clojure--unwind-last))) + (clojure--fix-sexp-whitespace 'move-out) + (setq n (1- n))))))) ;;;###autoload (defun clojure-unwind-all () "Fully unwind thread at point or above point." (interactive) - (while (clojure-unwind))) + (clojure-unwind '(4))) (defun clojure--remove-superfluous-parens () "Remove extra parens from a form." @@ -2362,6 +2405,10 @@ See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-privacy" "Check whether the point is currently in a string." (nth 3 (syntax-ppss))) +(defun clojure--in-comment-p () + "Check whether the point is currently in a comment." + (nth 4 (syntax-ppss))) + (defun clojure--goto-if () "Find the first surrounding if or if-not expression." (when (clojure--in-string-p) @@ -2426,7 +2473,7 @@ See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-if" (condition-case nil (backward-up-list) (scan-error (user-error "`clojure-cycle-not' must be invoked inside a list"))) - (if (looking-back "(not ") + (if (looking-back "(not " nil) (progn (delete-char -5) (forward-sexp) @@ -2619,10 +2666,26 @@ lists up." (insert sexp) (clojure--replace-sexps-with-bindings-and-indent))) +(defun clojure--rename-ns-alias-internal (current-alias new-alias) + "Rename a namespace alias CURRENT-ALIAS to NEW-ALIAS." + (clojure--find-ns-in-direction 'backward) + (let ((rgx (concat ":as +" current-alias)) + (bound (save-excursion (forward-list 1) (point)))) + (when (search-forward-regexp rgx bound t) + (replace-match (concat ":as " new-alias)) + (save-excursion + (while (re-search-forward (concat current-alias "/") nil t) + (when (not (nth 3 (syntax-ppss))) + (replace-match (concat new-alias "/"))))) + (save-excursion + (while (re-search-forward (concat "#::" current-alias "{") nil t) + (replace-match (concat "#::" new-alias "{")))) + (message "Successfully renamed alias '%s' to '%s'" current-alias new-alias)))) + ;;;###autoload (defun clojure-let-backward-slurp-sexp (&optional n) "Slurp the s-expression before the let form into the let form. -With a numberic prefix argument slurp the previous N s-expression +With a numeric prefix argument slurp the previous N s-expressions into the let form." (interactive "p") (let ((n (or n 1))) @@ -2642,10 +2705,11 @@ into the let form." ;;;###autoload (defun clojure-let-forward-slurp-sexp (&optional n) "Slurp the next s-expression after the let form into the let form. -With a numeric prefix argument slurp the next N s-expressions into the let form." +With a numeric prefix argument slurp the next N s-expressions +into the let form." (interactive "p") (unless n (setq n 1)) - (dotimes (k n) + (dotimes (_ n) (save-excursion (clojure--let-forward-slurp-sexp-internal)))) ;;;###autoload @@ -2661,6 +2725,95 @@ With a numeric prefix argument the let is introduced N lists up." (interactive) (clojure--move-to-let-internal (read-from-minibuffer "Name of bound symbol: "))) +;;;###autoload +(defun clojure-rename-ns-alias () + "Rename a namespace alias." + (interactive) + (let ((current-alias (read-from-minibuffer "Current alias: "))) + (save-excursion + (clojure--find-ns-in-direction 'backward) + (let ((rgx (concat ":as +" current-alias)) + (bound (save-excursion (forward-list 1) (point)))) + (if (save-excursion (search-forward-regexp rgx bound t)) + (let ((new-alias (read-from-minibuffer "New alias: "))) + (clojure--rename-ns-alias-internal current-alias new-alias)) + (message "Cannot find namespace alias: '%s'" current-alias)))))) + +(defun clojure--add-arity-defprotocol-internal () + "Add an arity to a signature inside a defprotocol. + +Assumes cursor is at beginning of signature." + (re-search-forward "\\[") + (save-excursion (insert "] ["))) + +(defun clojure--add-arity-reify-internal () + "Add an arity to a function inside a reify. + +Assumes cursor is at beginning of function." + (re-search-forward "\\(\\w+ \\)") + (insert "[") + (save-excursion (insert "])\n(" (match-string 0)))) + +(defun clojure--add-arity-internal () + "Add an arity to a function. + +Assumes cursor is at beginning of function." + (let ((beg-line (what-line)) + (end (save-excursion (forward-sexp) + (point)))) + (down-list 2) + (when (looking-back "{" 1) ;; skip metadata if present + (up-list) + (down-list)) + (cond + ((looking-back "(" 1) ;; multi-arity fn + (insert "[") + (save-excursion (insert "])\n("))) + ((looking-back "\\[" 1) ;; single-arity fn + (let* ((same-line (string= beg-line (what-line))) + (new-arity-text (concat (when same-line "\n") "(["))) + (save-excursion + (goto-char end) + (insert ")")) + + (re-search-backward " +\\[") + (replace-match new-arity-text) + (save-excursion (insert "])\n(["))))))) + +;;;###autoload +(defun clojure-add-arity () + "Add an arity to a function." + (interactive) + (let ((original-pos (point)) + (n 0)) + (while (not (looking-at-p "(\\(defn\\|letfn\\|fn\\|defmacro\\|defmethod\\|defprotocol\\|reify\\|proxy\\)")) + (setq n (1+ n)) + (backward-up-list 1 t)) + (let ((beg (point)) + (end-marker (make-marker)) + (end (save-excursion (forward-sexp) + (point))) + (jump-up (lambda (x) + (goto-char original-pos) + (backward-up-list x t)))) + (set-marker end-marker end) + (cond + ((looking-at-p "(\\(defn\\|fn\\|defmethod\\|defmacro\\)") + (clojure--add-arity-internal)) + ((looking-at-p "(letfn") + (funcall jump-up (- n 2)) + (clojure--add-arity-internal)) + ((looking-at-p "(proxy") + (funcall jump-up (- n 1)) + (clojure--add-arity-internal)) + ((looking-at-p "(defprotocol") + (funcall jump-up (- n 1)) + (clojure--add-arity-defprotocol-internal)) + ((looking-at-p "(reify") + (funcall jump-up (- n 1)) + (clojure--add-arity-reify-internal))) + (indent-region beg end-marker)))) + ;;; ClojureScript (defconst clojurescript-font-lock-keywords diff --git a/packages/clojure-snippets-20180314.1308.tar b/packages/clojure-snippets-20180314.1308.tar index 928db6d..9c5471a 100644 Binary files a/packages/clojure-snippets-20180314.1308.tar and b/packages/clojure-snippets-20180314.1308.tar differ diff --git a/packages/closql-20190731.1450.el b/packages/closql-20190731.1450.el new file mode 100644 index 0000000..c0b8804 --- /dev/null +++ b/packages/closql-20190731.1450.el @@ -0,0 +1,565 @@ +;;; closql.el --- store EIEIO objects using EmacSQL -*- lexical-binding: t; -*- + +;; Copyright (C) 2016-2019 Jonas Bernoulli + +;; Author: Jonas Bernoulli +;; Homepage: https://github.com/emacscollective/closql +;; Package-Requires: ((emacs "25.1") (emacsql-sqlite "3.0.0")) +;; Package-Version: 20190731.1450 +;; Keywords: extensions + +;; This file is not 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 of the License, +;; or (at your option) any later version. + +;; This file 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 GPL see http://www.gnu.org/licenses. + +;;; Commentary: + +;; Store uniform EIEIO objects in an EmacSQL database. SQLite is used +;; as backend. This library imposes some restrictions on what kind of +;; objects can be stored; it isn't intended to store arbitrary objects. +;; All objects have to share a common superclass and subclasses cannot +;; add any additional instance slots. + +;;; Code: + +(require 'eieio) +(require 'emacsql-sqlite) + +(eval-when-compile (require 'subr-x)) + +;;; Objects + +(defclass closql-object () + ((closql-class-prefix :initform nil :allocation :class) + (closql-class-suffix :initform nil :allocation :class) + (closql-table :initform nil :allocation :class) + (closql-primary-key :initform nil :allocation :class) + (closql-foreign-key :initform nil :allocation :class) + (closql-order-by :initform nil :allocation :class) + (closql-database :initform nil :initarg :closql-database)) + :abstract t) + +;;;; Oref + +(defun eieio-oref--closql-oref (fn obj slot) + (if (closql-object--eieio-childp obj) + (closql-oref obj slot) + (funcall fn obj slot))) + +(advice-add 'eieio-oref :around #'eieio-oref--closql-oref) + +(defun closql--oref (obj slot) + (aref obj (eieio--slot-name-index (eieio--object-class obj) slot))) + +(defun closql-oref (obj slot) + (cl-check-type slot symbol) + (cl-check-type obj (or eieio-object class)) + (let* ((class (cond ((symbolp obj) + (error "eieio-oref called on a class: %s" obj) + (let ((c (cl--find-class obj))) + (if (eieio--class-p c) (eieio-class-un-autoload obj)) + c)) + (t (eieio--object-class obj)))) + (c (eieio--slot-name-index class slot))) + (if (not c) + (if (setq c (eieio--class-slot-name-index class slot)) + (aref (eieio--class-class-allocation-values class) c) + (slot-missing obj slot 'oref)) + (cl-check-type obj eieio-object) + (let ((value (aref obj c)) + (class (closql--slot-class obj slot)) + (table (closql--slot-table obj slot)) + (db (closql--oref obj 'closql-database))) + (cond + (class + (aset obj c + (mapcar (lambda (row) + (closql--remake-instance class db row)) + (emacsql db (vconcat + [:select * :from $i1 + :where (= $i2 $s3)] + (vector + :order-by + (or (oref-default class closql-order-by) + [(asc $i4)]))) + (oref-default class closql-table) + (oref-default class closql-foreign-key) + (closql--oref + obj (oref-default obj closql-primary-key)) + (oref-default class closql-primary-key))))) + (table + (if (eq value eieio-unbound) + (let ((columns (closql--table-columns db table))) + (aset obj c + (mapcar + (if (= (length columns) 2) #'cadr #'cdr) + (emacsql db [:select * :from $i1 + :where (= $i2 $s3) + :order-by [(asc $i4)]] + table + (car columns) + (closql--oref + obj (oref-default obj closql-primary-key)) + (cadr columns))))) + value)) + (t + (eieio-barf-if-slot-unbound value obj slot 'oref))))))) + +;;;; Oset + +(defun eieio-oset--closql-oset (fn obj slot value) + (if (closql-object--eieio-childp obj) + (closql-oset obj slot value) + (funcall fn obj slot value))) + +(advice-add 'eieio-oset :around #'eieio-oset--closql-oset) + +(defun closql--oset (obj slot value) + (aset obj (eieio--slot-name-index (eieio--object-class obj) slot) value)) + +(defun closql-oset (obj slot value) + (cl-check-type obj eieio-object) + (cl-check-type slot symbol) + (let* ((class (eieio--object-class obj)) + (c (eieio--slot-name-index class slot))) + (if (not c) + (if (setq c (eieio--class-slot-name-index class slot)) + (progn (eieio--validate-class-slot-value class c value slot) + (aset (eieio--class-class-allocation-values class) c value)) + (slot-missing obj slot 'oset value)) + (eieio--validate-slot-value class c value slot) + (unless (eq slot 'closql-database) + (let ((db (closql--oref obj 'closql-database))) + (unless (or (not db) (eq db eieio-unbound)) + (closql--dset db obj slot value)))) + (aset obj c value)))) + +(defun closql--dset (db obj slot value) + (let* ((key (oref-default obj closql-primary-key)) + (id (closql--oref obj key)) + (class (closql--slot-class obj slot)) + (table (closql--slot-table obj slot))) + (cond + (class + (error "Not implemented for closql-class slots: oset")) + (table + (emacsql-with-transaction db + (let ((columns (closql--table-columns db table))) + ;; Caller might have modified value in place. + (closql--oset obj slot eieio-unbound) + (let ((list1 (closql-oref obj slot)) + (list2 value) + elt1 elt2) + (when (= (length columns) 2) + (setq list1 (mapcar #'list list1)) + (setq list2 (mapcar #'list list2))) + ;; `list2' may not be sorted at all and `list1' has to + ;; be sorted because Elisp and SQLite sort differently. + (setq list1 (cl-sort list1 'string< :key #'car)) + (setq list2 (cl-sort list2 'string< :key #'car)) + (while (progn (setq elt1 (car list1)) + (setq elt2 (car list2)) + (or elt1 elt2)) + (let ((key1 (car elt1)) + (key2 (car elt2))) + (cond + ((and elt1 (or (not elt2) (string< key1 key2))) + (apply #'emacsql db + (vconcat + [:delete-from $i1 :where] + (closql--where-equal (cons id elt1) 1)) + table + (cl-mapcan #'list columns (cons id elt1))) + (pop list1)) + ((string= key1 key2) + (unless (equal elt1 elt2) + (cl-mapcar + (lambda (col val1 val2) + (unless (equal val1 val2) + (emacsql db [:update $i1 :set (= $i2 $s3) + :where (and (= $i4 $s5) (= $i6 $s7))] + table col val2 + (car columns) id + (cadr columns) key2))) + (cddr columns) + (cdr elt1) + (cdr elt2))) + (pop list1) + (pop list2)) + (t + (emacsql db [:insert-into $i1 :values $v2] + table (vconcat (cons id elt2))) + (pop list2))))))))) + (t + (emacsql db [:update $i1 :set (= $i2 $s3) :where (= $i4 $s5)] + (oref-default obj closql-table) + slot + (if (eq value eieio-unbound) 'eieio-unbound value) + key id))))) + +;;;; Slot Properties + +(defun closql--slot-class (obj slot) + (closql--slot-get obj slot :closql-class)) + +(defun closql--slot-table (obj slot) + (let ((tbl (closql--slot-get obj slot :closql-table))) + (and tbl (intern (replace-regexp-in-string + "-" "_" + (symbol-name (if (symbolp tbl) tbl (car tbl)))))))) + +(defun closql--slot-get (object-or-class slot prop) + (let ((s (car (cl-member slot + (eieio-class-slots + (cond ((eieio-object-p object-or-class) + (eieio--object-class object-or-class)) + ((eieio--class-p object-or-class) + object-or-class) + (t + (find-class object-or-class 'error)))) + :key #'cl--slot-descriptor-name)))) + (and s (cdr (assoc prop (cl--slot-descriptor-props s)))))) + +(defconst closql--slot-properties '(:closql-class :closql-table)) + +(defun eieio-defclass-internal--set-closql-slot-props + (cname _superclasses slots _options) + (let ((class (cl--find-class cname))) + (when (child-of-class-p class 'closql-object) + (pcase-dolist (`(,name . ,slot) slots) + (let ((slot-obj + (car (cl-member name + (cl-coerce (eieio--class-slots class) 'list) + :key (lambda (elt) (aref elt 1)))))) + (dolist (prop closql--slot-properties) + (let ((val (plist-get slot prop))) + (when val + (setf (alist-get prop (cl--slot-descriptor-props slot-obj)) + val))))))))) + +(advice-add 'eieio-defclass-internal :after + #'eieio-defclass-internal--set-closql-slot-props) + +(defun eieio--slot-override--set-closql-slot-props (old new _) + (dolist (prop closql--slot-properties) + (when (alist-get prop (cl--slot-descriptor-props new)) + (setf (alist-get prop (cl--slot-descriptor-props old)) + (alist-get prop (cl--slot-descriptor-props new)))))) + +(advice-add 'eieio--slot-override :after + #'eieio--slot-override--set-closql-slot-props) + +;;; Database + +(defclass closql-database (emacsql-sqlite-connection) + ((object-class :allocation :class))) + +(cl-defmethod closql-db ((class (subclass closql-database)) + &optional variable file debug) + (or (let ((db (and variable (symbol-value variable)))) + (and db (emacsql-live-p db) db)) + (let ((db-init (not (and file (file-exists-p file)))) + (db (make-instance class :file file))) + (set-process-query-on-exit-flag (oref db process) nil) + (when debug + (emacsql-enable-debugging db)) + (when db-init + (closql--db-init db)) + (when variable + (set variable db)) + db))) + +(cl-defgeneric closql--db-init (db)) + +(cl-defmethod emacsql ((connection closql-database) sql &rest args) + (mapcar #'closql--extern-unbound + (apply #'cl-call-next-method connection sql + (mapcar (lambda (arg) + (if (stringp arg) + (let ((copy (copy-sequence arg))) + (set-text-properties 0 (length copy) nil copy) + copy) + arg)) + args)))) + +(cl-defmethod closql-insert ((db closql-database) obj &optional replace) + (closql--oset obj 'closql-database db) + (let (alist) + (dolist (slot (eieio-class-slots (eieio--object-class obj))) + (setq slot (cl--slot-descriptor-name slot)) + (let ((table (closql--slot-get obj slot :closql-table))) + (when table + (push (cons slot (closql-oref obj slot)) alist) + (closql--oset obj slot eieio-unbound)))) + (emacsql-with-transaction db + (emacsql db + (if replace + [:insert-or-replace-into $i1 :values $v2] + [:insert-into $i1 :values $v2]) + (oref-default obj closql-table) + (pcase-let ((`(,class ,_db . ,values) + (closql--intern-unbound + (closql--coerce obj 'list)))) + (vconcat (cons (closql--abbrev-class + (if (eieio--class-p class) + (eieio--class-name class) + class)) + values)))) + (pcase-dolist (`(,slot . ,value) alist) + (closql--dset db obj slot value)))) + obj) + +(cl-defmethod closql-delete ((obj closql-object)) + (let ((key (oref-default obj closql-primary-key))) + (emacsql (closql--oref obj 'closql-database) + [:delete-from $i1 :where (= $i2 $s3)] + (oref-default obj closql-table) + key + (closql--oref obj key)))) + +(cl-defmethod closql-reload ((obj closql-object)) + (or (closql-get (closql--oref obj 'closql-database) + (closql--oref obj (oref-default obj closql-primary-key)) + (eieio-object-class obj)) + (error "Cannot reload object"))) + +(cl-defmethod closql-get ((db closql-database) ident &optional class) + (unless class + (setq class (oref-default db object-class))) + (when-let ((row (car (emacsql db [:select * :from $i1 + :where (= $i2 $s3)] + (oref-default class closql-table) + (oref-default class closql-primary-key) + ident)))) + (closql--remake-instance class db row t))) + +(cl-defmethod closql-query ((db closql-database) &optional select pred class) + (if select + (let ((value (closql-select db select pred class))) + (if (and select (symbolp select)) + (mapcar #'car value) + value)) + (closql-entries db pred class))) + +(cl-defmethod closql-entries ((db closql-database) &optional pred class) + (unless class + (setq class (oref-default db object-class))) + (mapcar (lambda (row) + (closql--remake-instance class db row)) + (closql-select db '* pred class))) + +(cl-defmethod closql-select ((db closql-database) select &optional pred class) + (unless class + (setq class (oref-default db object-class))) + (emacsql db + (vconcat [:select $i1 :from $i2] + (and pred + [:where class :in $v3]) + (if-let ((order (oref-default class closql-order-by))) + (vector :order-by order) + [:order-by [(asc $i4)]])) + select + (oref-default class closql-table) + (and pred (closql-where-class-in pred)) + (oref-default class closql-primary-key))) + +(defun closql--table-columns (db table &optional prefixed) + (mapcar (if prefixed + (lambda (col) (intern (format "%s:%s" table (cadr col)))) + #'cadr) + (emacsql db (format "PRAGMA table_info(%s)" table)))) + +;;; Object/Row Conversion + +(cl-defmethod closql--remake-instance ((class (subclass closql-object)) + db row &optional resolve) + (pcase-let ((`(,abbrev . ,values) + (closql--extern-unbound row))) + (let* ((class-sym (closql--expand-abbrev class abbrev)) + (this (if (fboundp 'record) + (let* ((class-obj (eieio--class-object class-sym)) + (obj (copy-sequence + (eieio--class-default-object-cache + class-obj)))) + (setq values (apply #'vector (cons db values))) + (dotimes (i (length (eieio--class-slots class-obj))) + (aset obj (1+ i) (aref values i))) + obj) + (vconcat (list class-sym db) values)))) + (when resolve + (closql--resolve-slots this)) + this))) + +(cl-defmethod closql--resolve-slots ((obj closql-object)) + (dolist (slot (eieio-class-slots (eieio--object-class obj))) + (setq slot (cl--slot-descriptor-name slot)) + (when (and (not (slot-boundp obj slot)) + (or (closql--slot-get obj slot :closql-class) + (closql--slot-get obj slot :closql-table))) + (closql--oset obj slot (closql-oref obj slot))))) + +(defun closql--intern-unbound (row) + (mapcar (lambda (elt) + (if (eq elt eieio-unbound) 'eieio-unbound elt)) + row)) + +(defun closql--extern-unbound (row) + (mapcar (lambda (elt) + (if (eq elt 'eieio-unbound) eieio-unbound elt)) + row)) + +(defun closql--coerce (object type) + (cl-coerce (if (and (fboundp 'recordp) + (recordp object)) + (let* ((len (length object)) + (vec (make-vector len -1))) + (dotimes (i len) + (aset vec i (aref object i))) + vec) + object) + type)) + +(cl-defmethod closql--abbrev-class ((class-tag symbol)) + ;; This other method is only used for old-school eieio-class-tag--*. + (closql--abbrev-class (intern (substring (symbol-name class-tag) 17)))) + +(cl-defmethod closql--abbrev-class ((class (subclass closql-object))) + (let ((name (symbol-name class)) + (prefix (oref-default class closql-class-prefix)) + (suffix (oref-default class closql-class-suffix))) + (intern (substring name + (if prefix (length prefix) 0) + (if suffix (- (length suffix)) nil))))) + +(cl-defmethod closql--expand-abbrev ((class (subclass closql-object)) abbrev) + (intern (concat (and (not (fboundp 'record)) "eieio-class-tag--") + (oref-default class closql-class-prefix) + (symbol-name abbrev) + (oref-default class closql-class-suffix)))) + +(defun closql--where-equal (value offset) + (vector + (cons 'and + (mapcar (lambda (v) + (if v + (list '= + (intern (format "$i%i" (cl-incf offset))) + (intern (format "$s%i" (cl-incf offset)))) + (list 'isnull + (intern (format "$i%i" (1- (cl-incf offset 2))))))) + value)))) + +(defun closql-where-class-in (classes) + (vconcat + (mapcar 'closql--abbrev-class + (cl-mapcan (lambda (sym) + (let ((str (symbol-name sym))) + (cond ((string-match-p "--eieio-childp\\'" str) + (closql--list-subclasses + (intern (substring str 0 -14)) nil)) + ((string-match-p "-p\\'" str) + (list (intern (substring str 0 -2)))) + (t + (list sym))))) + (if (listp classes) classes (list classes)))))) + +(defun closql--list-subclasses (class &optional result) + (unless (class-abstract-p class) + (cl-pushnew class result)) + (dolist (child (eieio--class-children (cl--find-class class))) + (setq result (closql--list-subclasses child result))) + result) + +(cl-defmethod closql--list-subabbrevs ((class (subclass closql-object)) + &optional wildcards) + (cl-labels + ((types + (class) + (let ((children (eieio--class-children (cl--find-class class))) + ;; An abstract base-class may violate its own naming rules. + (abbrev (ignore-errors (closql--abbrev-class class)))) + (nconc (and (not (class-abstract-p class)) (list abbrev)) + (and wildcards children + (list (if abbrev (intern (format "%s*" abbrev)) '*))) + (cl-mapcan #'types children))))) + (sort (types class) #'string<))) + +(cl-defmethod closql--set-object-class ((db closql-database) obj class) + (let* ((table (oref-default obj closql-table)) + (key (oref-default obj closql-primary-key)) + (id (closql--oref obj key))) + (aset obj 0 + (if (fboundp 'record) + (aref (copy-sequence + (eieio--class-default-object-cache + (eieio--class-object class))) + 0) + (intern (format "eieio-class-tag--%s" class)))) + (emacsql db [:update $i1 :set (= class $s2) :where (= $i3 $s4)] + table + (closql--abbrev-class class) + key id))) + +;;; Experimental + +(defun closql--iref (obj slot) + (pcase-let* + ((db (closql--oref obj 'closql-database)) + (`(,d-table ,i-table) + (closql--slot-tables obj slot)) + (d-cols (closql--table-columns db d-table)) + (i-cols (closql--table-columns db i-table)) + (obj-id (closql--oref obj (oref-default obj closql-primary-key)))) + (emacsql db (format "\ +SELECT DISTINCT %s FROM %s AS d, %s AS i +WHERE d.%s = i.%s AND d.%s = '%S';" + (mapconcat (apply-partially #'format "i.%s") + (cddr i-cols) ", ") + d-table + i-table + (cadr d-cols) + (cadr i-cols) + (car d-cols) + obj-id)))) + +(defun closql--slot-tables (obj slot) + (let ((tbls (closql--slot-get obj slot :closql-table))) + (unless (listp tbls) + (error "%s isn't an indirect slot" slot)) + (pcase-let ((`(,d-tbl ,i-tbl) tbls)) + (list (intern (replace-regexp-in-string "-" "_" (symbol-name d-tbl))) + (intern (replace-regexp-in-string "-" "_" (symbol-name i-tbl))))))) + +;;; Utilities + +(defun closql-format (object string &rest slots) + "Format a string out of a format STRING and an OBJECT's SLOTS. + +STRING is a format-string like for `format'. OBJECT is an Eieio +object and SLOTS are slots of that object, their values are used +like `format' uses its OBJECTS arguments (which are unrelated to +this function's OBJECT argument, they just have similar names). + +While this function does not have much to do with the purpose of +`closql', it is being defined here anyway because Eieio does not +define a similar function under a more appropriate name such as +`eieio-format'." + (apply #'format string + (mapcar (lambda (slot) (eieio-oref object slot)) slots))) + +;;; _ +(provide 'closql) +;; Local Variables: +;; indent-tabs-mode: nil +;; End: +;;; closql.el ends here diff --git a/packages/cmake-ide-20181023.1430.el b/packages/cmake-ide-20190731.1009.el similarity index 90% rename from packages/cmake-ide-20181023.1430.el rename to packages/cmake-ide-20190731.1009.el index 72a3d57..0b7f4d5 100644 --- a/packages/cmake-ide-20181023.1430.el +++ b/packages/cmake-ide-20190731.1009.el @@ -4,7 +4,7 @@ ;; Author: Atila Neves ;; Version: 0.6 -;; Package-Version: 20181023.1430 +;; Package-Version: 20190731.1009 ;; Package-Requires: ((emacs "24.4") (cl-lib "0.5") (seq "1.11") (levenshtein "0") (s "1.11.0")) ;; Keywords: languages ;; URL: http://github.com/atilaneves/cmake-ide @@ -226,6 +226,16 @@ the closest possible matches available in cppcheck." "Whether or not to try all unique compiler flags for header files." ) +(defvar cmake-sentinel-flag + nil + "One interactive execution is allowed at the same time." + ) + +(defvar cmake-temp-project-dir + nil + "The project dir is kept while the sentinel works." + ) + (defun cide--make-hash-table () "Make a hash table with equal for the test function." (make-hash-table :test #'equal)) @@ -290,11 +300,11 @@ the closest possible matches available in cppcheck." "Run CMake if the compilation database JSON file is not found." (interactive) (when (cide--locate-project-dir) - (cmake-ide-maybe-start-rdm) - (if (cide--need-to-run-cmake) - (cmake-ide-run-cmake) - (progn - (cide--add-file-to-buffer-list) + (cmake-ide-maybe-start-rdm) + (if (cide--need-to-run-cmake) + (cmake-ide-run-cmake) + (progn + (cide--add-file-to-buffer-list) (cide--on-cmake-finished))))) (defun cide--add-file-to-buffer-list () @@ -320,23 +330,29 @@ This works by calling cmake in a temporary directory (or `cmake-ide-build-dir') and parsing the JSON file deposited there with the compiler flags." (interactive) - (when (buffer-file-name) ; if we call cmake-ide-run-cmake from a scatch buffer, do nothing - (when (file-readable-p (buffer-file-name)) ; new files need not apply - (save-some-buffers 1) - (let ((project-dir (cide--locate-project-dir))) - (if project-dir ; no point if it's not a CMake project - ;; register this buffer to be either a header or source file - ;; waiting for results - (progn - (cide--add-file-to-buffer-list) - ;; run cmake only if project dir contains a CMakeLists.txt file. - (if (cide--locate-cmakelists) - (let ((cmake-dir (cide--build-dir))) - (let ((default-directory cmake-dir)) - (cide--run-cmake-impl project-dir cmake-dir) - (cide--register-callback))) - (cide--message "No CMakeLists.txt found in project dir, skip cmake run."))) - (cide--message "try to run cmake on a non cmake project [%s]" default-directory)))))) + (if (not cmake-sentinel-flag) + (when (buffer-file-name) ; if we call cmake-ide-run-cmake from a scatch buffer, do nothing + (when (file-readable-p (buffer-file-name)) ; new files need not apply + (save-some-buffers 1) + (let ((project-dir (cide--locate-project-dir))) + (if project-dir ; no point if it's not a CMake project + (if (not (file-exists-p (expand-file-name "CMakeCache.txt" project-dir))) + ;; register this buffer to be either a header or source file + ;; waiting for results + (progn + (cide--add-file-to-buffer-list) + ;; run cmake only if project dir contains a CMakeLists.txt file. + (if (cide--locate-cmakelists) + (let ((cmake-dir (cide--build-dir))) + (let ((default-directory cmake-dir)) + (cide--run-cmake-impl project-dir cmake-dir) + (cide--register-callback) + (setq cmake-temp-project-dir project-dir) + (setq cmake-sentinel-flag t))) + (cide--message "No CMakeLists.txt found in project dir, skip cmake run."))) + (cide--message "CMakeCache.txt found in project dir, skip cmake run.")) + (cide--message "try to run cmake on a non cmake project [%s]" default-directory))))) + (cide--message "Another cmake is already running, skip cmake run."))) (defun cide--message (str &rest vars) @@ -350,7 +366,9 @@ This works by calling cmake in a temporary directory (or `cmake-ide-build-dir') (cide--message "Finished running CMake") (if (= 0 (process-exit-status process)) ; only perform post cmake operation on success. (cide--on-cmake-finished) - (cide--message "CMake failed, see *cmake* for details."))))) + (cide--message "CMake failed, see *cmake* for details.")) + (setq cmake-sentinel-flag nil) + (setq cmake-temp-project-dir nil)))) (defun cide--register-a-callback (callback) "Register CALLBACK to be called when CMake finishes running." @@ -370,14 +388,16 @@ This works by calling cmake in a temporary directory (or `cmake-ide-build-dir') (defun cmake-ide-load-db () "Load compilation DB and set flags for current buffer." (interactive) - (when (cide--locate-project-dir) - (cide--message "cmake-ide-load-db for file %s" (buffer-file-name)) - (cmake-ide-maybe-start-rdm) - (let* ((file-name buffer-file-name) - (buffers (list (current-buffer))) - (cide--src-buffers (if (cide--is-src-file file-name) buffers nil)) - (cide--hdr-buffers (if (cide--is-src-file file-name) nil buffers))) - (cide--on-cmake-finished)))) + (if (not cmake-sentinel-flag) + (when (cide--locate-project-dir) + (cide--message "cmake-ide-load-db for file %s" (buffer-file-name)) + (cmake-ide-maybe-start-rdm) + (let* ((file-name buffer-file-name) + (buffers (list (current-buffer))) + (cide--src-buffers (if (cide--is-src-file file-name) buffers nil)) + (cide--hdr-buffers (if (cide--is-src-file file-name) nil buffers))) + (cide--on-cmake-finished))) + (cide--message "cmake is running, skip run."))) (defvar cide--rdm-executable nil "Rdm executable location path.") @@ -568,13 +588,15 @@ the object file's name just above." ret-file-name))) -(defun cide--get-string-from-file (path) - "Return PATH's file content." - (if (file-exists-p path) - (with-temp-buffer - (insert-file-contents path) - (buffer-string)) - "")) +(defun cide--read-file (path) + "Return PATH's file content as a string." + (if (stringp path) + (if (file-exists-p path) + (with-temp-buffer + (insert-file-contents path) + (buffer-string)) + "") + (cide--message "cide--read-file ERROR: %s is not a string" path))) (defun cide--set-flags-for-hdr-from-all-flags (idb buffer sys-includes) "Use IDB to set flags from a header BUFFER with SYS-INCLUDES from all project source files." @@ -663,26 +685,29 @@ the object file's name just above." (setq flycheck-clang-includes includes) (setq flycheck-gcc-includes includes) (flycheck-clear) - (run-at-time "0.5 sec" nil 'flycheck-buffer))))) + (when (bound-and-true-p flycheck-mode) + (run-at-time "0.5 sec" nil 'flycheck-buffer)))))) (defun cmake-ide-delete-file () "Remove file connected to current buffer and kill buffer, then run CMake." (interactive) - (when (cide--locate-project-dir) - (if (cide--build-dir) - (let ((filename (buffer-file-name)) - (buffer (current-buffer)) - (name (buffer-name))) - (if (not (and filename (file-exists-p filename))) - (error "Buffer '%s' is not visiting a file!" name) - (when (yes-or-no-p "Are you sure you want to remove this file? ") - (delete-file filename) - (kill-buffer buffer) - (let ((project-dir (cide--locate-project-dir))) - (when (and project-dir (file-exists-p (expand-file-name "CMakeLists.txt" project-dir))) - (cide--run-cmake-impl project-dir (cide--build-dir))) - (cide--message "File '%s' successfully removed" filename))))) - (error "Not possible to delete a file without setting cmake-ide-build-dir")))) + (if (not cmake-sentinel-flag) + (when (cide--locate-project-dir) + (if (cide--build-dir) + (let ((filename (buffer-file-name)) + (buffer (current-buffer)) + (name (buffer-name))) + (if (not (and filename (file-exists-p filename))) + (error "Buffer '%s' is not visiting a file!" name) + (when (yes-or-no-p "Are you sure you want to remove this file? ") + (delete-file filename) + (kill-buffer buffer) + (let ((project-dir (cide--locate-project-dir))) + (when (and project-dir (file-exists-p (expand-file-name "CMakeLists.txt" project-dir))) + (cide--run-cmake-impl project-dir (cide--build-dir))) + (cide--message "File '%s' successfully removed" filename))))) + (error "Not possible to delete a file without setting cmake-ide-build-dir"))) + (cide--message "cmake is running, skip run."))) (defun cide--run-cmake-impl (project-dir cmake-dir) @@ -692,7 +717,8 @@ the object file's name just above." (cide--message "Running cmake for src path %s in build path %s" project-dir cmake-dir) (apply 'start-process (append (list "cmake" "*cmake*" cmake-ide-cmake-command) (cide--cmake-args) - (list "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON" project-dir)))))) + (list "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON" + "-B" "." "-S" project-dir)))))) (defun cide--project-key () @@ -792,7 +818,7 @@ Return nil for non-CMake project." (defun cide--get-file-params (response-file) "Get file parameters from a response file given as compilation argument." - (replace-regexp-in-string "\\\n" " " (cide--get-string-from-file (expand-file-name response-file (cide--build-dir))))) + (replace-regexp-in-string "\\\n" " " (cide--read-file (expand-file-name response-file (cide--build-dir))))) (defun cide--quote-if-spaces (str) "Add quotes to STR if it has spaces." @@ -997,7 +1023,8 @@ CMakeLists.txt file. Return nil if not found." "Return the path to the project directory." (let ((cmakelists (cide--locate-cmakelists))) ;; if project dir is set by the user, use this value. - (or (and (cide--project-dir-var) (expand-file-name (cide--project-dir-var))) + (or cmake-temp-project-dir + (and (cide--project-dir-var) (expand-file-name (cide--project-dir-var))) (and cmakelists (file-name-directory cmakelists)) ; else try to use cmakelists dir nil ; if no CMakeLists.txt nor project-dir set, return nil and prevent cmake-ide to do anything else ))) @@ -1012,7 +1039,7 @@ computed IDBs, and if none are found actually performs the conversion." (cide--message "Non-existent compilation DB file %s" (cide--comp-db-file-name)) (progn (cide--message "Converting JSON CDB %s to IDB" (cide--comp-db-file-name)) - (setq idb (cide--cdb-json-string-to-idb (cide--get-string-from-file (cide--comp-db-file-name)))) + (setq idb (cide--cdb-json-string-to-idb (cide--read-file (cide--comp-db-file-name)))) (puthash (cide--build-dir) idb cide--cache-dir-to-idb) (puthash (cide--build-dir) (cide--hash-file (cide--comp-db-file-name)) cide--cache-dir-to-cdb-hash) (remhash (cide--build-dir) cide--cache-irony-dirs)))) @@ -1029,7 +1056,7 @@ computed IDBs, and if none are found actually performs the conversion." (defun cide--hash-file (file-name) "Calculate the hash of FILE-NAME." - (secure-hash 'md5 (cide--get-string-from-file file-name))) + (secure-hash 'md5 (cide--read-file file-name))) (defun cide--cdb-json-string-to-idb (json-str) "Tranform JSON-STR into an IDB. @@ -1091,7 +1118,7 @@ The IDB is hash mapping files to all JSON objects (usually only one) in the CDB. (let* ((base-name (file-name-nondirectory file-name)) (src-file-name (cide--idb-obj-get obj 'file))) (if (string-match (concat "# *include +[\"<] *" base-name) - (cide--get-string-from-file src-file-name)) + (cide--read-file src-file-name)) src-file-name nil))) @@ -1135,24 +1162,26 @@ The IDB is hash mapping files to all JSON objects (usually only one) in the CDB. (defun cmake-ide-compile () "Compile the project." (interactive) - (when (cide--locate-project-dir) - (if (cide--build-dir) - (let ((compile-command (cide--get-compile-command (cide--build-dir)))) - ;; compile-command could be nil, if so prompt for compile command (i.e. in a non-cmake project ...) - (if compile-command - (if (functionp compile-command) - (funcall compile-command) - (compile compile-command)) - (call-interactively compile-command))) - (call-interactively compile-command)) - (cide--run-rc))) + (if (not cmake-sentinel-flag) + (when (cide--locate-project-dir) + (if (cide--build-dir) + (let ((compile-command (cide--get-compile-command (cide--build-dir)))) + ;; compile-command could be nil, if so prompt for compile command (i.e. in a non-cmake project ...) + (if compile-command + (if (functionp compile-command) + (funcall compile-command) + (compile compile-command)) + (call-interactively compile-command))) + (call-interactively compile-command)) + (cide--run-rc)) + (cide--message "cmake is running, skip run."))) (defun cide--get-compile-command (dir) "Return the compile command to use for DIR." (cond (cmake-ide-compile-command cmake-ide-compile-command) - ((file-exists-p (expand-file-name "build.ninja" dir)) (concat cmake-ide-ninja-command " -C " dir)) - ((file-exists-p (expand-file-name "Makefile" dir)) (concat cmake-ide-make-command " -C " dir)) + ((file-exists-p (expand-file-name "build.ninja" dir)) (concat cmake-ide-ninja-command " -C " (shell-quote-argument dir))) + ((file-exists-p (expand-file-name "Makefile" dir)) (concat cmake-ide-make-command " -C " (shell-quote-argument dir))) (t nil))) @@ -1175,7 +1204,7 @@ The IDB is hash mapping files to all JSON objects (usually only one) in the CDB. (sleep-for 0.8) (set-process-query-on-exit-flag rdm-process nil))))))) - + (defun cide--process-running-p (name) "If a process called NAME is running or not." (or (get-process name) (cide--system-process-running-p name))) diff --git a/packages/cmake-mode-20180709.1426.el b/packages/cmake-mode-20190710.1319.el similarity index 97% rename from packages/cmake-mode-20180709.1426.el rename to packages/cmake-mode-20190710.1319.el index 25d6f5a..838cab0 100644 --- a/packages/cmake-mode-20180709.1426.el +++ b/packages/cmake-mode-20190710.1319.el @@ -1,5 +1,7 @@ ;;; cmake-mode.el --- major-mode for editing CMake sources -;; Package-Version: 20180709.1426 + +;; Package-Requires: ((emacs "24.1")) +;; Package-Version: 20190710.1319 ; Distributed under the OSI-approved BSD 3-Clause License. See accompanying ; file Copyright.txt or https://cmake.org/licensing for details. @@ -225,17 +227,11 @@ the indentation. Otherwise it retains the same position on the line" ;; (defvar cmake-mode-hook nil) -;------------------------------------------------------------------------------ - -;; For compatibility with Emacs < 24 -(defalias 'cmake--parent-mode - (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode)) - ;;------------------------------------------------------------------------------ ;; Mode definition. ;; ;;;###autoload -(define-derived-mode cmake-mode cmake--parent-mode "CMake" +(define-derived-mode cmake-mode prog-mode "CMake" "Major mode for editing CMake source files." ; Setup font-lock mode. diff --git a/packages/color-identifiers-mode-20181011.2114.el b/packages/color-identifiers-mode-20190805.1455.el similarity index 99% rename from packages/color-identifiers-mode-20181011.2114.el rename to packages/color-identifiers-mode-20190805.1455.el index 0bcec3e..6a94cbf 100644 --- a/packages/color-identifiers-mode-20181011.2114.el +++ b/packages/color-identifiers-mode-20190805.1455.el @@ -4,7 +4,7 @@ ;; Author: Ankur Dave ;; Url: https://github.com/ankurdave/color-identifiers-mode -;; Package-Version: 20181011.2114 +;; Package-Version: 20190805.1455 ;; Created: 24 Jan 2014 ;; Version: 1.1 ;; Keywords: faces, languages @@ -45,6 +45,9 @@ (defgroup color-identifiers nil "Color identifiers based on their names." :group 'faces) +(defvar color-identifiers:timer nil + "Timer for running `color-identifiers:refresh'.") + ;;;###autoload (define-minor-mode color-identifiers-mode "Color the identifiers in the current buffer based on their names." @@ -572,9 +575,6 @@ For Emacs Lisp support within color-identifiers-mode." ;;; PACKAGE INTERNALS ========================================================== -(defvar color-identifiers:timer nil - "Timer for running `color-identifiers:refresh'.") - (defvar color-identifiers:colors nil "List of generated hex colors for internal use.") @@ -767,7 +767,7 @@ evaluates to true." (and flface-prop (memq flface-prop identifier-faces))) (get-text-property (point) 'color-identifiers:fontified))) (goto-char (next-property-change (point) nil limit)) - (if (not (and (looking-back identifier-context-re nil) + (if (not (and (looking-back identifier-context-re (line-beginning-position)) (or (not identifier-exclusion-re) (not (looking-at identifier-exclusion-re))) (looking-at identifier-re))) (progn diff --git a/packages/color-theme-sanityinc-solarized-20181021.2055.tar b/packages/color-theme-sanityinc-solarized-20190206.59.tar similarity index 89% rename from packages/color-theme-sanityinc-solarized-20181021.2055.tar rename to packages/color-theme-sanityinc-solarized-20190206.59.tar index 0cffd3a..ebb1004 100644 Binary files a/packages/color-theme-sanityinc-solarized-20181021.2055.tar and b/packages/color-theme-sanityinc-solarized-20190206.59.tar differ diff --git a/packages/color-theme-sanityinc-tomorrow-20181024.1728.tar b/packages/color-theme-sanityinc-tomorrow-20190819.2324.tar similarity index 89% rename from packages/color-theme-sanityinc-tomorrow-20181024.1728.tar rename to packages/color-theme-sanityinc-tomorrow-20190819.2324.tar index e652429..3f564d3 100644 Binary files a/packages/color-theme-sanityinc-tomorrow-20181024.1728.tar and b/packages/color-theme-sanityinc-tomorrow-20190819.2324.tar differ diff --git a/packages/common-lisp-snippets-20180226.1523.tar b/packages/common-lisp-snippets-20180226.1523.tar index 15238d3..8cb1ee9 100644 Binary files a/packages/common-lisp-snippets-20180226.1523.tar and b/packages/common-lisp-snippets-20180226.1523.tar differ diff --git a/packages/company-20181105.2312.tar b/packages/company-20190821.658.tar similarity index 95% rename from packages/company-20181105.2312.tar rename to packages/company-20190821.658.tar index 8602049..2f78d7d 100644 Binary files a/packages/company-20181105.2312.tar and b/packages/company-20190821.658.tar differ diff --git a/packages/company-ansible-20180701.1813.tar b/packages/company-ansible-20190301.2111.tar similarity index 79% rename from packages/company-ansible-20180701.1813.tar rename to packages/company-ansible-20190301.2111.tar index 911ad0c..3dfaaba 100644 Binary files a/packages/company-ansible-20180701.1813.tar and b/packages/company-ansible-20190301.2111.tar differ diff --git a/packages/company-cabal-20170917.1317.tar b/packages/company-cabal-20170917.1317.tar index fef1aeb..6a69626 100644 Binary files a/packages/company-cabal-20170917.1317.tar and b/packages/company-cabal-20170917.1317.tar differ diff --git a/packages/company-coq-20181107.2136.tar b/packages/company-coq-20190425.1851.tar similarity index 83% rename from packages/company-coq-20181107.2136.tar rename to packages/company-coq-20190425.1851.tar index 4f104c5..3a753cd 100644 Binary files a/packages/company-coq-20181107.2136.tar and b/packages/company-coq-20190425.1851.tar differ diff --git a/packages/company-dcd-20170516.910.el b/packages/company-dcd-20190116.256.el similarity index 61% rename from packages/company-dcd-20170516.910.el rename to packages/company-dcd-20190116.256.el index e34952f..15cbc51 100644 --- a/packages/company-dcd-20170516.910.el +++ b/packages/company-dcd-20190116.256.el @@ -1,8 +1,8 @@ -;;; company-dcd.el --- Company backend for Dlang using DCD. +;;; company-dcd.el --- Company backend for Dlang using DCD. -*- lexical-binding: t -*- ;; Author: tsukimizake ;; Version: 0.1 -;; Package-Version: 20170516.910 +;; Package-Version: 20190116.256 ;; Package-Requires: ((company "0.9") (flycheck-dmd-dub "0.7") (yasnippet "0.8") (popwin "0.7") (cl-lib "0.5") (ivy "20160804.326")) ;; Keywords: languages ;; URL: http://github.com/tsukimizake/company-dcd @@ -71,7 +71,7 @@ You can't put port number flag here. Set `company-dcd--server-port' instead." (defconst company-dcd--server-buffer-name "*dcd-server*") (defconst company-dcd--error-buffer-name "*dcd-error*") -(defconst company-dcd--output-buffer-name "*dcd-output*") +(defconst company-dcd--output-buffer-name-template "*dcd-output-%d*") (defconst company-dcd--documentation-buffer-name "*dcd-document*") (defcustom company-dcd-server-executable @@ -80,23 +80,41 @@ You can't put port number flag here. Set `company-dcd--server-port' instead." :group 'company-dcd :type 'file) -(defcustom company-dcd--server-port 9166 - "Port number of dcd-server. The default is 9166." - :group 'company-dcd) +(defcustom company-dcd-server-address nil + "Port number / UNIX socket path of dcd-server. + +Possible values: +- nil - use DCD's default connection method +- a number - use this TCP port (DCD's default is 9166) +- a string - use this UNIX socket path + +The default is nil." + :group 'company-dcd + :type '(choice + (const :tag "Use platform default" nil) + (integer :tag "Use this TCP port number") + (file :tag "Use this UNIX socket path"))) + +(define-obsolete-variable-alias 'company-dcd--server-port 'company-dcd-server-address) (defvar company-dcd--delay-after-kill-process 200 "Duration to wait after killing the server process, in milliseconds. If `company-dcd-restart-server' does not work correctly, please set this variable to a bigger number.") -(defvar company-dcd--version nil - "Version of dcd-server. This variable is automatically set when company-dcd--get-version is called.") +(defvar company-dcd--counter 0 + "Client request counter. Incremented to uniquely identify requests.") (defcustom company-dcd--ignore-template-argument nil "If non-nil, ignore template argument of calltip candidate." - :group 'company-dcd) + :group 'company-dcd + :type 'boolean) ;; Server management functions +(defun company-dcd--error (msg) + "Signal a company-dcd error with the given MSG." + (error (concat "company-dcd error: " msg))) + (defun company-dcd-stop-server () "Stop dcd-server manually. You shouldn't need to call this function directly. @@ -104,17 +122,27 @@ If you need to restart the server, use `company-dcd-restart-server' instead." (interactive) (interrupt-process "dcd-server")) +(defun company-dcd--server-address-flags () + "Return the client/server command line flags indicating the server address." + (cond + ((null company-dcd-server-address) '()) + ((numberp company-dcd-server-address) + (list "--tcp=true" "--port" (number-to-string company-dcd-server-address))) + ((stringp company-dcd-server-address) + (list "--tcp=false" "--socketFile" company-dcd-server-address)) + (t + (error "Invalid value of company-dcd-server-address (%S)" company-dcd-server-address)))) + (defun company-dcd--start-server () "Start dcd-server." (unless (executable-find company-dcd-server-executable) - (error "company-dcd error: dcd-server not found")) + (company-dcd--error "Could not find dcd-server")) (let (buf args proc) (setq buf (get-buffer-create company-dcd--server-buffer-name)) - (setq args (nconc (list company-dcd-server-executable - "-p" - (format "%s" company-dcd--server-port)) + (setq args (nconc (list company-dcd-server-executable) + (company-dcd--server-address-flags) company-dcd--flags)) (setq proc (with-current-buffer buf (apply 'start-process "dcd-server" (current-buffer) args))) @@ -137,32 +165,17 @@ If you need to restart the server, use `company-dcd-restart-server' instead." (when (company-dcd--server-is-alive-p) (company-dcd-stop-server) (sleep-for 0 company-dcd--delay-after-kill-process)) - (company-dcd--start-server) - (setq company-dcd--version nil)) - -(defun company-dcd--get-version () - "Get the version of dcd-server. Cache the value to `company-dcd--version'." - (if company-dcd--version - company-dcd--version - (progn - (let ((str (company-dcd--call-process '("--version"))) - verstr) - (unless str - (error "company-dcd error: Error obtaining dcd-server version")) - (string-match (rx "v" (submatch (* nonl)) (or "-" "\n")) str) - (setq verstr (match-string 1 str)) - (setq company-dcd--version (string-to-number verstr)) - )))) + (company-dcd--start-server)) ;; Output parsing functions -(defun company-dcd--parse-output-for-completion () - "Parse dcd output from a completion query. +(defun company-dcd--parse-output-for-completion (buffer) + "Parse dcd output from a completion query from BUFFER. Return a list of matches, where each match is a string, optionally with an attached `company-dcd--help' property containing the completion kind." - (with-current-buffer company-dcd--output-buffer-name + (with-current-buffer buffer (goto-char (point-min)) (let ((pattern company-dcd--completion-pattern) lines match detailed-info @@ -184,68 +197,92 @@ containing the completion kind." (rx (and (submatch (* nonl)) ": " (submatch (* nonl)) ": " (submatch (* nonl) eol))) "If this regexp matches the first line of dcd-client output, it indicates an error message.") -(defun company-dcd--handle-error (res args) - "Display error message from a failed dcd-client invocation with exit code RES and arguments ARGS." +(defun company-dcd--handle-error (outbuf err args) + "Display error message from a failed dcd-client invocation with buffer OUTBUF, error ERR, and arguments ARGS." (let* ((errbuf (get-buffer-create company-dcd--error-buffer-name)) - (outbuf (get-buffer company-dcd--output-buffer-name)) (cmd (concat company-dcd-client-executable " " (mapconcat 'identity args " "))) (errstr (with-current-buffer outbuf (goto-char (point-min)) - (re-search-forward company-dcd--error-message-regexp) - (concat - (match-string 2) " : " (match-string 3))) - )) + (if (re-search-forward company-dcd--error-message-regexp nil t) + (concat + (match-string 2) " : " (match-string 3)) + "(unknown)")))) (with-current-buffer errbuf (erase-buffer) - (insert (current-time-string) - "\n\"" cmd "\" failed." - (format "\nError type is: %s\n" errstr) - ) + (insert (format + "%s\n\"%s\" failed (%s).\nError type is: %s\n\ndcd-client output:\n\n%s" + (current-time-string) + cmd + err + errstr + (with-current-buffer outbuf (buffer-string)))) (goto-char (point-min))) (display-buffer errbuf))) -(defun company-dcd--output-buf-string () - "Return contents of dcd-output buffer." - (with-current-buffer company-dcd--output-buffer-name - (buffer-string))) - ;; Utility functions for process invocation -(defun company-dcd--call-process (args) - "Call dcd-client with ARGS and return output string. +(defun company-dcd--call-process (args send-buffer callback) + "Asynchronously call dcd-client with ARGS. Invoke CALLBACK with results. -The current buffer's contents is passed to dcd-client via stdin. -\(The entire buffer is sent, even if narrowed.\) +If SEND-BUFFER is non-nil, the current buffer's contents is +passed to dcd-client via stdin. (The entire buffer is sent, even +if narrowed.) -Returns the output from dcd-client, or nil if an error occurred." - (let ((buf (get-buffer-create company-dcd--output-buffer-name))) +CALLBACK is invoked as (BUFFER), where BUFFER is the buffer +holding the dcd-client output, or nil in case of error." + (let* ((index (cl-incf company-dcd--counter)) + (buf (get-buffer-create (format company-dcd--output-buffer-name-template index)))) (with-current-buffer buf (erase-buffer)) (if (executable-find company-dcd-client-executable) - ;; Execute dcd-client, get error code - (let ((res (apply 'call-process-region 1 (1+ (buffer-size)) - company-dcd-client-executable nil buf nil args))) - (with-current-buffer buf - (if (eq 0 res) - (buffer-string) ; Return output - (company-dcd--handle-error res args) - nil))) - - (message "company-dcd error: could not find dcd-client executable") - nil))) + (let ((process (make-process + :name (format "dcd-client-%d" index) + :buffer buf + :stderr buf + :command (cons company-dcd-client-executable args) + :noquery t + :sentinel + (lambda (_process event) + (when callback + (if (equal event "finished\n") + (funcall callback buf) + (funcall callback nil) + (company-dcd--handle-error buf (string-trim event) args)) + (setq callback nil) + (kill-buffer buf)))))) + (when send-buffer + (process-send-region process 1 (1+ (buffer-size)))) + (when (or send-buffer (process-live-p process)) + (process-send-eof process))) + (message "company-dcd error: could not find dcd-client executable")))) (defsubst company-dcd--cursor-position () "Get the current cursor position to pass to dcd-client." (1- (position-bytes (point)))) +(defun company-dcd--word-char-p (char) + "Return t if CHAR is a D word char (part of an identifier), nil otherwise." + (member (char-syntax char) '(?w ?_))) + +(defun company-dcd--symbol-position () + "Return a number representing a position of the symbol at point. + +The returned value is suitable for dcd-client queries which +operate on complete symbols, such as --symbolLocation and --doc." + (let ((pos (company-dcd--cursor-position))) + + ;; Work around https://github.com/Hackerpilot/DCD/issues/98 + (if (and (not (company-dcd--word-char-p (char-before (point)))) + (company-dcd--word-char-p (char-after (point)))) + (1+ pos) + pos))) + (defun company-dcd--build-args (&optional pos) "Build the argument list to pass to dcd-client. Optionally, pass POS as the --cursorPos argument if non-nil." (nconc - (list - "--port" - (format "%s" company-dcd--server-port)) + (company-dcd--server-address-flags) (when pos (list (concat "-I" default-directory) @@ -258,12 +295,17 @@ Optionally, pass POS as the --cursorPos argument if non-nil." ;; Interface functions to company-mode. -(defun company-dcd--get-candidates () - "Retrieve ordinary auto-completion candidates." +(defun company-dcd--get-candidates (callback) + "Retrieve ordinary auto-completion candidates. + +Invoke CALLBACK with candidates, or nil in case of error." (unless (company-dcd--in-string/comment) - (when (company-dcd--call-process - (company-dcd--build-args (company-dcd--cursor-position))) - (company-dcd--parse-output-for-completion)))) + (company-dcd--call-process + (company-dcd--build-args (company-dcd--cursor-position)) + t + (lambda (buf) + (funcall callback + (when buf (company-dcd--parse-output-for-completion buf))))))) (defun company-dcd--documentation (item) "Return a short documentation string of ITEM. @@ -297,7 +339,9 @@ highlighted. Currently this returns a string describing the item's kind." (defun company-dcd--action (lastcompl) "Post-completion action callback. -Used to display the argument list (calltips)." +Used to display the argument list (calltips). + +LASTCOMPL is the last completion, as received from company." ;; Q: Why run-with-timer? ;; A: See https://github.com/company-mode/company-mode/issues/320 (let ((candidate-type (company-dcd--get-help lastcompl))) @@ -321,32 +365,42 @@ Used to display the argument list (calltips)." (defvar company-dcd-mode nil) -(defun company-dcd (command &optional arg &rest ignored) - "The `company-mode' backend callback for DCD." +(defun company-dcd (command &optional arg &rest _ignored) + "The `company-mode' backend callback for DCD. + +COMMAND and ARG are the completion command and arguments." (interactive (list 'interactive)) (cl-case command (interactive (company-begin-backend 'company-dcd)) (prefix (and company-dcd-mode (company-grab-symbol))) - (candidates (company-dcd--get-candidates)) + (candidates (cons :async #'company-dcd--get-candidates)) (annotation (format " %s" (company-dcd--get-help arg))) (meta (company-dcd--documentation arg)) (post-completion (company-dcd--action arg)) - (doc-buffer (company-dcd--get-completion-documentation arg)) - (location (company-dcd--get-completion-location arg)))) + (doc-buffer (cons :async (lambda (callback) (company-dcd--get-completion-documentation arg callback)))) + (location (cons :async (lambda (callback) (company-dcd--get-completion-location arg callback)))))) ;; Function calltip expansion with yasnippet -(defun company-dcd--get-calltip-candidates () - "Return calltip completion candidates for the D symbol at point. +(defun company-dcd--get-calltip-candidates (callback) + "Get calltip completion candidates for the D symbol at point. The cursor must be at the end of a D symbol. -When the symbol is not a function, return nil." - (let ((buf (get-buffer-create company-dcd--output-buffer-name))) - (when (company-dcd--call-process-for-calltips) - (with-current-buffer buf (company-dcd--parse-calltips))))) +When the symbol is not a function, return nil. + +CALLBACK is invoked with the parsed calltips." + (company-dcd--call-process-for-calltips + (lambda (buf) + (funcall + callback + (when buf + (with-current-buffer buf + (company-dcd--parse-calltips))))))) -(defun company-dcd--call-process-for-calltips () - "Call process to get calltips of the function at point." +(defun company-dcd--call-process-for-calltips (callback) + "Call process to get calltips of the function at point. + +CALLBACK is invoked with the result buffer." (let ((src (buffer-string)) (pt (point))) (with-temp-buffer @@ -357,7 +411,8 @@ When the symbol is not a function, return nil." (backward-char 2) (company-dcd--call-process - (company-dcd--build-args (company-dcd--cursor-position)))))) + (company-dcd--build-args (company-dcd--cursor-position)) + t callback)))) (defconst company-dcd--normal-calltip-pattern @@ -365,14 +420,15 @@ When the symbol is not a function, return nil." "Regexp to parse calltip completion. \\1 is function return type (if exists) and name, and \\2 is args.") (defconst company-dcd--template-pattern (rx (submatch (* nonl)) (submatch "(" (*? nonl) ")") (submatch "(" (* nonl)")")) - "Regexp to parse template calltips. + "Regexp to parse template calltips. \\1 is function return type (if exists) and name, \\2 is template args, and \\3 is args.") (defconst company-dcd--calltip-pattern (rx (or (and bol (* nonl) "(" (* nonl) ")" eol) (and bol (* nonl) "(" (*? nonl) ")" "(" (* nonl)")" eol)))) (defcustom company-dcd--ignore-template-argument t "If non-nil, ignore template argument on calltip expansion." - :group 'company-dcd) + :group 'company-dcd + :type 'boolean) (defsubst company-dcd--cleanup-function-candidate (s) "Helper function for parsing calltips. @@ -448,14 +504,14 @@ Returns a list of calltip candidates." (if (company-dcd--candidate-is-template-p match) (progn (string-match company-dcd--template-pattern match) - (add-to-list 'lines (company-dcd--cleanup-function-candidate (format "%s%s" (match-string 1 match) (match-string 3 match)))) ;remove template argument + (push (company-dcd--cleanup-function-candidate (format "%s%s" (match-string 1 match) (match-string 3 match))) lines) ;remove template argument (unless company-dcd--ignore-template-argument (string-match company-dcd--template-pattern match) - (add-to-list 'lines (company-dcd--cleanup-template-candidate (format "%s!%s%s" (match-string 1 match) (match-string 2 match) (match-string 3 match))))) ; candidate with template argument + (push (company-dcd--cleanup-template-candidate (format "%s!%s%s" (match-string 1 match) (match-string 2 match) (match-string 3 match))) lines)) ; candidate with template argument ) (progn (string-match company-dcd--normal-calltip-pattern match) - (add-to-list 'lines (company-dcd--cleanup-function-candidate (format "%s%s" (match-string 1 match) (match-string 2 match))))) ; when it was not template argument + (push (company-dcd--cleanup-function-candidate (format "%s%s" (match-string 1 match) (match-string 2 match))) lines)) ; when it was not template argument )) lines )) @@ -477,7 +533,8 @@ Returns a list of calltip candidates." (defun company-dcd--calltip-action (lastcompl) "Post-completion callback: format and insert the calltip using yasnippet. -This function should be called at *dcd-output* buf." + +LASTCOMPL is the last completion, as received from company." (let* ((end (point)) (arg-beg (save-excursion (backward-sexp) @@ -499,23 +556,26 @@ This function should be called at *dcd-output* buf." (setq res (format "%s%s" (company-dcd--format-calltips template-args) res)))) (yas-expand-snippet res))) -(defun company-dcd--calltip-completion-available () - (if (company-dcd--get-calltip-candidates) - (company-grab-symbol) - nil)) +(defun company-dcd--calltip-completion-available (callback) + "`prefix' implementation for company-dcd calltips \"backends\". + +Invoke CALLBACK with prefix, or nil in case of error." + (company-dcd--get-calltip-candidates + (lambda (calltips) + (funcall callback (and calltips (company-grab-symbol)))))) -(defun company-dcd--calltips (command &optional arg &rest ignored) - "Company \"backend\" for DCD calltip completion." +(defun company-dcd--calltips (command &optional arg &rest _ignored) + "Company \"backend\" for DCD calltip completion. + +COMMAND and ARG are the completion command and arguments." (interactive (list 'interactive)) (cl-case command (interactive (company-begin-backend 'company-dcd--calltips)) - (prefix (company-dcd--calltip-completion-available)) - (candidates - (company-dcd--get-calltip-candidates) - ) + (prefix (cons :async #'company-dcd--calltip-completion-available)) + (candidates (cons :async #'company-dcd--get-calltip-candidates)) (post-completion (company-dcd--calltip-action arg)) - (doc-buffer (company-dcd--get-completion-documentation arg)) - (location (company-dcd--get-completion-location arg)))) + (doc-buffer (cons :async (lambda (callback) (company-dcd--get-completion-documentation arg callback)))) + (location (cons :async (lambda (callback) (company-dcd--get-completion-location arg callback)))))) ;; Struct constructor calltip expansion @@ -526,33 +586,41 @@ dcd-client outputs candidates which begin with \"this\" when completing struct c (while (search-forward "this" nil t) (replace-match struct-name))) -(defun company-dcd--get-calltip-candidate-for-struct-constructor (lastcompl) - "Almost the same as `company-dcd--get-calltip-candidates', but call `company-dcd--replace-this-to-struct-name' before parsing." - (let ((buf (get-buffer-create company-dcd--output-buffer-name))) - (company-dcd--call-process-for-calltips) - (with-current-buffer buf - (company-dcd--replace-this-to-struct-name lastcompl) - (company-dcd--parse-calltips)) - )) +(defun company-dcd--get-calltip-candidate-for-struct-constructor (lastcompl callback) + "`candidates' implementation for struct constructor \"backend\". + +Almost the same as `company-dcd--get-calltip-candidates', but +call `company-dcd--replace-this-to-struct-name' before parsing. + +LASTCOMPL is the last completion, as received from company. +Invoke CALLBACK with prefix, or nil in case of error." + (company-dcd--call-process-for-calltips + (lambda (buf) + (funcall + callback + (when buf + (with-current-buffer buf + (company-dcd--replace-this-to-struct-name lastcompl) + (company-dcd--parse-calltips))))))) -(defun company-dcd--calltips-for-struct-constructor (command &optional arg &rest ignored) - "Company \"backend\" for DCD struct/class constructor calltip completion." +(defun company-dcd--calltips-for-struct-constructor (command &optional arg &rest _ignored) + "Company \"backend\" for DCD struct/class constructor calltip completion. + +COMMAND and ARG are the completion command and arguments." (interactive (list 'interactive)) (cl-case command (interactive (company-begin-backend 'company-dcd--calltips)) - (prefix (company-dcd--calltip-completion-available)) - (candidates - (company-dcd--get-calltip-candidate-for-struct-constructor arg)) + (prefix (cons :async #'company-dcd--calltip-completion-available)) + (candidates (cons :async (lambda (callback) (company-dcd--get-calltip-candidate-for-struct-constructor arg callback)))) (post-completion (company-dcd--calltip-action arg)) - (doc-buffer (company-dcd--get-completion-documentation arg)) - (location (company-dcd--get-completion-location arg)))) + (doc-buffer (cons :async (lambda (callback) (company-dcd--get-completion-documentation arg callback)))) + (location (cons :async (lambda (callback) (company-dcd--get-completion-location arg callback)))))) ;; Documentation display (defun company-dcd--reformat-documentation () - "Prepare a documentation string for display. -Currently, it simply unescapes `\\n' unless it's in $(D ...) closure." + "Decode (unescape) the documentation text received from dcd-client." (with-current-buffer (get-buffer company-dcd--documentation-buffer-name) (goto-char (point-min)) (while (not (equal (point) (point-max))) @@ -560,48 +628,56 @@ Currently, it simply unescapes `\\n' unless it's in $(D ...) closure." ((looking-at (rx "\\n")) (delete-char 2) (insert "\n")) - ((looking-at (rx "$(")) ; skip D expr. - (forward-sexp 2)) - ) - (forward-char)) - )) + ((looking-at (rx "\\\\")) + (delete-char 1) + (forward-char)) + (t + (forward-char)))))) -(defun company-dcd--get-ddoc () +(defun company-dcd--get-ddoc (callback) "Retrieve symbol documentation using \"dcd-client --doc\". -Return nil on error or if the symbol is not documented." - (let ((args - (append - (company-dcd--build-args (company-dcd--cursor-position)) - '("--doc")))) - - (let ((result (company-dcd--call-process args))) - (when (and - result ; invocation succeeded - (string-match (rx (not (syntax whitespace))) - result)) ; result not empty (contains non-whitespace) - result)))) +Invoke CALLBACK with the result, or nil on error or if the symbol +is not documented." + (company-dcd--call-process + (append + (company-dcd--build-args (company-dcd--symbol-position)) + '("--doc")) + t + (lambda (buf) + (funcall + callback + (let ((result (and buf (with-current-buffer buf (buffer-string))))) + (when (and + result ; invocation succeeded + (string-match (rx (not (syntax whitespace))) + result)) ; result not empty (contains non-whitespace) + result)))))) (defun company-dcd-show-ddoc-with-buffer () "Display Ddoc of symbol at point using `display-buffer'." (interactive) - (let ((raw-doc (company-dcd--get-ddoc))) - (if raw-doc - (progn - (with-current-buffer (get-buffer-create company-dcd--documentation-buffer-name) - (erase-buffer) - (insert raw-doc)) - (company-dcd--reformat-documentation) - (display-buffer (get-buffer-create company-dcd--documentation-buffer-name))) - (message "No documentation for the symbol at point.")))) - - -(defun company-dcd--call-process-with-compl (lastcompl switch) + (company-dcd--get-ddoc + (lambda (raw-doc) + (if raw-doc + (progn + (with-current-buffer (get-buffer-create company-dcd--documentation-buffer-name) + (erase-buffer) + (insert raw-doc)) + (company-dcd--reformat-documentation) + (display-buffer (get-buffer-create company-dcd--documentation-buffer-name))) + (message "No documentation for the symbol at point."))))) + + +(defun company-dcd--call-process-with-compl (lastcompl switch callback) "Call dcd-client with a hypothetically-expanded completion candidate. -Create a temporary buffer, which is a copy of the current buffer but with -LASTCOMPL expanded. Execute DCD with the additional parameter SWITCH. -Return the result." +Create a temporary buffer, which is a copy of the current buffer +but with LASTCOMPL expanded. Execute DCD with the additional +parameter SWITCH. + +Invoke CALLBACK with the dcd-client output buffer, or nil in case +of error." (let ((src (buffer-string)) (pt (point))) (with-temp-buffer @@ -616,26 +692,36 @@ Return the result." (company-dcd--call-process (append (company-dcd--build-args (company-dcd--cursor-position)) - (list switch)))))) - -(defun company-dcd--get-completion-documentation (lastcompl) - "Company callback for displaying the documentation for a completion candidate." - (let ((raw-doc (company-dcd--call-process-with-compl lastcompl "--doc"))) - (when raw-doc - (company-doc-buffer - (with-current-buffer (get-buffer-create company-dcd--documentation-buffer-name) - (erase-buffer) - (insert raw-doc) - (company-dcd--reformat-documentation) - (buffer-string)))))) - + (list switch)) + t callback)))) + +(defun company-dcd--get-completion-documentation (lastcompl callback) + "Company callback for displaying the documentation for a completion candidate. + +LASTCOMPL is the last completion, as received from company. + +Invoke CALLBACK with the documentation string, or nil in case of error." + (company-dcd--call-process-with-compl + lastcompl "--doc" + (lambda (buf) + (funcall + callback + (when buf + (let ((raw-doc (with-current-buffer buf (buffer-string)))) + (company-doc-buffer + (with-current-buffer (get-buffer-create company-dcd--documentation-buffer-name) + (erase-buffer) + (insert raw-doc) + (company-dcd--reformat-documentation) + (buffer-string))))))))) ;; Go to definition ;; Thanks to jedi.el by Takafumi Arakaki (defcustom company-dcd--goto-definition-marker-ring-length 16 "Length of marker ring to store `company-dcd-goto-definition' call positions." - :group 'company-dcd) + :group 'company-dcd + :type 'integer) (defvar company-dcd--goto-definition-marker-ring (make-ring company-dcd--goto-definition-marker-ring-length) @@ -649,10 +735,10 @@ Return the result." "Goto the point where `company-dcd-goto-definition' was last called." (interactive) (if (ring-empty-p company-dcd--goto-definition-marker-ring) - (error "Marker ring is empty, can't pop") + (company-dcd--error "Marker ring is empty, can't pop") (let ((marker (ring-remove company-dcd--goto-definition-marker-ring 0))) (switch-to-buffer (or (marker-buffer marker) - (error "Buffer has been deleted"))) + (company-dcd--error "Buffer has been deleted"))) (goto-char (marker-position marker)) ;; Cleanup the marker so as to avoid them piling up. (set-marker marker nil nil)))) @@ -662,63 +748,65 @@ Return the result." (defun company-dcd-goto-definition () "Goto declaration of symbol at point." (interactive) - (when (company-dcd--call-process-for-symbol-declaration) - (let ((data (company-dcd--parse-output-for-get-symbol-declaration))) - (if data - (let ((file (company-dcd--position-data-file data)) - (offset (company-dcd--position-data-offset data))) - (company-dcd--goto-def-push-marker) - (unless (string= file "stdin") ; the declaration is in the current file - (find-file file)) - (goto-char (byte-to-position offset))) - (message "Not found"))))) - -(defun company-dcd--get-completion-location (lastcompl) - "Company callback for opening the definition for a completion candidate." - (when (company-dcd--call-process-with-compl lastcompl "--symbolLocation") - (let ((data (company-dcd--parse-output-for-get-symbol-declaration))) - (when data - (let* ((file (company-dcd--position-data-file data)) - (offset (company-dcd--position-data-offset data)) - (buffer (if (string= file "stdin") - (current-buffer) - (find-file-noselect file))) - (position (with-current-buffer buffer (byte-to-position offset)))) - (cons buffer position)))))) + (company-dcd--call-process-for-symbol-declaration + (lambda (buf) + (when buf + (let ((data (company-dcd--parse-output-for-get-symbol-declaration buf))) + (if data + (let ((file (company-dcd--position-data-file data)) + (offset (company-dcd--position-data-offset data))) + (company-dcd--goto-def-push-marker) + (unless (string= file "stdin") ; the declaration is in the current file + (find-file file)) + (goto-char (byte-to-position offset))) + (message "Not found"))))))) + +(defun company-dcd--get-completion-location (lastcompl callback) + "Company callback for opening the definition for a completion candidate. + +LASTCOMPL is the last completion, as received from company. +Invoke CALLBACK with (buffer . position), or nil in case of error." + (company-dcd--call-process-with-compl + lastcompl "--symbolLocation" + (lambda (buf) + (funcall + callback + (when buf + (let ((data (company-dcd--parse-output-for-get-symbol-declaration buf))) + (when data + (let* ((file (company-dcd--position-data-file data)) + (offset (company-dcd--position-data-offset data)) + (buffer (if (string= file "stdin") + (current-buffer) + (find-file-noselect file))) + (position (with-current-buffer buffer (byte-to-position offset)))) + (cons buffer position))))))))) ;; Utilities for goto-definition -(defun company-dcd--word-char-p (char) - "Return t if CHAR is a D word char (part of an identifier), nil otherwise." - (member (char-syntax char) '(?w ?_))) - -(defun company-dcd--call-process-for-symbol-declaration () - "Call process for `dcd-client --symbolLocation'." - (let ((pos (company-dcd--cursor-position))) - - ;; Work around https://github.com/Hackerpilot/DCD/issues/98 - (when (and - (not (company-dcd--word-char-p (char-before (point)))) - (company-dcd--word-char-p (char-after (point)))) - (setq pos (1+ pos))) +(defun company-dcd--call-process-for-symbol-declaration (callback) + "Call process for `dcd-client --symbolLocation'. - (company-dcd--call-process - (append (company-dcd--build-args pos) '("--symbolLocation"))))) +Invoke CALLBACK with the dcd-client output buffer, or nil in case +of error." + (company-dcd--call-process + (append (company-dcd--build-args (company-dcd--symbol-position)) + '("--symbolLocation")) + t callback)) -(defun company-dcd--parse-output-for-get-symbol-declaration () - "Parse output of `company-dcd--get-symbol-declaration'. +(defun company-dcd--parse-output-for-get-symbol-declaration (buf) + "Parse output of `company-dcd--get-symbol-declaration' from BUF. Output is a `company-dcd--position-data', whose `type' is nil." - (let ((buf (get-buffer-create company-dcd--output-buffer-name))) - (with-current-buffer buf - (goto-char (point-min)) - (if (not (string= "Not found\n" (buffer-string))) - (progn (re-search-forward (rx (submatch (* nonl)) "\t" (submatch (* nonl)) "\n")) - (make-company-dcd--position-data - :file (match-string 1) - :offset (1+ (string-to-number (match-string 2))))) - nil)) - )) + (with-current-buffer buf + (goto-char (point-min)) + (if (not (string= "Not found\n" (buffer-string))) + (progn (re-search-forward (rx (submatch (* nonl)) "\t" (submatch (* nonl)) "\n")) + (make-company-dcd--position-data + :file (match-string 1) + :offset (1+ (string-to-number (match-string 2))))) + nil)) + ) ;;; Symbol search. @@ -726,37 +814,46 @@ Output is a `company-dcd--position-data', whose `type' is nil." (rx (and bol (submatch (* nonl)) "\t" (submatch char) "\t" (submatch (* digit)) eol)) "Regex pattern to parse dcd output for symbol location.") -(defun company-dcd--parse-output-for-symbol-search () - "Return a list of company-dcd--position-data." - (with-current-buffer company-dcd--output-buffer-name +(defun company-dcd--parse-output-for-symbol-search (buf) + "Return a list of `company-dcd--position-data' from BUF." + (with-current-buffer buf (goto-char (point-min)) (let (res) (while (re-search-forward company-dcd--symbol-search-pattern nil t) - (add-to-list 'res - (make-company-dcd--position-data - :file (match-string 1) - :type (match-string 2) - :offset (string-to-number (match-string 3))) - )) + (push (make-company-dcd--position-data + :file (match-string 1) + :type (match-string 2) + :offset (string-to-number (match-string 3))) + res)) res))) -(defun company-dcd--call-process-for-symbol-search (str) - "Invoke dcd-client to find symbol STR." +(defun company-dcd--call-process-for-symbol-search (str callback) + "Invoke dcd-client to find symbol STR. + +Invoke CALLBACK with the dcd-client output buffer, or nil in case +of error." (let ((args (append (company-dcd--build-args) '("--search") (list str)))) - (company-dcd--call-process args))) + (company-dcd--call-process args t callback))) -(defun company-dcd--symbol-search (str) +(defun company-dcd--symbol-search (str callback) "Search symbol using DCD with query STR. -Return a list of `company-dcd--position-data' structs." - (when (company-dcd--call-process-for-symbol-search str) - (company-dcd--parse-output-for-symbol-search))) +Invoke CALLBACK with a list of `company-dcd--position-data' +structs, or nil in case of error." + (company-dcd--call-process-for-symbol-search + str + (lambda (buf) + (funcall + callback + (when buf + (company-dcd--parse-output-for-symbol-search buf)))))) (defun company-dcd--pos-data-to-ivy-candidate-string (pos-data) + "Convert `company-dcd--position-data' POS-DATA to Ivy candidate string." (with-current-buffer (company-dcd--find-file-of-pos-data pos-data) (company-dcd--goto-char-of-pos-data pos-data) (let ((line-string (company-dcd--line-string-at-pos))) @@ -768,6 +865,7 @@ Return a list of `company-dcd--position-data' structs." ))) (defun company-dcd--ivy-candidate-string-to-pos-data (str) + "Convert Ivy candidate string STR to `company-dcd--position-data'." (string-match (rx (submatch (* nonl)) ":" (submatch (* nonl)) ":" (submatch (* nonl)) "\n" (* nonl)) str) (let ((file (match-string 1 str)) (type (match-string 2 str)) @@ -775,12 +873,15 @@ Return a list of `company-dcd--position-data' structs." (make-company-dcd--position-data :file file :type type :offset offset))) (defun company-dcd--find-file-of-pos-data (pos-data) + "Return buffer corresponding to `company-dcd--position-data' POS-DATA, creating it if necessary." (find-file-noselect (company-dcd--position-data-file pos-data))) (defun company-dcd--goto-char-of-pos-data (pos-data) + "Place point according to `company-dcd--position-data' POS-DATA." (goto-char (byte-to-position (company-dcd--position-data-offset pos-data)))) (defun company-dcd--line-string-at-pos () + "Return the contents of the line at point as a plain string." (let ((beg (point-at-bol)) (end (point-at-eol))) (buffer-substring-no-properties beg end))) @@ -794,40 +895,47 @@ Else, read query." (read-string "Query: "))) (defun company-dcd-ivy-search-symbol () + "Begin symbol search using ivy-mode." (interactive) - (let* ((ivy-format-function 'ivy-format-function-arrow) - (query (company-dcd--read-query-or-region-str)) - (candidates (company-dcd--symbol-search query)) - (candidates-strlist (mapcar 'company-dcd--pos-data-to-ivy-candidate-string candidates)) - (res (company-dcd--ivy-candidate-string-to-pos-data (ivy-read "Search: " candidates-strlist)))) - (company-dcd--goto-def-push-marker) - (switch-to-buffer (company-dcd--find-file-of-pos-data res)) - (company-dcd--goto-char-of-pos-data res) - )) + (let ((ivy-format-function 'ivy-format-function-arrow) + (query (company-dcd--read-query-or-region-str))) + (company-dcd--symbol-search + query + (lambda (candidates) + (let* ((candidates-strlist (mapcar 'company-dcd--pos-data-to-ivy-candidate-string candidates)) + (res (company-dcd--ivy-candidate-string-to-pos-data (ivy-read "Search: " candidates-strlist)))) + (company-dcd--goto-def-push-marker) + (switch-to-buffer (company-dcd--find-file-of-pos-data res)) + (company-dcd--goto-char-of-pos-data res) + ))))) ;;; Automatic import path detection. (defvar company-dcd--imports-cache (make-hash-table :test #'equal) "A cache variable to store import paths from dub.") (defun company-dcd--get-project-dir () - "Get current dub project dir" + "Get current Dub project dir." (fldd--get-project-dir)) (defun company-dcd--get-include-dirs () - "Get include dir using dub." + "Get include dir using Dub." (fldd--get-dub-package-dirs)) (defun company-dcd--initialize-imports-cache () + "Initialize imports cache." (setq company-dcd--imports-cache (make-hash-table :test #'equal))) (defun company-dcd--delete-imports-cache () + "Clear imports cache." (interactive) (company-dcd--initialize-imports-cache)) (defun company-dcd--put-imports-cache (project-root-dir import-dirs) + "Add entry IMPORT-DIRS to imports cache for given PROJECT-ROOT-DIR." (puthash project-root-dir import-dirs company-dcd--imports-cache)) (defun company-dcd--get-imports-cache (project-root-dir) + "Query entry from imports cache for given PROJECT-ROOT-DIR." (gethash project-root-dir company-dcd--imports-cache)) (defun company-dcd--parent-directory (dir) @@ -889,8 +997,9 @@ If cache was found, use it instead of calling dub." (append (company-dcd--build-args) (company-dcd--find-imports-dmd) - cached-or-dub-imports - )))) + cached-or-dub-imports) + nil + (lambda (_buf))))) (defvar company-dcd-mode-map (make-keymap)) (define-key company-dcd-mode-map (kbd "C-c ?") 'company-dcd-show-ddoc-with-buffer) diff --git a/packages/company-emoji-20180925.2008.tar b/packages/company-emoji-20180925.2008.tar index f34317f..e38b0c6 100644 Binary files a/packages/company-emoji-20180925.2008.tar and b/packages/company-emoji-20180925.2008.tar differ diff --git a/packages/company-ghci-20160311.200.el b/packages/company-ghci-20190707.311.el similarity index 96% rename from packages/company-ghci-20160311.200.el rename to packages/company-ghci-20190707.311.el index 7cca1b6..24e3e54 100644 --- a/packages/company-ghci-20160311.200.el +++ b/packages/company-ghci-20190707.311.el @@ -2,7 +2,7 @@ ;; Author: Hector Orellana ;; Package-Requires: ((company "0.8.11") (haskell-mode "13")) -;; Package-Version: 20160311.200 +;; Package-Version: 20190707.311 ;; Package-X-Original-Version: 0.03 ;; This program is free software; you can redistribute it and/or modify @@ -38,7 +38,7 @@ (defun company-ghci/hoogle-info (symbol) "Use hoogle --info to search documentation of SYMBOL" (when (executable-find "hoogle") - (shell-command-to-string (format "hoogle --info %s" symbol)))) + (shell-command-to-string (format "hoogle --info \"%s\"" symbol)))) (defun company-ghci/repl-command (cmd) "Execute CMD in the ghci process." diff --git a/packages/company-go-20180427.1856.el b/packages/company-go-20190203.19.el similarity index 97% rename from packages/company-go-20180427.1856.el rename to packages/company-go-20190203.19.el index 118ae56..9d0532c 100644 --- a/packages/company-go-20180427.1856.el +++ b/packages/company-go-20190203.19.el @@ -4,7 +4,7 @@ ;; Author: nsf ;; Keywords: languages -;; Package-Version: 20180427.1856 +;; Package-Version: 20190203.19 ;; Package-Requires: ((company "0.8.0") (go-mode "1.0.0")) ;; No license, this code is under public domain, do whatever you want. @@ -19,15 +19,6 @@ (require 'go-mode) (require 'company) -;; Close gocode daemon at exit unless it was already running -(eval-after-load "go-mode" - '(progn - (let* ((user (or (getenv "USER") "all")) - (sock (format (concat temporary-file-directory "gocode-daemon.%s") user))) - (unless (file-exists-p sock) - (add-hook 'kill-emacs-hook #'(lambda () - (ignore-errors - (call-process company-go-gocode-command nil nil nil "close")))))))) (defgroup company-go nil "Completion back-end for Go." @@ -69,6 +60,20 @@ symbol is preceded by a \".\", ignoring `company-minimum-prefix-length'." :group 'company-go :type 'string) + +(defun company-go--close-daemon () + "Close gocode daemon." + (ignore-errors + (call-process company-go-gocode-command nil nil nil "close"))) + +;; Close gocode daemon at exit unless it was already running +(eval-after-load "go-mode" + '(progn + (let* ((user (or (getenv "USER") "all")) + (sock (format (concat temporary-file-directory "gocode-daemon.%s") user))) + (unless (file-exists-p sock) + (add-hook 'kill-emacs-hook #'company-go--close-daemon))))) + (defun company-go--invoke-autocomplete () (let ((code-buffer (current-buffer)) (gocode-args (append company-go-gocode-args diff --git a/packages/company-lsp-20181105.1644.el b/packages/company-lsp-20190612.1553.el similarity index 50% rename from packages/company-lsp-20181105.1644.el rename to packages/company-lsp-20190612.1553.el index b9f015e..a1a1afc 100644 --- a/packages/company-lsp-20181105.1644.el +++ b/packages/company-lsp-20190612.1553.el @@ -1,8 +1,8 @@ ;;; company-lsp.el --- Company completion backend for lsp-mode. -*- lexical-binding: t -*- -;; Version: 2.0.2 -;; Package-Version: 20181105.1644 -;; Package-Requires: ((emacs "25.1") (lsp-mode "3.4") (company "0.9.0") (s "1.2.0") (dash "2.11.0")) +;; Version: 2.1.0 +;; Package-Version: 20190612.1553 +;; Package-Requires: ((emacs "25.1") (lsp-mode "6.0") (company "0.9.0") (s "1.2.0") (dash "2.11.0")) ;; URL: https://github.com/tigersoldier/company-lsp ;; This program is free software: you can redistribute it and/or modify @@ -40,7 +40,7 @@ :prefix "company-lsp-" :group 'tools) -(defcustom company-lsp-cache-candidates 'auto +(defcustom company-lsp-cache-candidates nil "Whether or not to cache completion candidates. When set to 'auto, company-lsp caches the completion. It sends @@ -50,17 +50,59 @@ sorted or filtered as the server would for cached completion results. When set to t, company-mode caches the completion. It won't send -incremental completion requests to the server. +incremental completion requests to the server. Candidates are +filtered on client side. -When set to nil, results are not cached at all. The candidates -are always sorted and filtered by the server. Use this option if +When set to nil, results are not cached at all. Each incremental +completion will send requests to the server. Use this option if the server handles caching for incremental completion or -sorting/matching provided by the server is critical." +sorting/matching provided by the server is critical. If +`company-lsp-filter-candidates' is non-nil for the language +server, returned candidates are filtered by company-lsp. +Otherwise candidates are not filtered." :type '(choice (const :tag "Respect server response" auto) (const :tag "Always cache" t) (const :tag "Never cache" nil)) :group 'company-lsp) +(defcustom company-lsp-filter-candidates + ;; The server ID of bingo has been renamed to go-bingo. Keeping both for + ;; backward compatibility. + '((bingo . nil) + (ccls . nil) + (clangd . nil) + (cquery . nil) + (go-bingo . nil) + (gopls . nil) + (javacomp . nil) + (jdtls . nil) + (pyls . nil) + (rls . nil) + (t . t)) + "Whether or not to filter completion candidates returned by server. + +Some servers return unfiltered candidates while others do +server-side filtering. This option controls whether or not to +filter candidates on client-side when +`company-lsp-cache-candidates' is nil for the current server. This +option doesn't change the filtering behavior when +`company-lsp-cache-candidates' is set to auto or t. + +Value can be t, nil, or an alist. When set +to t, always filter candidates regardless of the current language +server. When set to candidates are never filtered. + +When set to an alist, the key is either a symbol of the server-id +defined by the LSP client for the server, or t that matches other +servers. The value is a boolean." + :type '(choice (const :tag "Always filter" t) + (const :tag "Never filter" nil) + (alist :tag "Depends on language server" + :key-type (choice (const :tag "Other servers" t) + (symbol :tag "Server ID")) + :value-type boolean)) + :group 'company-lsp) + (defcustom company-lsp-async t "Whether or not to use async operations to fetch data." :type 'boolean @@ -76,7 +118,12 @@ item with the snippet and use yas-snippet to expand it." :type 'boolean :group 'company-lsp) -(defcustom company-lsp-enable-recompletion nil +(defcustom company-lsp-enable-trigger-kind t + "Whether or not to populate triggerKind field in the completion request." + :type 'boolean + :group 'company-lsp) + +(defcustom company-lsp-enable-recompletion t "Whether or not to re-trigger completion for trigger characters. If set to non-nil, when company-lsp finishes completion, it checks if @@ -87,8 +134,63 @@ This is useful in cases such as 'std' is completed as 'std::' in C++." :type 'boolean :group 'company-lsp) +(defcustom company-lsp-enable-additional-text-edit t + "Whether or not to apply additional text edit. + +If set to non-nil, company-lsp will apply additional text edits +from the server. Otherwise, the additional text edits are +ignored." + :type 'boolean + :group 'company-lsp) + +(defcustom company-lsp-match-candidate-predicate #'company-lsp-match-candidate-flex + "Predicate function that determines whether a candidate matches given input. + +The function takes two parameters: CANDIDATE and PREFIX. +CANDIDATE is a string created by `company-lsp--make-candidate'. +PREFIX is the symbol before point that should be used for +filtering. If the function returns non-nil, CANDIDATE will +be presented in the completion list. + +Company-lsp provides two builtin predicates: +`company-lsp-match-candidate-prefix' and +`company-lsp-match-candidate-flex'." + :type 'function + :group 'company-lsp) + +(defconst company-lsp--trigger-kind-invoked 1 + "The completion is triggered by typing identifier or invoking `company-lsp'. + +Defined in LSP spec as CompletionTriggerKind.Invoked.") + +(defconst company-lsp--trigger-kind-trigger-character 2 + "The completion is triggered by typing a trigger character. + +Defined in LSP spec as CompletionTriggerKind.TriggerCharacter.") + +(defconst company-lsp--trigger-kind-incomplete 3 + "The completion is triggered by narrowing incomplete completion list. + +Defined in LSP spec as +CompletionTriggerKind.TriggerForIncompleteCompletions.") + (declare-function yas-expand-snippet "ext:yasnippet.el") +(defun company-lsp--get-config (config server-id) + "Get the CONFIG value for SERVER-ID. + +If CONFIG is a list in the form of (server-id . value), return +the value of key SERVER-ID. When there is no value of key +SERVER-ID, return the value of key t if it's present, or return +nil otherwise. + +If CONFIG is not a list, return it directly." + (if (listp config) + (if-let (server-config (assq server-id config)) + (cdr server-config) + (alist-get t config)) + config)) + (defvar company-lsp--snippet-functions '(("rust" . company-lsp--rust-completion-snippet)) "Alist of functions to insert our snippets for each language.") @@ -98,6 +200,10 @@ This is useful in cases such as 'std' is completed as 'std::' in C++." PREFIX is the prefix string. COMPLETION is a cache-item created by `company-lsp--cache-item-new'.") +(defvar-local company-lsp--last-request-id nil + "The last request ID for completion sent to the language + server. nil means no outstanding requests.") + (defun company-lsp--trigger-characters () "Return a list of completion trigger characters specified by server." (let ((provider (lsp--capability "completionProvider"))) @@ -208,9 +314,7 @@ It looks for function corresponding to the language in ITEM is a hashtable of the CompletionItem message. Return a string of the snippet to expand, or nil if no snippet is available." - (-when-let* ((language-id-fn (lsp--client-language-id (lsp--workspace-client lsp--cur-workspace))) - (language-id (funcall language-id-fn (current-buffer))) - (fn-cons (assoc language-id company-lsp--snippet-functions)) + (-when-let* ((fn-cons (assoc (lsp-buffer-language) company-lsp--snippet-functions)) (fn (cdr fn-cons))) (funcall fn item))) @@ -245,10 +349,18 @@ CANDIDATE is a string returned by `company-lsp--make-candidate'." (delete-region (- (point) (length candidate)) (point)) (insert prefix) (let* ((range (gethash "range" text-edit)) - (start-point (lsp--position-to-point (gethash "start" range))) (new-text-length (length insert-text))) + ;; No that the text edit start may not be equal to prefix/label start. + ;; For example jdtls can insert "java.util.List" for "java.uti". The + ;; prefix start is before "uti", while the text edit start is before + ;; "java". + ;; + ;; We need to adjust `start' to be the text edit start, because the + ;; snippet expansion below will replace text between `start' and point + ;; with insert-text again. + (setq start (lsp--position-to-point (gethash "start" range))) (lsp--apply-text-edit text-edit) - (goto-char (+ start-point new-text-length)))) + (goto-char (+ start new-text-length)))) ((and insert-text (not (eq insert-text-format 2))) (cl-assert (string-equal (buffer-substring-no-properties start (point)) label)) (goto-char start) @@ -256,7 +368,7 @@ CANDIDATE is a string returned by `company-lsp--make-candidate'." (insert insert-text))) (let ((start-marker (set-marker (make-marker) start))) - (when additional-text-edits + (when (and additional-text-edits company-lsp-enable-additional-text-edit) (lsp--apply-text-edits additional-text-edits)) (when (and company-lsp-enable-snippet (fboundp 'yas-expand-snippet)) @@ -310,21 +422,90 @@ Return a list of strings as the completion candidates." ((sequencep response) response))) (candidates (mapcar (lambda (item) (company-lsp--make-candidate item prefix)) - (lsp--sort-completions items)))) + (lsp--sort-completions items))) + (server-id (lsp--client-server-id (lsp--workspace-client lsp--cur-workspace))) + (should-filter (or (eq company-lsp-cache-candidates t) + (and (null company-lsp-cache-candidates) + (company-lsp--get-config company-lsp-filter-candidates server-id))))) (when (null company-lsp--completion-cache) - (add-hook 'company-completion-cancelled-hook #'company-lsp--cleanup-cache) - (add-hook 'company-completion-finished-hook #'company-lsp--cleanup-cache)) + (add-hook 'company-completion-cancelled-hook #'company-lsp--cleanup-cache nil t) + (add-hook 'company-completion-finished-hook #'company-lsp--cleanup-cache nil t)) (when (eq company-lsp-cache-candidates 'auto) ;; Only cache candidates on auto mode. If it's t company caches the ;; candidates for us. (company-lsp--cache-put prefix (company-lsp--cache-item-new candidates incomplete))) - candidates)) + (if should-filter + (company-lsp--filter-candidates candidates prefix) + candidates))) + +(defun company-lsp--filter-candidates (candidates prefix) + "Filter CANDIDATES by PREFIX. + +CANDIDATES are a list of strings of candidate labels created by +`company-lsp--make-candidate'. + +Returns a new list of candidates." + ;; TODO: Allow customizing matching functions to support fuzzy matching. + ;; Consider supporting company-flx out of box. + (let (resort) + (--> candidates + ;; candidate -> (score matched candidate) + (mapcar (lambda (candidate) + (let ((match (funcall company-lsp-match-candidate-predicate candidate prefix))) + (if (consp match) + (progn + (setq resort t) + (list (car match) (cdr match) candidate)) + (list -1 match candidate)))) + it) + (-filter (lambda (item) + (nth 1 item)) + it) + (if resort + (sort it (lambda (a b) (< (car a) (car b)))) + it) + (mapcar (lambda (item) (nth 2 item)) + it)))) + +(defun company-lsp-match-candidate-prefix (candidate prefix) + "Return non-nil if the filter text of CANDIDATE starts with PREFIX. + +The match is case-insensitive." + (s-starts-with-p prefix (company-lsp--candidate-filter-text candidate) t)) + +(defun company-lsp-match-candidate-flex (candidate prefix) + "Return non-nil if the filter text of CANDIDATE matches PREFIX. + +See `company-lsp--compute-flex-match' for more details." + (company-lsp--compute-flex-match (company-lsp--candidate-filter-text candidate) + prefix + t)) + +(defun company-lsp--candidate-filter-text (candidate) + "Return filter string of CANDIDATE. + +CANDIDATE is a string created by `company-lsp--make-candidate'. +If the CompletionItem of CANDIDATE has filterText field, return +the value of filterText. Otherwise return CANDIDATE itself." + (let* ((candidate-item (company-lsp--candidate-item candidate)) + (filter-text (gethash "filterText" candidate-item))) + (or filter-text candidate))) (defun company-lsp--cleanup-cache (_) "Clean up completion cache and company hooks." (setq company-lsp--completion-cache nil) - (remove-hook 'company-completion-finished-hook #'company-lsp--cleanup-cache) - (remove-hook 'company-completion-cancelled-hook #'company-lsp--cleanup-cache)) + (remove-hook 'company-completion-finished-hook #'company-lsp--cleanup-cache t) + (remove-hook 'company-completion-cancelled-hook #'company-lsp--cleanup-cache t)) + +(defun company-lsp--cancel-outstanding-request () + "Cancels outstanding completion requests. + +A cancel command with `company-lsp--last-request-id' will be sent +to the server. `company-lsp--last-request-id' is reset to nil +after cancellation." + (when company-lsp--last-request-id + (lsp--cancel-request company-lsp--last-request-id) + (setq company-lsp--last-request-id nil))) (defun company-lsp--cache-put (prefix candidates) "Set cache for PREFIX to be CANDIDATES. @@ -338,24 +519,34 @@ CANDIDATES is a cache item created by `company-lsp--cache-item-new'." "Get the cached completion for PREFIX. Return a cache item if cache for PREFIX exists. Otherwise return nil." - (let ((cache (cdr (assoc prefix company-lsp--completion-cache))) - (len (length prefix)) - previous-cache) - (if cache - cache - (cl-dotimes (i len) - (when (setq previous-cache - (cdr (assoc (substring prefix 0 (- len i 1)) - company-lsp--completion-cache))) - (if (company-lsp--cache-item-incomplete-p previous-cache) - (cl-return nil) - ;; TODO: Allow customizing matching functions to support fuzzy matching. - ;; Consider supporting company-flx out of box. - (let* ((previous-candidates (company-lsp--cache-item-candidates previous-cache)) - (new-candidates (all-completions prefix previous-candidates)) - (new-cache (company-lsp--cache-item-new new-candidates nil))) - (company-lsp--cache-put prefix new-cache) - (cl-return new-cache)))))))) + (-when-let* ((cached (company-lsp--cache-find-closest prefix)) + (subprefix (car cached)) + (cache-item (cdr cached))) + (cond + ((string= prefix subprefix) + ;; Found exact match. + cache-item) + ((company-lsp--cache-item-incomplete-p cache-item) + ;; Closest subprefix has incomplete result. Return nil to ask for narrowed + ;; down results. + nil) + (t + ;; Narrow down complete results for subprefix. + (let* ((candidates (company-lsp--cache-item-candidates cache-item)) + (new-candidates (company-lsp--filter-candidates candidates prefix)) + (new-cache (company-lsp--cache-item-new new-candidates nil))) + (company-lsp--cache-put prefix new-cache) + new-cache))))) + +(defun company-lsp--cache-find-closest (prefix) + "Find cached completion with the longest sub-prefix of PREFIX. + +Return a cons cell of (subprefix . cache-item) or nil." + (let ((len (length prefix))) + (cl-dotimes (i (1+ len)) + (when-let (item (assoc (substring prefix 0 (- len i)) + company-lsp--completion-cache)) + (cl-return item))))) (defun company-lsp--cache-item-new (candidates incomplete) "Create a new cache item. @@ -382,10 +573,8 @@ which company can handle." (let* ((resolved-candidate (company-lsp--resolve-candidate candidate "documentation")) (item (company-lsp--candidate-item resolved-candidate)) (documentation (gethash "documentation" item))) - (if - (hash-table-p documentation) ;; If true, then the documentation is a MarkupContent. String otherwise. - (gethash "value" documentation) - documentation))) + (when documentation + (lsp--render-element documentation)))) (defun company-lsp--candidates-sync (prefix) "Get completion candidates synchronously. @@ -393,55 +582,166 @@ which company can handle." PREFIX is the prefix string for completion. Return a list of strings as completion candidates." - (let ((req (lsp--make-request "textDocument/completion" - (lsp--text-document-position-params)))) - (company-lsp--on-completion (lsp--send-request req) prefix))) + (company-lsp--on-completion + (lsp--send-request (company-lsp--make-completion-request prefix)) + prefix)) (defun company-lsp--candidates-async (prefix callback) "Get completion candidates asynchronously. PREFIX is the prefix string for completion. CALLBACK is a function that takes a list of strings as completion candidates." - (let ((req (lsp--make-request "textDocument/completion" - (lsp--text-document-position-params)))) - (lsp--send-request-async req - (lambda (resp) - (funcall callback (company-lsp--on-completion resp prefix)))))) - -(defun company-lsp--compute-match (candidate) - "Compute the matched parts of CANDIDATE. - -CANDIDATE is a string of the candidate label. - -Return an alist of (CHUNK-START . CHUNK-END), representing parts -within CANDIDATE that matches the current prefix. See the -\"match\" section of `company-backends' for more info." - (let* ((prefix (company-lsp--completion-prefix)) - (prefix-str (downcase (if (consp prefix) (car prefix) - prefix))) + (let ((req (company-lsp--make-completion-request prefix)) + body) + (company-lsp--cancel-outstanding-request) + (setq body + (lsp--send-request-async req + (lambda (resp) + (setq company-lsp--last-request-id nil) + (funcall callback (company-lsp--on-completion resp prefix))))) + (setq company-lsp--last-request-id (plist-get body :id)))) + +(defun company-lsp--make-completion-request (prefix) + "Make request body for completion. + +PREFIX is a string prefix given by company-mode. + +Returns the request body that can be used by `lsp-send-request' +or `lsp-send-request-async'." + (let ((params (lsp--text-document-position-params))) + (when company-lsp-enable-trigger-kind + (setq params (plist-put params :context + (company-lsp--get-completion-context prefix)))) + (lsp--make-request "textDocument/completion" + params))) + +(defun company-lsp--get-completion-context (prefix) + "Return a plist representing a CompletionContext message for PREFIX. + +Returns one of `company-lsp--trigger-kind-invoked', +`company-lsp--trigger-kind-trigger-character' and +`company-lsp--trigger-kind-incomplete'." + (cond + ((or (eq this-command 'company-lsp) + (eq this-command 'company-begin-backend) + (eq this-command 'company-complete) + (eq this-command 'company-complete-common)) + ;; Explicitly calling completion command. + (company-lsp--make-completion-context company-lsp--trigger-kind-invoked)) + ((company-lsp--cache-find-closest prefix) + ;; Has incomplete candidates for sub-prefix. This assumes that if the + ;; candidates for sub-prefix, completion won't reach this step since the + ;; candidates for the sub-prefix can be narrowed down and returned directly. + (company-lsp--make-completion-context + company-lsp--trigger-kind-incomplete)) + ((or (null company-point) (< company-point (point))) + ;; `company-point' is updated after backend gets called. So it's nil if + ;; backend is called for a new completion, or less than current point if + ;; backend is called after typing. Both cases indicates completion is + ;; triggered by typing. + (if-let (trigger-character (company-lsp--get-context-trigger-characters)) + (company-lsp--make-completion-context + company-lsp--trigger-kind-trigger-character trigger-character) + (company-lsp--make-completion-context + company-lsp--trigger-kind-invoked))) + (t (company-lsp--make-completion-context company-lsp--trigger-kind-invoked)))) + +(defun company-lsp--make-completion-context (trigger-kind &optional trigger-character) + "Create a plist representing a CompletionContext message. + +TRIGGER-KIND: one of `company-lsp--trigger-kind-invoked', +`company-lsp--trigger-kind-trigger-character' and +`company-lsp--trigger-kind-incomplete'. + +TRIGGER-CHARACTER: The trigger characters that triggers +completion of kind `company-lsp--trigger-kind-trigger-character'. +If the length of it is greater than 1, only the last character is +used." + (let* ((trigger-len (if trigger-character (length trigger-character) + 0)) + (single-trigger (if (> trigger-len 1) + (substring trigger-character (1- trigger-len)) + trigger-character))) + (if trigger-character + (list :triggerKind trigger-kind + :triggerCharacter single-trigger) + (list :triggerKind trigger-kind)))) + +(defun company-lsp--get-context-trigger-characters () + "Return the trigger characters after current point. + +If there are multiple trigger characters matched (e.g. one is a +suffix of another), return any of them. If no trigger characters +match, return nil." + (let ((trigger-chars (company-lsp--trigger-characters))) + (seq-find (lambda (trigger-char) + (and (>= (point) (length trigger-char)) + (string= (buffer-substring (- (point) (length trigger-char)) + (point)) + trigger-char))) + trigger-chars))) + +(defun company-lsp--compute-flex-match (label &optional prefix full-match) + "Perform flex match for PREFIX in LABEL. + +This function finds out substrings in LABEL. The concatenation of +those substrings is a prefix of PREFIX if FULL-MATCH is nil, or +is exactly PREFIX if FULL-MATCH is non-nil. + +If PREFIX is nil, the return value of +`company-lsp--completion-prefix' is used as PREFIX. + +Return a cons cell of (score . substrings). Score is a number for +sorting, the smaller the better. When FULL-MATCH is non-nil and +there is no match, score is always -1. Substrings is an alist +of (substring-start . substring-end), representing the inclusive +start position and exclusive end position of those substrings. +The alist of strings is compatible with the result for the +\"match\" command for company-mode backends. See the \"match\" +section of `company-backends' for more info. Note that if +FULL-MATCH is non-nil and the concatenation of substrings does +not equal to PREFIX, nil is returned." + (let* ((prefix-obj (or prefix (company-lsp--completion-prefix))) + (prefix-str (if (consp prefix-obj) (car prefix-obj) prefix-obj)) + (prefix-low (downcase prefix-str)) (prefix-pos 0) - (prefix-len (length prefix-str)) - (candidate-pos 0) - (candidate-len (length candidate)) - (candidate-str (downcase candidate)) - chunks - chunk-start) - (while (and (< prefix-pos prefix-len) - (< candidate-pos candidate-len)) - (if (= (aref prefix-str prefix-pos) - (aref candidate-str candidate-pos)) - (progn - (when (not chunk-start) - (setq chunk-start candidate-pos)) - (incf prefix-pos) - (incf candidate-pos)) - (when chunk-start - (push (cons chunk-start candidate-pos) chunks) - (setq chunk-start nil)) - (incf candidate-pos))) - (when chunk-start - (push (cons chunk-start candidate-pos) chunks)) - (nreverse chunks))) + (prefix-len (length prefix-low)) + (label-pos 0) + (label-len (length label)) + (label-low (downcase label)) + substrings + substring-start + ;; Initial penalty for the difference of length, but with lower weight. + (score (abs (- label-len prefix-len)))) + (if (string-empty-p prefix-str) + '(0 . ((0 . 0))) + (while (and (< prefix-pos prefix-len) + (< label-pos label-len)) + (if (= (aref prefix-low prefix-pos) + (aref label-low label-pos)) + (progn + (when (not substring-start) + (setq substring-start label-pos) + ;; We simply use the sum of all substring start positions as the + ;; score. This is a good proxy that prioritize fewer substring parts + ;; and earlier occurrence of substrings. + (cl-incf score (* substring-start 100))) + (when (not (= (aref prefix-str prefix-pos) + (aref label label-pos))) + ;; The prefix and label have different cases. Adding penalty to + ;; the score. It has lower weight than substring start but higher + ;; than the length difference. + (cl-incf score 10)) + (cl-incf prefix-pos)) + (when substring-start + (push (cons substring-start label-pos) substrings) + (setq substring-start nil))) + (cl-incf label-pos)) + (when substring-start + (push (cons substring-start label-pos) substrings)) + (if (or (not full-match) (= prefix-pos prefix-len)) + (cons score (nreverse substrings)) + (cons -1 nil))))) ;;;###autoload (defun company-lsp (command &optional arg &rest _) @@ -451,11 +751,14 @@ See the documentation of `company-backends' for COMMAND and ARG." (interactive (list 'interactive)) (cl-case command (interactive (company-begin-backend #'company-lsp)) - (prefix (and - (bound-and-true-p lsp-mode) - (lsp--capability "completionProvider") - (not (company-in-string-or-comment)) - (or (company-lsp--completion-prefix) 'stop))) + (prefix + (and + (bound-and-true-p lsp-mode) + (lsp--capability "completionProvider") + (or (--some (lsp--client-completion-in-comments? (lsp--workspace-client it)) + (lsp-workspaces)) + (not (company-in-string-or-comment))) + (or (company-lsp--completion-prefix) 'stop))) (candidates ;; If the completion items in the response have textEdit action populated, ;; we'll apply them in `company-lsp--post-completion'. However, textEdit @@ -472,7 +775,7 @@ See the documentation of `company-backends' for COMMAND and ARG." (annotation (lsp--annotate arg)) (quickhelp-string (company-lsp--documentation arg)) (doc-buffer (company-doc-buffer (company-lsp--documentation arg))) - (match (company-lsp--compute-match arg)) + (match (cdr (company-lsp--compute-flex-match arg))) (post-completion (company-lsp--post-completion arg)))) (defun company-lsp--client-capabilities () diff --git a/packages/company-lua-20171108.2306.tar b/packages/company-lua-20171108.2306.tar index a961eea..62acc20 100644 Binary files a/packages/company-lua-20171108.2306.tar and b/packages/company-lua-20171108.2306.tar differ diff --git a/packages/company-math-20171016.1514.el b/packages/company-math-20190507.2006.el similarity index 87% rename from packages/company-math-20171016.1514.el rename to packages/company-math-20190507.2006.el index 60ac7e2..1d6bc1c 100644 --- a/packages/company-math-20171016.1514.el +++ b/packages/company-math-20190507.2006.el @@ -1,9 +1,9 @@ -;;; company-math.el --- Completion backends for unicode math symbols and latex tags +;;; company-math.el --- Completion backends for unicode math symbols and latex tags -*- lexical-binding: t -*- ;; -;; Copyright (C) 2015 Free Software Foundation, Inc. -;; Author: Vitalie Spinu +;; Copyright (C) 2015-2019 Free Software Foundation, Inc. +;; Author: Vitalie Spinu ;; URL: https://github.com/vspinu/company-math -;; Package-Version: 20171016.1514 +;; Package-Version: 20190507.2006 ;; Keywords: Unicode, symbols, completion ;; Version: 1.3 ;; Package-Requires: ((company "0.8.0") (math-symbol-lists "1.2")) @@ -23,12 +23,12 @@ ;; General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License -;; along with this program; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth -;; Floor, Boston, MA 02110-1301, USA. +;; along with GNU Emacs. If not, see . ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; +;;; Commentary: +;; ;;; Code: (require 'math-symbol-lists) @@ -47,7 +47,7 @@ (defcustom company-math-subscript-prefix "__" "Prefix for unicode subscripts. -When nil, no custom prefix is active. Irrespective of the value +When nil, no custom prefix is active. Irrespective of the value of this variable, prefix composed of `company-math-symbol-prefix' and \"_\" is always active (\"\\_\"). This variable takes effect in a new Emacs session." @@ -57,7 +57,7 @@ in a new Emacs session." (defcustom company-math-superscript-prefix "^^" "Prefix for unicode superscripts. -When nil, no custom prefix is active. Irrespective of the value +When nil, no custom prefix is active. Irrespective of the value of this variable, prefix composed of `company-math-symbol-prefix' and \"^\" is always active (\"\\^\"). This variable takes effect in a new Emacs session." @@ -79,7 +79,7 @@ in a new Emacs session." (psup (when company-math-superscript-prefix (concat "\\|" (regexp-quote company-math-superscript-prefix))))) (setq company-math--unicode-prefix-regexp - (concat "\\(" psym psub psup "\\)[^ \t\n]*"))) + (concat "\\(" psym psub psup "\\)[^ \t\n]*"))) (defcustom company-math-allow-unicode-symbols-in-faces t "List of faces to allow the insertion of Unicode symbols. @@ -112,9 +112,10 @@ When set to special value t, allow on all faces except those in (defun company-math--make-candidates (alist prefix) "Build a list of math symbols ready to be used in a company backend. -ALIST is one of the defined alist in package -`math-symbol-lists'. Return a list of LaTeX symbols with text -property :symbol being the corresponding unicode symbol." +ALIST is one of the defined alist in package `math-symbol-lists'. +PREFIX is a string to be prefixed to each symbol. Return a list +of LaTeX symbols with text property :symbol being the +corresponding unicode symbol." (delq nil (mapcar (lambda (el) @@ -146,6 +147,9 @@ property :symbol being the corresponding unicode symbol." "List of math completion candidates for unicode backend.") (defun company-math--prefix (regexp allow-faces disallow-faces) + "Response to company prefix command. +REGEXP is the regexp, ALLOW-FACES and DISALLOW-FACES are list of +various faces to allow or disallow completion on." (let* ((face (get-text-property (point) 'face)) (face (or (car-safe face) face)) (insertp (and (not (memq face disallow-faces)) @@ -178,8 +182,9 @@ property :symbol being the corresponding unicode symbol." ;;; BACKENDS ;;;###autoload -(defun company-latex-commands (command &optional arg &rest ignored) - "Company backend for latex commands." +(defun company-latex-commands (command &optional arg &rest _ignored) + "Company backend for latex commands. +COMMAND and ARG is as required by company backends." (interactive (list 'interactive)) (cl-case command (interactive (company-begin-backend 'company-latex-commands)) @@ -189,8 +194,9 @@ property :symbol being the corresponding unicode symbol." (sorted t))) ;;;###autoload -(defun company-math-symbols-latex (command &optional arg &rest ignored) - "Company backend for LaTeX mathematical symbols." +(defun company-math-symbols-latex (command &optional arg &rest _ignored) + "Company backend for LaTeX mathematical symbols. +COMMAND and ARG is as required by company backends." (interactive (list 'interactive)) (cl-case command (interactive (company-begin-backend 'company-math-symbols-latex)) @@ -202,16 +208,16 @@ property :symbol being the corresponding unicode symbol." (candidates (all-completions arg company-math--symbols)))) ;;;###autoload -(defun company-math-symbols-unicode (command &optional arg &rest ignored) +(defun company-math-symbols-unicode (command &optional arg &rest _ignored) "Company backend for insertion of Unicode mathematical symbols. +COMMAND and ARG is as required by company backends. See the unicode-math page [1] for a list of fonts that have a good support for mathematical symbols. Unicode provides only a limited range of sub(super)scripts; see the wikipedia page [2] for details. [1] http://ftp.snt.utwente.nl/pub/software/tex/help/Catalogue/entries/unicode-math.html - [2] https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts -" + [2] https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts" (interactive (list 'interactive)) (cl-case command (interactive (company-begin-backend 'company-math-symbols-unicode)) diff --git a/packages/company-php-20181110.303.el b/packages/company-php-20190424.222.el similarity index 85% rename from packages/company-php-20181110.303.el rename to packages/company-php-20190424.222.el index 5482291..8a7350e 100644 --- a/packages/company-php-20181110.303.el +++ b/packages/company-php-20190424.222.el @@ -1,11 +1,18 @@ -;;; company-php.el --- company completion source for php -;; Copyright (C) 2014 - 2016 jim -;; Author: xcwenn@qq.com [https://github.com/xcwen] +;;; company-php.el --- A company back-end for PHP. + +;; Copyright (C) 2014-2019 jim + +;; Author: jim +;; Maintainer: jim ;; URL: https://github.com/xcwen/ac-php -;; Package-Version: 20181110.303 -;; Package-X-Original-Version: 20171209.2243 +;; Package-Version: 20190424.222 ;; Keywords: completion, convenience, intellisense -;; Package-Requires: ( (cl-lib "0.5") (ac-php-core "1") (company "0.9") ) +;; Package-Requires: ((cl-lib "0.5") (ac-php-core "2.0") (company "0.9")) +;; Compatibility: GNU Emacs: 24.4, 25.x, 26.x, 27.x + +;; This file is NOT part of GNU Emacs. + +;;; License ;; 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 @@ -21,16 +28,25 @@ ;; along with this program. If not, see . ;;; Commentary: -;; company source for php. -;; support Linux and OSX, but windows need more test -;; More info and **example** at : https://github.com/xcwen/ac-php -;;(add-hook 'php-mode-hook -;; '(lambda () +;; A company back-end for PHP. +;; +;; (add-hook 'php-mode-hook +;; '(lambda () ;; (require 'company-php) ;; (company-mode t) ;; (add-to-list 'company-backends 'company-ac-php-backend ))) - +;; +;; Many options available under Help:Customize +;; Options specific to ac-php are in +;; Convenience/Completion/Auto Complete +;; Convenience/Completion/Company +;; +;; Known to work with Linux and macOS. Windows support is in beta stage. +;; For more info and examples see URL `https://github.com/xcwen/ac-php' . +;; +;; Bugs: Bug tracking is currently handled using the GitHub issue tracker +;; (see URL `https://github.com/xcwen/ac-php/issues') ;;; Code: @@ -50,7 +66,9 @@ symbol is preceded by \"->\" or \"::\", ignoring If `company-begin-commands' is a list, it should include `c-electric-lt-gt' and `c-electric-colon', for automatic completion right after \">\" and -\":\".") +\":\"." + :group 'company-php + :type 'boolean) (defun company-ac-php-annotation (item) (let ((doc (ac-php-clean-document (get-text-property 0 'ac-php-help item)))) @@ -81,12 +99,11 @@ matches IDLE-BEGIN-AFTER-RE, return it wrapped in a cons." (cons symbol t) symbol))))) -;; TODO it bad for namespace like \App\add\ss +;; TODO: May not work for namespace like \App\add\ss (defun company-ac-php--prefix () (if company-php-begin-after-member-access - (company-ac-php-company-grab-symbol-cons "->\\|::" 2) - (company-ac-php--prefix-symbol))) - + (company-ac-php-company-grab-symbol-cons "->\\|::" 2) + (company-ac-php--prefix-symbol))) (defun company-ac-php-candidate (arg) (let* ((ac-php-prefix-str (company-ac-php--prefix-symbol)) diff --git a/packages/company-reftex-20181222.906.el b/packages/company-reftex-20181222.906.el new file mode 100644 index 0000000..1a242f2 --- /dev/null +++ b/packages/company-reftex-20181222.906.el @@ -0,0 +1,249 @@ +;;; company-reftex.el --- Company backend based on RefTeX. -*- lexical-binding: t -*- + +;; Copyright (C) 2018 TheBB +;; +;; Author: Eivind Fonn +;; URL: https://github.com/TheBB/company-reftex +;; Package-Version: 20181222.906 +;; Version: 0.1.0 +;; Keywords: bib tex company latex reftex references labels citations +;; Package-Requires: ((emacs "25.1") (s "1.12") (company "0.8")) + +;; 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 . + +;;; Commentary: + +;; To use, add `company-reftex-labels' and `company-reftex-citations' to `company-backends' in the +;; buffers where you want it activated. The major mode must be derived from `latex-mode', and +;; `reftex-mode' must be switched on for them to work. +;; +;; - `company-reftex-labels' will trigger inside forms like \ref{}, \eqref{}, \auroref{}, etc. +;; - `company-reftex-citations' will trigger inside cite{}. +;; +;; These backends collect data from RefTeX, which is very powerful. Citations from external bibtex +;; files should be found automatically. In multi-file documents, make sure `TeX-master' is set +;; appropriately. + +;;; Code: + + +(eval-when-compile + (require 'rx)) + +(require 'cl-lib) +(require 'company) +(require 'reftex) +(require 'reftex-cite) +(require 's) + + +;; Customization + +(defgroup company-reftex nil + "Completion backend for RefTeX." + :prefix "company-reftex-" + :tag "Company RefTeX" + :group 'company) + +(defcustom company-reftex-annotate-citations "%t" + "If non-nil, a format string with which to annotate citations. +See `reftex-format-citation'." + :type '(choice string (const nil)) + :group 'company-reftex) + +(defcustom company-reftex-annotate-labels t + "Whether to annotate labels with their contents." + :type 'boolean + :group 'company-reftex) + +(defcustom company-reftex-max-annotation-length nil + "Truncate annotations to this length." + :type '(choice (const :tag "Off" nil) integer) + :group 'company-reftex) + +(defcustom company-reftex-labels-regexp + (rx "\\" + ;; List taken from `reftex-ref-style-alist' + (or "autoref" + "autopageref" + "Cpageref" + "cpageref" + "Cref" + "cref" + "eqref" + "Fref" + "fref" + "pageref" + "Ref" + "ref" + "vpageref" + "Vref" + "vref") + "{" + (group (* (not (any "}")))) + (regexp "\\=")) + "Regular expression to use when lookng for the label prefix. +Group number 1 should be the prefix itself." + :type 'string + :group 'company-reftex) + +(defcustom company-reftex-citations-regexp + (rx "\\" + ;; List taken from `reftex-cite-format-builtin' + (or "autocite" + "autocite*" + "bibentry" + "cite" + "cite*" + "citeA" + "citeaffixed" + "citeasnoun" + "citeauthor" + "citeauthor*" + "citeauthory" + "citefield" + "citeN" + "citename" + "cites" + "citet" + "citet*" + "citetitle" + "citetitle*" + "citep" + "citeyear" + "citeyear*" + "footcite" + "footfullcite" + "fullcite" + "fullocite" + "nocite" + "ocite" + "ocites" + "parencite" + "parencite*" + "possessivecite" + "shortciteA" + "shortciteN" + "smartcite" + "textcite" + "textcite*" + "ycite" + "ycites") + (* (not (any "[{"))) + (* (seq "[" (* (not (any "]"))) "]")) + "{" + (* (seq (* (not (any "},"))) ",")) + (group (* (not (any "},"))))) + "Regular expression to use when lookng for the citation prefix. +Group number 1 should be the prefix itself." + :type 'string + :group 'company-reftex) + + + +;; Auxiliary functions + +(defun company-reftex-prefix (regexp) + "Return the prefix for matching given REGEXP." + (and (derived-mode-p 'latex-mode) + reftex-mode + (when (looking-back regexp nil) + (match-string-no-properties 1)))) + +(defun company-reftex-annotate (key annotation) + "Annotate KEY with ANNOTATION if the latter is not nil. +Obeys the setting of `company-reftex-max-annotation-length'." + (cond + ((not annotation) key) + ((not company-reftex-max-annotation-length) + (propertize key 'reftex-annotation annotation)) + (t (propertize key 'reftex-annotation + (s-truncate company-reftex-max-annotation-length annotation))))) + + + +;; Citations + +(defun company-reftex-citation-candidates (prefix) + "Find all citation candidates matching PREFIX." + (reftex-access-scan-info) + ;; Reftex will ask for a regexp by using `completing-read' + ;; Override this programatically with a regexp from the prefix + (cl-letf (((symbol-function 'reftex--query-search-regexps) + (lambda (_) (list (regexp-quote prefix))))) + (let* ((bibtype (reftex-bib-or-thebib)) + (candidates + (cond + ((eq 'thebib bibtype) + (reftex-extract-bib-entries-from-thebibliography + (reftex-uniquify + (mapcar 'cdr + (reftex-all-assq + 'thebib (symbol-value reftex-docstruct-symbol)))))) + ((eq 'bib bibtype) + (reftex-extract-bib-entries (reftex-get-bibfile-list))) + (reftex-default-bibliography + (reftex-extract-bib-entries (reftex-default-bibliography)))))) + (cl-loop + for entry in candidates + collect + (let ((key (substring-no-properties (car entry)))) + (company-reftex-annotate + key + (when company-reftex-annotate-citations + (reftex-format-citation entry company-reftex-annotate-citations)))))))) + +;;;###autoload +(defun company-reftex-citations (command &optional arg &rest _) + "Company backend for LaTeX citations, powered by reftex. +For more information on COMMAND and ARG see `company-backends'." + (interactive (list 'interactive)) + (cl-case command + (interactive (company-begin-backend 'company-reftex-labels)) + (prefix (company-reftex-prefix company-reftex-citations-regexp)) + (candidates (company-reftex-citation-candidates arg)) + (annotation (when company-reftex-annotate-citations + (concat + (unless company-tooltip-align-annotations " -> ") + (get-text-property 0 'reftex-annotation arg)))))) + + + +;; Labels + +(defun company-reftex-label-candidates (prefix) + "Find all label candidates matching PREFIX." + (reftex-access-scan-info) + (cl-loop for entry in (symbol-value reftex-docstruct-symbol) + if (and (stringp (car entry)) (string-prefix-p prefix (car entry))) + collect + (company-reftex-annotate (car entry) (cl-caddr entry)))) + +;;;###autoload +(defun company-reftex-labels (command &optional arg &rest _) + "Company backend for LaTeX labels, powered by reftex. +For more information on COMMAND and ARG see `company-backends'." + (interactive (list 'interactive)) + (cl-case command + (interactive (company-begin-backend 'company-reftex-labels)) + (prefix (company-reftex-prefix company-reftex-labels-regexp)) + (candidates (company-reftex-label-candidates arg)) + (annotation (when company-reftex-annotate-labels + (concat + (unless company-tooltip-align-annotations " -> ") + (get-text-property 0 'reftex-annotation arg)))))) + +(provide 'company-reftex) + +;;; company-reftex.el ends here diff --git a/packages/company-restclient-20151202.1201.el b/packages/company-restclient-20190426.1312.el similarity index 95% rename from packages/company-restclient-20151202.1201.el rename to packages/company-restclient-20190426.1312.el index 18112e4..02ea275 100644 --- a/packages/company-restclient-20151202.1201.el +++ b/packages/company-restclient-20190426.1312.el @@ -1,11 +1,11 @@ -;;; company-restclient.el --- company-mode completion back-end for restclient-mode +;;; company-restclient.el --- company-mode completion back-end for restclient-mode -*- lexical-binding: t -*- ;; Public domain. ;; Author: Iku Iwasa ;; URL: https://github.com/iquiw/company-restclient -;; Package-Version: 20151202.1201 -;; Version: 0.2.0 +;; Package-Version: 20190426.1312 +;; Version: 0.3.0 ;; Package-Requires: ((cl-lib "0.5") (company "0.8.0") (emacs "24") (know-your-http-well "0.2.0") (restclient "0.0.0")) ;;; Commentary: @@ -67,13 +67,13 @@ The key is header name and the value is list of header values.") (header (or (company-grab "^[-[:alpha:]]*") (company-restclient--grab-var) (company-grab-symbol))) - (vardecl nil) (comment nil) + ;; Try to grab variable for vardecl too, as it can be variable reference. (t (company-restclient--grab-var)))) (defun company-restclient--grab-var () "Grab variable for completion prefix." - (company-grab ".\\(:[^: \n]*\\)" 1)) + (company-grab "\\(:[^: \n]*\\)" 1)) (defun company-restclient-candidates (prefix) "Provide completion candidates for the given PREFIX." diff --git a/packages/company-rtags-20180730.338.el b/packages/company-rtags-20190821.449.el similarity index 98% rename from packages/company-rtags-20180730.338.el rename to packages/company-rtags-20190821.449.el index f93cbde..26f1735 100644 --- a/packages/company-rtags-20180730.338.el +++ b/packages/company-rtags-20190821.449.el @@ -5,7 +5,7 @@ ;; Author: Jan Erik Hanssen ;; Anders Bakken ;; URL: http://rtags.net -;; Package-Version: 20180730.338 +;; Package-Version: 20190821.449 ;; Version: 0.5 ;; Package-Requires: ((emacs "24.3") (company "0.8.1") (rtags "2.10")) @@ -188,7 +188,8 @@ otherwise 'meta property. See also `company-rtags--meta'." (let ((meta (company-rtags--meta candidate insert))) (cond ((null meta) nil) - ((string-match "\\((.*)\\)" meta) + ((and (string-match "\\((.*)\\)" meta) + (not (string-match "^struct (anonymous)" meta))) (match-string 1 meta))))) (defun company-rtags-completions-calculate-maxwidth () diff --git a/packages/company-terraform-20180703.1233.tar b/packages/company-terraform-20190607.1037.tar similarity index 99% rename from packages/company-terraform-20180703.1233.tar rename to packages/company-terraform-20190607.1037.tar index 0f2bb4d..970f721 100644 Binary files a/packages/company-terraform-20180703.1233.tar and b/packages/company-terraform-20190607.1037.tar differ diff --git a/packages/company-web-20180402.1155.tar b/packages/company-web-20180402.1155.tar index 1654ef9..338a04f 100644 Binary files a/packages/company-web-20180402.1155.tar and b/packages/company-web-20180402.1155.tar differ diff --git a/packages/confluence-20151021.128.tar b/packages/confluence-20151021.128.tar index eb3c4de..806e3e3 100644 Binary files a/packages/confluence-20151021.128.tar and b/packages/confluence-20151021.128.tar differ diff --git a/packages/copy-as-format-20171216.16.el b/packages/copy-as-format-20190523.258.el similarity index 84% rename from packages/copy-as-format-20171216.16.el rename to packages/copy-as-format-20190523.258.el index 7841740..7f21669 100644 --- a/packages/copy-as-format-20171216.16.el +++ b/packages/copy-as-format-20190523.258.el @@ -1,9 +1,9 @@ -;;; copy-as-format.el --- Copy buffer locations as GitHub/Slack/JIRA/HipChat/... formatted code -*- lexical-binding: t; -*- +;;; copy-as-format.el --- Copy buffer locations as GitHub/Slack/JIRA etc... formatted code -*- lexical-binding: t; -*- ;; Copyright (C) 2016-2017 Skye Shaw ;; Author: Skye Shaw -;; Package-Version: 20171216.16 -;; Package-X-Original-Version: 0.0.7 +;; Package-Version: 20190523.258 +;; Package-X-Original-Version: 0.0.8 ;; Keywords: github, slack, jira, hipchat, gitlab, bitbucket, org-mode, pod, rst, asciidoc, tools, convenience ;; URL: https://github.com/sshaw/copy-as-format ;; Package-Requires: ((cl-lib "0.5")) @@ -39,6 +39,9 @@ ;;; Change Log: +;; 2019-01-19 - v0.0.8 +;; * Add more languages to Jira (thanks Peter Oliver) +;; ;; 2017-12-15 - v0.0.7 ;; * Add support for AsciiDoc ;; * Remove use of string-empty-p to support pre 24.4 versions of Emacs @@ -70,10 +73,19 @@ (require 'tabify) (require 'xml) -(defvar copy-as-format-default "markdown" - "Name of the default formatter, defaults to `markdown'.") +(defgroup copy-as-format nil + "Copy buffer locations as GitHub/Slack/JIRA etc... formatted code" + :prefix "copy-as-format-" + :link '(url-link :tag "Report a Bug" "https://github.com/sshaw/copy-as-format/issues") + :link '(url-link :tag "Homepage" "https://github.com/sshaw/copy-as-format") + :group 'convenience) + +(defcustom copy-as-format-default "markdown" + "Name of the default formatter, defaults to `markdown'." + :type 'string + :group 'copy-as-format) -(defvar copy-as-format-format-alist +(defcustom copy-as-format-format-alist '(("asciidoc" copy-as-format--asciidoc) ("bitbucket" copy-as-format--github) ("disqus" copy-as-format--disqus) @@ -88,24 +100,47 @@ ("pod" copy-as-format--pod) ("rst" copy-as-format--rst) ("slack" copy-as-format--slack)) - "Alist of format names and the function to do the formatting.") + "Alist of format names and the function to do the formatting." + :type '(alist :key-type string :value-type (group function)) + :group 'copy-as-format) -(defvar copy-as-format-asciidoc-include-file-name nil - "If non-nil include the buffer's file name.") +(defcustom copy-as-format-asciidoc-include-file-name nil + "If non-nil include the buffer's file name." + :type 'boolean + :group 'copy-as-format) -(defvar copy-as-format-asciidoc-language-alist nil +(defcustom copy-as-format-asciidoc-language-alist nil "Alist of file name patterns to language names used for syntax highlighting. By default the buffer's file extension is used. If this does not -work with your processor add the appropriate mapping here.") +work with your processor add the appropriate mapping here." + :type '(alist :key-type string :value-type string) + :group 'copy-as-format) (defconst copy-as-format--jira-supported-languages '(("as" "actionscript") + ("adb" "ada") + ("ads" "ada") + ("cs" "c#") + ("erl" "erlang") + ("hs" "haskel") ("htm" "html") - ("js" "javascript"))) - -(dolist (lang '("html" "java" "sql" "xhtml" "xml")) + ("mm" "objc") + ("pl" "perl") + ("pm" "perl") + ("py" "python") + ("rb" "ruby") + ("ksh" "sh") + ("vb" "visualbasic") + ("yml" "yaml")) + "Alist mapping file extensions to Jira language names. +Jira's {code} markup blocks are documented at URL `https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=advanced', +but you can get a complete list from Jira itself by trying to use +a language unknown to it.") + +(dolist (lang '("applescript" "bash" "c" "cpp" "css" "go" "groovy" "html" "java" "js" "json" "lua" "php" "r" "scala" "sh" "sql" "swift" "xml" "yaml")) (add-to-list 'copy-as-format--jira-supported-languages (list lang lang))) + (defun copy-as-format--extract-text () (if (not (use-region-p)) (buffer-substring-no-properties (line-beginning-position) (line-end-position)) @@ -181,11 +216,9 @@ work with your processor add the appropriate mapping here.") (defun copy-as-format--jira (text multiline) (if multiline - (let ((lang (car (assoc (copy-as-format--language) - copy-as-format--jira-supported-languages)))) - (format "{code%s}\n%s\n{code}\n" - (if (null lang) "" (concat ":" lang)) - text)) + (let ((lang (car (cdr (assoc (copy-as-format--language) + copy-as-format--jira-supported-languages))))) + (format "{code:%s}\n%s\n{code}\n" (or lang "none") text)) (format "{{%s}}" (copy-as-format--trim text)))) (defun copy-as-format--markdown (text multiline) diff --git a/packages/counsel-20181111.1805.el b/packages/counsel-20190821.1027.el similarity index 68% rename from packages/counsel-20181111.1805.el rename to packages/counsel-20190821.1027.el index 21efde3..b1ec0c5 100644 --- a/packages/counsel-20181111.1805.el +++ b/packages/counsel-20190821.1027.el @@ -1,12 +1,12 @@ ;;; counsel.el --- Various completion functions using Ivy -*- lexical-binding: t -*- -;; Copyright (C) 2015-2018 Free Software Foundation, Inc. +;; Copyright (C) 2015-2019 Free Software Foundation, Inc. ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/swiper -;; Package-Version: 20181111.1805 -;; Version: 0.10.0 -;; Package-Requires: ((emacs "24.3") (swiper "0.9.0")) +;; Package-Version: 20190821.1027 +;; Version: 0.12.0 +;; Package-Requires: ((emacs "24.3") (swiper "0.12.0")) ;; Keywords: convenience, matching, tools ;; This file is part of GNU Emacs. @@ -22,7 +22,7 @@ ;; GNU General Public License for more details. ;; For a full copy of the GNU General Public License -;; see . +;; see . ;;; Commentary: @@ -31,11 +31,11 @@ ;; ;; Currently available: ;; - Symbol completion for Elisp, Common Lisp, Python, Clojure, C, C++. -;; - Describe fuctions for Elisp: function, variable, library, command, +;; - Describe functions for Elisp: function, variable, library, command, ;; bindings, theme. ;; - Navigation functions: imenu, ace-line, semantic, outline. ;; - Git utilities: git-files, git-grep, git-log, git-stash, git-checkout. -;; - Grep utitilies: grep, ag, pt, recoll, ack, rg. +;; - Grep utilities: grep, ag, pt, recoll, ack, rg. ;; - System utilities: process list, rhythmbox, linux-app. ;; - Many more. @@ -45,36 +45,60 @@ (require 'compile) (require 'dired) +(defgroup counsel nil + "Completion functions using Ivy." + :group 'matching + :prefix "counsel-") + ;;* Utility -(defvar counsel-more-chars-alist - '((counsel-grep . 2) - (t . 3)) - "Map commands to their minimum required input length. -That is the number of characters prompted for before fetching -candidates. The special key t is used as a fallback.") - -(defun counsel-more-chars () - "Return two fake candidates prompting for at least N input. -N is obtained from `counsel-more-chars-alist'." - (let ((diff (- (ivy-alist-setting counsel-more-chars-alist) - (length ivy-text)))) - (when (> diff 0) - (list "" (format "%d chars more" diff))))) - -(defun counsel-unquote-regex-parens (str) - "Unquote regexp parentheses in STR." - (if (consp str) - (mapconcat #'car (cl-remove-if-not #'cdr str) ".*") - (replace-regexp-in-string "\\\\[(){}]\\|[()]" - (lambda (s) - (or (cdr (assoc s '(("\\(" . "(") - ("\\)" . ")") - ("(" . "\\(") - (")" . "\\)") - ("\\{" . "{") - ("\\}" . "}")))) - (error "Unexpected parenthesis: %S" s))) - str t t))) +(define-obsolete-variable-alias 'counsel-more-chars-alist 'ivy-more-chars-alist "0.10.0") + +(define-obsolete-function-alias 'counsel-more-chars 'ivy-more-chars "0.10.0") + +(defun counsel--elisp-to-pcre (regex &optional look-around) + "Convert REGEX from Elisp format to PCRE format, on best-effort basis. +REGEX may be of any format returned by an Ivy regex function, +namely a string or a list. The return value is always a string. + +Note that incorrect results may be returned for sufficiently +complex regexes." + (if (consp regex) + (if (and look-around + (or (cdr regex) + (not (cdar regex)))) + (concat + "^" + (mapconcat + (lambda (pair) + (let ((subexp (counsel--elisp-to-pcre (car pair)))) + (format "(?%c.*%s)" + (if (cdr pair) ?= ?!) + subexp))) + regex + "")) + (mapconcat + (lambda (pair) + (let ((subexp (counsel--elisp-to-pcre (car pair)))) + (if (string-match-p "|" subexp) + (format "(?:%s)" subexp) + subexp))) + (cl-remove-if-not #'cdr regex) + ".*")) + (replace-regexp-in-string + "\\\\[(){}|`']\\|[()]" + (lambda (s) + (or (cdr (assoc s '(("\\(" . "(") + ("\\)" . ")") + ("(" . "\\(") + (")" . "\\)") + ("\\{" . "{") + ("\\}" . "}") + ("\\|" . "|") + ("\\`" . "^") + ("\\'" . "$")))) + (error + "Unexpected error in `counsel--elisp-to-pcre' (got match %S)" s))) + regex t t))) (defun counsel-directory-name (dir) "Return the name of directory DIR with a slash." @@ -91,33 +115,35 @@ N is obtained from `counsel-more-chars-alist'." str) str)) -(defun counsel-require-program (program) - "Check system for PROGRAM, printing error if unfound." - (or (and (stringp program) - (not (string= program "")) - (executable-find program)) - (user-error "Required program \"%s\" not found in your path" program))) +(defun counsel-require-program (cmd) + "Check system for program used in CMD, printing error if not found. +CMD is either a string or a list of strings. +To skip the `executable-find' check, start the string with a space." + (unless (and (stringp cmd) (string-match-p "^ " cmd)) + (let ((program (if (listp cmd) + (car cmd) + (car (split-string cmd))))) + (or (and (stringp program) + (not (string= program "")) + (executable-find program)) + (user-error "Required program \"%s\" not found in your path" program))))) (defun counsel-prompt-function-default () "Return prompt appended with a semicolon." - (ivy-add-prompt-count - (format "%s: " (ivy-state-prompt ivy-last)))) + (declare (obsolete ivy-set-prompt "0.10.0")) + (ivy-add-prompt-count (concat (ivy-state-prompt ivy-last) ": "))) (declare-function eshell-split-path "esh-util") (defun counsel-prompt-function-dir () "Return prompt appended with the parent directory." (require 'esh-util) - (ivy-add-prompt-count - (let ((directory (ivy-state-directory ivy-last))) - (format "%s [%s]: " - (ivy-state-prompt ivy-last) - (let ((dir-list (eshell-split-path directory))) - (if (> (length dir-list) 3) - (apply #'concat - (append '("...") - (cl-subseq dir-list (- (length dir-list) 3)))) - directory)))))) + (let* ((dir (ivy-state-directory ivy-last)) + (parts (nthcdr 3 (eshell-split-path dir))) + (dir (format " [%s]: " (if parts (apply #'concat "..." parts) dir)))) + (ivy-add-prompt-count + (replace-regexp-in-string ; Insert dir before any trailing colon. + "\\(?:: ?\\)?\\'" dir (ivy-state-prompt ivy-last) t t)))) ;;* Async Utility (defvar counsel--async-time nil @@ -137,6 +163,9 @@ The time is measured in seconds.") This plist maps commands to a plist mapping their exit codes to descriptions.") +(defvar counsel--async-last-error-string nil + "When the process returned non-0, store the output here.") + (defun counsel-set-async-exit-code (cmd number str) "For CMD, associate NUMBER exit code with STR." (let ((plist (plist-get counsel--async-exit-code-plist cmd))) @@ -147,24 +176,40 @@ descriptions.") (defvar counsel-async-split-string-re "\n" "Store the regexp for splitting shell command output.") +(make-obsolete-variable + 'counsel-async-split-string-re 'counsel-async-split-string-re-alist "<2019-07-16 Tue>") + +(defvar counsel-async-split-string-re-alist '((t . "\n")) + "Store the regexp for splitting shell command output.") (defvar counsel-async-ignore-re nil "Regexp matching candidates to ignore in `counsel--async-filter'.") +(make-obsolete-variable 'counsel-async-ignore-re 'counsel-async-ignore-re-alist "<2019-07-16 Tue>") + +(defvar counsel-async-ignore-re-alist nil + "An alist of regexp matching candidates to ignore in `counsel--async-filter'.") + +(defvar counsel--async-last-command nil + "Store the last command ran by `counsel--async-command'.") (defun counsel--async-command (cmd &optional sentinel filter name) "Start and return new counsel process by calling CMD. +CMD can be either a shell command as a string, or a list of the +program name to be called directly, followed by its arguments. If the default counsel process or one with NAME already exists, kill it and its associated buffer before starting a new one. Give the process the functions SENTINEL and FILTER, which default to `counsel--async-sentinel' and `counsel--async-filter', respectively." (counsel-delete-process name) - (let ((name (or name " *counsel*")) - proc) - (when (get-buffer name) - (kill-buffer name)) - (setq proc (start-file-process-shell-command - name (get-buffer-create name) cmd)) + (setq name (or name " *counsel*")) + (when (get-buffer name) + (kill-buffer name)) + (setq counsel--async-last-command cmd) + (let* ((buf (get-buffer-create name)) + (proc (if (listp cmd) + (apply #'start-file-process name buf cmd) + (start-file-process-shell-command name buf cmd)))) (setq counsel--async-time (current-time)) (setq counsel--async-start counsel--async-time) (set-process-sentinel proc (or sentinel #'counsel--async-sentinel)) @@ -173,6 +218,12 @@ respectively." (defvar counsel-grep-last-line nil) +(defun counsel--split-string (&optional str) + (split-string + (or str (buffer-string)) + (ivy-alist-setting counsel-async-split-string-re-alist) + t)) + (defun counsel--async-sentinel (process _msg) "Sentinel function for an asynchronous counsel PROCESS." (when (eq (process-status process) 'exit) @@ -181,14 +232,16 @@ respectively." (ivy--set-candidates (ivy--sort-maybe (with-current-buffer (process-buffer process) - (split-string (buffer-string) counsel-async-split-string-re t)))) + (counsel--split-string)))) (setq counsel-grep-last-line nil) (when counsel--async-start (setq counsel--async-duration (time-to-seconds (time-since counsel--async-start)))) (let ((re (ivy-re-to-str (funcall ivy--regex-function ivy-text)))) (if ivy--old-cands - (ivy--recompute-index ivy-text re ivy--all-candidates) + (if (eq (ivy-alist-setting ivy-index-functions-alist) 'ivy-recompute-index-zero) + (ivy-set-index 0) + (ivy--recompute-index ivy-text re ivy--all-candidates)) (unless (ivy-set-index (ivy--preselect-index (ivy-state-preselect ivy-last) @@ -198,6 +251,8 @@ respectively." (if ivy--all-candidates (ivy--exhibit) (ivy--insert-minibuffer ""))) + (setq counsel--async-last-error-string + (with-current-buffer (process-buffer process) (buffer-string))) (setq ivy--all-candidates (let ((status (process-exit-status process)) (plist (plist-get counsel--async-exit-code-plist @@ -208,10 +263,8 @@ respectively." (ivy--exhibit)))) (defcustom counsel-async-filter-update-time 500000 - "The amount of time in microseconds to wait until updating -`counsel--async-filter'." - :type 'integer - :group 'ivy) + "The amount of microseconds to wait until updating `counsel--async-filter'." + :type 'integer) (defun counsel--async-filter (process str) "Receive from PROCESS the output STR. @@ -225,16 +278,14 @@ Update the minibuffer with the amount of lines collected every (with-current-buffer (process-buffer process) (setq numlines (count-lines (point-min) (point-max))) (ivy--set-candidates - (let ((lines (split-string (buffer-string) - counsel-async-split-string-re - t))) - (if (stringp counsel-async-ignore-re) + (let ((lines (counsel--split-string)) + (ignore-re (ivy-alist-setting counsel-async-ignore-re-alist))) + (if (stringp ignore-re) (cl-remove-if (lambda (line) - (string-match-p counsel-async-ignore-re line)) + (string-match-p ignore-re line)) lines) lines)))) - (let ((ivy--prompt (format (concat "%d++ " (ivy-state-prompt ivy-last)) - numlines))) + (let ((ivy--prompt (format "%d++ %s" numlines (ivy-state-prompt ivy-last)))) (ivy--insert-minibuffer (ivy--format ivy--all-candidates))) (setq counsel--async-time (current-time))))) @@ -299,6 +350,7 @@ Update the minibuffer with the amount of lines collected every (declare-function jedi:complete-request "ext:jedi-core") (declare-function jedi:ac-direct-matches "ext:jedi") +;;;###autoload (defun counsel-jedi () "Python completion at point." (interactive) @@ -357,12 +409,11 @@ Update the minibuffer with the amount of lines collected every ;;** `counsel-company' (defvar company-candidates) -(defvar company-point) (defvar company-common) +(defvar company-prefix) +(declare-function company-abort "ext:company") (declare-function company-complete "ext:company") (declare-function company-mode "ext:company") -(declare-function company-complete-common "ext:company") -(declare-function company-abort "ext:company") ;;;###autoload (defun counsel-company () @@ -371,13 +422,17 @@ Update the minibuffer with the amount of lines collected every (company-mode 1) (unless company-candidates (company-complete)) - (when company-point - (when (looking-back company-common (line-beginning-position)) - (setq ivy-completion-beg (match-beginning 0)) - (setq ivy-completion-end (match-end 0))) - (ivy-read "company cand: " company-candidates - :action #'ivy-completion-in-region-action - :unwind #'company-abort))) + (let ((len (cond (company-common + (length company-common)) + (company-prefix + (length company-prefix))))) + (when len + (setq ivy-completion-beg (- (point) len)) + (setq ivy-completion-end (point)) + (ivy-read "Candidate: " company-candidates + :action #'ivy-completion-in-region-action + :unwind #'company-abort + :caller 'counsel-company)))) ;;** `counsel-irony' (declare-function irony-completion-candidates-async "ext:irony-completion") @@ -476,9 +531,6 @@ Used by commands `counsel-describe-variable' and (error "Couldn't find definition of %s" sym)))))))) -(define-obsolete-function-alias 'counsel-symbol-at-point - 'ivy-thing-at-point "0.7.0") - (defun counsel--variable-p (symbol) "Return non-nil if SYMBOL is a bound or documented variable." (or (and (boundp symbol) @@ -487,8 +539,7 @@ Used by commands `counsel-describe-variable' and (defcustom counsel-describe-variable-function #'describe-variable "Function to call to describe a variable passed as parameter." - :type 'function - :group 'ivy) + :type 'function) (defun counsel-describe-variable-transformer (var) "Propertize VAR if it's a custom variable." @@ -526,8 +577,7 @@ Variables declared using `defcustom' are highlighted according to (defcustom counsel-describe-function-function #'describe-function "Function to call to describe a function passed as parameter." - :type 'function - :group 'ivy) + :type 'function) (defun counsel-describe-function-transformer (function-name) "Propertize FUNCTION-NAME if it's an interactive function." @@ -544,7 +594,6 @@ Variables declared using `defcustom' are highlighted according to (defcustom counsel-describe-function-preselect #'ivy-thing-at-point "Determine what `counsel-describe-function' should preselect." - :group 'ivy :type '(radio (function-item ivy-thing-at-point) (function-item ivy-function-called-at-point))) @@ -601,23 +650,32 @@ to `ivy-highlight-face'." (defun counsel--setq-doconst (x) "Return a cons of description and value for X. X is an item of a radio- or choice-type defcustom." - (let (y) - (when (and (listp x) - (consp (setq y (last x)))) - (unless (equal y '(function)) - (setq x (car y)) - (cons (prin1-to-string x) - (if (symbolp x) - (list 'quote x) - x)))))) + (when (listp x) + (let ((v (car-safe (last x))) + (tag (and (eq (car x) 'const) + (plist-get (cdr x) :tag)))) + (when (and (or v tag) (not (eq v 'function))) + (cons + (concat + (when tag + (concat tag ": ")) + (if (stringp v) v (prin1-to-string v))) + (if (symbolp v) + (list 'quote v) + v)))))) (declare-function lv-message "ext:lv") (declare-function lv-delete-window "ext:lv") (declare-function custom-variable-documentation "cus-edit") +(defface counsel-variable-documentation + '((t :inherit font-lock-comment-face)) + "Face for displaying Lisp documentation." + :group 'ivy-faces) + ;;;###autoload (defun counsel-set-variable (sym) - "Set a variable, with completion. + "Set a variable SYM, with completion. When the selected variable is a `defcustom' with the type boolean or radio, offer completion of all possible values. @@ -638,26 +696,25 @@ With a prefix arg, restrict list to variables defined using (require 'lv nil t) (not (string= "nil" (custom-variable-documentation sym))) (propertize (custom-variable-documentation sym) - 'face 'font-lock-comment-face))) + 'face 'counsel-variable-documentation))) sym-type cands) (unwind-protect (progn (when doc - (lv-message doc)) + (lv-message (ivy--quote-format-string doc))) (if (and (boundp sym) (setq sym-type (get sym 'custom-type)) (cond ((and (consp sym-type) (memq (car sym-type) '(choice radio))) - (setq cands (delq nil (mapcar #'counsel--setq-doconst (cdr sym-type))))) + (setq cands (delq nil (mapcar #'counsel--setq-doconst + (cdr sym-type))))) ((eq sym-type 'boolean) (setq cands '(("nil" . nil) ("t" . t)))) (t nil))) (let* ((sym-val (symbol-value sym)) - ;; Escape '%' chars if present - (sym-val-str (replace-regexp-in-string "%" "%%" (format "%s" sym-val))) - (res (ivy-read (format "Set (%S <%s>): " sym sym-val-str) + (res (ivy-read (format "Set (%S <%s>): " sym sym-val) cands :preselect (prin1-to-string sym-val)))) (when res @@ -715,7 +772,8 @@ a symbol and how to search for them." ;;;###autoload (defun counsel-info-lookup-symbol (symbol &optional mode) - "Forward to `info-lookup-symbol' with ivy completion." + "Forward SYMBOL to `info-lookup-symbol' with ivy completion. +With prefix arg MODE a query for the symbol help mode is offered." (interactive (progn (require 'info-look) @@ -742,22 +800,30 @@ a symbol and how to search for them." "Face used by `counsel-M-x' for key bindings." :group 'ivy-faces) +(defcustom counsel-alias-expand t + "When non-nil, show the expansion of aliases in `counsel-M-x'." + :type 'boolean + :group 'ivy) + (defun counsel-M-x-transformer (cmd) "Return CMD annotated with its active key binding, if any." - (let ((key (where-is-internal (intern cmd) nil t))) - (if (not key) - cmd - ;; Prefer `' over `C-x 6' where applicable - (let ((i (cl-search [?\C-x ?6] key))) - (when i - (let ((dup (vconcat (substring key 0 i) [f2] (substring key (+ i 2)))) - (map (current-global-map))) - (when (equal (lookup-key map key) - (lookup-key map dup)) - (setq key dup))))) - (setq key (key-description key)) - (put-text-property 0 (length key) 'face 'counsel-key-binding key) - (format "%s (%s)" cmd key)))) + (let ((alias (symbol-function (intern cmd))) + (key (where-is-internal (intern cmd) nil t))) + (concat cmd + (when (and (symbolp alias) counsel-alias-expand) + (format " (%s)" alias)) + (when key + ;; Prefer `' over `C-x 6' where applicable + (let ((i (cl-search [?\C-x ?6] key))) + (when i + (let ((dup (vconcat (substring key 0 i) [f2] (substring key (+ i 2)))) + (map (current-global-map))) + (when (equal (lookup-key map key) + (lookup-key map dup)) + (setq key dup))))) + (setq key (key-description key)) + (put-text-property 0 (length key) 'face 'counsel-key-binding key) + (format " (%s)" key))))) (defvar amx-initialized) (defvar amx-cache) @@ -793,21 +859,33 @@ packages are, in order of precedence, `amx' and `smex'." (defun counsel--M-x-prompt () "String for `M-x' plus the string representation of `current-prefix-arg'." - (if (not current-prefix-arg) - "M-x " - (concat - (if (eq current-prefix-arg '-) - "- " - (if (integerp current-prefix-arg) - (format "%d " current-prefix-arg) - (if (= (car current-prefix-arg) 4) - "C-u " - (format "%d " (car current-prefix-arg))))) - "M-x "))) + (concat (cond ((null current-prefix-arg) + nil) + ((eq current-prefix-arg '-) + "- ") + ((integerp current-prefix-arg) + (format "%d " current-prefix-arg)) + ((= (car current-prefix-arg) 4) + "C-u ") + (t + (format "%d " (car current-prefix-arg)))) + "M-x ")) (defvar counsel-M-x-history nil "History for `counsel-M-x'.") +(defun counsel-M-x-action (cmd) + "Execute CMD." + (setq cmd (intern cmd)) + (cond ((bound-and-true-p amx-initialized) + (amx-rank cmd)) + ((bound-and-true-p smex-initialized-p) + (smex-rank cmd))) + (setq prefix-arg current-prefix-arg) + (setq this-command cmd) + (setq real-this-command cmd) + (command-execute cmd 'record)) + ;;;###autoload (defun counsel-M-x (&optional initial-input) "Ivy version of `execute-extended-command'. @@ -822,19 +900,13 @@ when available, in that order of precedence." (setq real-this-command real-last-command) (let ((externs (counsel--M-x-externs))) (ivy-read (counsel--M-x-prompt) (or externs obarray) - :predicate (and (not externs) #'commandp) + :predicate (and (not externs) + (lambda (sym) + (and (commandp sym) + (not (get sym 'byte-obsolete-info))))) :require-match t :history 'counsel-M-x-history - :action (lambda (cmd) - (setq cmd (intern cmd)) - (cond ((bound-and-true-p amx-initialized) - (amx-rank cmd)) - ((bound-and-true-p smex-initialized-p) - (smex-rank cmd))) - (setq prefix-arg current-prefix-arg) - (setq this-command cmd) - (setq real-this-command cmd) - (command-execute cmd 'record)) + :action #'counsel-M-x-action :sort (not externs) :keymap counsel-describe-map :initial-input initial-input @@ -863,10 +935,11 @@ when available, in that order of precedence." '(("r" counsel-command-history-action-eval "eval command") ("e" counsel-command-history-action-edit-and-eval "edit and eval command"))) +;;;###autoload (defun counsel-command-history () "Show the history of commands." (interactive) - (ivy-read "%d Command: " (mapcar #'prin1-to-string command-history) + (ivy-read "Command: " (mapcar #'prin1-to-string command-history) :require-match t :action #'counsel-command-history-action-eval :caller 'counsel-command-history)) @@ -987,7 +1060,8 @@ Usable with `ivy-resume', `ivy-next-line-and-call' and (ivy-set-actions 'counsel-descbinds '(("d" counsel-descbinds-action-find "definition") - ("I" counsel-descbinds-action-info "info"))) + ("I" counsel-descbinds-action-info "info") + ("x" counsel-descbinds-action-exec "execute"))) (defvar counsel-descbinds-history nil "History for `counsel-descbinds'.") @@ -1021,18 +1095,28 @@ See `describe-buffer-bindings' for further information." (push (cons (format "%-15s %s" - (propertize key 'face 'font-lock-builtin-face) + (propertize key 'face 'counsel-key-binding) fun) (cons key cmd)) res)))) (forward-line 1))) (nreverse res))) +(defcustom counsel-descbinds-function #'describe-function + "Function to call to describe a function passed as parameter." + :type 'function) + (defun counsel-descbinds-action-describe (x) "Describe function of candidate X. See `describe-function' for further information." (let ((cmd (cddr x))) - (describe-function cmd))) + (funcall counsel-descbinds-function cmd))) + +(defun counsel-descbinds-action-exec (x) + "Run candidate X. +See `execute-extended-command' for further information." + (let ((cmd (cddr x))) + (command-execute cmd 'record))) (defun counsel-descbinds-action-find (x) "Find symbol definition of candidate X. @@ -1060,8 +1144,7 @@ BUFFER defaults to the current one." ;;** `counsel-describe-face' (defcustom counsel-describe-face-function #'describe-face "Function to call to describe a face or face name argument." - :type 'function - :group 'ivy) + :type 'function) (defun counsel--face-at-point () "Return name of face around point. @@ -1070,6 +1153,7 @@ back to the face of the character after point, and finally the `default' face." (symbol-name (or (face-at-point t) 'default))) +;;;###autoload (defun counsel-describe-face () "Completion for `describe-face'." (interactive) @@ -1095,17 +1179,20 @@ back to the face of the character after point, and finally the ("C" counsel-customize-face-other-window "customize other window"))) ;;** `counsel-faces' -(defun counsel--faces-format-function (format) - "Return an `ivy-format-function' for `counsel-faces'. +(defvar counsel--faces-format "%-40s %s") + +(defun counsel--faces-format-function (names) + "Customize `ivy-format-functions-alist' for `counsel-faces'. Each candidate is formatted based on the given FORMAT string." - (let ((formatter (lambda (name) - (format format name (propertize list-faces-sample-text - 'face (intern name)))))) - (lambda (names) - (ivy--format-function-generic - (lambda (name) - (funcall formatter (ivy--add-face name 'ivy-current-match))) - formatter names "\n")))) + (let ((formatter + (lambda (name) + (format counsel--faces-format name + (propertize list-faces-sample-text + 'face (intern name)))))) + (ivy--format-function-generic + (lambda (name) + (funcall formatter (ivy--add-face name 'ivy-current-match))) + formatter names "\n"))) ;;;###autoload (defun counsel-faces () @@ -1114,10 +1201,9 @@ Actions are provided by default for describing or customizing the selected face." (interactive) (let* ((names (mapcar #'symbol-name (face-list))) - (ivy-format-function - (counsel--faces-format-function - (format "%%-%ds %%s" - (apply #'max 0 (mapcar #'string-width names)))))) + (counsel--faces-format + (format "%%-%ds %%s" + (apply #'max 0 (mapcar #'string-width names))))) (ivy-read "Face: " names :require-match t :history 'face-name-history @@ -1126,6 +1212,8 @@ selected face." :action counsel-describe-face-function :caller 'counsel-faces))) +(add-to-list 'ivy-format-functions-alist '(counsel-faces . counsel--faces-format-function)) + (ivy-set-actions 'counsel-faces '(("c" counsel-customize-face "customize") @@ -1141,29 +1229,37 @@ selected face." '(("j" find-file-other-window "other window") ("x" counsel-find-file-extern "open externally"))) +(defun counsel--dominating-file (file &optional dir) + "Look up directory hierarchy for FILE, starting in DIR. +Like `locate-dominating-file', but DIR defaults to +`default-directory' and the return value is expanded." + (and (setq dir (locate-dominating-file (or dir default-directory) file)) + (expand-file-name dir))) + (defun counsel-locate-git-root () - "Locate the root of the git repository containing the current buffer." - (or (locate-dominating-file default-directory ".git") - (error "Not in a git repository"))) + "Return the root of the Git repository containing the current buffer." + (or (counsel--git-root) + (error "Not in a Git repository"))) + +(defun counsel-git-cands () + (let ((default-directory (counsel-locate-git-root))) + (split-string + (shell-command-to-string counsel-git-cmd) + "\n" + t))) ;;;###autoload (defun counsel-git (&optional initial-input) "Find file in the current Git repository. INITIAL-INPUT can be given as the initial minibuffer input." (interactive) - (counsel-require-program (car (split-string counsel-git-cmd))) - (let* ((default-directory (expand-file-name (counsel-locate-git-root))) - (cands (split-string - (shell-command-to-string counsel-git-cmd) - "\n" - t))) - (ivy-read "Find file" cands + (counsel-require-program counsel-git-cmd) + (let ((default-directory (counsel-locate-git-root))) + (ivy-read "Find file: " (counsel-git-cands) :initial-input initial-input :action #'counsel-git-action :caller 'counsel-git))) -(ivy-set-prompt 'counsel-git #'counsel-prompt-function-default) - (defun counsel-git-action (x) "Find file X in current Git repository." (with-ivy-window @@ -1175,9 +1271,9 @@ INITIAL-INPUT can be given as the initial minibuffer input." (cd (ivy-state-directory ivy-last)) (counsel-cmd-to-dired (counsel--expand-ls - (format "%s | grep -i -E '%s' | xargs ls" + (format "%s | %s | xargs ls" counsel-git-cmd - (counsel-unquote-regex-parens ivy--old-re))))) + (counsel--file-name-filter))))) (defvar counsel-dired-listing-switches "-alh" "Switches passed to `ls' for `counsel-cmd-to-dired'.") @@ -1227,12 +1323,6 @@ INITIAL-INPUT can be given as the initial minibuffer input." (defvar counsel-git-grep-cmd nil "Store the command for `counsel-git-grep'.") -(defvar counsel--git-grep-count nil - "Store the line count in current repository.") - -(defvar counsel--git-grep-count-threshold 20000 - "The maximum threshold beyond which repositories are considered large.") - (defvar counsel-git-grep-history nil "History for `counsel-git-grep'.") @@ -1243,21 +1333,34 @@ INITIAL-INPUT can be given as the initial minibuffer input." (defcustom counsel-grep-post-action-hook nil "Hook that runs after the point moves to the next candidate. Typical value: '(recenter)." - :type 'hook - :group 'ivy) + :type 'hook) -(defun counsel-git-grep-function (str &optional _pred &rest _unused) - "Grep in the current git repository for STRING." +(defcustom counsel-git-grep-cmd-function #'counsel-git-grep-cmd-function-default + "How a git-grep shell call is built from the input." + :type '(radio + (function-item counsel-git-grep-cmd-function-default) + (function-item counsel-git-grep-cmd-function-ignore-order) + (function :tag "Other"))) + +(defun counsel-git-grep-cmd-function-default (str) + (format counsel-git-grep-cmd + (setq ivy--old-re (ivy--regex str t)))) + +(defun counsel-git-grep-cmd-function-ignore-order (str) + (setq ivy--old-re (ivy--regex str t)) + (let ((parts (split-string str " " t))) + (concat + "git --no-pager grep --full-name -n --no-color -i -e " + (mapconcat #'shell-quote-argument parts " --and -e ")))) + +(defun counsel-git-grep-function (string) + "Grep in the current Git repository for STRING." (or - (and (> counsel--git-grep-count counsel--git-grep-count-threshold) - (counsel-more-chars)) - (let* ((default-directory (ivy-state-directory ivy-last)) - (cmd (format counsel-git-grep-cmd - (setq ivy--old-re (ivy--regex str t))))) - (if (<= counsel--git-grep-count counsel--git-grep-count-threshold) - (split-string (shell-command-to-string cmd) "\n" t) - (counsel--gg-candidates (ivy--regex str)) - nil)))) + (ivy-more-chars) + (progn + (counsel--async-command + (funcall counsel-git-grep-cmd-function string)) + nil))) (defun counsel-git-grep-action (x) "Go to occurrence X in current Git repository." @@ -1276,39 +1379,14 @@ Typical value: '(recenter)." (swiper--cleanup) (swiper--add-overlays (ivy--regex ivy-text)))))) -(defun counsel-git-grep-matcher (regexp candidates) - "Return REGEXP matching CANDIDATES for `counsel-git-grep'." - (or (and (equal regexp ivy--old-re) - ivy--old-cands) - (prog1 - (setq ivy--old-cands - (cl-remove-if-not - (lambda (x) - (ignore-errors - (when (string-match "^[^:]+:[^:]+:" x) - (setq x (substring x (match-end 0))) - (if (stringp regexp) - (string-match regexp x) - (let ((res t)) - (dolist (re regexp) - (setq res - (and res - (ignore-errors - (if (cdr re) - (string-match (car re) x) - (not (string-match (car re) x))))))) - res))))) - candidates)) - (setq ivy--old-re regexp)))) - (defun counsel-git-grep-transformer (str) "Higlight file and line number in STR." (when (string-match "\\`\\([^:]+\\):\\([^:]+\\):" str) (ivy-add-face-text-property (match-beginning 1) (match-end 1) - 'compilation-info + 'ivy-grep-info str) (ivy-add-face-text-property (match-beginning 2) (match-end 2) - 'compilation-line-number + 'ivy-grep-line-number str)) str) @@ -1339,18 +1417,51 @@ files in a project.") (setq cmd counsel-git-grep-cmd-default))) (cons proj cmd))) -(defun counsel--git-grep-count-func-default () - "Default defun to calculate `counsel--git-grep-count'." - (if (eq system-type 'windows-nt) - 0 - (read (shell-command-to-string "du -s \"$(git rev-parse --git-dir)\" 2>/dev/null")))) - -(defvar counsel--git-grep-count-func #'counsel--git-grep-count-func-default - "Defun to calculate `counsel--git-grep-count' for `counsel-git-grep'.") +(defun counsel--call (command &optional result-fn) + "Synchronously call COMMAND and return its output as a string. +COMMAND comprises the program name followed by its arguments, as +in `make-process'. Signal `file-error' and emit a warning if +COMMAND fails. Obey file handlers based on `default-directory'. +On success, RESULT-FN is called in output buffer with no arguments." + (let ((stderr (make-temp-file "counsel-call-stderr-")) + status) + (unwind-protect + (with-temp-buffer + (setq status (apply #'process-file (car command) nil + (list t stderr) nil (cdr command))) + (if (eq status 0) + (if result-fn + (funcall result-fn) + ;; Return all output except trailing newline. + (buffer-substring (point-min) + (- (point) + (if (eq (bobp) (bolp)) + 0 + 1)))) + ;; Convert process status into error list. + (setq status (list 'file-error + (mapconcat #'identity `(,@command "failed") " ") + status)) + ;; Print stderr contents, if any, to *Warnings* buffer. + (let ((msg (condition-case err + (unless (zerop (cadr (insert-file-contents + stderr nil nil nil t))) + (buffer-string)) + (error (error-message-string err))))) + (lwarn 'ivy :warning "%s" (apply #'concat + (error-message-string status) + (and msg (list "\n" msg))))) + ;; Signal `file-error' with process status. + (signal (car status) (cdr status)))) + (delete-file stderr)))) + +(defun counsel--command (&rest command) + "Forward COMMAND to `counsel--call'." + (counsel--call command)) ;;;###autoload (defun counsel-git-grep (&optional cmd initial-input) - "Grep for a string in the current git repository. + "Grep for a string in the current Git repository. When CMD is a string, use it as a \"git grep\" command. When CMD is non-nil, prompt for a specific \"git grep\" command. INITIAL-INPUT can be given as the initial minibuffer input." @@ -1359,41 +1470,32 @@ INITIAL-INPUT can be given as the initial minibuffer input." proj) (setq proj (car proj-and-cmd)) (setq counsel-git-grep-cmd (cdr proj-and-cmd)) - (counsel-require-program (car (split-string counsel-git-grep-cmd))) + (counsel-require-program counsel-git-grep-cmd) (let ((collection-function (if proj #'counsel-git-grep-proj-function #'counsel-git-grep-function)) (unwind-function - (if proj - (lambda () - (counsel-delete-process) - (swiper--cleanup)) - (lambda () - (swiper--cleanup)))) + (lambda () + (counsel-delete-process) + (swiper--cleanup))) (default-directory (if proj (car proj) (counsel-locate-git-root)))) - (setq counsel--git-grep-count (funcall counsel--git-grep-count-func)) - (ivy-read "git grep" collection-function + (ivy-read "git grep: " collection-function :initial-input initial-input - :matcher #'counsel-git-grep-matcher - :dynamic-collection (or proj - (> - counsel--git-grep-count - counsel--git-grep-count-threshold)) + :dynamic-collection t :keymap counsel-git-grep-map :action #'counsel-git-grep-action :unwind unwind-function :history 'counsel-git-grep-history :caller 'counsel-git-grep)))) -(ivy-set-prompt 'counsel-git-grep #'counsel-prompt-function-default) (cl-pushnew 'counsel-git-grep ivy-highlight-grep-commands) (defun counsel-git-grep-proj-function (str) - "Grep for STR in the current git repository." + "Grep for STR in the current Git repository." (or - (counsel-more-chars) + (ivy-more-chars) (let ((regex (setq ivy--old-re (ivy--regex str t)))) (counsel--async-command (format counsel-git-grep-cmd regex)) @@ -1411,66 +1513,17 @@ INITIAL-INPUT can be given as the initial minibuffer input." (setq ivy--all-candidates (all-completions "" 'counsel-git-grep-function)))) -(defvar counsel-gg-state nil - "The current state of candidates / count sync.") - -(defun counsel--gg-candidates (regex) - "Return git grep candidates for REGEX." - (setq counsel-gg-state -2) - (counsel--gg-count regex) - (let ((default-directory (ivy-state-directory ivy-last))) - (set-process-filter - (counsel--async-command (concat (format counsel-git-grep-cmd regex) - " | head -n 200") - #'counsel--gg-sentinel) - nil))) - -(defun counsel--gg-sentinel (process _msg) - "Sentinel function for a `counsel-git-grep' PROCESS." - (when (eq (process-status process) 'exit) - (cl-case (process-exit-status process) - ((0 141) - (with-current-buffer (process-buffer process) - (setq ivy--all-candidates - (or (split-string (buffer-string) "\n" t) - '(""))) - (setq ivy--old-cands ivy--all-candidates)) - (when (zerop (cl-incf counsel-gg-state)) - (ivy--exhibit))) - (1 - (setq ivy--all-candidates '("Error")) - (setq ivy--old-cands ivy--all-candidates) - (ivy--exhibit))))) - -(defun counsel--gg-count-sentinel (process _msg) - "Sentinel function for a `counsel--gg-count' PROCESS." - (when (and (eq (process-status process) 'exit) - (zerop (process-exit-status process))) - (with-current-buffer (process-buffer process) - (setq ivy--full-length (string-to-number (buffer-string)))) - (when (zerop (cl-incf counsel-gg-state)) - (ivy--exhibit)))) - -(defun counsel--gg-count (regex &optional no-async) - "Count the number of results matching REGEX in `counsel-git-grep'. -The command to count the matches is called asynchronously. -If NO-ASYNC is non-nil, do it synchronously instead." - (let ((default-directory (ivy-state-directory ivy-last)) - (cmd (concat - (format (replace-regexp-in-string - "--full-name" "-c" - counsel-git-grep-cmd) - ;; "git grep -i -c '%s'" - (replace-regexp-in-string - "-" "\\\\-" - (replace-regexp-in-string "'" "''" regex))) - " | sed 's/.*:\\(.*\\)/\\1/g' | awk '{s+=$1} END {print s}'"))) - (if no-async - (string-to-number (shell-command-to-string cmd)) - (set-process-filter - (counsel--async-command cmd #'counsel--gg-count-sentinel - nil " *counsel-gg-count*") - nil)))) +(defun counsel--normalize-grep-match (str) + ;; Prepend ./ if necessary: + (unless (ivy--starts-with-dotslash str) + (setq str (concat "./" str))) + ;; Remove column info if any: + (save-match-data + (when (string-match + "[^\n:]+?[^\n/:]:[\t ]*[1-9][0-9]*[\t ]*:\\([1-9][0-9]*:\\)" + str) + (setq str (replace-match "" t t str 1)))) + str) (defun counsel-git-grep-occur () "Generate a custom occur buffer for `counsel-git-grep'. @@ -1485,7 +1538,7 @@ When REVERT is non-nil, regenerate the current *ivy-occur* buffer." (positive-pattern (replace-regexp-in-string ;; git-grep can't handle .*? "\\.\\*\\?" ".*" - (if (stringp regex) regex (caar regex)))) + (ivy-re-to-str regex))) (negative-patterns (if (stringp regex) "" (mapconcat (lambda (x) @@ -1495,18 +1548,13 @@ When REVERT is non-nil, regenerate the current *ivy-occur* buffer." " "))) (cmd (concat (format counsel-git-grep-cmd positive-pattern) negative-patterns)) cands) - (setq cands (split-string - (shell-command-to-string cmd) - counsel-async-split-string-re - t)) + (setq cands (counsel--split-string (shell-command-to-string cmd))) ;; 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 - (mapcar - (lambda (cand) (concat "./" cand)) - cands)))) + (mapcar #'counsel--normalize-grep-match cands)))) (defun counsel-git-grep-query-replace () "Start `query-replace' with string to replace from last search string." @@ -1558,13 +1606,15 @@ done") "\n" t))) (defvar counsel-git-log-cmd "GIT_PAGER=cat git log --grep '%s'" "Command used for \"git log\".") -(defvar counsel-git-log-split-string-re "\ncommit " +(defvar counsel-git-log-split-string-re "^commit " "The `split-string' separates when split output of `counsel-git-log-cmd'.") +(make-obsolete-variable + 'counsel-git-log-split-string-re 'counsel-async-split-string-re-alist "<2019-07-16 Tue>") (defun counsel-git-log-function (str) "Search for STR in git log." (or - (counsel-more-chars) + (ivy-more-chars) (progn ;; `counsel--yank-pop-format-function' uses this (setq ivy--old-re (funcall ivy--regex-function str)) @@ -1580,6 +1630,18 @@ done") "\n" t))) "Add candidate X to kill ring." (message "%S" (kill-new x))) +(declare-function magit-show-commit "ext:magit-diff") + +(defun counsel-git-log-show-commit-action (log-entry) + "Visit the commit corresponding to LOG-ENTRY." + (require 'magit-diff) + (let ((commit (substring-no-properties log-entry 0 (string-match-p "\\W" log-entry)))) + (magit-show-commit commit))) + +(ivy-set-actions + 'counsel-git-log + '(("v" counsel-git-log-show-commit-action "visit commit"))) + ;;** `counsel-git-change-worktree' (defun counsel-git-change-worktree-action (git-root-dir tree) "Find the corresponding file in the worktree located at tree. @@ -1591,13 +1653,13 @@ TREE is the selected candidate." (find-file file-name))) (defun counsel-git-worktree-list () - "List worktrees in the git repository containing the current buffer." + "List worktrees in the Git repository containing the current buffer." (let ((default-directory (counsel-locate-git-root))) (split-string (shell-command-to-string "git worktree list") "\n" t))) (defun counsel-git-worktree-parse-root (tree) "Return worktree from candidate TREE." - (substring tree 0 (string-match " " tree))) + (substring tree 0 (string-match-p " " tree))) (defun counsel-git-close-worktree-files-action (root-dir) "Close all buffers from the worktree located at ROOT-DIR." @@ -1635,10 +1697,12 @@ The command is passed a single argument comprising all characters in BRANCH up to, but not including, the first space character (#x20), or the string's end if it lacks a space." (shell-command - (format "git checkout %s" (substring branch 0 (string-match-p " " branch))))) + (format "git checkout %s" + (shell-quote-argument + (substring branch 0 (string-match-p " " branch)))))) (defun counsel-git-branch-list () - "Return list of branches in the current git repository. + "Return list of branches in the current Git repository. Value comprises all local and remote branches bar the one currently checked out." (cl-mapcan (lambda (line) @@ -1658,21 +1722,24 @@ currently checked out." (defvar counsel-yank-pop-truncate-radius) +(defun counsel--git-log-format-function (str) + (let ((counsel-yank-pop-truncate-radius 5)) + (counsel--yank-pop-format-function str))) + ;;;###autoload (defun counsel-git-log () "Call the \"git log --grep\" shell command." (interactive) - (let ((counsel-async-split-string-re counsel-git-log-split-string-re) - (counsel-async-ignore-re "^[ \n]*$") - (counsel-yank-pop-truncate-radius 5) - (ivy-format-function #'counsel--yank-pop-format-function)) - (ivy-read "Grep log: " #'counsel-git-log-function - :dynamic-collection t - :action #'counsel-git-log-action - :unwind #'counsel-delete-process - :caller 'counsel-git-log))) + (ivy-read "Grep log: " #'counsel-git-log-function + :dynamic-collection t + :action #'counsel-git-log-action + :unwind #'counsel-delete-process + :caller 'counsel-git-log)) +(add-to-list 'ivy-format-functions-alist '(counsel-git-log . counsel--git-log-format-function)) (add-to-list 'ivy-height-alist '(counsel-git-log . 4)) +(add-to-list 'counsel-async-split-string-re-alist '(counsel-git-log . "^commit ")) +(add-to-list 'counsel-async-ignore-re-alist '(counsel-git-log . "^[ \n]*$")) ;;* File ;;** `counsel-find-file' @@ -1680,13 +1747,11 @@ currently checked out." (let ((map (make-sparse-keymap))) (define-key map (kbd "C-DEL") 'counsel-up-directory) (define-key map (kbd "C-") 'counsel-up-directory) - (define-key map (kbd "C-M-y") 'counsel-yank-directory) + (define-key map (kbd "`") (ivy-make-magic-action 'counsel-find-file "b")) map)) -(defun counsel-yank-directory () - "Yank the current directory into the minibuffer." - (interactive) - (insert ivy--directory)) +(define-obsolete-function-alias 'counsel-yank-directory 'ivy-insert-current-full + "<2019-06-13 Thu>") (when (executable-find "git") (add-to-list 'ivy-ffap-url-functions 'counsel-github-url-p) @@ -1706,8 +1771,7 @@ currently checked out." (defcustom counsel-root-command "sudo" "Command to gain root privileges." - :type 'string - :group 'ivy) + :type 'string) (defun counsel-find-file-as-root (x) "Find file X with root privileges." @@ -1739,6 +1803,15 @@ choose between `yes-or-no-p' and `y-or-n-p'; otherwise default to #'yes-or-no-p) (apply #'format fmt args))) +(defun counsel-find-file-copy (x) + "Copy file X." + (require 'dired-aux) + (counsel--find-file-1 "Copy file to: " + ivy--directory + (lambda (new-name) + (dired-copy-file x new-name 1)) + 'counsel-find-file-copy)) + (defun counsel-find-file-delete (x) "Delete file X." (when (or delete-by-moving-to-trash @@ -1747,20 +1820,27 @@ choose between `yes-or-no-p' and `y-or-n-p'; otherwise default to (counsel--yes-or-no-p "Delete %s? " x)) (dired-delete-file x dired-recursive-deletes delete-by-moving-to-trash) (dired-clean-up-after-deletion x) - (ivy--reset-state ivy-last))) + (let ((win (and (not (eq ivy-exit 'done)) + (active-minibuffer-window)))) + (when win (with-selected-window win (ivy--cd ivy--directory)))))) (defun counsel-find-file-move (x) "Move or rename file X." - (ivy-read "Rename file to: " #'read-file-name-internal - :matcher #'counsel--find-file-matcher - :action (lambda (new-name) - (require 'dired-aux) - (dired-rename-file x new-name 1)) - :keymap counsel-find-file-map - :caller 'counsel-find-file-move)) + (require 'dired-aux) + (counsel--find-file-1 "Rename file to: " + ivy--directory + (lambda (new-name) + (dired-rename-file x new-name 1)) + 'counsel-find-file-move)) (defun counsel-find-file-mkdir-action (_x) - (make-directory (expand-file-name ivy-text ivy--directory))) + "Create a directory and any nonexistent parent dirs from `ivy-text'." + (let ((dir (file-name-as-directory + (expand-file-name ivy-text ivy--directory))) + (win (and (not (eq ivy-exit 'done)) + (active-minibuffer-window)))) + (make-directory dir t) + (when win (with-selected-window win (ivy--cd dir))))) (ivy-set-actions 'counsel-find-file @@ -1770,18 +1850,17 @@ choose between `yes-or-no-p' and `y-or-n-p'; otherwise default to ("x" counsel-find-file-extern "open externally") ("r" counsel-find-file-as-root "open as root") ("k" counsel-find-file-delete "delete") + ("c" counsel-find-file-copy "copy file") ("m" counsel-find-file-move "move or rename") ("d" counsel-find-file-mkdir-action "mkdir"))) (defcustom counsel-find-file-at-point nil "When non-nil, add file-at-point to the list of candidates." - :type 'boolean - :group 'ivy) + :type 'boolean) (defcustom counsel-preselect-current-file nil "When non-nil, preselect current file in list of candidates." - :type 'boolean - :group 'ivy) + :type 'boolean) (defcustom counsel-find-file-ignore-regexp nil "A regexp of files to ignore while in `counsel-find-file'. @@ -1795,10 +1874,9 @@ Choosing the dotfiles option, \"\\`\\.\", might be convenient, since you can still access the dotfiles if your input starts with a dot. The generic way to toggle ignored files is \\[ivy-toggle-ignore], but the leading dot is a lot faster." - :group 'ivy :type `(choice (const :tag "None" nil) - (const :tag "Dotfiles" "\\`\\.") + (const :tag "Dotfiles and Lockfiles" "\\(?:\\`\\|[/\\]\\)\\(?:[#.]\\)") (const :tag "Ignored Extensions" ,(regexp-opt completion-ignored-extensions)) (regexp :tag "Regex"))) @@ -1814,12 +1892,12 @@ Skip some dotfiles unless `ivy-text' requires them." (string-match re-str (directory-file-name x))))))) (if (or (null ivy-use-ignore) (null counsel-find-file-ignore-regexp) - (string-match "\\`\\." ivy-text)) + (string-match-p "\\`\\." ivy-text)) res (or (cl-remove-if (lambda (x) (and - (string-match counsel-find-file-ignore-regexp x) + (string-match-p counsel-find-file-ignore-regexp x) (not (member x ivy-extra-directories)))) res) res)))) @@ -1829,18 +1907,25 @@ Skip some dotfiles unless `ivy-text' requires them." (defvar counsel-find-file-speedup-remote t "Speed up opening remote files by disabling `find-file-hook' for them.") +(defcustom counsel-find-file-extern-extensions '("mp4" "mkv" "xlsx") + "List of extensions that make `counsel-find-file' use `counsel-find-file-extern'." + :type '(repeat string)) + (defun counsel-find-file-action (x) "Find file X." (with-ivy-window - (if (and counsel-find-file-speedup-remote - (file-remote-p ivy--directory)) - (let ((find-file-hook nil)) - (find-file (expand-file-name x ivy--directory))) - (find-file (expand-file-name x ivy--directory))))) + (cond ((and counsel-find-file-speedup-remote + (file-remote-p ivy--directory)) + (let ((find-file-hook nil)) + (find-file (expand-file-name x ivy--directory)))) + ((member (file-name-extension x) counsel-find-file-extern-extensions) + (counsel-find-file-extern x)) + (t + (find-file (expand-file-name x ivy--directory)))))) (defun counsel--preselect-file () "Return candidate to preselect during filename completion. -The preselect behaviour can be customized via user options +The preselect behavior can be customized via user options `counsel-find-file-at-point' and `counsel-preselect-current-file', which see." (or @@ -1852,24 +1937,30 @@ The preselect behaviour can be customized via user options buffer-file-name (file-name-nondirectory buffer-file-name)))) -;;;###autoload -(defun counsel-find-file (&optional initial-input) - "Forward to `find-file'. -When INITIAL-INPUT is non-nil, use it in the minibuffer during completion." - (interactive) - (ivy-read "Find file: " #'read-file-name-internal +(defun counsel--find-file-1 (prompt initial-input action caller) + (ivy-read prompt #'read-file-name-internal :matcher #'counsel--find-file-matcher :initial-input initial-input - :action #'counsel-find-file-action + :action action :preselect (counsel--preselect-file) :require-match 'confirm-after-completion :history 'file-name-history :keymap counsel-find-file-map - :caller 'counsel-find-file)) + :caller caller)) + +;;;###autoload +(defun counsel-find-file (&optional initial-input) + "Forward to `find-file'. +When INITIAL-INPUT is non-nil, use it in the minibuffer during completion." + (interactive) + (counsel--find-file-1 + "Find file: " initial-input + #'counsel-find-file-action + 'counsel-find-file)) (ivy-set-occur 'counsel-find-file 'counsel-find-file-occur) -(defvar counsel-find-file-occur-cmd "ls -a | grep -i -E '%s' | xargs -d '\\n' ls -d --group-directories-first" +(defvar counsel-find-file-occur-cmd "ls -a | %s | xargs -d '\\n' ls -d --group-directories-first" "Format string for `counsel-find-file-occur'.") (defvar counsel-find-file-occur-use-find (not (eq system-type 'gnu/linux)) @@ -1879,11 +1970,51 @@ When INITIAL-INPUT is non-nil, use it in the minibuffer during completion." "Expand CMD that ends in \"ls\" with switches." (concat cmd " " counsel-dired-listing-switches " | sed -e \"s/^/ /\"")) +(defvar counsel-file-name-filter-alist + '(("ag -i '%s'" . t) + ("ack -i '%s'" . t) + ("perl -ne '/(%s.*)/i && print \"$1\\n\";'" . t) + ("grep -i -E '%s'")) + "Alist of file name filtering commands. +The car is a shell command and the cdr is t when the shell +command supports look-arounds. The executable for the commands +will be checked for existence via `executable-find'. The first +one that exists will be used.") + +(defun counsel--file-name-filter (&optional use-ignore) + "Return a command that filters a file list to match ivy candidates. +If USE-IGNORE is non-nil, try to generate a command that respects +`counsel-find-file-ignore-regexp'." + (let ((regex ivy--old-re)) + (if (= 0 (length regex)) + "cat" + (let ((filter-cmd (cl-find-if + (lambda (x) + (executable-find + (car (split-string (car x))))) + counsel-file-name-filter-alist)) + cmd) + (when (and use-ignore ivy-use-ignore + counsel-find-file-ignore-regexp + (cdr filter-cmd) + (not (string-match-p "\\`\\." ivy-text)) + (not (string-match-p counsel-find-file-ignore-regexp + (or (car ivy--old-cands) "")))) + (let ((ignore-re (list (counsel--elisp-to-pcre + counsel-find-file-ignore-regexp)))) + (setq regex (if (stringp regex) + (list ignore-re (cons regex t)) + (cons ignore-re regex))))) + (setq cmd (format (car filter-cmd) + (counsel--elisp-to-pcre regex (cdr filter-cmd)))) + (if (string-match-p "csh\\'" shell-file-name) + (replace-regexp-in-string "\\?!" "?\\\\!" cmd) + cmd))))) + (defun counsel--occur-cmd-find () - (let* ((regex (counsel-unquote-regex-parens ivy--old-re)) - (cmd (format - "find . -maxdepth 1 | grep -i -E '%s' | xargs -I {} find {} -maxdepth 0 -ls" - regex))) + (let ((cmd (format + "find . -maxdepth 1 | %s | xargs -I {} find {} -maxdepth 0 -ls" + (counsel--file-name-filter t)))) (concat (counsel--cmd-to-dired-by-type "d" cmd) " && " @@ -1908,13 +2039,29 @@ When INITIAL-INPUT is non-nil, use it in the minibuffer during completion." (counsel-cmd-to-dired (counsel--expand-ls (format counsel-find-file-occur-cmd - (counsel-unquote-regex-parens ivy--old-re)))))) + (if (string-match-p "grep" counsel-find-file-occur-cmd) + ;; for backwards compatibility + (counsel--elisp-to-pcre ivy--old-re) + (counsel--file-name-filter t))))))) + +(defvar counsel-up-directory-level t + "Control whether `counsel-up-directory' goes up a level or always a directory. + +If non-nil, then `counsel-up-directory' will remove the final level of the path. +For example: /a/long/path/file.jpg => /a/long/path/ + /a/long/path/ => /a/long/ + +If nil, then `counsel-up-directory' will go up a directory. +For example: /a/long/path/file.jpg => /a/long/ + /a/long/path/ => /a/long/") (defun counsel-up-directory () "Go to the parent directory preselecting the current one. If the current directory is remote and it's not possible to go up any -further, make the remote prefix editable" +further, make the remote prefix editable. + +See variable `counsel-up-directory-level'." (interactive) (let* ((cur-dir (directory-file-name (expand-file-name ivy--directory))) (up-dir (file-name-directory cur-dir))) @@ -1929,15 +2076,22 @@ further, make the remote prefix editable" (setq ivy-text "") (delete-minibuffer-contents) (insert up-dir)) - (ivy--cd up-dir) - (setf (ivy-state-preselect ivy-last) - (file-name-as-directory (file-name-nondirectory cur-dir)))))) + (if (and counsel-up-directory-level (not (string= ivy-text ""))) + (delete-region (line-beginning-position) (line-end-position)) + (ivy--cd up-dir) + (setf (ivy-state-preselect ivy-last) + (file-name-as-directory (file-name-nondirectory cur-dir))))))) + +(defun counsel-down-directory () + "Descend into the current directory." + (interactive) + (ivy--directory-enter)) (defun counsel-at-git-issue-p () "When point is at an issue in a Git-versioned file, return the issue string." (and (looking-at "#[0-9]+") (or (eq (vc-backend buffer-file-name) 'Git) - (eq major-mode 'magit-commit-mode) + (memq major-mode '(magit-commit-mode vc-git-log-view-mode)) (bound-and-true-p magit-commit-mode)) (match-string-no-properties 0))) @@ -1969,7 +2123,7 @@ further, make the remote prefix editable" (let ((origin (shell-command-to-string "git remote get-url origin"))) (when (string-match "git.sv.gnu.org:/srv/git/emacs.git" origin) - (format "http://debbugs.gnu.org/cgi/bugreport.cgi?bug=%s" + (format "https://debbugs.gnu.org/cgi/bugreport.cgi?bug=%s" (substring url 1))))))) (defvar counsel-url-expansions-alist nil @@ -1994,7 +2148,7 @@ If the format element is a function, more powerful transformations are possible. As an example, '(\"\\`issue\\([[:digit:]]+\\)\\'\" . (lambda (word) - (concat \"http://debbugs.gnu.org/cgi/bugreport.cgi?bug=\" + (concat \"https://debbugs.gnu.org/cgi/bugreport.cgi?bug=\" (match-string 1 word)))) trims the \"issue\" prefix from the word at point before creating the URL.") @@ -2005,15 +2159,29 @@ will be expanded according to its format. This function is intended to be used in `ivy-ffap-url-functions' to browse the result as a URL." (let ((word-at-point (current-word))) - (cl-some - (lambda (pair) - (let ((regexp (car pair)) - (formatter (cdr pair))) - (when (string-match regexp word-at-point) - (if (functionp formatter) - (funcall formatter word-at-point) - (format formatter word-at-point))))) - counsel-url-expansions-alist))) + (when word-at-point + (cl-some + (lambda (pair) + (let ((regexp (car pair)) + (formatter (cdr pair))) + (when (string-match regexp word-at-point) + (if (functionp formatter) + (funcall formatter word-at-point) + (format formatter word-at-point))))) + counsel-url-expansions-alist)))) + +;;** `counsel-dired' +(declare-function dired "dired") + +;;;###autoload +(defun counsel-dired (&optional initial-input) + "Forward to `dired'. +When INITIAL-INPUT is non-nil, use it in the minibuffer during completion." + (interactive) + (counsel--find-file-1 + "Dired (directory): " initial-input + (lambda (d) (dired (expand-file-name d))) + 'counsel-dired)) ;;** `counsel-recentf' (defvar recentf-list) @@ -2029,6 +2197,7 @@ result as a URL." :action (lambda (f) (with-ivy-window (find-file f))) + :require-match t :caller 'counsel-recentf)) (ivy-set-actions 'counsel-recentf @@ -2036,12 +2205,54 @@ result as a URL." ("f" find-file-other-frame "other frame") ("x" counsel-find-file-extern "open externally"))) +(defun counsel-buffer-or-recentf-candidates () + "Return candidates for `counsel-buffer-or-recentf'." + (require 'recentf) + (recentf-mode) + (let ((buffers + (delq nil + (mapcar (lambda (b) + (when (buffer-file-name b) + (buffer-file-name b))) + (buffer-list))))) + (append + buffers + (cl-remove-if (lambda (f) (member f buffers)) + (mapcar #'substring-no-properties recentf-list))))) + +;;;###autoload +(defun counsel-buffer-or-recentf () + "Find a buffer visiting a file or file on `recentf-list'." + (interactive) + (ivy-read "Buffer File or Recentf: " (counsel-buffer-or-recentf-candidates) + :action (lambda (s) + (with-ivy-window + (if (bufferp s) + (switch-to-buffer s) + (find-file s)))) + :require-match t + :caller 'counsel-buffer-or-recentf)) + +(ivy-set-actions + 'counsel-buffer-or-recentf + '(("j" find-file-other-window "other window") + ("f" find-file-other-frame "other frame") + ("x" counsel-find-file-extern "open externally"))) + +(defun counsel-buffer-or-recentf-transformer (var) + "Propertize VAR if it's a buffer visiting a file." + (if (member var (mapcar #'buffer-file-name (buffer-list))) + (ivy-append-face var 'ivy-highlight-face) + var)) + +(ivy-set-display-transformer + 'counsel-buffer-or-recentf 'counsel-buffer-or-recentf-transformer) + ;;** `counsel-bookmark' (defcustom counsel-bookmark-avoid-dired nil "If non-nil, open directory bookmarks with `counsel-find-file'. By default `counsel-bookmark' opens a dired buffer for directories." - :type 'boolean - :group 'ivy) + :type 'boolean) (defvar bookmark-alist) (declare-function bookmark-location "bookmark") @@ -2072,7 +2283,7 @@ By default `counsel-bookmark' opens a dired buffer for directories." :caller 'counsel-bookmark)) (defun counsel--apply-bookmark-fn (fn) - "Return a function applyinig FN to a bookmark's location." + "Return a function applying FN to a bookmark's location." (lambda (bookmark) (funcall fn (bookmark-location bookmark)))) @@ -2128,7 +2339,7 @@ can use `C-x r j i' to open that file." (interactive) (ivy-read "File Register: " ;; Use the `register-alist' variable to filter out file - ;; registers. Each entry for a file registar will have the + ;; registers. Each entry for a file register will have the ;; following layout: ;; ;; (NUMBER 'file . "string/path/to/file") @@ -2152,7 +2363,7 @@ can use `C-x r j i' to open that file." '(("j" find-file-other-window "other window"))) ;;** `counsel-locate' -(defcustom counsel-locate-cmd (cond ((eq system-type 'darwin) +(defcustom counsel-locate-cmd (cond ((memq system-type '(darwin berkeley-unix)) 'counsel-locate-cmd-noregex) ((and (eq system-type 'windows-nt) (executable-find "es.exe")) @@ -2163,7 +2374,6 @@ can use `C-x r j i' to open that file." The function takes a string - the current input, and returns a string - the full shell command to run." - :group 'ivy :type '(choice (const :tag "Default" counsel-locate-cmd-default) (const :tag "No regex" counsel-locate-cmd-noregex) @@ -2181,6 +2391,7 @@ string - the full shell command to run." (defvar counsel-locate-history nil "History for `counsel-locate'.") +;;;###autoload (defun counsel-locate-action-extern (x) "Pass X to `xdg-open' or equivalent command via the shell." (interactive "FFile: ") @@ -2207,7 +2418,7 @@ string - the full shell command to run." "Return a shell command based on INPUT." (counsel-require-program "locate") (format "locate -i --regex '%s'" - (counsel-unquote-regex-parens + (counsel--elisp-to-pcre (ivy--regex input)))) (defun counsel-locate-cmd-noregex (input) @@ -2224,23 +2435,42 @@ string - the full shell command to run." "Return a shell command based on INPUT." (counsel-require-program "es.exe") (format "es.exe -i -r -p %s" - (counsel-unquote-regex-parens + (counsel--elisp-to-pcre (ivy--regex input t)))) (defun counsel-locate-function (input) "Call the \"locate\" shell command with INPUT." (or - (counsel-more-chars) + (ivy-more-chars) (progn (counsel--async-command (funcall counsel-locate-cmd input)) '("" "working...")))) +(defcustom counsel-locate-db-path "~/.local/mlocate.db" + "Location where to put the locatedb in case your home folder is encrypted." + :type 'file) + +(defun counsel--locate-updatedb () + (when (file-exists-p "~/.Private") + (let ((db-fname (expand-file-name counsel-locate-db-path))) + (setenv "LOCATE_PATH" db-fname) + (when (or (not (file-exists-p db-fname)) + (> (time-to-seconds + (time-subtract + (current-time) + (nth 5 (file-attributes db-fname)))) + 60)) + (message "Updating %s..." db-fname) + (counsel--command + "updatedb" "-l" "0" "-o" db-fname "-U" (expand-file-name "~")))))) + ;;;###autoload (defun counsel-locate (&optional initial-input) "Call the \"locate\" shell command. INITIAL-INPUT can be given as the initial minibuffer input." (interactive) + (counsel--locate-updatedb) (ivy-read "Locate: " #'counsel-locate-function :initial-input initial-input :dynamic-collection t @@ -2273,12 +2503,9 @@ INITIAL-INPUT can be given as the initial minibuffer input." (defun counsel-fzf-function (str) (let ((default-directory counsel--fzf-dir)) + (setq ivy--old-re (ivy--regex-fuzzy str)) (counsel--async-command - (format counsel-fzf-cmd - (if (string-equal str "") - "\"\"" - (setq ivy--old-re (ivy--regex-fuzzy str)) - str)))) + (format counsel-fzf-cmd str))) nil) ;;;###autoload @@ -2294,20 +2521,18 @@ FZF-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." (read-directory-name (concat fzf-basename " in directory: ")))))) - - (let ((fzf-basename (car (split-string counsel-fzf-cmd)))) - (counsel-require-program fzf-basename) - (setq counsel--fzf-dir - (or initial-directory - (funcall counsel-fzf-dir-function))) - (ivy-read (or fzf-prompt (concat fzf-basename ": ")) - #'counsel-fzf-function - :initial-input initial-input - :re-builder #'ivy--regex-fuzzy - :dynamic-collection t - :action #'counsel-fzf-action - :unwind #'counsel-delete-process - :caller 'counsel-fzf))) + (counsel-require-program counsel-fzf-cmd) + (setq counsel--fzf-dir + (or initial-directory + (funcall counsel-fzf-dir-function))) + (ivy-read (or fzf-prompt "fzf: ") + #'counsel-fzf-function + :initial-input initial-input + :re-builder #'ivy--regex-fuzzy + :dynamic-collection t + :action #'counsel-fzf-action + :unwind #'counsel-delete-process + :caller 'counsel-fzf)) (defun counsel-fzf-action (x) "Find file X in current fzf directory." @@ -2375,55 +2600,80 @@ FZF-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." (message (cdr x))) :caller 'counsel-rpm))) +(defun counsel--find-return-list (args) + (unless (listp args) + (user-error "`counsel-file-jump-args' is a list now, please customize accordingly.")) + (counsel--call + (cons find-program args) + (lambda () + (let (files) + (goto-char (point-min)) + (while (< (point) (point-max)) + (when (looking-at "\\./") + (goto-char (match-end 0))) + (push (buffer-substring (point) (line-end-position)) files) + (beginning-of-line 2)) + (nreverse files))))) + +(defcustom counsel-file-jump-args (split-string ". -name .git -prune -o -type f -print") + "Arguments for the `find-command' when using `counsel-file-jump'." + :type '(repeat string)) + ;;** `counsel-file-jump' ;;;###autoload (defun counsel-file-jump (&optional initial-input initial-directory) "Jump to a file below the current directory. -List all files within the current directory or any of its subdirectories. +List all files within the current directory or any of its sub-directories. INITIAL-INPUT can be given as the initial minibuffer input. INITIAL-DIRECTORY, if non-nil, is used as the root directory for search." (interactive (list nil (when current-prefix-arg (read-directory-name "From directory: ")))) - (counsel-require-program "find") - (let* ((default-directory (or initial-directory default-directory))) + (counsel-require-program find-program) + (let ((default-directory (or initial-directory default-directory))) (ivy-read "Find file: " - (split-string - (shell-command-to-string - (concat find-program " * -type f -not -path '*\/.git*'")) - "\n" t) + (counsel--find-return-list counsel-file-jump-args) :matcher #'counsel--find-file-matcher :initial-input initial-input - :action (lambda (x) - (with-ivy-window - (find-file (expand-file-name x ivy--directory)))) + :action #'find-file :preselect (counsel--preselect-file) :require-match 'confirm-after-completion :history 'file-name-history :keymap counsel-find-file-map :caller 'counsel-file-jump))) +(ivy-set-actions + 'counsel-file-jump + `(("d" ,(lambda (x) + (dired (or (file-name-directory x) default-directory))) + "open in dired"))) + +(defcustom counsel-dired-jump-args (split-string ". -name .git -prune -o -type d -print") + "Arguments for the `find-command' when using `counsel-dired-jump'." + :type '(repeat string)) + ;;** `counsel-dired-jump' ;;;###autoload (defun counsel-dired-jump (&optional initial-input initial-directory) - "Jump to a directory (in dired) below the current directory. -List all subdirectories within the current directory. + "Jump to a directory (see `dired-jump') below the current directory. +List all sub-directories within the current directory. INITIAL-INPUT can be given as the initial minibuffer input. INITIAL-DIRECTORY, if non-nil, is used as the root directory for search." (interactive (list nil (when current-prefix-arg (read-directory-name "From directory: ")))) - (counsel-require-program "find") - (let* ((default-directory (or initial-directory default-directory))) - (ivy-read "Directory: " - (split-string - (shell-command-to-string - (concat find-program " * -type d -not -path '*\/.git*'")) - "\n" t) + (counsel-require-program find-program) + (let ((default-directory (or initial-directory default-directory))) + (ivy-read "Find directory: " + (cdr + (counsel--find-return-list counsel-dired-jump-args)) + :matcher #'counsel--find-file-matcher :initial-input initial-input :action (lambda (d) (dired-jump nil (expand-file-name d))) + :history 'file-name-history + :keymap counsel-find-file-map :caller 'counsel-dired-jump))) ;;* Grep @@ -2436,21 +2686,16 @@ This function expects that the candidates have already been filtered. It applies no filtering to ivy--all-candidates." (unless (eq major-mode 'ivy-occur-grep-mode) (ivy-occur-grep-mode)) - (let* ((directory - (if git-grep-dir-is-file - (file-name-directory (ivy-state-directory ivy-last)) - (ivy-state-directory ivy-last))) - (prepend - (if git-grep-dir-is-file - (concat (file-name-nondirectory - (ivy-state-directory ivy-last)) ":") - ""))) + (let ((directory + (if git-grep-dir-is-file + (file-name-directory (ivy-state-directory ivy-last)) + (ivy-state-directory ivy-last)))) (setq default-directory directory) ;; 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 ivy--all-candidates))) (ivy--occur-insert-lines - (mapcar (lambda (cand) (concat "./" prepend cand)) ivy--all-candidates)))) + (mapcar #'counsel--normalize-grep-match ivy--all-candidates)))) ;;** `counsel-ag' (defvar counsel-ag-map @@ -2458,6 +2703,7 @@ It applies no filtering to ivy--all-candidates." (define-key map (kbd "C-l") 'ivy-call-and-recenter) (define-key map (kbd "M-q") 'counsel-git-grep-query-replace) (define-key map (kbd "C-'") 'swiper-avy) + (define-key map (kbd "C-x C-d") 'counsel-cd) map)) (defcustom counsel-ag-base-command @@ -2467,11 +2713,14 @@ It applies no filtering to ivy--all-candidates." "Format string to use in `counsel-ag-function' to construct the command. The %s will be replaced by optional extra ag arguments followed by the regex string." - :type 'string - :group 'ivy) + :type 'string) (defvar counsel-ag-command nil) +(defvar counsel--grep-tool-look-around t) + +(defvar counsel--regex-look-around nil) + (counsel-set-async-exit-code 'counsel-ag 1 "No matches found") (ivy-set-occur 'counsel-ag 'counsel-ag-occur) (ivy-set-display-transformer 'counsel-ag 'counsel-git-grep-transformer) @@ -2500,33 +2749,49 @@ NEEDLE is the search string." (replace-match needle t t extra-args 1) (concat extra-args " " needle)))) +(defun counsel--grep-regex (str) + (counsel--elisp-to-pcre + (setq ivy--old-re + (funcall ivy--regex-function str)) + counsel--regex-look-around)) + +(defun counsel--ag-extra-switches (regex) + "Get additional switches needed for look-arounds." + (and (stringp counsel--regex-look-around) + ;; using look-arounds + (string-match-p "\\`\\^(\\?[=!]" regex) + (concat " " counsel--regex-look-around " "))) + (defun counsel-ag-function (string) "Grep in the current directory for STRING." - (let ((command-args (counsel--split-command-args string))) - (let ((switches (car command-args)) - (search-term (cdr command-args))) - (if (< (length search-term) 3) - (let ((ivy-text search-term)) - (counsel-more-chars)) - (let ((default-directory (ivy-state-directory ivy-last)) - (regex (counsel-unquote-regex-parens - (setq ivy--old-re - (ivy--regex search-term))))) - (counsel--async-command (counsel--format-ag-command - switches - (shell-quote-argument regex))) - nil))))) + (let* ((command-args (counsel--split-command-args string)) + (search-term (cdr command-args))) + (or + (let ((ivy-text search-term)) + (ivy-more-chars)) + (let* ((default-directory (ivy-state-directory ivy-last)) + (regex (counsel--grep-regex search-term)) + (switches (concat (car command-args) + (counsel--ag-extra-switches regex) + (and (ivy--case-fold-p string) " -i ")))) + (counsel--async-command (counsel--format-ag-command + switches + (shell-quote-argument regex))) + nil)))) ;;;###autoload -(defun counsel-ag (&optional initial-input initial-directory extra-ag-args ag-prompt) +(cl-defun counsel-ag (&optional initial-input initial-directory extra-ag-args ag-prompt + &key caller) "Grep for a string in the current directory using ag. INITIAL-INPUT can be given as the initial minibuffer input. INITIAL-DIRECTORY, if non-nil, is used as the root directory for search. EXTRA-AG-ARGS string, if non-nil, is appended to `counsel-ag-base-command'. -AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." +AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument. +CALLER is passed to `ivy-read'." (interactive) (setq counsel-ag-command counsel-ag-base-command) - (counsel-require-program (car (split-string counsel-ag-command))) + (setq counsel--regex-look-around counsel--grep-tool-look-around) + (counsel-require-program counsel-ag-command) (when current-prefix-arg (setq initial-directory (or initial-directory @@ -2540,9 +2805,10 @@ AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." (car (split-string counsel-ag-command))))))) (setq counsel-ag-command (counsel--format-ag-command (or extra-ag-args "") "%s")) (let ((default-directory (or initial-directory - (locate-dominating-file default-directory ".git") + (counsel--git-root) default-directory))) - (ivy-read (or ag-prompt (car (split-string counsel-ag-command))) + (ivy-read (or ag-prompt + (concat (car (split-string counsel-ag-command)) ": ")) #'counsel-ag-function :initial-input initial-input :dynamic-collection t @@ -2552,9 +2818,17 @@ AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." :unwind (lambda () (counsel-delete-process) (swiper--cleanup)) - :caller 'counsel-ag))) + :caller (or caller 'counsel-ag)))) + +(defun counsel-cd () + "Change the directory for the currently running Ivy command." + (interactive) + (let ((input ivy-text) + (new-dir (read-directory-name "cd: "))) + (ivy-quit-and-run + (let ((default-directory new-dir)) + (funcall (ivy-state-caller ivy-last) input))))) -(ivy-set-prompt 'counsel-ag #'counsel-prompt-function-default) (cl-pushnew 'counsel-ag ivy-highlight-grep-commands) (defun counsel-grep-like-occur (cmd-template) @@ -2565,23 +2839,20 @@ AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." (and (string-match "\"\\(.*\\)\"" (buffer-name)) (match-string 1 (buffer-name)))) (let* ((command-args (counsel--split-command-args ivy-text)) + (regex (counsel--grep-regex (cdr command-args))) + (switches (concat (car command-args) + (counsel--ag-extra-switches regex))) (cmd (format cmd-template (concat - (car command-args) - (shell-quote-argument - (counsel-unquote-regex-parens - (ivy--regex (cdr command-args))))))) - (cands (split-string (shell-command-to-string cmd) - counsel-async-split-string-re - t))) + switches + (shell-quote-argument regex)))) + (cands (counsel--split-string (shell-command-to-string cmd)))) ;; 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 - (mapcar - (lambda (cand) (concat "./" cand)) - cands)))) + (mapcar #'counsel--normalize-grep-match cands)))) (defun counsel-ag-occur () "Generate a custom occur buffer for `counsel-ag'." @@ -2591,8 +2862,7 @@ AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." ;;** `counsel-pt' (defcustom counsel-pt-base-command "pt --nocolor --nogroup -e %s" "Alternative to `counsel-ag-base-command' using pt." - :type 'string - :group 'ivy) + :type 'string) ;;;###autoload (defun counsel-pt (&optional initial-input) @@ -2601,8 +2871,9 @@ INITIAL-INPUT can be given as the initial minibuffer input. This uses `counsel-ag' with `counsel-pt-base-command' instead of `counsel-ag-base-command'." (interactive) - (let ((counsel-ag-base-command counsel-pt-base-command)) - (counsel-ag initial-input))) + (let ((counsel-ag-base-command counsel-pt-base-command) + (counsel--grep-tool-look-around nil)) + (counsel-ag initial-input :caller 'counsel-pt))) (cl-pushnew 'counsel-pt ivy-highlight-grep-commands) ;;** `counsel-ack' @@ -2612,8 +2883,7 @@ This uses `counsel-ag' with `counsel-pt-base-command' instead of (or (executable-find "ack-grep") "ack")) " --nocolor --nogroup %s") "Alternative to `counsel-ag-base-command' using ack." - :type 'string - :group 'ivy) + :type 'string) ;;;###autoload (defun counsel-ack (&optional initial-input) @@ -2622,17 +2892,20 @@ INITIAL-INPUT can be given as the initial minibuffer input. This uses `counsel-ag' with `counsel-ack-base-command' replacing `counsel-ag-base-command'." (interactive) - (let ((counsel-ag-base-command counsel-ack-base-command)) - (counsel-ag initial-input))) + (let ((counsel-ag-base-command counsel-ack-base-command) + (counsel--grep-tool-look-around t)) + (counsel-ag initial-input :caller 'counsel-ack))) ;;** `counsel-rg' -(defcustom counsel-rg-base-command "rg -S --no-heading --line-number --color never %s ." +(defcustom counsel-rg-base-command + (if (memq system-type '(ms-dos windows-nt)) + "rg -S --no-heading --line-number --color never %s ." + "rg -S --no-heading --line-number --color never %s") "Alternative to `counsel-ag-base-command' using ripgrep. Note: don't use single quotes for the regex." - :type 'string - :group 'ivy) + :type 'string) (counsel-set-async-exit-code 'counsel-rg 1 "No matches found") (ivy-set-occur 'counsel-rg 'counsel-ag-occur) @@ -2644,10 +2917,19 @@ Note: don't use single quotes for the regex." INITIAL-INPUT can be given as the initial minibuffer input. INITIAL-DIRECTORY, if non-nil, is used as the root directory for search. EXTRA-RG-ARGS string, if non-nil, is appended to `counsel-rg-base-command'. -RG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." +RG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument. + +Example input with inclusion and exclusion file patterns: + -g*.py -g!*test* -- ..." (interactive) - (let ((counsel-ag-base-command counsel-rg-base-command)) - (counsel-ag initial-input initial-directory extra-rg-args rg-prompt))) + (let ((counsel-ag-base-command counsel-rg-base-command) + (counsel--grep-tool-look-around + (let ((rg (car (split-string counsel-rg-base-command))) + (switch "--pcre2")) + (and (eq 0 (call-process rg nil nil nil switch "--version")) + switch)))) + (counsel-ag initial-input initial-directory extra-rg-args rg-prompt + :caller 'counsel-rg))) (cl-pushnew 'counsel-rg ivy-highlight-grep-commands) ;;** `counsel-grep' @@ -2663,16 +2945,15 @@ RG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." It should contain two %-sequences (see function `format') to be substituted by the search regexp and file, respectively. Neither %-sequence should be contained in single quotes." - :type 'string - :group 'ivy) + :type 'string) (defvar counsel-grep-command nil) (defun counsel-grep-function (string) "Grep in the current directory for STRING." (or - (counsel-more-chars) - (let ((regex (counsel-unquote-regex-parens + (ivy-more-chars) + (let ((regex (counsel--elisp-to-pcre (setq ivy--old-re (ivy--regex string))))) (counsel--async-command @@ -2725,6 +3006,9 @@ substituted by the search regexp and file, respectively. Neither (ivy-set-occur 'counsel-grep 'counsel-grep-occur) (counsel-set-async-exit-code 'counsel-grep 1 "") +(defvar counsel-grep-history nil + "History for `counsel-grep'.") + ;;;###autoload (defun counsel-grep (&optional initial-input) "Grep for a string in the file visited by the current buffer. @@ -2732,12 +3016,15 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (interactive) (unless buffer-file-name (user-error "Current buffer is not visiting a file")) - (counsel-require-program (car (split-string counsel-grep-base-command))) + (counsel-require-program counsel-grep-base-command) (setq counsel-grep-last-line nil) (setq counsel-grep-command (format counsel-grep-base-command - "%s" (shell-quote-argument buffer-file-name))) - (let ((init-point (point)) + "%s" (shell-quote-argument + (file-name-nondirectory + buffer-file-name)))) + (let ((default-directory (file-name-directory buffer-file-name)) + (init-point (point)) res) (unwind-protect (setq res (ivy-read "grep: " 'counsel-grep-function @@ -2753,9 +3040,8 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (line-end-position))))) :keymap counsel-grep-map - :history 'counsel-git-grep-history - :update-fn (lambda () - (counsel-grep-action (ivy-state-current ivy-last))) + :history 'counsel-grep-history + :update-fn 'auto :re-builder #'ivy--regex :action #'counsel-grep-action :unwind (lambda () @@ -2765,13 +3051,35 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (unless res (goto-char init-point))))) +;;;###autoload +(defun counsel-grep-backward (&optional initial-input) + "Grep for a string in the file visited by the current buffer going +backward similar to `swiper-backward'. When non-nil, INITIAL-INPUT is +the initial search pattern." + (interactive) + (let ((ivy-index-functions-alist + '((counsel-grep . ivy-recompute-index-swiper-async-backward)))) + (counsel-grep initial-input))) + ;;** `counsel-grep-or-swiper' (defcustom counsel-grep-swiper-limit 300000 "Buffer size threshold for `counsel-grep-or-swiper'. When the number of characters in a buffer exceeds this threshold, `counsel-grep' will be used instead of `swiper'." - :type 'integer - :group 'ivy) + :type 'integer) + +(defcustom counsel-grep-use-swiper-p #'counsel-grep-use-swiper-p-default + "When this function returns non-nil, call `swiper', else `counsel-grep'." + :type '(choice + (const :tag "Rely on `counsel-grep-swiper-limit'." + counsel-grep-use-swiper-p-default) + (const :tag "Always use `counsel-grep'." ignore) + (function :tag "Custom"))) + +(defun counsel-grep-use-swiper-p-default () + (<= (buffer-size) + (/ counsel-grep-swiper-limit + (if (eq major-mode 'org-mode) 4 1)))) ;;;###autoload (defun counsel-grep-or-swiper (&optional initial-input) @@ -2783,19 +3091,28 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (ignore-errors (file-remote-p buffer-file-name)) (jka-compr-get-compression-info buffer-file-name) - (<= (buffer-size) - (/ counsel-grep-swiper-limit - (if (eq major-mode 'org-mode) 4 1)))) + (funcall counsel-grep-use-swiper-p)) (swiper initial-input) (when (file-writable-p buffer-file-name) (save-buffer)) (counsel-grep initial-input))) +;;** `counsel-grep-or-swiper-backward' +;;;###autoload +(defun counsel-grep-or-swiper-backward (&optional initial-input) + "Call `swiper-backward' for small buffers and `counsel-grep-backward' for +large ones. When non-nil, INITIAL-INPUT is the initial search pattern." + (interactive) + (let ((ivy-index-functions-alist + '((swiper . ivy-recompute-index-swiper-backward) + (counsel-grep . ivy-recompute-index-swiper-async-backward)))) + (counsel-grep-or-swiper initial-input))) + ;;** `counsel-recoll' (defun counsel-recoll-function (str) "Run recoll for STR." (or - (counsel-more-chars) + (ivy-more-chars) (progn (counsel--async-command (format "recoll -t -b %s" @@ -2804,12 +3121,13 @@ When non-nil, INITIAL-INPUT is the initial search pattern." ;; This command uses the recollq command line tool that comes together ;; with the recoll (the document indexing database) source: -;; http://www.lesbonscomptes.com/recoll/download.html +;; https://www.lesbonscomptes.com/recoll/download.html ;; You need to build it yourself (together with recoll): ;; cd ./query && make && sudo cp recollq /usr/local/bin ;; You can try the GUI version of recoll with: ;; sudo apt-get install recoll ;; Unfortunately, that does not install recollq. +;;;###autoload (defun counsel-recoll (&optional initial-input) "Search for a string in the recoll database. You'll be given a list of files that match. @@ -2847,7 +3165,7 @@ INITIAL-INPUT can be given as the initial minibuffer input." (defun counsel--org-make-tag-string () (if (fboundp #'org-make-tag-string) ;; >= Org 9.2 - (org-make-tag-string (org-get-tags)) + (org-make-tag-string (counsel--org-get-tags)) (with-no-warnings (org-get-tags-string)))) @@ -2931,7 +3249,7 @@ otherwise continue prompting for tags." (goto-char m) (setq counsel-org-tags (delete-dups - (append (org-get-tags) add-tags))) + (append (counsel--org-get-tags) add-tags))) (counsel-org--set-tags)))))) (counsel-org--set-tags))) ((eq this-command 'ivy-call) @@ -2957,6 +3275,12 @@ otherwise continue prompting for tags." (declare-function org-agenda-set-tags "org-agenda") (declare-function org-tags-completion-function "org") +;;;###autoload +(defun counsel--org-get-tags () + (delete "" (condition-case nil + (org-get-tags nil t) + (error (org-get-tags))))) + ;;;###autoload (defun counsel-org-tag () "Add or remove tags in `org-mode'." @@ -2969,10 +3293,10 @@ otherwise continue prompting for tags." (org-agenda-error)))) (with-current-buffer (marker-buffer hdmarker) (goto-char hdmarker) - (setq counsel-org-tags (org-get-tags))))) + (setq counsel-org-tags (counsel--org-get-tags))))) (unless (org-at-heading-p) (org-back-to-heading t)) - (setq counsel-org-tags (org-get-tags))) + (setq counsel-org-tags (counsel--org-get-tags))) (let ((org-last-tags-completion-table (append (and (or org-complete-tags-always-offer-all-agenda-tags (eq major-mode 'org-agenda-mode)) @@ -2992,38 +3316,35 @@ otherwise continue prompting for tags." :action #'counsel-org-tag-action :caller 'counsel-org-tag)))) +(defvar org-version) + ;;;###autoload (defun counsel-org-tag-agenda () "Set tags for the current agenda item." (interactive) - (let ((store (symbol-function 'org-set-tags))) - (unwind-protect - (progn - (fset 'org-set-tags - (symbol-function 'counsel-org-tag)) - (org-agenda-set-tags nil nil)) - (fset 'org-set-tags store)))) + (cl-letf (((symbol-function (if (version< org-version "9.2") + 'org-set-tags + 'org-set-tags-command)) + #'counsel-org-tag)) + (org-agenda-set-tags))) (define-obsolete-variable-alias 'counsel-org-goto-display-tags 'counsel-org-headline-display-tags "0.10.0") (defcustom counsel-org-headline-display-tags nil "If non-nil, display tags in matched `org-mode' headlines." - :type 'boolean - :group 'ivy) + :type 'boolean) (define-obsolete-variable-alias 'counsel-org-goto-display-todo 'counsel-org-headline-display-todo "0.10.0") (defcustom counsel-org-headline-display-todo nil "If non-nil, display todo keywords in matched `org-mode' headlines." - :type 'boolean - :group 'ivy) + :type 'boolean) (defcustom counsel-org-headline-display-priority nil "If non-nil, display priorities in matched `org-mode' headlines." - :type 'boolean - :group 'ivy) + :type 'boolean) (declare-function org-get-heading "org") (declare-function org-goto-marker-or-bmk "org") @@ -3032,6 +3353,89 @@ otherwise continue prompting for tags." ;;;###autoload (defalias 'counsel-org-goto #'counsel-outline) +(defcustom counsel-org-goto-all-outline-path-prefix nil + "Prefix for outline candidates in `counsel-org-goto-all'." + :type '(choice + (const :tag "None" nil) + (const :tag "File name" file-name) + (const :tag "File name (nondirectory part)" file-name-nondirectory) + (const :tag "Buffer name" buffer-name))) + +(defun counsel-org-goto-all--outline-path-prefix () + (cl-case counsel-org-goto-all-outline-path-prefix + (file-name buffer-file-name) + (file-name-nondirectory (file-name-nondirectory buffer-file-name)) + (buffer-name (buffer-name)))) + +(defvar counsel-outline-settings + '((emacs-lisp-mode + :outline-regexp ";;[;*]+[\s\t]+" + :outline-level counsel-outline-level-emacs-lisp) + (org-mode + :outline-title counsel-outline-title-org + :action counsel-org-goto-action + :history counsel-org-goto-history + :caller counsel-org-goto) + ;; markdown-mode package + (markdown-mode + :outline-title counsel-outline-title-markdown) + ;; Built-in mode or AUCTeX package + (latex-mode + :outline-title counsel-outline-title-latex)) + "Alist mapping major modes to their `counsel-outline' settings. + +Each entry is a pair (MAJOR-MODE . PLIST). `counsel-outline' +checks whether an entry exists for the current buffer's +MAJOR-MODE and, if so, loads the settings specified by PLIST +instead of the default settings. The following settings are +recognized: + +- `:outline-regexp' is a regexp to match the beginning of an + outline heading. It is only checked at the start of a line and + so need not start with \"^\". + Defaults to the value of the variable `outline-regexp'. + +- `:outline-level' is a function of no arguments which computes + the level of an outline heading. It is called with point at + the beginning of `outline-regexp' and with the match data + corresponding to `outline-regexp'. + Defaults to the value of the variable `outline-level'. + +- `:outline-title' is a function of no arguments which returns + the title of an outline heading. It is called with point at + the end of `outline-regexp' and with the match data + corresponding to `outline-regexp'. + Defaults to the function `counsel-outline-title'. + +- `:action' is a function of one argument, the selected outline + heading to jump to. This setting corresponds directly to its + eponymous `ivy-read' keyword, as used by `counsel-outline', so + the type of the function's argument depends on the value + returned by `counsel-outline-candidates'. + Defaults to the function `counsel-outline-action'. + +- `:history' is a history list, usually a symbol representing a + history list variable. It corresponds directly to its + eponymous `ivy-read' keyword, as used by `counsel-outline'. + Defaults to the symbol `counsel-outline-history'. + +- `:caller' is a symbol to uniquely identify the caller to + `ivy-read'. It corresponds directly to its eponymous + `ivy-read' keyword, as used by `counsel-outline'. + Defaults to the symbol `counsel-outline'. + +- `:display-style' overrides the variable + `counsel-outline-display-style'. + +- `:path-separator' overrides the variable + `counsel-outline-path-separator'. + +- `:face-style' overrides the variable + `counsel-outline-face-style'. + +- `:custom-faces' overrides the variable + `counsel-outline-custom-faces'.") + ;;;###autoload (defun counsel-org-goto-all () "Go to a different location in any org file." @@ -3040,7 +3444,11 @@ otherwise continue prompting for tags." (dolist (b (buffer-list)) (with-current-buffer b (when (derived-mode-p 'org-mode) - (setq entries (nconc entries (counsel-outline-candidates)))))) + (setq entries + (nconc entries + (counsel-outline-candidates + (cdr (assq 'org-mode counsel-outline-settings)) + (counsel-org-goto-all--outline-path-prefix))))))) (ivy-read "Goto: " entries :history 'counsel-org-goto-history :action #'counsel-org-goto-action @@ -3050,8 +3458,6 @@ otherwise continue prompting for tags." "Go to headline in candidate X." (org-goto-marker-or-bmk (cdr x))) -(defvar org-version) - (defun counsel--org-get-heading-args () "Return list of arguments for `org-get-heading'. Try to return the right number of arguments for the current Org @@ -3077,26 +3483,19 @@ attachment directory associated with the current buffer, all contained files are listed, so the return value could conceivably include attachments of other Org buffers." (require 'org-attach) - (let* ((ids (let (res) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward "^:ID:[\t ]+\\(.*\\)$" nil t) - (push (match-string-no-properties 1) res)) - (nreverse res)))) - (files - (cl-remove-if-not - #'file-exists-p - (mapcar (lambda (id) - (expand-file-name - (concat (substring id 0 2) "/" (substring id 2)) - org-attach-directory)) - ids)))) + (let (dirs) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^:\\(ATTACH_DIR\\|ID\\):[\t ]+\\(.*\\)$" nil t) + (let ((dir (org-attach-dir))) + (when dir + (push dir dirs))))) (cl-mapcan (lambda (dir) (mapcar (lambda (file) (file-relative-name (expand-file-name file dir))) (org-attach-file-list dir))) - files))) + (nreverse dirs)))) ;;;###autoload (defun counsel-org-file () @@ -3230,8 +3629,7 @@ For displaying tags and TODO keywords in `org-mode' buffers, see :type '(choice (const :tag "Title only" title) (const :tag "Headline" headline) - (const :tag "Path" path)) - :group 'ivy) + (const :tag "Path" path))) (define-obsolete-variable-alias 'counsel-org-goto-separator 'counsel-outline-path-separator "0.10.0") @@ -3242,8 +3640,7 @@ For displaying tags and TODO keywords in `org-mode' buffers, see "String separating path entries in matched outline headings. This variable has no effect unless `counsel-outline-display-style' is set to `path'." - :type 'string - :group 'ivy) + :type 'string) (declare-function org-get-outline-path "org") @@ -3299,11 +3696,49 @@ This variable has no effect unless ;;* Misc. Emacs ;;** `counsel-mark-ring' +(defface counsel--mark-ring-highlight + '((t (:inherit highlight))) + "Face for current `counsel-mark-ring' line." + :group 'ivy-faces) + +(defvar counsel--mark-ring-overlay nil + "Internal overlay to highlight line by candidate of `counsel-mark-ring'.") + +(defun counsel--mark-ring-add-highlight () + "Add highlight to current line." + (setq counsel--mark-ring-overlay + (make-overlay (line-beginning-position) (1+ (line-end-position)))) + (with-ivy-window + (overlay-put counsel--mark-ring-overlay 'face + 'counsel--mark-ring-highlight))) + +(defun counsel--mark-ring-delete-highlight () + "If `counsel-mark-ring' have highlight, delete highlight." + (if counsel--mark-ring-overlay (delete-overlay counsel--mark-ring-overlay))) + +(defvar counsel--mark-ring-calling-point 0 + "Internal variable to remember calling position.") + +(defun counsel--mark-ring-unwind () + "Return back to calling position of `counsel-mark-ring'." + (goto-char counsel--mark-ring-calling-point) + (counsel--mark-ring-delete-highlight)) + +(defun counsel--mark-ring-update-fn () + "Show preview by candidate." + (let ((linenum (string-to-number (ivy-state-current ivy-last)))) + (counsel--mark-ring-delete-highlight) + (unless (= linenum 0) + (with-ivy-window + (forward-line (- linenum (line-number-at-pos))))))) + +;;;###autoload (defun counsel-mark-ring () "Browse `mark-ring' interactively. Obeys `widen-automatically', which see." (interactive) - (let ((cands + (let ((counsel--mark-ring-calling-point (point)) + (cands (save-excursion (save-restriction ;; Widen, both to save `line-number-at-pos' the trouble @@ -3323,6 +3758,7 @@ Obeys `widen-automatically', which see." (if cands (ivy-read "Mark: " cands :require-match t + :update-fn #'counsel--mark-ring-update-fn :action (lambda (cand) (let ((pos (cdr-safe cand))) (when pos @@ -3332,6 +3768,7 @@ Obeys `widen-automatically', which see." (error "\ Position of selected mark outside accessible part of buffer"))) (goto-char pos)))) + :unwind #'counsel--mark-ring-unwind :caller 'counsel-mark-ring) (message "Mark ring is empty")))) @@ -3343,6 +3780,9 @@ Position of selected mark outside accessible part of buffer"))) (declare-function package-delete "package") (declare-function package-desc-extras "package") +(defvar counsel-package-history nil + "History for `counsel-package'.") + (defun counsel--package-candidates () "Return completion alist for `counsel-package'." (unless package--initialized @@ -3357,6 +3797,7 @@ Position of selected mark outside accessible part of buffer"))) package-archive-contents) #'counsel--package-sort)) +;;;###autoload (defun counsel-package () "Install or delete packages. @@ -3375,9 +3816,10 @@ Additional actions:\\ (counsel--package-candidates) :action #'counsel-package-action :require-match t + :history 'counsel-package-history :caller 'counsel-package)) -(cl-pushnew '(counsel-package . "^+ ") ivy-initial-inputs-alist :key #'car) +(cl-pushnew '(counsel-package . "^+") ivy-initial-inputs-alist :key #'car) (defun counsel-package-action (package) "Delete or install PACKAGE." @@ -3441,7 +3883,7 @@ Additional actions:\\ ;;;###autoload (defun counsel-tmm () - "Text-mode emulation of looking and choosing from a menubar." + "Text-mode emulation of looking and choosing from a menu bar." (interactive) (require 'tmm) (run-hooks 'menu-bar-update-hook) @@ -3451,8 +3893,7 @@ Additional actions:\\ ;;** `counsel-yank-pop' (defcustom counsel-yank-pop-truncate-radius 2 "Number of context lines around `counsel-yank-pop' candidates." - :type 'integer - :group 'ivy) + :type 'integer) (defun counsel--yank-pop-truncate (str) "Truncate STR for use in `counsel-yank-pop'." @@ -3481,18 +3922,13 @@ Additional actions:\\ (defcustom counsel-yank-pop-separator "\n" "Separator for the kill ring strings in `counsel-yank-pop'." - :group 'ivy - :type 'string) - -(make-obsolete-variable - 'counsel-yank-pop-height - 'ivy-height-alist - "<2018-04-14 Fri>") ;; TODO: Add version tag + :type '(choice + (const :tag "Plain" "\n") + (const :tag "Dashes" "\n----\n") + string)) -(defcustom counsel-yank-pop-height 5 - "The `ivy-height' of `counsel-yank-pop'." - :group 'ivy - :type 'integer) +(define-obsolete-variable-alias 'counsel-yank-pop-height + 'ivy-height-alist "0.11.0") (defun counsel--yank-pop-format-function (cand-pairs) "Transform CAND-PAIRS into a string for `counsel-yank-pop'." @@ -3507,7 +3943,7 @@ Additional actions:\\ (lambda (str) (counsel--yank-pop-truncate str)) cand-pairs - counsel-yank-pop-separator)) + (propertize counsel-yank-pop-separator 'face 'ivy-separator))) (defun counsel--yank-pop-position (s) "Return position of S in `kill-ring' relative to last yank." @@ -3528,7 +3964,6 @@ Newlines and carriage returns are considered blank." All elements of `kill-ring' for which this function returns nil will be destructively removed from `kill-ring' before completion. All blank strings are deleted from `kill-ring' by default." - :group 'ivy :type '(radio (function-item counsel-string-non-blank-p) (function-item identity) @@ -3537,7 +3972,7 @@ All blank strings are deleted from `kill-ring' by default." (defun counsel--yank-pop-kills () "Return filtered `kill-ring' for `counsel-yank-pop' completion. Both `kill-ring' and `kill-ring-yank-pointer' may be -destructively modifed to eliminate duplicates under +destructively modified to eliminate duplicates under `equal-including-properties', satisfy `counsel-yank-pop-filter', and incorporate `interprogram-paste-function'." ;; Protect against `kill-ring' and result of @@ -3556,7 +3991,6 @@ Nil means `counsel-yank-pop' puts point at the end of the yanked text and mark at its beginning, as per the default \\[yank]. Non-nil means `counsel-yank-pop' swaps the resulting point and mark, as per \\[universal-argument] \\[yank]." - :group 'ivy :type 'boolean) (defun counsel-yank-pop-action (s) @@ -3567,9 +4001,12 @@ buffer position." (barf-if-buffer-read-only) (setq last-command 'yank) (setq yank-window-start (window-start)) - ;; Avoid unexpected additions to `kill-ring' - (let (interprogram-paste-function) - (yank-pop (counsel--yank-pop-position s))) + (condition-case nil + ;; Avoid unexpected additions to `kill-ring' + (let (interprogram-paste-function) + (yank-pop (counsel--yank-pop-position s))) + (error + (insert s))) (when (funcall (if counsel-yank-pop-after-point #'> #'<) (point) (mark t)) (exchange-point-and-mark t)))) @@ -3613,7 +4050,6 @@ prefix argument of `counsel-yank-pop' defaults to 1 (as per `yank-pop'), which causes the next-to-last kill to be preselected. Otherwise, the prefix argument defaults to 0, which results in the most recent kill being preselected." - :group 'ivy :type 'boolean) (autoload 'xor "array") @@ -3639,8 +4075,7 @@ Note: Duplicate elements of `kill-ring' are always deleted." (t 1)) t))) (counsel-yank-pop-after-point - (xor (consp arg) counsel-yank-pop-after-point)) - (ivy-format-function #'counsel--yank-pop-format-function)) + (xor (consp arg) counsel-yank-pop-after-point))) (unless (eq last-command 'yank) (push-mark)) (ivy-read "kill-ring: " kills @@ -3648,7 +4083,7 @@ Note: Duplicate elements of `kill-ring' are always deleted." :preselect preselect :action #'counsel-yank-pop-action :caller 'counsel-yank-pop))) - +(add-to-list 'ivy-format-functions-alist '(counsel-yank-pop . counsel--yank-pop-format-function)) (add-to-list 'ivy-height-alist '(counsel-yank-pop . 5)) (ivy-set-actions @@ -3656,30 +4091,76 @@ Note: Duplicate elements of `kill-ring' are always deleted." '(("d" counsel-yank-pop-action-remove "delete") ("r" counsel-yank-pop-action-rotate "rotate"))) -;;** `counsel-evil-registers' -(make-obsolete-variable - 'counsel-evil-registers-height - 'ivy-height-alist - "<2018-04-14 Fri>") ;; TODO: Add version tag +;;** `counsel-register' +(defvar counsel-register-actions + '(("\\`buffer position" . jump-to-register) + ("\\`text" . insert-register) + ("\\`rectangle" . insert-register) + ("\\`window configuration" . jump-to-register) + ("\\`frame configuration" . jump-to-register) + ("\\`[-+]?[0-9]+\\(?:\\.[0-9]\\)?\\'" . insert-register) + ("\\`the file" . jump-to-register) + ("\\`keyboard macro" . jump-to-register) + ("\\`file-query" . jump-to-register)) + "Alist of (REGEXP . FUNCTION) pairs for `counsel-register'. +Selecting a register whose description matches REGEXP specifies +FUNCTION as the action to take on the register.") + +(defvar counsel-register-history nil + "History for `counsel-register'.") + +(defun counsel-register-action (register) + "Default action for `counsel-register'. + +Call a function on REGISTER. The function is determined by +matching the register's value description against a regexp in +`counsel-register-actions'." + (let* ((val (get-text-property 0 'register register)) + (desc (register-describe-oneline val)) + (action (cdr (cl-assoc-if (lambda (re) (string-match-p re desc)) + counsel-register-actions)))) + (if action + (funcall action val) + (error "No action was found for register %s" + (single-key-description val))))) +;;;###autoload +(defun counsel-register () + "Interactively choose a register." + (interactive) + (ivy-read "Register: " + (cl-mapcan + (lambda (reg) + (let ((s (funcall register-preview-function reg))) + (setq s (substring s 0 (string-match-p "[ \t\n\r]+\\'" s))) + (unless (string= s "") + (put-text-property 0 1 'register (car reg) s) + (list s)))) + register-alist) + :require-match t + :sort t + :history 'counsel-register-history + :action #'counsel-register-action + :caller 'counsel-register)) + +;;** `counsel-evil-registers' (defcustom counsel-evil-registers-height 5 "The `ivy-height' of `counsel-evil-registers'." - :group 'ivy :type 'integer) +;;;###autoload (defun counsel-evil-registers () "Ivy replacement for `evil-show-registers'." (interactive) (if (fboundp 'evil-register-list) - (let ((ivy-format-function #'counsel--yank-pop-format-function)) - (ivy-read "evil-registers: " - (cl-loop for (key . val) in (evil-register-list) - collect (format "[%c]: %s" key (if (stringp val) val ""))) - :require-match t - :action #'counsel-evil-registers-action - :caller 'counsel-evil-registers)) + (ivy-read "evil-registers: " + (cl-loop for (key . val) in (evil-register-list) + collect (format "[%c]: %s" key (if (stringp val) val ""))) + :require-match t + :action #'counsel-evil-registers-action + :caller 'counsel-evil-registers) (user-error "Required feature `evil' not installed."))) - +(add-to-list 'ivy-format-functions-alist '(counsel-evil-registers . counsel--yank-pop-format-function)) (add-to-list 'ivy-height-alist '(counsel-evil-registers . 5)) (defun counsel-evil-registers-action (s) @@ -3709,7 +4190,7 @@ PREFIX is used to create the key." (let ((key (concat (when prefix (concat - (propertize prefix 'face 'compilation-info) + (propertize prefix 'face 'ivy-grep-info) ": ")) (car elm)))) (list (cons key @@ -3819,58 +4300,25 @@ An extra action allows to switch to the process buffer." :caller 'counsel-ace-link)))) ;;** `counsel-minibuffer-history' -(make-obsolete - 'counsel-expression-history - 'counsel-minibuffer-history - "0.10.0 <2017-11-13 Mon>") - -(make-obsolete - 'counsel-shell-command-history - 'counsel-minibuffer-history - "0.10.0 <2017-11-13 Mon>") - -;;;###autoload -(defun counsel-expression-history () - "Select an element of `read-expression-history'. -And insert it into the minibuffer. Useful during `eval-expression'." - (interactive) - (let ((enable-recursive-minibuffers t)) - (ivy-read "Expression: " - (delete-dups (copy-sequence read-expression-history)) - :action #'insert - :caller 'counsel-expression-history))) - -;;;###autoload -(defun counsel-shell-command-history () - "Browse shell command history." - (interactive) - (ivy-read "Command: " shell-command-history - :action #'insert - :caller 'counsel-shell-command-history)) - ;;;###autoload (defun counsel-minibuffer-history () "Browse minibuffer history." (interactive) (let ((enable-recursive-minibuffers t)) - (ivy-read "History: " - (delete-dups (copy-sequence - (symbol-value minibuffer-history-variable))) + (ivy-read "History: " (ivy-history-contents minibuffer-history-variable) + :keymap ivy-reverse-i-search-map :action #'insert :caller 'counsel-minibuffer-history))) ;;** `counsel-esh-history' -(defun counsel--browse-history (elements) - "Use Ivy to navigate through ELEMENTS." +(defun counsel--browse-history (ring) + "Use Ivy to navigate through RING." (setq ivy-completion-beg (point)) (setq ivy-completion-end (point)) - (let ((cands - (delete-dups - (when (> (ring-size elements) 0) - (ring-elements elements))))) - (ivy-read "Symbol name: " cands - :action #'ivy-completion-in-region-action - :caller 'counsel-shell-history))) + (ivy-read "History: " (ivy-history-contents ring) + :keymap ivy-reverse-i-search-map + :action #'ivy-completion-in-region-action + :caller 'counsel-shell-history)) (defvar eshell-history-ring) @@ -3894,6 +4342,7 @@ And insert it into the minibuffer. Useful during `eval-expression'." (defvar hydra-curr-body-fn) (declare-function hydra-keyboard-quit "ext:hydra") +;;;###autoload (defun counsel-hydra-heads () "Call a head of the current/last hydra." (interactive) @@ -3968,6 +4417,7 @@ TREEP is used to expand internal nodes." (semantic-tag-get-attribute tag :members))))) (semantic-fetch-tags))) +;;;###autoload (defun counsel-semantic () "Jump to a semantic tag in the current buffer." (interactive) @@ -3982,6 +4432,7 @@ TREEP is used to expand internal nodes." :history 'counsel-semantic-history :caller 'counsel-semantic))) +;;;###autoload (defun counsel-semantic-or-imenu () (interactive) (require 'semantic/fw) @@ -3996,9 +4447,10 @@ TREEP is used to expand internal nodes." (defcustom counsel-outline-face-style nil "Determines how to style outline headings during completion. -If `org', the default faces from `org-mode' are applied, -i.e. `org-level-1' through `org-level-8'. Note that no cycling -is performed, so headings on levels 9 and higher are not styled. +If `org', the faces `counsel-outline-1' through +`counsel-outline-8' are applied in a similar way to Org. +Note that no cycling is performed, so headings on levels 9 and +higher are not styled. If `verbatim', the faces used in the buffer are applied. For simple headlines in `org-mode' buffers, this is usually the same @@ -4018,7 +4470,8 @@ are applied. Note that no cycling is performed, so if there is no face defined for a certain level, headlines on that level will not be styled. -If `nil', no faces are applied to the headlines. +If `nil', all headlines are highlighted using +`counsel-outline-default'. For displaying tags and TODO keywords in `org-mode' buffers, see `counsel-org-headline-display-tags' and @@ -4027,8 +4480,7 @@ For displaying tags and TODO keywords in `org-mode' buffers, see (const :tag "Same as org-mode" org) (const :tag "Verbatim" verbatim) (const :tag "Custom" custom) - (const :tag "No style" nil)) - :group 'ivy) + (const :tag "No style" nil))) (define-obsolete-variable-alias 'counsel-org-goto-custom-faces 'counsel-outline-custom-faces "0.10.0") @@ -4042,75 +4494,7 @@ entry in this list will not be styled. This variable has no effect unless `counsel-outline-face-style' is set to `custom'." - :type '(repeat face) - :group 'ivy) - -(defvar counsel-outline-settings - '((emacs-lisp-mode - :outline-regexp ";;[;*]+[\s\t]+" - :outline-level counsel-outline-level-emacs-lisp) - (org-mode - :outline-title counsel-outline-title-org - :action counsel-org-goto-action - :history counsel-org-goto-history - :caller counsel-org-goto) - (markdown-mode ; markdown-mode package - :outline-title counsel-outline-title-markdown) - (latex-mode ; Built-in mode or AUCTeX package - :outline-title counsel-outline-title-latex)) - "Alist mapping major modes to their `counsel-outline' settings. - -Each entry is a pair (MAJOR-MODE . PLIST). `counsel-outline' -checks whether an entry exists for the current buffer's -MAJOR-MODE and, if so, loads the settings specified by PLIST -instead of the default settings. The following settings are -recognized: - -- `:outline-regexp' is a regexp to match the beggining of an - outline heading. It is only checked at the start of a line and - so need not start with \"^\". - Defaults to the value of the variable `outline-regexp'. - -- `:outline-level' is a function of no arguments which computes - the level of an outline heading. It is called with point at - the beginning of `outline-regexp' and with the match data - corresponding to `outline-regexp'. - Defaults to the value of the variable `outline-level'. - -- `:outline-title' is a function of no arguments which returns - the title of an outline heading. It is called with point at - the end of `outline-regexp' and with the match data - corresponding to `outline-regexp'. - Defaults to the function `counsel-outline-title'. - -- `:action' is a function of one argument, the selected outline - heading to jump to. This setting corresponds directly to its - eponymous `ivy-read' keyword, as used by `counsel-outline', so - the type of the function's argument depends on the value - returned by `counsel-outline-candidates'. - Defaults to the function `counsel-outline-action'. - -- `:history' is a history list, usually a symbol representing a - history list variable. It corresponds directly to its - eponymous `ivy-read' keyword, as used by `counsel-outline'. - Defaults to the symbol `counsel-outline-history'. - -- `:caller' is a symbol to uniquely idendify the caller to - `ivy-read'. It corresponds directly to its eponymous - `ivy-read' keyword, as used by `counsel-outline'. - Defaults to the symbol `counsel-outline'. - -- `:display-style' overrides the variable - `counsel-outline-display-style'. - -- `:path-separator' overrides the variable - `counsel-outline-path-separator'. - -- `:face-style' overrides the variable - `counsel-outline-face-style'. - -- `:custom-faces' overrides the variable - `counsel-outline-custom-faces'.") + :type '(repeat face)) (defun counsel-outline-title () "Return title of current outline heading. @@ -4166,32 +4550,35 @@ setting in `counsel-outline-settings', which see." (funcall outline-level))) (defvar counsel-outline--preselect 0 - "Index of the presected candidate in `counsel-outline'.") + "Index of the preselected candidate in `counsel-outline'.") -(defun counsel-outline-candidates (&optional settings) +(defun counsel-outline-candidates (&optional settings prefix) "Return an alist of outline heading completion candidates. Each element is a pair (HEADING . MARKER), where the string HEADING is located at the position of MARKER. SETTINGS is a -plist entry from `counsel-outline-settings', which see." - (let ((bol-regex (concat "^\\(?:" - (or (plist-get settings :outline-regexp) - outline-regexp) - "\\)")) - (outline-title-fn (or (plist-get settings :outline-title) - #'counsel-outline-title)) - (outline-level-fn (or (plist-get settings :outline-level) - outline-level)) - (display-style (or (plist-get settings :display-style) - counsel-outline-display-style)) - (path-separator (or (plist-get settings :path-separator) - counsel-outline-path-separator)) - (face-style (or (plist-get settings :face-style) - counsel-outline-face-style)) - (custom-faces (or (plist-get settings :custom-faces) - counsel-outline-custom-faces)) - (stack-level 0) - (orig-point (point)) - cands name level marker stack) +plist entry from `counsel-outline-settings', which see. +PREFIX is a string prepended to all candidates." + (let* ((bol-regex (concat "^\\(?:" + (or (plist-get settings :outline-regexp) + outline-regexp) + "\\)")) + (outline-title-fn (or (plist-get settings :outline-title) + #'counsel-outline-title)) + (outline-level-fn (or (plist-get settings :outline-level) + outline-level)) + (display-style (or (plist-get settings :display-style) + counsel-outline-display-style)) + (path-separator (or (plist-get settings :path-separator) + counsel-outline-path-separator)) + (face-style (or (plist-get settings :face-style) + counsel-outline-face-style)) + (custom-faces (or (plist-get settings :custom-faces) + counsel-outline-custom-faces)) + (stack-level 0) + (orig-point (point)) + (stack (and prefix (list (counsel-outline--add-face + prefix 0 face-style custom-faces)))) + cands name level marker) (save-excursion (setq counsel-outline--preselect 0) (goto-char (point-min)) @@ -4239,8 +4626,8 @@ the face to apply." (verbatim) (custom (nth (1- level) (or custom-faces counsel-outline-custom-faces))) - (org (format "org-level-%d" level)) - (t 'minibuffer-prompt)))) + (org (format "counsel-outline-%d" level)) + (t 'counsel-outline-default)))) (when face (put-text-property 0 (length name) 'face face name))) name) @@ -4393,19 +4780,26 @@ Candidates comprise `counsel--unicode-names', which see.") "Insert COUNT copies of a Unicode character at point. COUNT defaults to 1." (interactive "p") - (let ((ivy-sort-max-size (expt 256 6))) - (setq ivy-completion-beg (point)) - (setq ivy-completion-end (point)) - (ivy-read "Unicode name: " counsel--unicode-table - :history 'counsel-unicode-char-history - :sort t - :action (lambda (name) - (with-ivy-window - (delete-region ivy-completion-beg ivy-completion-end) - (setq ivy-completion-beg (point)) - (insert-char (get-text-property 0 'code name) count) - (setq ivy-completion-end (point)))) - :caller 'counsel-unicode-char))) + (setq ivy-completion-beg (point)) + (setq ivy-completion-end (point)) + (ivy-read "Unicode name: " counsel--unicode-table + :history 'counsel-unicode-char-history + :sort t + :action (lambda (name) + (with-ivy-window + (delete-region ivy-completion-beg ivy-completion-end) + (setq ivy-completion-beg (point)) + (insert-char (get-text-property 0 'code name) count) + (setq ivy-completion-end (point)))) + :caller 'counsel-unicode-char)) + +(defun counsel-unicode-copy (name) + "Ivy action to copy the unicode from NAME to the kill ring." + (kill-new (char-to-string (get-text-property 0 'code name)))) + +(ivy-set-actions + 'counsel-unicode-char + '(("w" counsel-unicode-copy "copy"))) ;;** `counsel-colors' (defun counsel-colors-action-insert-hex (color) @@ -4421,17 +4815,50 @@ COUNT defaults to 1." "History for `counsel-colors-emacs'.") (defun counsel-colors--name-to-hex (name) - "Return hexadecimal RGB value of color with NAME." - (apply #'color-rgb-to-hex (color-name-to-rgb name))) + "Return hexadecimal RGB value of color with NAME. + +Return nil if NAME does not designate a valid color." + (let ((rgb (color-name-to-rgb name))) + (when rgb + (apply #'color-rgb-to-hex rgb)))) (defvar shr-color-visible-luminance-min) (declare-function shr-color-visible "shr-color") +(defvar counsel--colors-format "%-20s %s %s%s") -(defun counsel-colors--formatter (formatter) - "Turn FORMATTER into format function for `counsel-colors-*'. -Return closure suitable for `ivy-format-function'." +(defun counsel--colors-emacs-format-function (colors) + "Format function for `counsel-colors-emacs'." (require 'shr-color) - (lambda (colors) + (let* ((blank (make-string 10 ?\s)) + (formatter + (lambda (color) + (let ((fg (list :foreground color))) + (format counsel--colors-format color + (propertize (get-text-property 0 'hex color) 'face fg) + (propertize blank 'face (list :background color)) + (propertize (mapconcat (lambda (dup) + (concat " " dup)) + (get-text-property 0 'dups color) + ",") + 'face fg)))))) + (ivy--format-function-generic + (lambda (color) + (let* ((hex (get-text-property 0 'hex color)) + (shr-color-visible-luminance-min 100) + (fg (cadr (shr-color-visible hex "black" t)))) + (propertize (funcall formatter color) + 'face (list :foreground fg :background hex)))) + formatter colors "\n"))) + +(defun counsel--colors-web-format-function (colors) + "Format function for `counsel-colors-web'." + (require 'shr-color) + (let* ((blank (make-string 10 ?\s)) + (formatter (lambda (color) + (let ((hex (get-text-property 0 'hex color))) + (format counsel--colors-format color + (propertize hex 'face (list :foreground hex)) + (propertize blank 'face (list :background hex))))))) (ivy--format-function-generic (lambda (color) (let* ((hex (get-text-property 0 'hex color)) @@ -4448,32 +4875,24 @@ Return closure suitable for `ivy-format-function'." You can insert or kill the name or hexadecimal RGB value of the selected color." (interactive) - (let* ((colors (mapcar (lambda (cell) - (let ((name (car cell))) - (propertize name - 'hex (counsel-colors--name-to-hex name) - 'dups (cdr cell)))) - (list-colors-duplicates))) - (fmt (format "%%-%ds %%s %%s%%s" - (apply #'max 0 (mapcar #'string-width colors)))) - (blank (make-string 10 ?\s)) - (ivy-format-function - (counsel-colors--formatter - (lambda (color) - (let ((fg (list :foreground color))) - (format fmt color - (propertize (get-text-property 0 'hex color) 'face fg) - (propertize blank 'face (list :background color)) - (propertize (mapconcat (lambda (dup) - (concat " " dup)) - (get-text-property 0 'dups color) - ",") - 'face fg))))))) + (let* ((colors + (delete nil + (mapcar (lambda (cell) + (let* ((name (car cell)) + (dups (cdr cell)) + (hex (counsel-colors--name-to-hex name))) + (when hex + (propertize name 'hex hex 'dups dups)))) + (list-colors-duplicates)))) + (counsel--colors-format + (format "%%-%ds %%s %%s%%s" + (apply #'max 0 (mapcar #'string-width colors))))) (ivy-read "Emacs color: " colors :require-match t :history 'counsel-colors-emacs-history :action #'insert :caller 'counsel-colors-emacs))) +(add-to-list 'ivy-format-functions-alist '(counsel-colors-emacs . counsel--colors-emacs-format-function)) (ivy-set-actions 'counsel-colors-emacs @@ -4484,7 +4903,7 @@ selected color." (defvar shr-color-html-colors-alist) (defun counsel-colors--web-alist () - "Return list of CSS colours for `counsel-colors-web'." + "Return list of CSS colors for `counsel-colors-web'." (require 'shr-color) (let* ((alist (copy-alist shr-color-html-colors-alist)) (mp (assoc "MediumPurple" alist)) @@ -4511,16 +4930,9 @@ You can insert or kill the name or hexadecimal RGB value of the selected color." (interactive) (let* ((colors (counsel-colors--web-alist)) - (blank (make-string 10 ?\s)) - (fmt (format "%%-%ds %%s %%s" - (apply #'max 0 (mapcar #'string-width colors)))) - (ivy-format-function - (counsel-colors--formatter - (lambda (color) - (let ((hex (get-text-property 0 'hex color))) - (format fmt color - (propertize hex 'face (list :foreground hex)) - (propertize blank 'face (list :background hex)))))))) + (counsel--colors-format + (format "%%-%ds %%s %%s" + (apply #'max 0 (mapcar #'string-width colors))))) (ivy-read "Web color: " colors :require-match t :history 'counsel-colors-web-history @@ -4528,6 +4940,7 @@ selected color." :action #'insert :caller 'counsel-colors-web))) +(add-to-list 'ivy-format-functions-alist '(counsel-colors-web . counsel--colors-web-format-function)) (ivy-set-actions 'counsel-colors-web '(("h" counsel-colors-action-insert-hex "insert hexadecimal value") @@ -4538,13 +4951,33 @@ selected color." (declare-function dbus-call-method "dbus") (declare-function dbus-get-property "dbus") +(defun counsel--run (&rest program-and-args) + (let ((name (mapconcat #'identity program-and-args " "))) + (apply #'start-process name nil program-and-args) + name)) + +(defun counsel--sl (cmd) + "Shell command to list." + (split-string (shell-command-to-string cmd) "\n" t)) + (defun counsel-rhythmbox-play-song (song) "Let Rhythmbox play SONG." - (let ((service "org.gnome.Rhythmbox3") + (let ((first (string= (shell-command-to-string "pidof rhythmbox") "")) + (service "org.gnome.Rhythmbox3") (path "/org/mpris/MediaPlayer2") (interface "org.mpris.MediaPlayer2.Player")) + (when first + (counsel--run "nohup" "rhythmbox") + (sit-for 1.5)) (dbus-call-method :session service path interface - "OpenUri" (cdr song)))) + "OpenUri" (cdr song)) + (let ((id (and first + (cdr (counsel--wmctrl-parse + (shell-command-to-string + "wmctrl -l -p | grep $(pidof rhythmbox)")))))) + (when id + (sit-for 0.2) + (counsel--run "wmctrl" "-ic" id))))) (defun counsel-rhythmbox-enqueue-song (song) "Let Rhythmbox enqueue SONG." @@ -4554,6 +4987,21 @@ selected color." (dbus-call-method :session service path interface "AddToQueue" (cdr song)))) +(defun counsel-rhythmbox-toggle-shuffle (_song) + "Toggle Rhythmbox shuffle setting." + (let* ((old-order (counsel--command "dconf" "read" "/org/gnome/rhythmbox/player/play-order")) + (new-order (if (string= old-order "'shuffle'") + "'linear'" + "'shuffle'"))) + (counsel--command + "dconf" + "write" + "/org/gnome/rhythmbox/player/play-order" + new-order) + (message (if (string= new-order "'shuffle'") + "shuffle on" + "shuffle off")))) + (defvar counsel-rhythmbox-history nil "History for `counsel-rhythmbox'.") @@ -4574,11 +5022,11 @@ selected color." (format "%s - %s - %s" artist album title)))) ;;;###autoload -(defun counsel-rhythmbox () +(defun counsel-rhythmbox (&optional arg) "Choose a song from the Rhythmbox library to play or enqueue." - (interactive) + (interactive "P") (require 'dbus) - (unless counsel-rhythmbox-songs + (when (or arg (null counsel-rhythmbox-songs)) (let* ((service "org.gnome.Rhythmbox3") (path "/org/gnome/UPnP/MediaServer2/Library/all") (interface "org.gnome.UPnP.MediaContainer2") @@ -4599,30 +5047,50 @@ selected color." :session service path interface "ListChildren" 0 nb-songs '("*"))))))) (ivy-read "Rhythmbox: " counsel-rhythmbox-songs + :require-match t :history 'counsel-rhythmbox-history :preselect (counsel-rhythmbox-current-song) :action '(1 ("p" counsel-rhythmbox-play-song "Play song") - ("e" counsel-rhythmbox-enqueue-song "Enqueue song")) + ("e" counsel-rhythmbox-enqueue-song "Enqueue song") + ("s" counsel-rhythmbox-toggle-shuffle "Shuffle on/off")) :caller 'counsel-rhythmbox)) ;;** `counsel-linux-app' +(require 'xdg nil t) + +(defalias 'counsel--xdg-data-home + (if (fboundp 'xdg-data-home) + #'xdg-data-home + (lambda () + (let ((directory (getenv "XDG_DATA_HOME"))) + (if (or (null directory) (string= directory "")) + "~/.local/share" + directory)))) + "Compatibility shim for `xdg-data-home'.") + +(defalias 'counsel--xdg-data-dirs + (if (fboundp 'xdg-data-dirs) + #'xdg-data-dirs + (lambda () + (let ((path (getenv "XDG_DATA_DIRS"))) + (if (or (null path) (string= path "")) + '("/usr/local/share" "/usr/share") + (parse-colon-path path))))) + "Compatibility shim for `xdg-data-dirs'.") + (defcustom counsel-linux-apps-directories - '("~/.local/share/applications/" - "~/.guix-profile/share/applications/" - "/usr/local/share/applications/" - "/var/lib/flatpak/exports/share/applications/" - "/usr/share/applications/") + (mapcar (lambda (dir) (expand-file-name "applications" dir)) + (cons (counsel--xdg-data-home) + (counsel--xdg-data-dirs))) "Directories in which to search for applications (.desktop files)." - :group 'ivy :type '(repeat directory)) (defcustom counsel-linux-app-format-function #'counsel-linux-app-format-function-default "Function to format Linux application names the `counsel-linux-app' menu. The format function will be passed the application's name, comment, and command as arguments." - :group 'ivy :type '(choice (const :tag "Command : Name - Comment" counsel-linux-app-format-function-default) (const :tag "Name - Comment (Command)" counsel-linux-app-format-function-name-first) @@ -4630,6 +5098,56 @@ as arguments." (const :tag "Command" counsel-linux-app-format-function-command-only) (function :tag "Custom"))) +(defface counsel-application-name + '((t :inherit font-lock-builtin-face)) + "Face for displaying executable names." + :group 'ivy-faces) + +(defface counsel-outline-1 + '((t :inherit org-level-1)) + "Face for displaying level 1 headings." + :group 'ivy-faces) + +(defface counsel-outline-2 + '((t :inherit org-level-2)) + "Face for displaying level 2 headings." + :group 'ivy-faces) + +(defface counsel-outline-3 + '((t :inherit org-level-3)) + "Face for displaying level 3 headings." + :group 'ivy-faces) + +(defface counsel-outline-4 + '((t :inherit org-level-4)) + "Face for displaying level 4 headings." + :group 'ivy-faces) + +(defface counsel-outline-5 + '((t :inherit org-level-5)) + "Face for displaying level 5 headings." + :group 'ivy-faces) + +(defface counsel-outline-6 + '((t :inherit org-level-6)) + "Face for displaying level 6 headings." + :group 'ivy-faces) + +(defface counsel-outline-7 + '((t :inherit org-level-7)) + "Face for displaying level 7 headings." + :group 'ivy-faces) + +(defface counsel-outline-8 + '((t :inherit org-level-8)) + "Face for displaying level 8 headings." + :group 'ivy-faces) + +(defface counsel-outline-default + '((t :inherit minibuffer-prompt)) + "Face for displaying headings." + :group 'ivy-faces) + (defvar counsel-linux-apps-faulty nil "List of faulty desktop files.") @@ -4650,7 +5168,9 @@ as arguments." NAME is the name of the application, COMMENT its comment and EXEC the command to launch it." (format "% -45s: %s%s" - (propertize exec 'face 'font-lock-builtin-face) + (propertize + (ivy--truncate-string exec 45) + 'face 'counsel-application-name) name (if comment (concat " - " comment) @@ -4664,7 +5184,7 @@ EXEC is the command to launch the application." (if comment (concat " - " comment) "") - (propertize exec 'face 'font-lock-builtin-face))) + (propertize exec 'face 'counsel-application-name))) (defun counsel-linux-app-format-function-name-only (name comment _exec) "Format Linux application names with the NAME (and COMMENT) only." @@ -4694,6 +5214,56 @@ This function always returns its elements in a stable order." (puthash id file hash))))))) result)) +(defun counsel-linux-app--parse-file (file) + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (let ((start (re-search-forward "^\\[Desktop Entry\\] *$" nil t)) + (end (re-search-forward "^\\[" nil t)) + (visible t) + name comment exec) + (catch 'break + (unless start + (push file counsel-linux-apps-faulty) + (message "Warning: File %s has no [Desktop Entry] group" file) + (throw 'break nil)) + + (goto-char start) + (when (re-search-forward "^\\(Hidden\\|NoDisplay\\) *= *\\(1\\|true\\) *$" end t) + (setq visible nil)) + (setq name (match-string 1)) + + (goto-char start) + (unless (re-search-forward "^Type *= *Application *$" end t) + (throw 'break nil)) + (setq name (match-string 1)) + + (goto-char start) + (unless (re-search-forward "^Name *= *\\(.+\\)$" end t) + (push file counsel-linux-apps-faulty) + (message "Warning: File %s has no Name" file) + (throw 'break nil)) + (setq name (match-string 1)) + + (goto-char start) + (when (re-search-forward "^Comment *= *\\(.+\\)$" end t) + (setq comment (match-string 1))) + + (goto-char start) + (unless (re-search-forward "^Exec *= *\\(.+\\)$" end t) + ;; Don't warn because this can technically be a valid desktop file. + (throw 'break nil)) + (setq exec (match-string 1)) + + (goto-char start) + (when (re-search-forward "^TryExec *= *\\(.+\\)$" end t) + (let ((try-exec (match-string 1))) + (unless (locate-file try-exec exec-path nil #'file-executable-p) + (throw 'break nil)))) + (propertize + (funcall counsel-linux-app-format-function name comment exec) + 'visible visible))))) + (defun counsel-linux-apps-parse (desktop-entries-alist) "Parse the given alist of Linux desktop entries. Each entry in DESKTOP-ENTRIES-ALIST is a pair of ((id . file-name)). @@ -4702,56 +5272,11 @@ Any desktop entries that fail to parse are recorded in (let (result) (setq counsel-linux-apps-faulty nil) (dolist (entry desktop-entries-alist result) - (let ((id (car entry)) - (file (cdr entry))) - (with-temp-buffer - (insert-file-contents file) - (goto-char (point-min)) - (let ((start (re-search-forward "^\\[Desktop Entry\\] *$" nil t)) - (end (re-search-forward "^\\[" nil t)) - name comment exec) - (catch 'break - (unless start - (push file counsel-linux-apps-faulty) - (message "Warning: File %s has no [Desktop Entry] group" file) - (throw 'break nil)) - - (goto-char start) - (when (re-search-forward "^\\(Hidden\\|NoDisplay\\) *= *\\(1\\|true\\) *$" end t) - (throw 'break nil)) - (setq name (match-string 1)) - - (goto-char start) - (unless (re-search-forward "^Type *= *Application *$" end t) - (throw 'break nil)) - (setq name (match-string 1)) - - (goto-char start) - (unless (re-search-forward "^Name *= *\\(.+\\)$" end t) - (push file counsel-linux-apps-faulty) - (message "Warning: File %s has no Name" file) - (throw 'break nil)) - (setq name (match-string 1)) - - (goto-char start) - (when (re-search-forward "^Comment *= *\\(.+\\)$" end t) - (setq comment (match-string 1))) - - (goto-char start) - (unless (re-search-forward "^Exec *= *\\(.+\\)$" end t) - ;; Don't warn because this can technically be a valid desktop file. - (throw 'break nil)) - (setq exec (match-string 1)) - - (goto-char start) - (when (re-search-forward "^TryExec *= *\\(.+\\)$" end t) - (let ((try-exec (match-string 1))) - (unless (locate-file try-exec exec-path nil #'file-executable-p) - (throw 'break nil)))) - - (push - (cons (funcall counsel-linux-app-format-function name comment exec) id) - result)))))))) + (let* ((id (car entry)) + (file (cdr entry)) + (r (counsel-linux-app--parse-file file))) + (when r + (push (cons r id) result)))))) (defun counsel-linux-apps-list () "Return list of all Linux desktop applications." @@ -4767,10 +5292,10 @@ Any desktop entries that fail to parse are recorded in counsel--linux-apps-cache-timestamp (nth 5 (file-attributes file)))) new-files))) - (setq counsel--linux-apps-cache (counsel-linux-apps-parse new-desktop-alist) - counsel--linux-apps-cache-format-function counsel-linux-app-format-function - counsel--linux-apps-cache-timestamp (current-time) - counsel--linux-apps-cached-files new-files))) + (setq counsel--linux-apps-cache (counsel-linux-apps-parse new-desktop-alist)) + (setq counsel--linux-apps-cache-format-function counsel-linux-app-format-function) + (setq counsel--linux-apps-cache-timestamp (current-time)) + (setq counsel--linux-apps-cached-files new-files))) counsel--linux-apps-cache) @@ -4798,42 +5323,523 @@ Any desktop entries that fail to parse are recorded in ("d" counsel-linux-app-action-open-desktop "open desktop file"))) ;;;###autoload -(defun counsel-linux-app () - "Launch a Linux desktop application, similar to Alt-." - (interactive) +(defun counsel-linux-app (&optional arg) + "Launch a Linux desktop application, similar to Alt-. +When ARG is non-nil, ignore NoDisplay property in *.desktop files." + (interactive "P") (ivy-read "Run a command: " (counsel-linux-apps-list) + :predicate (unless arg (lambda (x) (get-text-property 0 'visible (car x)))) :action #'counsel-linux-app-action-default :caller 'counsel-linux-app)) ;;** `counsel-wmctrl' (defun counsel-wmctrl-action (x) "Select the desktop window that corresponds to X." - (shell-command - (format "wmctrl -i -a \"%s\"" (cdr x)))) + (counsel--run "wmctrl" "-i" "-a" (cdr x))) (defvar counsel-wmctrl-ignore '("XdndCollectionWindowImp" "unity-launcher" "unity-panel" "unity-dash" "Hud" "Desktop") "List of window titles to ignore for `counsel-wmctrl'.") +(defun counsel--wmctrl-parse (s) + (when (string-match "\\`\\([0-9a-fx]+\\) +\\([-0-9]+\\) +\\(?:[0-9]+\\) +\\([^ ]+\\) \\(.+\\)$" s) + (let ((title (match-string 4 s)) + (id (match-string 1 s))) + (unless (member title counsel-wmctrl-ignore) + (cons title id))))) + +;;;###autoload (defun counsel-wmctrl () "Select a desktop window using wmctrl." (interactive) - (let* ((cands1 (split-string (shell-command-to-string "wmctrl -l") "\n" t)) - (cands2 - (mapcar (lambda (s) - (when (string-match - "\\`\\([0-9a-fx]+\\) \\([0-9]+\\) \\([^ ]+\\) \\(.+\\)\\'" - s) - (let ((title (match-string 4 s)) - (id (match-string 1 s))) - (unless (member title counsel-wmctrl-ignore) - (cons title id))))) - cands1))) + (let* ((cands1 (counsel--sl "wmctrl -l -p")) + (cands2 (delq nil (mapcar #'counsel--wmctrl-parse cands1)))) (ivy-read "window: " cands2 :action #'counsel-wmctrl-action :caller 'counsel-wmctrl))) +(defvar counsel--switch-buffer-temporary-buffers nil + "Internal.") + +(defvar counsel--switch-buffer-previous-buffers nil + "Internal.") + +(defun counsel--switch-buffer-unwind () + "Clear temporary file buffers and restore `buffer-list'. +The buffers are those opened during a session of `counsel-switch-buffer'." + (mapc #'kill-buffer counsel--switch-buffer-temporary-buffers) + (mapc #'bury-buffer (cl-remove-if-not + #'buffer-live-p + counsel--switch-buffer-previous-buffers)) + (setq counsel--switch-buffer-temporary-buffers nil + counsel--switch-buffer-previous-buffers nil)) + +(defun counsel--switch-buffer-update-fn () + (unless counsel--switch-buffer-previous-buffers + (setq counsel--switch-buffer-previous-buffers (buffer-list))) + (let* ((current (ivy-state-current ivy-last)) + (virtual (assoc current ivy--virtual-buffers))) + (cond + ((get-buffer current) + (ivy-call)) + ((and virtual (file-exists-p (cdr virtual))) + (let ((buf (ignore-errors + ;; may not open due to `large-file-warning-threshold' etc. + (find-file-noselect (cdr virtual))))) + (if buf + (progn + (push buf counsel--switch-buffer-temporary-buffers) + (ivy-call)) + ;; clean up the minibuffer so that there's no delay before + ;; the Ivy candidates are displayed once again + (message "")))) + (t + (with-ivy-window + (switch-to-buffer (ivy-state-buffer ivy-last))))))) + +;;;###autoload +(defun counsel-switch-buffer () + "Switch to another buffer. +Display a preview of the selected ivy completion candidate buffer +in the current window." + (interactive) + (ivy-read "Switch to buffer: " 'internal-complete-buffer + :preselect (buffer-name (other-buffer (current-buffer))) + :keymap ivy-switch-buffer-map + :action #'ivy--switch-buffer-action + :matcher #'ivy--switch-buffer-matcher + :caller 'counsel-switch-buffer + :unwind #'counsel--switch-buffer-unwind + :update-fn 'counsel--switch-buffer-update-fn)) + +;;;###autoload +(defun counsel-switch-buffer-other-window () + "Switch to another buffer in another window. +Display a preview of the selected ivy completion candidate buffer +in the current window." + (interactive) + (ivy-read "Switch to buffer in other window: " 'internal-complete-buffer + :preselect (buffer-name (other-buffer (current-buffer))) + :action #'ivy--switch-buffer-other-window-action + :matcher #'ivy--switch-buffer-matcher + :caller 'counsel-switch-buffer-other-window + :unwind #'counsel--switch-buffer-unwind + :update-fn 'counsel--switch-buffer-update-fn)) + +(defun counsel-open-buffer-file-externally (buffer) + "Open the file associated with BUFFER with an external program." + (when (zerop (length buffer)) + (user-error "Can't open that")) + (let* ((virtual (assoc buffer ivy--virtual-buffers)) + (filename (if virtual + (cdr virtual) + (buffer-file-name (get-buffer buffer))))) + (unless filename + (user-error "Can't open `%s' externally" buffer)) + (counsel-locate-action-extern (expand-file-name filename)))) + +(ivy-add-actions + 'ivy-switch-buffer + '(("x" counsel-open-buffer-file-externally "open externally"))) + +;;** `counsel-compile' +(defvar counsel-compile-history nil + "History for `counsel-compile'. + +This is a list of strings with additional properties which allow +the history to be filtered depending on the context of the call. +The properties include: + +`srcdir' + the root directory of the source code +`blddir' + the root directory of the build (in or outside the `srcdir') +`bldenv' + the build environment as passed to `compilation-environment' +`recursive' + the completion should be run again in `blddir' of this result +`cmd' + if set, pass only the substring with this property to `compile' + +This variable is suitable for addition to +`savehist-additional-variables'.") + +(defvar counsel-compile-root-functions + '(counsel--project-current + counsel--configure-root + counsel--git-root + counsel--dir-locals-root) + "Special hook to find the project root for compile commands. +Each function on this hook is called in turn with no arguments +and should return either a directory, or nil if no root was +found.") + +(defun counsel--compile-root () + "Return root of current project or signal an error on failure. +The root is determined by `counsel-compile-root-functions'." + (or (run-hook-with-args-until-success 'counsel-compile-root-functions) + (error "Couldn't find project root"))) + +(defun counsel--project-current () + "Return root of current project or nil on failure. +Use `project-current' to determine the root." + (and (fboundp 'project-current) + (cdr (project-current)))) + +(defun counsel--configure-root () + "Return root of current project or nil on failure. +Use the presence of a \"configure\" file to determine the root." + (counsel--dominating-file "configure")) + +(defun counsel--git-root () + "Return root of current project or nil on failure. +Use the presence of a \".git\" file to determine the root." + (counsel--dominating-file ".git")) + +(defun counsel--dir-locals-root () + "Return root of current project or nil on failure. +Use the presence of a `dir-locals-file' to determine the root." + (counsel--dominating-file dir-locals-file)) + +(defvar counsel-compile-local-builds + '(counsel-compile-get-filtered-history + counsel-compile-get-build-directories + counsel-compile-get-make-invocation) + "Additional compile invocations to feed into `counsel-compile'. + +This can either be a list of compile invocation strings or +functions that will provide such a list. You should customize +this if you want to provide specific non-standard build types to +`counsel-compile'. The default helpers are set up to handle +common build environments.") + +(defcustom counsel-compile-make-args "-k" + "Additional arguments for make. +You may, for example, want to add \"-jN\" for the number of cores +N in your system." + :type 'string) + +(defcustom counsel-compile-env nil + "List of environment variables for compilation to inherit. +Each element should be a string of the form ENVVARNAME=VALUE. This +list is passed to `compilation-environment'." + :type '(repeat (string :tag "ENVVARNAME=VALUE"))) + +(defvar counsel-compile-env-history nil + "History for `counsel-compile-env'.") + +(defvar counsel-compile-env-pattern + "[_[:digit:][:upper:]]+=[/[:alnum:]]*" + "Pattern to match valid environment variables.") + +(defcustom counsel-compile-make-pattern "\\`\\(?:GNUm\\|[Mm]\\)akefile\\'" + "Regexp for matching the names of Makefiles." + :type 'regexp) + +(defcustom counsel-compile-build-directories + '("build" "builds" "bld" ".build") + "List of potential build subdirectory names to check for." + :type '(repeat directory)) + +(defvar counsel-compile-phony-pattern "^\\.PHONY:[\t ]+\\(.+\\)$" + "Regexp for extracting phony targets from Makefiles.") + +;; This is loosely based on the Bash Make completion code +(defun counsel-compile--probe-make-targets (dir) + "Return a list of Make targets for DIR. + +Return an empty list is Make exits with an error. This might +happen because some sort of configuration needs to be done first +or the source tree is pristine and being used for multiple build +trees." + (let ((default-directory dir) + (targets nil)) + (with-temp-buffer + ;; 0 = no-rebuild, -q & 1 needs rebuild, 2 error (for GNUMake at + ;; least) + (when (< (call-process "make" nil t nil "-nqp") 2) + (goto-char (point-min)) + (while (re-search-forward counsel-compile-phony-pattern nil t) + (setq targets + (nconc targets (split-string + (match-string-no-properties 1))))))) + (sort targets #'string-lessp))) + +(defun counsel-compile--pretty-propertize (leader text face) + "Return a pretty string of the form \" LEADER TEXT\". +LEADER is propertized with a warning face and the remaining +text with FACE." + (concat (propertize (concat " " leader " ") + 'face + 'font-lock-warning-face) + (propertize text 'face face))) + +(defun counsel--compile-get-make-targets (srcdir &optional blddir) + "Return a list of Make targets for a given SRCDIR/BLDDIR combination. + +We search the Makefile for a list of phony targets which are +generally the top level targets a Make system provides. +The resulting strings are tagged with properties that +`counsel-compile-history' can use for filtering results." + (let ((fmt (format (propertize "make %s %%s" 'cmd t) + counsel-compile-make-args)) + (suffix (and blddir + (counsel-compile--pretty-propertize "in" blddir + 'dired-directory))) + (build-env (and counsel-compile-env + (counsel-compile--pretty-propertize + "with" + (mapconcat #'identity counsel-compile-env " ") + 'font-lock-variable-name-face))) + (props `(srcdir ,srcdir blddir ,blddir bldenv ,counsel-compile-env))) + (mapcar (lambda (target) + (setq target (concat (format fmt target) suffix build-env)) + (add-text-properties 0 (length target) props target) + target) + (counsel-compile--probe-make-targets (or blddir srcdir))))) + +(defun counsel-compile-get-make-invocation (&optional blddir) + "Have a look in the root directory for any build control files. + +The optional BLDDIR is useful for other helpers that have found +sub-directories that builds may be invoked in." + (let ((srcdir (counsel--compile-root))) + (when (directory-files (or blddir srcdir) nil + counsel-compile-make-pattern t) + (counsel--compile-get-make-targets srcdir blddir)))) + +(defun counsel--find-build-subdir (srcdir) + "Return builds subdirectory of SRCDIR, if one exists." + (cl-some (lambda (dir) + (setq dir (expand-file-name dir srcdir)) + (and (file-directory-p dir) dir)) + counsel-compile-build-directories)) + +(defun counsel--get-build-subdirs (blddir) + "Return all subdirs under BLDDIR sorted by modification time. +If there are non-directory files in BLDDIR, include BLDDIR in the +list as it may also be a build directory." + (let* ((files (directory-files-and-attributes + blddir t directory-files-no-dot-files-regexp t)) + (dirs (cl-remove-if-not #'cl-second files))) + ;; Any non-dir files? + (when (< (length dirs) + (length files)) + (push (cons blddir (file-attributes blddir)) dirs)) + (mapcar #'car (sort dirs (lambda (x y) + (time-less-p (nth 6 y) (nth 6 x))))))) + +(defun counsel-compile-get-build-directories (&optional dir) + "Return a list of potential build directories." + (let* ((srcdir (or dir (counsel--compile-root))) + (blddir (counsel--find-build-subdir srcdir)) + (props `(srcdir ,srcdir recursive t)) + (fmt (concat (propertize "Select build in " + 'face 'font-lock-warning-face) + (propertize "%s" 'face 'dired-directory)))) + (mapcar (lambda (subdir) + (let ((s (format fmt subdir))) + (add-text-properties 0 (length s) `(blddir ,subdir ,@props) s) + s)) + (and blddir (counsel--get-build-subdirs blddir))))) + +;; This is a workaround for the fact there is no concept of "project" +;; local variables (as opposed to for example buffer-local). So we +;; store all our history in a global list filter out the results we +;; don't want. +(defun counsel-compile-get-filtered-history (&optional dir) + "Return a compile history relevant to current project." + (let ((root (or dir (counsel--compile-root))) + history) + (dolist (item counsel-compile-history) + (let ((srcdir (get-text-property 0 'srcdir item)) + (blddir (get-text-property 0 'blddir item))) + (when (or (and srcdir (file-in-directory-p srcdir root)) + (and blddir (file-in-directory-p blddir root))) + (push item history)))) + (nreverse history))) + +(defun counsel--get-compile-candidates (&optional dir) + "Return the list of compile commands. +This is determined by `counsel-compile-local-builds', which see." + (let (cands) + (dolist (cmds counsel-compile-local-builds) + (when (functionp cmds) + (setq cmds (funcall cmds dir))) + (when cmds + (push (if (listp cmds) cmds (list cmds)) cands))) + (apply #'append (nreverse cands)))) + +;; This is a workaround to ensure we tag all the relevant metadata in +;; our compile history. This also allows M-x compile to do fancy +;; things like infer `default-directory' from 'cd's in the string. +(defun counsel-compile--update-history (_proc) + "Update `counsel-compile-history' from the compilation state." + (let* ((srcdir (counsel--compile-root)) + (blddir default-directory) + (bldenv compilation-environment) + (cmd (concat + (propertize (car compilation-arguments) 'cmd t) + (unless (file-equal-p blddir srcdir) + (counsel-compile--pretty-propertize "in" blddir + 'dired-directory)) + (when bldenv + (counsel-compile--pretty-propertize "with" + (mapconcat #'identity bldenv " ") + 'font-lock-variable-name-face))))) + (add-text-properties 0 (length cmd) + `(srcdir ,srcdir blddir ,blddir bldenv ,bldenv) cmd) + (add-to-history 'counsel-compile-history cmd))) + +(defvar counsel-compile--current-build-dir nil + "Tracks the last directory `counsel-compile' was called with. + +This state allows us to set it correctly if the user has manually +edited the command, thus losing our embedded state.") + +(defun counsel-compile--action (cmd) + "Process CMD to call `compile'. + +If CMD has the `recursive' property set we call `counsel-compile' +again to further refine the compile options in the directory +specified by the `blddir' property." + (let ((blddir (get-text-property 0 'blddir cmd)) + (bldenv (get-text-property 0 'bldenv cmd))) + (if (get-text-property 0 'recursive cmd) + (counsel-compile blddir) + (when (get-char-property 0 'cmd cmd) + (setq cmd (substring-no-properties + cmd 0 (next-single-property-change 0 'cmd cmd)))) + (let ((default-directory (or blddir + counsel-compile--current-build-dir + default-directory)) + (compilation-environment bldenv)) + ;; No need to specify `:history' because of this hook. + (add-hook 'compilation-start-hook #'counsel-compile--update-history) + (unwind-protect + (compile cmd) + (remove-hook 'compilation-start-hook #'counsel-compile--update-history)))))) + +;;;###autoload +(defun counsel-compile (&optional dir) + "Call `compile' completing with smart suggestions, optionally for DIR." + (interactive) + (setq counsel-compile--current-build-dir (or dir default-directory)) + (ivy-read "Compile command: " + (counsel--get-compile-candidates dir) + :action #'counsel-compile--action + :caller 'counsel-compile)) + + +(defun counsel-compile-env--format-hint (cands) + "Return a formatter for compile-env CANDS." + (let ((rmstr + (propertize "remove" 'face 'font-lock-warning-face)) + (addstr + (propertize "add" 'face 'font-lock-variable-name-face))) + (ivy--format-function-generic + (lambda (selected) + (format "%s %s" + (if (member selected counsel-compile-env) rmstr addstr) + selected)) + #'identity + cands + "\n"))) + +(defun counsel-compile-env--update (var) + "Update `counsel-compile-env' either adding or removing VAR." + (cond ((member var counsel-compile-env) + (setq counsel-compile-env (delete var counsel-compile-env))) + ((string-match-p counsel-compile-env-pattern var) + (push var counsel-compile-env)) + (t (user-error "Ignoring malformed variable: '%s'" var)))) + +;;;###autoload +(defun counsel-compile-env () + "Update `counsel-compile-env' interactively." + (interactive) + (ivy-read "Compile environment variable: " + (delete-dups (append + counsel-compile-env counsel-compile-env-history)) + :action #'counsel-compile-env--update + :predicate (lambda (cand) + (string-match-p counsel-compile-env-pattern + cand)) + :history 'counsel-compile-env-history + :caller 'counsel-compile-env)) +(add-to-list 'ivy-format-functions-alist '(counsel-compile-env . counsel-compile-env--format-hint)) + +;;** `counsel-minor' +(defvar counsel-minor-history nil + "History for `counsel-minor'.") + +(defun counsel--minor-candidates () + "Return completion alist for `counsel-minor'. + +The alist element is cons of minor mode string with its lighter +and minor mode symbol." + (delq nil + (mapcar + (lambda (mode) + (when (and (boundp mode) (commandp mode)) + (let ((lighter (alist-get mode minor-mode-alist))) + (cons (concat + (if (symbol-value mode) "-" "+") + (symbol-name mode) + (propertize + (if lighter + (format " \"%s\"" + (format-mode-line (cons t lighter))) + "") + 'face font-lock-string-face)) + mode)))) + minor-mode-list))) + +;;;###autoload +(defun counsel-minor () + "Enable or disable minor mode. + +Disabled minor modes are prefixed with \"+\", and +selecting one of these will enable it. +Enabled minor modes are prefixed with \"-\", and +selecting one of these will enable it. + +Additional actions:\\ + + \\[ivy-dispatching-done] d: Go to minor mode definition + \\[ivy-dispatching-done] h: Describe minor mode" + + (interactive) + (ivy-read "Minor modes (enable +mode or disable -mode): " + (counsel--minor-candidates) + :require-match t + :history 'counsel-minor-history + :sort t + :action (lambda (x) + (call-interactively (cdr x))))) + +(cl-pushnew '(counsel-minor . "^+") ivy-initial-inputs-alist :key #'car) + +(ivy-set-actions + 'counsel-minor + `(("d" ,(lambda (x) (find-function (cdr x))) "definition") + ("h" ,(lambda (x) (describe-function (cdr x))) "help"))) + +;;;###autoload +(defun counsel-major () + (interactive) + (ivy-read "Major modes: " obarray + :predicate (lambda (f) + (and (commandp f) (string-match "-mode$" (symbol-name f)) + (or (and (autoloadp (symbol-function f)) + (let ((doc-split (help-split-fundoc (documentation f) f))) + ;; major mode starters have no arguments + (and doc-split (null (cdr (read (car doc-split))))))) + (null (help-function-arglist f))))) + :action #'counsel-M-x-action + :caller 'counsel-major)) + ;;* `counsel-mode' (defvar counsel-mode-map (let ((map (make-sparse-keymap))) @@ -4861,7 +5867,6 @@ Remaps built-in functions to counsel replacements.") (defcustom counsel-mode-override-describe-bindings nil "Whether to override `describe-bindings' when `counsel-mode' is active." - :group 'ivy :type 'boolean) ;;;###autoload @@ -4873,7 +5878,6 @@ replacements. Local bindings (`counsel-mode-map'): \\{counsel-mode-map}" - :group 'ivy :global t :keymap counsel-mode-map :lighter " counsel" diff --git a/packages/counsel-dash-20160729.1529.el b/packages/counsel-dash-20160729.1529.el deleted file mode 100644 index 14600b7..0000000 --- a/packages/counsel-dash-20160729.1529.el +++ /dev/null @@ -1,87 +0,0 @@ -;;; counsel-dash.el --- Browse dash docsets using Ivy -*- lexical-binding: t -*- - -;; Copyright (C) 2016 Nathan Kot - -;; Author: Nathan Kot -;; Version: 0.1.3 -;; Package-Version: 20160729.1529 -;; Package-Requires: ((emacs "24.4") (dash "2.12.1") (dash-functional "1.2.0") (helm-dash "1.3.0") (counsel "0.8.0")) -;; Keywords: dash, ivy, counsel -;; URL: https://github.com/nathankot/counsel-dash - -;;; Commentary: - -;; Provides counsel-dash, which is an ivy-mode interface for searching dash docsets. - -;;; Code: - -(require 'dash) -(require 'dash-functional) -(require 'counsel) - -; Aliases are used so that we can provide a common interface, irrespective of -; any library changes in the future (e.g if helm-dash de-couples itself into two libraries.) - -(defvaralias 'counsel-dash-docsets-path 'helm-dash-docsets-path) -(defvaralias 'counsel-dash-docsets-url 'helm-dash-docsets-url) -(defvaralias 'counsel-dash-min-length 'helm-dash-min-length) -(defvaralias 'counsel-dash-candidate-format 'helm-dash-candidate-format) -(defvaralias 'counsel-dash-enable-debugging 'helm-dash-enable-debugging) -(defvaralias 'counsel-dash-browser-func 'helm-dash-browser-func) -(defvaralias 'counsel-dash-common-docsets 'helm-dash-common-docsets) -(defvaralias 'counsel-dash-ignored-docsets 'helm-dash-ignored-docsets) - -(defalias 'counsel-dash-activate-docset 'helm-dash-activate-docset) -(defalias 'counsel-dash-deactivate-docset 'helm-dash-deactivate-docset) -(defalias 'counsel-dash-install-docset 'helm-dash-install-docset) -(defalias 'counsel-dash-install-docset-from-file 'helm-dash-install-docset-from-file) -(defalias 'counsel-dash-install-user-docset 'helm-dash-install-user-docset) -(defalias 'counsel-dash-reset-connections 'helm-dash-reset-connections) - -(require 'helm-dash) - -(defgroup counsel-dash nil - "Search Dash docsets using ivy" - :group 'ivy) - -(defvar counsel-dash-history-input nil - "Input history used by `ivy-read'.") - -(defvar counsel-dash--results nil - "Stores the previously retrieved docset results.") - -(defvar-local counsel-dash-docsets nil - "Docsets to use for this buffer.") - -(advice-add #'helm-dash-buffer-local-docsets :around - (lambda (old-fun &rest args) - (let ((old (apply old-fun args))) - (-union old counsel-dash-docsets)))) - -(defun counsel-dash-collection (s &rest _) - "Given a string S, query docsets and retrieve result." - (when (>= (length s) counsel-dash-min-length) - (setq helm-pattern s) - (setq counsel-dash--results (helm-dash-search)) - (mapcar 'car counsel-dash--results))) - -;;;###autoload -(defun counsel-dash (&optional initial) - "Query dash docsets. -INITIAL will be used as the initial input, if given." - (interactive) - (helm-dash-initialize-debugging-buffer) - (helm-dash-create-buffer-connections) - (helm-dash-create-common-connections) - (let ((cb (current-buffer))) - (ivy-read "Documentation for: " - #'(lambda (s &rest _) (with-current-buffer cb (counsel-dash-collection s))) - :dynamic-collection t - :history 'counsel-dash-history-input - :initial-input initial - :action (lambda (s) - (-when-let (result (-drop 1 (-first (-compose (-partial 'string= s) 'car) counsel-dash--results))) - (helm-dash-browse-url result)))))) - -(provide 'counsel-dash) -;;; counsel-dash.el ends here diff --git a/packages/counsel-dash-20190510.708.el b/packages/counsel-dash-20190510.708.el new file mode 100644 index 0000000..2ced659 --- /dev/null +++ b/packages/counsel-dash-20190510.708.el @@ -0,0 +1,101 @@ +;;; counsel-dash.el --- Browse dash docsets using Ivy -*- lexical-binding: t -*- + +;; Copyright (C) 2016 Nathan Kot + +;; Author: Nathan Kot +;; Version: 0.1.3 +;; Package-Version: 20190510.708 +;; Package-Requires: ((emacs "24.4") (dash-docs "1.4.0") (counsel "0.8.0") (cl-lib "0.5")) +;; Keywords: dash, ivy, counsel +;; URL: https://github.com/nathankot/counsel-dash +;; +;;; Commentary: +;; Provides counsel-dash, which is an ivy-mode interface for searching dash docsets. +;; +;; M-x counsel-dash +;; M-x counsel-dash-at-point +;; +;;; Code: + +(require 'cl-lib) +(require 'dash-docs) + +(defgroup counsel-dash nil + "Search Dash docsets using ivy" + :prefix "counsel-dash" + :group 'ivy) + +; Aliases are used so that we can provide a common interface, irrespective of +; any library changes in the future (e.g if helm-dash de-couples itself into two libraries.) + +(defvaralias 'counsel-dash-docsets-path 'dash-docs-docsets-path) +(defvaralias 'counsel-dash-docsets-url 'dash-docs-docsets-url) +(defvaralias 'counsel-dash-min-length 'dash-docs-min-length) +(defvaralias 'counsel-dash-candidate-format 'dash-docs-candidate-format) +(defvaralias 'counsel-dash-enable-debugging 'dash-docs-enable-debugging) +(defvaralias 'counsel-dash-browser-func 'dash-docs-browser-func) +(defvaralias 'counsel-dash-common-docsets 'dash-docs-common-docsets) +(defvaralias 'counsel-dash-ignored-docsets 'dash-docs-ignored-docsets) + +(defalias 'counsel-dash-activate-docset 'dash-docs-activate-docset) +(defalias 'counsel-dash-deactivate-docset 'dash-docs-deactivate-docset) +(defalias 'counsel-dash-install-docset 'dash-docs-install-docset) +(defalias 'counsel-dash-install-docset-from-file 'dash-docs-install-docset-from-file) +(defalias 'counsel-dash-install-user-docset 'dash-docs-install-user-docset) +(defalias 'counsel-dash-reset-connections 'dash-docs-reset-connections) + +(defvar counsel-dash-history-input nil + "Input history used by `ivy-read'.") + +(defvar counsel-dash--results nil + "Stores the previously retrieved docset results.") + +(defvar-local counsel-dash-docsets nil + "Docsets to use for this buffer.") + +(advice-add #'dash-docs-buffer-local-docsets :around + (lambda (old-fun &rest args) + (let ((old (apply old-fun args))) + (remove-duplicates (append old counsel-dash-docsets))))) + +(defun counsel-dash--collection (s &rest _) + "Given a string S, query docsets and retrieve result." + (setq counsel-dash--results (dash-docs-search s)) + (mapcar 'car counsel-dash--results)) + +(defun counsel-dash--browse-matching-result (match) + "Given a MATCH, find matching result and browse it's url." + (when-let (result + (cdr (cl-find-if (lambda (e) + (string= match (car e))) counsel-dash--results))) + (dash-docs-browse-url result))) + + +;;; Autoloads + +;;;###autoload +(defun counsel-dash (&optional initial) + "Query dash docsets. +INITIAL will be used as the initial input, if given." + (interactive) + (dash-docs-initialize-debugging-buffer) + (dash-docs-create-buffer-connections) + (dash-docs-create-common-connections) + (let ((cb (current-buffer))) + (ivy-read "Documentation for: " + #'(lambda (s &rest _) (with-current-buffer cb (counsel-dash--collection s))) + :dynamic-collection t + :history #'dash-docs-history-input + :initial-input initial + :action #'counsel-dash--browse-matching-result))) + +;;;###autoload +(defun counsel-dash-at-point () + "Bring up a `counsel-dash' search interface with symbol at point." + (interactive) + (counsel-dash + (substring-no-properties (or (thing-at-point 'symbol) "")))) + +(provide 'counsel-dash) + +;;; counsel-dash.el ends here diff --git a/packages/counsel-gtags-20170326.1259.el b/packages/counsel-gtags-20190422.1501.el similarity index 51% rename from packages/counsel-gtags-20170326.1259.el rename to packages/counsel-gtags-20190422.1501.el index 688d013..4406ecf 100644 --- a/packages/counsel-gtags-20170326.1259.el +++ b/packages/counsel-gtags-20190422.1501.el @@ -4,9 +4,9 @@ ;; Author: Syohei YOSHIDA ;; URL: https://github.com/syohex/emacs-counsel-gtags -;; Package-Version: 20170326.1259 +;; Package-Version: 20190422.1501 ;; Version: 0.01 -;; Package-Requires: ((emacs "24.3") (counsel "0.8.0")) +;; Package-Requires: ((emacs "25.1") (counsel "0.8.0") (seq "1.0")) ;; 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 @@ -29,6 +29,8 @@ (require 'counsel) (require 'cl-lib) +(require 'rx) +(require 'seq) (declare-function cygwin-convert-file-name-from-windows "cygw32.c") (declare-function cygwin-convert-file-name-to-windows "cygw32.c") @@ -69,16 +71,24 @@ If non-nil, the symbol at point is used as default value when searching for a tag." :type 'boolean) +(defcustom counsel-gtags-global-extra-update-options-list nil + "List of extra arguments passed to global when updating database." + :type 'list) + +(defcustom counsel-gtags-gtags-extra-update-options-list nil + "List of extra arguments passed to gtags when updating database." + :type 'list) + (defcustom counsel-gtags-prefix-key "\C-c" "Key binding used for `counsel-gtags-mode-map'. This variable does not have any effect unless `counsel-gtags-use-suggested-key-map' is non-nil." :type 'string) +(defvaralias 'counsel-gtags-suggested-key-mapping 'counsel-gtags-use-suggested-key-map) (defcustom counsel-gtags-use-suggested-key-map nil "Whether to use the suggested key bindings." :type 'boolean) -(defvaralias 'counsel-gtags-suggested-key-mapping 'counsel-gtags-use-suggested-key-map) (make-obsolete-variable 'counsel-gtags-suggested-key-mapping 'counsel-gtags-use-suggested-key-map "0.01") (defconst counsel-gtags--prompts @@ -88,9 +98,10 @@ This variable does not have any effect unless (symbol . "Find Symbol: "))) (defconst counsel-gtags--complete-options - '((reference . "-r") - (symbol . "-s") - (pattern . "-g"))) + '((file . "-P") + (pattern . "-g") + (reference . "-r") + (symbol . "-s"))) (defvar counsel-gtags--last-update-time 0) (defvar counsel-gtags--context nil) @@ -99,43 +110,64 @@ This variable does not have any effect unless "Last `default-directory' where command is invoked.") (defun counsel-gtags--select-gtags-label () + "Get label from user to be used to generate tags." (let ((labels '("default" "native" "ctags" "pygments"))) (ivy-read "GTAGSLABEL(Default: default): " labels))) (defun counsel-gtags--generate-tags () + "Query user for tag generation and do so if accepted." (if (not (yes-or-no-p "File GTAGS not found. Run 'gtags'? ")) - (error "Abort generating tag files.") + (error "Abort generating tag files") (let* ((root (read-directory-name "Root Directory: ")) (label (counsel-gtags--select-gtags-label)) (default-directory root)) (message "gtags is generating tags....") (unless (zerop (process-file "gtags" nil nil nil "-q" (concat "--gtagslabel=" label))) - (error "Faild: 'gtags -q'")) + (error "Failed: 'gtags -q'")) root))) (defun counsel-gtags--root () + "Get gtags root by looking at env vars or looking for GTAGS. + +Will trigger tags generation if not found." (or (getenv "GTAGSROOT") (locate-dominating-file default-directory "GTAGS") (counsel-gtags--generate-tags))) (defsubst counsel-gtags--windows-p () + "Whether we're inside non-free Gates OS." (memq system-type '(windows-nt ms-dos))) -(defun counsel-gtags--set-absolute-option-p () - (or (eq counsel-gtags-path-style 'absolute) - (and (counsel-gtags--windows-p) - (getenv "GTAGSLIBPATH")))) +(defun counsel-gtags--file-path-style () + "Return current `counsel-gtags-path-style' option as argument to global cmd. + +Kept free of whitespaces." + (format "--path-style=%s" + (pcase counsel-gtags-path-style + ((or 'relative 'absolute) + (symbol-name counsel-gtags-path-style)) + ('root "through") + (_ + (error "Unexpected counsel-gtags-path-style: %s" + (symbol-name counsel-gtags-path-style)))))) (defun counsel-gtags--command-options (type &optional extra-options) - (let ((options '("--result=grep"))) - (when extra-options - (setq options (append extra-options options))) + "Get list with options for global command according to TYPE. + +Prepend EXTRA-OPTIONS. If \"--result=.\" is in EXTRA-OPTIONS, it will have +precedence over default \"--result=grep\"." + (let* ((options extra-options) + (has-result (seq-filter (lambda (opt) + (and (stringp opt) + (string-prefix-p "--result=" opt))) + options))) + (unless has-result + (setq options (append '("--result=grep") options))) (let ((opt (assoc-default type counsel-gtags--complete-options))) (when opt (push opt options))) - (when (counsel-gtags--set-absolute-option-p) - (push "-a" options)) + (push (counsel-gtags--file-path-style) options) (when counsel-gtags-ignore-case (push "-i" options)) (when current-prefix-arg ;; XXX @@ -144,14 +176,84 @@ This variable does not have any effect unless (push "-T" options)) options)) -(defun counsel-gtags--complete-candidates (type) - (let ((cmd-options (counsel-gtags--command-options type))) - (push "-c" cmd-options) - (counsel--async-command - (mapconcat #'identity (cons "global" (reverse cmd-options)) " ")) - nil)) +(defun counsel-gtags--string-looks-like-regex (s) + "Return non-nil if S has special regex characters." + (and s + (save-match-data + (string-match (rx (any "." "^" "*" "+" "?" "{" "}" "[" "]" + "$" "(" ")")) + s)))) + +(defun counsel-gtags--get-grep-command () + "Get a grep command to be used to filter candidates. + +Returns a command without arguments. + +Otherwise, returns nil if couldn't find any." + (cl-loop + for command in (list grep-command "rg" "ag" "grep") + for actual-command = (and command + (let ((command-no-args (car + (split-string command)))) + (executable-find command-no-args))) + while (not actual-command) + finally return actual-command)) + +(defun counsel-gtags--build-command-to-collect-candidates (query &optional extra-args) + "Build command to collect condidates filtering by QUERY. + +Used in `counsel-gtags--async-tag-query'. Forward QUERY and EXTRA-ARGS to +`counsel-gtags--command-options'. +Since it's a tag query, we use definition as type when getting options" + (mapconcat #'shell-quote-argument + (append + `("global") + (counsel-gtags--command-options 'definition extra-args) + `(,(counsel--elisp-to-pcre (ivy--regex query)))) + " ")) +(defun counsel-gtags--filter-tags (s) + "Filter function receving S. + +Extract the first part of each line, containing the tag." + (replace-regexp-in-string (rx (char space) (* any) line-end) + "" + s)) + +(defun counsel-gtags--async-tag-query-process (query) + "Add filter to tag query command. + +Input for searching is QUERY. + +Since we can't look for tags by regex, we look for their definition and filter +the location, giving us a list of tags with no locations." + (counsel--async-command + (counsel-gtags--build-command-to-collect-candidates query '("--result=ctags")) + nil ;; default sentinel + (lambda (p s) + (counsel--async-filter p (counsel-gtags--filter-tags s))))) + +(defun counsel-gtags--async-tag-query (query) + "Gather the object names asynchronously for `ivy-read'. + +Use global flags according to TYPE. + +Forward QUERY to global command to be treated as regex. + +Because «global -c» only accepts letters-and-numbers, we actually search for +tags matching QUERY, but filter the list. + +Inspired on ivy.org's `counsel-locate-function'." + (or + (ivy-more-chars) + (progn + (counsel-gtags--async-tag-query-process query) + '("" "Filtering …")))) (defun counsel-gtags--file-and-line (candidate) + "Return list with file and position per CANDIDATE. + +Candidates are supposed to be strings of the form \"file:line\" as returned by +global. Line number is returned as number (and not string)." (if (and (counsel-gtags--windows-p) (string-match-p "\\`[a-zA-Z]:" candidate)) ;; Windows Driver letter (when (string-match "\\`\\([^:]+:[^:]+:\\):\\([^:]+\\)" candidate) @@ -160,29 +262,87 @@ This variable does not have any effect unless (let ((fields (split-string candidate ":"))) (list (cl-first fields) (string-to-number (or (cl-second fields) "1")))))) +(defun counsel-gtags--resolve-actual-file-from (file-candidate) + "Resolve actual file path from CANDIDATE taken from a global cmd query. + +Note: candidates are handled as ⎡file:location⎦ and ⎡(file . location)⎦. + FILE-CANDIDATE is supposed to be *only* the file part of a candidate." + (let ((file-path-per-style + (concat + (pcase counsel-gtags-path-style + ((or 'relative 'absolute) + "") + ('root + (file-name-as-directory + (counsel-gtags--default-directory))) + (_ + (error + "Unexpected counsel-gtags-path-style: %s" + (symbol-name counsel-gtags-path-style)))) + file-candidate))) + (file-truename file-path-per-style))) + +(defun counsel-gtags--jump-to (candidate &optional push) + "Call `find-file' and `forward-line' on file location from CANDIDATE . + +Calls `counsel-gtags--push' at the end if PUSH is non-nil. +Returns (buffer line)" + (cl-multiple-value-bind (file-path line) + (counsel-gtags--file-and-line candidate) + (let* ((default-directory (file-name-as-directory + (or counsel-gtags--original-default-directory + default-directory))) + (file (counsel-gtags--resolve-actual-file-from file-path)) + (opened-buffer (find-file file))) + ;; position correctly within the file + (goto-char (point-min)) + (forward-line (1- line)) + (back-to-indentation) + (if push + (counsel-gtags--push 'to)) + `(,opened-buffer ,line)))) + (defun counsel-gtags--find-file (candidate) + "Open file-at-position per CANDIDATE using `find-file'. + +This is the `:action' callback for `ivy-read' calls." (with-ivy-window (swiper--cleanup) - (cl-destructuring-bind (file line) (counsel-gtags--file-and-line candidate) - (counsel-gtags--push 'from) - (let ((default-directory counsel-gtags--original-default-directory)) - (find-file file) - (goto-char (point-min)) - (forward-line (1- line)) - (back-to-indentation)) - (counsel-gtags--push 'to)))) + (counsel-gtags--push 'from) + (counsel-gtags--jump-to candidate 'push))) + +(defun counsel-gtags--read-tag-ivy-parameters (type) + "Get `counsel-gtags--read-tag' the parameters from TYPE to call `ivy-read'." + `(,(assoc-default type counsel-gtags--prompts) + counsel-gtags--async-tag-query + :initial-input ,(and counsel-gtags-use-input-at-point + (thing-at-point 'symbol)) + :unwind ,(lambda () + (counsel-delete-process) + (swiper--cleanup)) + :dynamic-collection t)) (defun counsel-gtags--read-tag (type) - (let ((default-val (and counsel-gtags-use-input-at-point (thing-at-point 'symbol))) - (prompt (assoc-default type counsel-gtags--prompts))) - (ivy-read prompt (counsel-gtags--complete-candidates type) - :initial-input default-val - :unwind (lambda () - (counsel-delete-process) - (swiper--cleanup)) - :caller 'counsel-gtags--read-tag))) + "Prompt the user for selecting a tag using `ivy-read'. + +Returns selected tag + +Use TYPE ∈ '(definition reference symbol) for defining global parameters. +If `counsel-gtags-use-input-at-point' is non-nil, will use symbol at point as +initial input for `ivy-read'. + +TYPE ∈ `counsel-gtags--prompts' + +See `counsel-gtags--async-tag-query' for more info." + (apply 'ivy-read + (plist-put + (counsel-gtags--read-tag-ivy-parameters type) + :caller 'counsel-gtags--read-tag))) + + (defun counsel-gtags--tag-directory () + "Get directory from either GTAGSROOT env var or by running global." (with-temp-buffer (or (getenv "GTAGSROOT") (progn @@ -194,23 +354,81 @@ This variable does not have any effect unless (cygwin-convert-file-name-from-windows dir) dir))))))) +(defun counsel-gtags--process-lines (command &rest args) + "Like `process-lines' on COMMAND and ARGS, but using `process-file'. + +`process-lines' does not support Tramp because it uses `call-process'. Using +`process-file' makes Tramp support auto-magical." + ;; Space before buffer name to make it "invisible" + (let ((global-run-buffer (get-buffer-create (format " *global @ %s*" default-directory)))) + ;; The buffer needs to be cleared, this can be done after split-string, + ;; but for now it is better to keep it like this for debugging purposed + ;; between calls + (with-current-buffer global-run-buffer + (erase-buffer)) + (apply #'process-file command + nil ;; no input file + global-run-buffer;;BUFFER + nil ;;DISPLAY + args) + (with-current-buffer global-run-buffer + (split-string + (buffer-string) "\n" t)))) + (defun counsel-gtags--collect-candidates (type tagname encoding extra-options) - (let ((options (counsel-gtags--command-options type extra-options)) - (default-directory default-directory) - (coding-system-for-read encoding) - (coding-system-for-write encoding)) - (apply #'process-lines "global" (append (reverse options) (list tagname))))) + "Collect lines for ⎡global …⎦ using TAGNAME as query. + +TAGNAME may be nil, suggesting a match-any query. +Use TYPE to specify query type (tag, file). +Use ENCODING to specify encoding. +Use EXTRA-OPTIONS to specify encoding. + +This is for internal use and not for final user." + (let* ((options (counsel-gtags--command-options type extra-options)) + (default-directory default-directory) + (coding-system-for-read encoding) + (coding-system-for-write encoding) + (query-as-list (pcase tagname + ((pred null) '()) + ("" '()) + (`definition '()) + (_ (list tagname)))) + (global-args (append (reverse options) query-as-list))) + (apply #'counsel-gtags--process-lines "global" global-args))) + +(defun counsel-gtags--select-file-ivy-parameters (type tagname extra-options auto-select-only-candidate) + "Get `counsel-gtags--select-file' the parameters from TYPE to call `ivy-read'." + (if (string-empty-p tagname) + (message "No candidate tags") + (let* ((root (counsel-gtags--default-directory)) + (encoding buffer-file-coding-system) + (default-directory root) + (collection (counsel-gtags--collect-candidates + type tagname encoding extra-options)) + (ivy-auto-select-single-candidate t) ;; see issue #7 + ) + `("Pattern: " ,collection + :action counsel-gtags--find-file)))) (defun counsel-gtags--select-file (type tagname &optional extra-options auto-select-only-candidate) - (let* ((root (counsel-gtags--default-directory)) - (encoding buffer-file-coding-system) - (default-directory root) - (collection (counsel-gtags--collect-candidates type tagname encoding extra-options))) + "Prompt the user to select a file_path:position according to query. + +Use TYPE ∈ '(definition reference symbol) for defining global parameters. +Use TAGNAME for global query. +Use AUTO-SELECT-ONLY-CANDIDATE to skip `ivy-read' if have a single candidate. +Extra command line parameters to global are forwarded through EXTRA-OPTIONS." + (let* ((the-ivy-arguments + (counsel-gtags--select-file-ivy-parameters type + tagname + extra-options + auto-select-only-candidate)) + (collection (cadr the-ivy-arguments))) (if (and auto-select-only-candidate (= (length collection) 1)) (counsel-gtags--find-file (car collection)) - (ivy-read "Pattern: " collection - :action #'counsel-gtags--find-file - :caller 'counsel-gtags--select-file)))) + ;; else + (apply 'ivy-read (plist-put + the-ivy-arguments + :caller 'counsel-gtags--select-file))))) ;;;###autoload (defun counsel-gtags-find-definition (tagname) @@ -240,46 +458,58 @@ Prompt for TAGNAME if not given." "\\`\\s-*#\\(?:include\\|import\\)\\s-*[\"<]\\(?:[./]*\\)?\\(.*?\\)[\">]") (defun counsel-gtags--include-file () + "Get ⎡#include …⎦ from first line." (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) (when (string-match counsel-gtags--include-regexp line) (match-string-no-properties 1 line)))) -(defun counsel-gtags--read-file-name () - (let ((default-file (counsel-gtags--include-file)) - (candidates - (with-temp-buffer - (let* ((options (cl-case counsel-gtags-path-style - (absolute "-Poa") - (root "-Poc") - (relative "")))) - (unless (zerop (process-file "global" nil t nil options)) - (error "Failed: collect file names.")) - (goto-char (point-min)) - (let (files) - (while (not (eobp)) - (push (buffer-substring-no-properties (point) (line-end-position)) files) - (forward-line 1)) - (reverse files)))))) - (ivy-read "Find File: " candidates - :initial-input default-file - :action #'counsel-gtags--find-file - :caller 'counsel-gtags--read-tag))) - (defun counsel-gtags--default-directory () + "Return default directory per `counsel-gtags-path-style'. + +Useful for jumping from a location when using global commands (like with +\"--from-here\")." (setq counsel-gtags--original-default-directory (cl-case counsel-gtags-path-style ((relative absolute) default-directory) (root (counsel-gtags--root))))) +(defun counsel-gtags--get-files () + "Get a list of all files from global." + (let* ((encoding buffer-file-coding-system) + (candidates (counsel-gtags--collect-candidates + 'file + nil ;; match any + encoding + nil)) + (files (mapcar (lambda (candidate) + (cl-multiple-value-bind (file-path _) + (counsel-gtags--file-and-line candidate) + file-path)) + candidates + ))) + (cl-remove-duplicates files + :test #'string-equal))) + +(defun counsel-gtags--find-file-ivy-parameters (filename) + "Get `counsel-gtags-find-file' the parameters from FILENAME to call `ivy-read'." + + (let* ((initial-input (or filename + (counsel-gtags--include-file))) + (collection (counsel-gtags--get-files))) + `("Find File: " + ,collection + :initial-input ,initial-input + :action counsel-gtags--find-file))) + ;;;###autoload -(defun counsel-gtags-find-file (filename) - "Search for FILENAME among tagged files. -Prompt for FILENAME if not given." - (interactive - (list (counsel-gtags--read-file-name))) - (let ((default-directory (counsel-gtags--default-directory))) - (find-file filename))) +(defun counsel-gtags-find-file (&optional filename) + "Search/narrow for FILENAME among tagged files." + (interactive) + (apply 'ivy-read + (plist-put + (counsel-gtags--find-file-ivy-parameters filename) + :caller 'counsel-gtags-find-file-name))) ;;;###autoload (defun counsel-gtags-go-backward () @@ -312,7 +542,7 @@ Prompt for FILENAME if not given." (defun counsel-gtags--goto (position) "Go to POSITION in context stack. -Return t on success, nil otherwise." + Return t on success, nil otherwise." (let ((context (nth position counsel-gtags--context))) (when (and context (cond @@ -328,9 +558,11 @@ Return t on success, nil otherwise." t))) (defun counsel-gtags--push (direction) - "Add new entry to context stack." + "Add new entry to context stack. + + DIRECTION ∈ '(from, to)." (let ((new-context (list :file (and (buffer-file-name) - (counsel-gtags--real-file-name)) + (file-truename (buffer-file-name))) :buffer (current-buffer) :line (line-number-at-pos) :direction direction))) @@ -346,6 +578,9 @@ Return t on success, nil otherwise." (setq counsel-gtags--context-position 0))) (defun counsel-gtags--make-gtags-sentinel (action) + "Return default sentinel that messages success/failed exit. + + Message printed has ACTION as detail." (lambda (process _event) (when (eq (process-status process) 'exit) (if (zerop (process-exit-status process)) @@ -355,8 +590,8 @@ Return t on success, nil otherwise." ;;;###autoload (defun counsel-gtags-create-tags (rootdir label) "Create tag database in ROOTDIR. -LABEL is passed as the value for the environment variable GTAGSLABEL. -Prompt for ROOTDIR and LABEL if not given. This command is asynchronous." + LABEL is passed as the value for the environment variable GTAGSLABEL. + Prompt for ROOTDIR and LABEL if not given. This command is asynchronous." (interactive (list (read-directory-name "Directory: " nil nil t) (counsel-gtags--select-gtags-label))) @@ -369,32 +604,57 @@ Prompt for ROOTDIR and LABEL if not given. This command is asynchronous." proc (counsel-gtags--make-gtags-sentinel 'create)))) -(defun counsel-gtags--real-file-name () - (let ((buffile (buffer-file-name))) - (unless buffile - (error "This buffer is not related to file.")) - (if (file-remote-p buffile) - (tramp-file-name-localname (tramp-dissect-file-name buffile)) - (file-truename buffile)))) +(defun counsel-gtags--remote-truename (&optional file-path) + "Return real file name for file path FILE-PATH in remote machine. + + If file is local, return its `file-truename' + + FILE-PATH defaults to current buffer's file if it was not provided." + (let ((filename (or file-path + (buffer-file-name) + (error "This buffer is not related to any file"))) + (default-directory (file-name-as-directory default-directory))) + (if (file-remote-p filename) + (tramp-file-name-localname (tramp-dissect-file-name filename)) + (file-truename filename)))) (defun counsel-gtags--read-tag-directory () + "Get directory for tag generation from user." (let ((dir (read-directory-name "Directory tag generated: " nil nil t))) ;; On Windows, "gtags d:/tmp" work, but "gtags d:/tmp/" doesn't (directory-file-name (expand-file-name dir)))) (defsubst counsel-gtags--how-to-update-tags () + "Read prefix input from user and return corresponding type of tag update." (cl-case (prefix-numeric-value current-prefix-arg) (4 'entire-update) (16 'generate-other-directory) (otherwise 'single-update))) (defun counsel-gtags--update-tags-command (how-to) + "Build global command line to update commands. + HOW-TO ∈ '(entire-update generate-other-directory single-update) per + `counsel-gtags--how-to-update-tags' (user prefix)." + ;; note: mayble use `-flatten' here (cl-case how-to - (entire-update '("global" "-u")) - (generate-other-directory (list "gtags" (counsel-gtags--read-tag-directory))) - (single-update (list "global" "--single-update" (counsel-gtags--real-file-name))))) + (entire-update + (append '("global" "-u") + counsel-gtags-global-extra-update-options-list)) + (generate-other-directory + (append '("gtags") + counsel-gtags-global-extra-update-options-list + (list (counsel-gtags--read-tag-directory)))) + (single-update + (append '("global" "--single-update") + counsel-gtags-global-extra-update-options-list + (list (counsel-gtags--remote-truename)))))) (defun counsel-gtags--update-tags-p (how-to interactive-p current-time) + "Should we update tags now?. + + Will update if being called interactively per INTERACTIVE-P. + If HOW-TO equals 'single-update, will update only if + `counsel-gtags-update-interval-second' seconds have passed up to CURRENT-TIME." (or interactive-p (and (eq how-to 'single-update) (buffer-file-name) @@ -405,9 +665,9 @@ Prompt for ROOTDIR and LABEL if not given. This command is asynchronous." ;;;###autoload (defun counsel-gtags-update-tags () "Update tag database for current file. -Changes in other files are ignored. With a prefix argument, update -tags for all files. With two prefix arguments, generate new tag -database in prompted directory." + Changes in other files are ignored. With a prefix argument, update + tags for all files. With two prefix arguments, generate new tag + database in prompted directory." (interactive) (let ((how-to (counsel-gtags--how-to-update-tags)) (interactive-p (called-interactively-p 'interactive)) @@ -421,15 +681,18 @@ database in prompted directory." (setq counsel-gtags--last-update-time current-time)))))) (defun counsel-gtags--from-here (tagname) + "Try to open file by querying TAGNAME and \"--from-here\"." (let* ((line (line-number-at-pos)) - (from-here-opt (format "--from-here=%d:%s" line (counsel-gtags--real-file-name)))) + (root (counsel-gtags--remote-truename (counsel-gtags--default-directory))) + (file (counsel-gtags--remote-truename)) + (from-here-opt (format "--from-here=%d:%s" line (file-relative-name file root)))) (counsel-gtags--select-file 'from-here tagname (list from-here-opt) t))) ;;;###autoload (defun counsel-gtags-dwim () "Find definition or reference of thing at point (Do What I Mean). -If point is at a definition, find its references, otherwise, find -its definition." + If point is at a definition, find its references, otherwise, find + its definition." (interactive) (let ((cursor-symbol (thing-at-point 'symbol))) (if (and (buffer-file-name) cursor-symbol) @@ -442,8 +705,8 @@ its definition." ;;;###autoload (define-minor-mode counsel-gtags-mode () "Minor mode of counsel-gtags. -If `counsel-gtags-update-tags' is non-nil, the tag files are updated -after saving buffer." + If `counsel-gtags-update-tags' is non-nil, the tag files are updated + after saving buffer." :init-value nil :global nil :keymap counsel-gtags-mode-map diff --git a/packages/counsel-notmuch-20180714.40.el b/packages/counsel-notmuch-20181203.935.el similarity index 98% rename from packages/counsel-notmuch-20180714.40.el rename to packages/counsel-notmuch-20181203.935.el index e40310d..efba618 100644 --- a/packages/counsel-notmuch-20180714.40.el +++ b/packages/counsel-notmuch-20181203.935.el @@ -4,7 +4,7 @@ ;; Author: Alexander Fu Xi ;; URL: https://github.com/fuxialexander/counsel-notmuch -;; Package-Version: 20180714.40 +;; Package-Version: 20181203.935 ;; Keywords: mail ;; Version: 1.0 ;; Package-Requires: ((emacs "24") (ivy "0.10.0") (notmuch "0.21") (s "1.12.0")) @@ -85,7 +85,7 @@ (defun counsel-notmuch-function (input) "Get mail from notmuch using INPUT." (if (< (length input) 3) - (counsel-more-chars) + (ivy-more-chars) (counsel--async-command (counsel-notmuch-cmd input)) '("" "working..."))) diff --git a/packages/counsel-projectile-20181020.1906.el b/packages/counsel-projectile-20190817.102.el similarity index 96% rename from packages/counsel-projectile-20181020.1906.el rename to packages/counsel-projectile-20190817.102.el index c4a0e25..f2fd8c8 100644 --- a/packages/counsel-projectile-20181020.1906.el +++ b/packages/counsel-projectile-20190817.102.el @@ -1,13 +1,13 @@ ;;; counsel-projectile.el --- Ivy integration for Projectile -*- lexical-binding: t -*- -;; Copyright (C) 2016-2018 Eric Danan +;; Copyright (C) 2016-2019 Eric Danan ;; Author: Eric Danan ;; URL: https://github.com/ericdanan/counsel-projectile -;; Package-Version: 20181020.1906 +;; Package-Version: 20190817.102 ;; Keywords: project, convenience -;; Version: 0.3.0-snapshot -;; Package-Requires: ((counsel "0.10.0") (projectile "1.0.0")) +;; Version: 0.3.0 +;; Package-Requires: ((counsel "0.12.0") (projectile "2.0.0")) ;; This file is NOT part of GNU Emacs. @@ -244,6 +244,17 @@ If anything goes wrong, throw an error and do not modify ACTION-VAR." (cdr action-list)))))) (set action-var action-list))) +;; Copy the function `string-trim-right' from emacs 26 here so as to +;; support emacs 25 (the function exists in emacs 25 but doesn't +;; accept the REGEXP optional argument). +(defsubst counsel-projectile--string-trim-right (string &optional regexp) + "Trim STRING of trailing string matching REGEXP. + +REGEXP defaults to \"[ \\t\\n\\r]+\"." + (if (string-match (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") string) + (replace-match "" t t string) + string)) + ;;* counsel-projectile-find-file (defcustom counsel-projectile-sort-files nil @@ -610,9 +621,9 @@ Note that you can always insert the value of `(ivy-thing-at-point)' by hitting \"M-n\" in the minibuffer." :type '(choice (const :tag "None" nil) - (const :tag "Symbol at point (generic)" '(thing-at-point 'symbol t)) - (const :tag "Symbol or selection at point (projectile)" '(projectile-symbol-or-selection-at-point)) - (const :tag "Thing at point (ivy)" '(ivy-thing-at-point)) + (const :tag "Symbol at point (generic)" (thing-at-point 'symbol t)) + (const :tag "Symbol or selection at point (projectile)" (projectile-symbol-or-selection-at-point)) + (const :tag "Thing at point (ivy)" (ivy-thing-at-point)) (sexp :tag "Custom expression")) :group 'counsel-projectile) @@ -646,11 +657,9 @@ construct the command.") (defun counsel-projectile-grep-function (string) "Grep for STRING in the current project." - (or (counsel-more-chars) + (or (ivy-more-chars) (let ((default-directory (ivy-state-directory ivy-last)) - (regex (counsel-unquote-regex-parens - (setq ivy--old-re - (ivy--regex string))))) + (regex (counsel--grep-regex string))) (counsel--async-command (format counsel-projectile-grep-command (shell-quote-argument regex))) nil))) @@ -672,24 +681,8 @@ construct the command.") (defun counsel-projectile-grep-occur () "Generate a custom occur buffer for `counsel-projectile-grep'." - ;; Copied from `counsel-grep-like-occur', except that we don't - ;; prepend "./" to the candidates since grep already does so. - (unless (eq major-mode 'ivy-occur-grep-mode) - (ivy-occur-grep-mode) - (setq default-directory (ivy-state-directory ivy-last))) - (setq ivy-text - (and (string-match "\"\\(.*\\)\"" (buffer-name)) - (match-string 1 (buffer-name)))) - (let* ((cmd (format counsel-projectile-grep-command - (shell-quote-argument - (counsel-unquote-regex-parens - (ivy--regex ivy-text))))) - (cands (split-string (shell-command-to-string cmd) "\n" 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))) + (counsel-grep-like-occur + counsel-projectile-grep-command)) ;;;###autoload (defun counsel-projectile-grep (&optional options-or-cmd) @@ -734,7 +727,7 @@ called with a prefix argument." (format counsel-projectile-grep-base-command ignored path)) (ivy-read (projectile-prepend-project-name "grep: ") #'counsel-projectile-grep-function - :initial-input counsel-projectile-grep-initial-input + :initial-input (eval counsel-projectile-grep-initial-input) :dynamic-collection t :keymap counsel-ag-map :history 'counsel-git-grep-history @@ -744,6 +737,7 @@ called with a prefix argument." (swiper--cleanup)) :caller 'counsel-projectile-grep))))) +(cl-pushnew 'counsel-projectile-grep ivy-highlight-grep-commands) (counsel-set-async-exit-code 'counsel-projectile-grep 1 "No matches found") (ivy-set-occur 'counsel-projectile-grep 'counsel-projectile-grep-occur) (ivy-set-display-transformer 'counsel-projectile-grep 'counsel-projectile-grep-transformer) @@ -766,13 +760,13 @@ with a prefix argument." (car (projectile-parse-dirconfig-file))) " ")) (counsel-git-grep-cmd-default - (concat (string-trim-right counsel-git-grep-cmd-default " \\.") + (concat (counsel-projectile--string-trim-right counsel-git-grep-cmd-default " \\.") " " path))) (ivy-add-actions 'counsel-git-grep counsel-projectile-git-grep-extra-actions) (counsel-git-grep (or current-prefix-arg cmd) - counsel-projectile-grep-initial-input)))) + (eval counsel-projectile-grep-initial-input))))) ;;* counsel-projectile-ag @@ -785,9 +779,9 @@ Note that you can always insert the value of `(ivy-thing-at-point)' by hitting \"M-n\" in the minibuffer." :type '(choice (const :tag "None" nil) - (const :tag "Symbol at point (generic)" '(thing-at-point 'symbol t)) - (const :tag "Symbol or selection at point (projectile)" '(projectile-symbol-or-selection-at-point)) - (const :tag "Thing at point (ivy)" '(ivy-thing-at-point)) + (const :tag "Symbol at point (generic)" (thing-at-point 'symbol t)) + (const :tag "Symbol or selection at point (projectile)" (projectile-symbol-or-selection-at-point)) + (const :tag "Thing at point (ivy)" (ivy-thing-at-point)) (sexp :tag "Custom expression")) :group 'counsel-projectile) @@ -833,7 +827,7 @@ is called with a prefix argument." (projectile-ignored-directories-rel)) " ")) (counsel-ag-base-command - (format (string-trim-right counsel-ag-base-command " \\.") + (format (counsel-projectile--string-trim-right counsel-ag-base-command " \\.") (concat ignored " %s " path)))) (ivy-add-actions 'counsel-ag @@ -842,7 +836,7 @@ is called with a prefix argument." (projectile-project-root) options (projectile-prepend-project-name - (car (split-string counsel-ag-base-command))))))) + (concat (car (split-string counsel-ag-base-command)) ": ")))))) ;;* counsel-projectile-rg @@ -855,9 +849,9 @@ Note that you can always insert the value of `(ivy-thing-at-point)' by hitting \"M-n\" in the minibuffer." :type '(choice (const :tag "None" nil) - (const :tag "Symbol at point (generic)" '(thing-at-point 'symbol t)) - (const :tag "Symbol or selection at point (projectile)" '(projectile-symbol-or-selection-at-point)) - (const :tag "Thing at point (ivy)" '(ivy-thing-at-point)) + (const :tag "Symbol at point (generic)" (thing-at-point 'symbol t)) + (const :tag "Symbol or selection at point (projectile)" (projectile-symbol-or-selection-at-point)) + (const :tag "Thing at point (ivy)" (ivy-thing-at-point)) (sexp :tag "Custom expression")) :group 'counsel-projectile) @@ -905,7 +899,7 @@ is called with a prefix argument." (projectile-ignored-directories-rel)) " ")) (counsel-rg-base-command - (format (string-trim-right counsel-rg-base-command " \\.") + (format (counsel-projectile--string-trim-right counsel-rg-base-command " \\.") (concat ignored " %s " path)))) (ivy-add-actions 'counsel-ag @@ -914,7 +908,7 @@ is called with a prefix argument." (projectile-project-root) options (projectile-prepend-project-name - (car (split-string counsel-rg-base-command))))))) + (concat (car (split-string counsel-rg-base-command)) ": ")))))) ;;* counsel-projectile-org-capture @@ -1155,7 +1149,7 @@ Optional arguments ARG, KEYS, and RESTRICTION are as in (let* ((root (projectile-project-root)) (org-agenda-files (cl-remove-if-not (lambda (file) - (string-prefix-p root file)) + (string-prefix-p root (expand-file-name file))) (org-agenda-files t 'ifmode)))) (org-agenda arg keys restriction)))) diff --git a/packages/counsel-spotify-20180320.322.el b/packages/counsel-spotify-20190406.2025.el similarity index 95% rename from packages/counsel-spotify-20180320.322.el rename to packages/counsel-spotify-20190406.2025.el index c754c88..7ce293c 100644 --- a/packages/counsel-spotify-20180320.322.el +++ b/packages/counsel-spotify-20190406.2025.el @@ -4,7 +4,7 @@ ;; Author: Lautaro García ;; Package: counsel-spotify ;; Package-Requires: ((emacs "25") (ivy "0.9.0")) -;; Package-Version: 20180320.322 +;; Package-Version: 20190406.2025 ;; Version: 0.1 ;; This file is not part of GNU Emacs. @@ -29,6 +29,7 @@ (require 'url) (require 'json) (require 'ivy) +(require 'dbus) (defgroup counsel-spotify nil "Customs for `counsel-spotify'" @@ -169,17 +170,21 @@ ('gnu/linux (make-instance 'counsel-spotify-linux-backend)) ('darwin (make-instance 'counsel-spotify-darwin-backend)))) +(cl-defun counsel-spotify-call-spotify-via-dbus (method &rest args) + (apply #'dbus-call-method `(:session + "org.mpris.MediaPlayer2.spotify" + "/org/mpris/MediaPlayer2" "org.mpris.MediaPlayer2.Player" + ,method + ,@args))) + (cl-defgeneric counsel-spotify-tell-backend-to (backend action) "Tells the given BACKEND to execute the given ACTION") (cl-defmethod counsel-spotify-tell-backend-to ((backend counsel-spotify-darwin-backend) action) (shell-command (concat "osascript -e 'tell application \"Spotify\" to '" (shell-quote-argument (funcall action (commands backend)))))) -(defconst counsel-spotify-dbus-call "dbus-send --session --type=method_call --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 " - "Variable to hold the dbus call string.") - (cl-defmethod counsel-spotify-tell-backend-to ((backend counsel-spotify-linux-backend) action) - (shell-command (concat counsel-spotify-dbus-call "org.mpris.MediaPlayer2.Player." (shell-quote-argument (funcall action (commands backend)))))) + (counsel-spotify-call-spotify-via-dbus (funcall action (commands backend)))) (cl-defgeneric counsel-spotify-do-play (backend playable) "Tells the BACKEND to play the PLAYABLE object") @@ -188,7 +193,7 @@ (shell-command (concat "osascript -e 'tell application \"Spotify\" to play track \"" (uri playable) "\"'"))) (cl-defmethod counsel-spotify-do-play ((backend counsel-spotify-linux-backend) (playable counsel-spotify-playable)) - (shell-command (concat counsel-spotify-dbus-call "org.mpris.MediaPlayer2.Player.OpenUri \"string:" (uri playable) "\""))) + (counsel-spotify-call-spotify-via-dbus "OpenUri" (uri playable))) (defun counsel-spotify-unwrap-property (elem) "Unwrap the property of ELEM." @@ -235,21 +240,25 @@ ;; Controllers ;; ;;;;;;;;;;;;;;;;; +;;;###autoload (defun counsel-spotify-play () "Start playing current track." (interactive) (counsel-spotify-tell-backend-to counsel-spotify-current-backend #'play)) +;;;###autoload (defun counsel-spotify-toggle-play-pause () "Toggle play or pause of the current track." (interactive) (counsel-spotify-tell-backend-to counsel-spotify-current-backend #'playpause)) +;;;###autoload (defun counsel-spotify-previous () "Start playing previous song." (interactive) (counsel-spotify-tell-backend-to counsel-spotify-current-backend #'previous)) +;;;###autoload (defun counsel-spotify-next () "Start playing next song." (interactive) @@ -264,6 +273,7 @@ "Macro that create the function to search by SEARCH-KEYWORD and other SEARCH-ARGS." `(lambda (search-term) (mapcar #'counsel-spotify-get-formatted-object (counsel-spotify-search-query ,search-keyword search-term ,@search-args)))) +;;;###autoload (defun counsel-spotify-search-track () "Bring Ivy frontend to choose and play a track." (interactive) @@ -275,24 +285,28 @@ ("a" (lambda (elem) (counsel-spotify-do-play counsel-spotify-current-backend (album (counsel-spotify-unwrap-property elem)))) "Play album") ("A" (lambda (elem) (counsel-spotify-do-play counsel-spotify-current-backend (artist (counsel-spotify-unwrap-property elem)))) "Play artist")))) +;;;###autoload (defun counsel-spotify-search-artist () "Bring Ivy frontend to choose and play an artist." (interactive) (counsel-spotify-verify-credentials) (ivy-read "Seach artist: " (counsel-spotify-search-by-term :artist :type 'artist) :dynamic-collection t :action #'counsel-spotify-play-property)) +;;;###autoload (defun counsel-spotify-search-album () "Bring Ivy frontend to choose and play an album." (interactive) (counsel-spotify-verify-credentials) (ivy-read "Search album: " (counsel-spotify-search-by-term :album :type 'album) :dynamic-collection t :action #'counsel-spotify-play-property)) +;;;###autoload (defun counsel-spotify-search-tracks-by-artist () "Bring Ivy frontend to search for all tracks for a given artist." (interactive) (counsel-spotify-verify-credentials) (ivy-read "Search tracks by artist: " (counsel-spotify-search-by-term :artist :type 'track) :dynamic-collection t :action #'counsel-spotify-play-property)) +;;;###autoload (defun counsel-spotify-search-tracks-by-album () "Bring Ivy frontend to search for all track on a given album." (interactive) diff --git a/packages/cpp-auto-include-20160426.412.el b/packages/cpp-auto-include-20160426.412.el new file mode 100644 index 0000000..b84946b --- /dev/null +++ b/packages/cpp-auto-include-20160426.412.el @@ -0,0 +1,224 @@ +;;; cpp-auto-include.el --- auto include header file for C++ + +;; Copyright (C) 2015 by Syohei YOSHIDA + +;; Author: Syohei YOSHIDA +;; URL: https://github.com/syohex/emacs-cpp-auto-include +;; Package-Version: 20160426.412 +;; Version: 0.01 +;; Package-Requires: ((cl-lib "0.5")) + +;; 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 . + +;;; Commentary: + +;;; Code: + +(require 'cl-lib) +(require 'rx) + +(defvar cpp-auto-include--header-regexp + `(("cstdio" nil t + ,(rx (and symbol-start + (or (and (or "scanf" "sscanf" "puts" "sprintf" "printf" + "gets" "fgets" "putchar") + (* space) "(") + (and (or "FILE" "stdin" "stdout" "stderr") + symbol-end))))) + ("cassert" nil t "\\bassert\\s-+(") + ("cstring" nil t + ,(rx (and symbol-start + (or "memcpy" "memset" "memcmp" "memncmp" + "strlen" "strcmp" "strncmp" "strcpy" "strncpy" "strerr" "strcat" + "strstr" "strchr") + symbol-end))) + ("cstdlib" nil t + ,(rx (and symbol-start + (or (and (or "system" "abs" "atoi" "atof" "itoa" + "strtod" "strtold" "strtoul" "strtof" "strtol" + "strtoll" "strtoull" "strtoq" "strtouq" + "free" "exit" "labs" "srand" "srandom" "srandom_r" + "rand" "rand_r" "random" "random_r" "qsort") + (* space) "(") + (and (or (and "EXIT_" (1+ (in "A-Z"))) + "NULL")))))) + ("cmath" nil t + ,(rx (and symbol-start + (or (and (or "powf" "powl" + "acos" "acosf" "acosh" "acoshf" "acoshl" "acosl" + "asin" "asinf" "asinh" "asinhf" "asinhl" "asin" + "atan" "atan2" "atan2f" "atan2l" "atanf" "atanh" "atanhf" + "atanhl" "atanl" "exp" "expf" "expl" "exp10" "exp10f" + "exp10l" "exp2" "exp2f" "exp2l" "expm1" "expm1f" "expm1l" + "fabs" "fabsf" "fabsl" "log" "logf" "logl" + "log2" "log2f" "log2l" "log10" "log10f" "log10l" "log1p" + "log1pf" "log1pl" "nan" "nanf" "nanl" + "ceil" "ceilf" "ceill" "floor" "floorf" "floorl" + "round" "roundf" "roundl" "lround" "lroundf" "lroundl" + "llround" "llroundf" "llroundl" "sqrt" "sqrtf" "sqrtl") + (* space) "(") + (and (or "NAN" "INFINITY" "HUGE_VAL" "HUGE_VALF" "HUGE_VALL") + symbol-end))))) + ("strings.h" nil t + ,(rx (and symbol-start + (or "bcmp" "bcopy" "bzero" "strcasecmp" "strncasecmp") + (* space) "("))) + ("typeinfo" nil t "\\btypeid\\b") + ("new" t t ,(rx (and symbol-start + (or "set_new_handler" "nothrow") + (* space) "("))) + ("limits" t t "\\bnumeric_limits\\s-*<\\b") + ("algorithm" t t + ,(rx (and symbol-start + (or "sort" "stable_sort" "partial_sort" "partial_sort_copy" + "unique" "unique_copy" "reverse" "reverse_copy" + "nth_element" "lower_bound" "upper_bound" "binary_search" + "next_permutation" "prev_permutation" + "min" "max" "count" "random_shuffle" "swap") + (* space) "("))) + ("numeric" t t + ,(rx (and symbol-start + (or "partial_sum" "accumulate" "adjacent_difference" "inner_product") + (* space) "("))) + ("iostream" t t ,(rx (and symbol-start + (or "cin" "cout" "cerr") + symbol-end))) + ("sstream" t t ,(rx (and symbol-start + (or "stringstream" "istringstream" "ostringstream") + symbol-end))) + ("bitset" t t "\\bbitset\\s-*<\\b") + ("complex" t t "\\bcomplex\\s-*<\\b") + ("deque" t t "\\bdeque\\s-*<\\b") + ("queue" t t ,(rx (and symbol-start + (or "queue" "priority_queue") + (* space) "<" word-boundary))) + ("list" t t "\\blist\\s-*<") + ("map" t t ,(rx (and symbol-start + (or "map" "multimap") + (* space) "<" word-boundary))) + ("set" t t ,(rx (and symbol-start + (or "set" "multiset") + (* space) "<" word-boundary))) + ("vector" t t "\\bvector\\s-*<") + ("iomanip" t t ,(rx (and symbol-start + (or (and (or "setprecision" "setbase" "setw") + (* space) "(") + (and (or "fixed" "hex") + symbol-end))))) + ("fstream" t t "\\bfstream\\s-*<") + ("ctime" nil t ,(rx (and symbol-start + (or (and (or "time" "clock") + (* space) "(") + (and (or "fixed" "hex") + symbol-end))))) + ("string" t t "\\bstring\\b") + ("utility" t t "\\b\\(?:pair\\s-*<\\|make_pair\\)"))) + +(defun cpp-auto-include--include-line (header) + (save-excursion + (goto-char (point-min)) + (and (re-search-forward (concat "<" header ">") nil t) + (line-number-at-pos)))) + +(defsubst cpp-auto-include--in-string-or-comment-p () + (nth 8 (syntax-ppss))) + +(defun cpp-auto-include--has-keyword-p (regexp line) + (save-excursion + (goto-char (point-min)) + (when line + (forward-line line)) + (let (finish) + (while (and (not finish) (re-search-forward regexp nil t)) + (unless (cpp-auto-include--in-string-or-comment-p) + (setq finish t))) + finish))) + +(defun cpp-auto-include--parse-file () + (cl-loop with use-std = nil + with added = nil + with removed = nil + with case-fold-search = nil + for info in cpp-auto-include--header-regexp + for header = (nth 0 info) + for regexp = (nth 3 info) + for included-line = (cpp-auto-include--include-line header) + for has-keyword = (cpp-auto-include--has-keyword-p regexp included-line) + + when (and (not use-std) has-keyword) + do (setq use-std t) + + do + (cond ((and has-keyword (not included-line)) + (cl-pushnew header added :test 'equal)) + ((and included-line (not has-keyword)) + (cl-pushnew (cons header included-line) removed :test 'equal))) + + finally + return (list :use-std use-std + :added added :removed removed))) + +(defun cpp-auto-include--header-files () + (save-excursion + (goto-char (point-min)) + (let ((re "^\\s-*#\\s-*include\\s-*<\\([^>]+\\)>") + headers) + (while (re-search-forward re nil t) + (cl-pushnew (match-string-no-properties 1) headers :test 'equal)) + headers))) + +(defun cpp-auto-include--header-insert-point () + (save-excursion + (goto-char (point-max)) + (when (re-search-backward "^#\\s-*include\\s-*[<\"]" nil t) + (forward-line 1) + (point)))) + +(defun cpp-auto-include--add-headers (headers) + (save-excursion + (let ((insert-point (or (cpp-auto-include--header-insert-point) (point-min)))) + (goto-char insert-point) + (dolist (header headers) + (insert (format "#include <%s>\n" header))) + (unless (re-search-forward "^\\s-*$" (line-end-position) t) + (insert "\n"))))) + +(defun cpp-auto-include--remove-headers (headers) + (save-excursion + (cl-loop with deleted-lines = 0 + initially (goto-char (point-min)) + for (header . line) in (sort headers (lambda (a b) (< (cdr a) (cdr b)))) + for curline = 1 then (line-number-at-pos) + do + (progn + (forward-line (- line curline deleted-lines)) + (let ((beg (point))) + (forward-line 1) + (delete-region beg (point)) + (cl-incf deleted-lines)))))) + +;;;###autoload +(defun cpp-auto-include () + (interactive) + (let* ((info (cpp-auto-include--parse-file)) + (added (plist-get info :added)) + (removed (plist-get info :removed))) + (when removed + (cpp-auto-include--remove-headers removed)) + (when added + (cpp-auto-include--add-headers added)))) + +(provide 'cpp-auto-include) + +;;; cpp-auto-include.el ends here diff --git a/packages/cquery-20180811.2131.tar b/packages/cquery-20190118.542.tar similarity index 79% rename from packages/cquery-20180811.2131.tar rename to packages/cquery-20190118.542.tar index 7af670b..273568d 100644 Binary files a/packages/cquery-20180811.2131.tar and b/packages/cquery-20190118.542.tar differ diff --git a/packages/crystal-mode-20180827.329.el b/packages/crystal-mode-20190604.1254.el similarity index 99% rename from packages/crystal-mode-20180827.329.el rename to packages/crystal-mode-20190604.1254.el index 10865c4..9c0b452 100644 --- a/packages/crystal-mode-20180827.329.el +++ b/packages/crystal-mode-20190604.1254.el @@ -5,7 +5,7 @@ ;; Authors: Jason Pellerin ;; crystal-lang-tools ;; URL: https://github.com/crystal-lang-tools/emacs-crystal-mode -;; Package-Version: 20180827.329 +;; Package-Version: 20190604.1254 ;; Created: Tue Jun 23 2015 ;; Keywords: languages crystal ;; Version: 0.2.0 @@ -2763,7 +2763,7 @@ directory of the current file." (boundp 'compilation-error-regexp-alist-alist)) (add-to-list 'compilation-error-regexp-alist 'crystal-spec) (add-to-list 'compilation-error-regexp-alist-alist - '(crystal-spec . ("^in \\([^()\t\n]+\\):\\([0-9]+\\):? .*$" 1 2)) t))) + '(crystal-spec . ("^\\(Error \\)?in \\([^()\t\n]+\\):\\([0-9]+\\):? .*$" 2 3)) t))) ;;; Invoke crystal-mode when appropriate diff --git a/packages/csharp-mode-20181011.718.el b/packages/csharp-mode-20190717.1024.el similarity index 99% rename from packages/csharp-mode-20181011.718.el rename to packages/csharp-mode-20190717.1024.el index 70a4c36..5779700 100644 --- a/packages/csharp-mode-20181011.718.el +++ b/packages/csharp-mode-20190717.1024.el @@ -5,7 +5,7 @@ ;; Created : Feburary 2005 ;; Modified : 2018 ;; Version : 0.9.2 -;; Package-Version: 20181011.718 +;; Package-Version: 20190717.1024 ;; Keywords : c# languages oop mode ;; X-URL : https://github.com/josteink/csharp-mode ;; Last-saved : 2018-Jul-08 @@ -1270,7 +1270,7 @@ Currently handled: ;; instead of create one. (c-lang-defconst c-type-modifier-kwds ;; EMCA-344, S? - csharp '("readonly" "const" "volatile" "new" "unsafe")) + csharp '("readonly" "const" "volatile" "new")) ;; Tue, 20 Apr 2010 16:02 @@ -1325,7 +1325,7 @@ Currently handled: csharp '("public" "partial" "private" "const" "abstract" "sealed" "protected" "ref" "out" "static" "virtual" "implicit" "explicit" "fixed" - "override" "params" "internal" "async" "extern")) + "override" "params" "internal" "async" "extern" "unsafe")) ;; Thu, 22 Apr 2010 23:02 @@ -1364,7 +1364,7 @@ This regexp is assumed to not match any non-operator identifier." ;; Statement keywords followed directly by a substatement. ;; catch is not one of them, because catch has a paren (typically). (c-lang-defconst c-block-stmt-1-kwds - csharp '("do" "else" "try" "finally" "unsafe")) + csharp '("do" "else" "try" "finally")) ;; Statement keywords followed by a paren sexp and then by a substatement. @@ -1385,7 +1385,7 @@ This regexp is assumed to not match any non-operator identifier." ;; Constant keywords (c-lang-defconst c-constant-kwds - csharp '("true" "false" "null")) + csharp '("true" "false" "null" "value")) ;; Keywords that start "primary expressions." (c-lang-defconst c-primary-expr-kwds @@ -2928,14 +2928,14 @@ Otherwise run `c-inside-bracelist-p'." (brace-list-close . 0) (brace-list-entry . 0) (brace-list-intro . +) - (brace-list-open . +) + (brace-list-open . 0) (c . c-lineup-C-comments) (case-label . +) (catch-clause . 0) (class-close . 0) (class-open . 0) (comment-intro . c-lineup-comment) - (cpp-macro . 0) + (cpp-macro . [0]) (cpp-macro-cont . c-lineup-dont-change) (defun-block-intro . +) (defun-close . 0) @@ -2947,7 +2947,7 @@ Otherwise run `c-inside-bracelist-p'." (friend . 0) (func-decl-cont . +) (inclass . +) - (inexpr-class . +) + (inexpr-class . 0) (inexpr-statement . 0) (inextern-lang . +) (inher-cont . c-lineup-multi-inher) diff --git a/packages/cyberpunk-theme-20180609.509.el b/packages/cyberpunk-theme-20190717.1509.el similarity index 99% rename from packages/cyberpunk-theme-20180609.509.el rename to packages/cyberpunk-theme-20190717.1509.el index 1ed0d47..d537633 100644 --- a/packages/cyberpunk-theme-20180609.509.el +++ b/packages/cyberpunk-theme-20190717.1509.el @@ -3,8 +3,9 @@ ;; Copyright 2012-2018, Nicholas M. Van Horn ;; Author: Nicholas M. Van Horn +;; Homepage: https://github.com/n3mo/cyberpunk-theme.el ;; Keywords: color theme cyberpunk -;; Package-Version: 20180609.509 +;; Package-Version: 20190717.1509 ;; Version: 1.21 ;; This file is free software; you can redistribute it and/or modify @@ -29,10 +30,10 @@ ;;; Commentary: -;; This theme is a port of the overtone/emacs-live theme of the same name -;; (https://github.com/overtone/emacs-live). The original theme was -;; designed for use with the color-theme package. This theme adopts the -;; new built-in theme support deftheme. Additionally, this +;; This theme is a port of Sam Aaron's overtone/emacs-live theme of the +;; same name (https://github.com/overtone/emacs-live). The original theme +;; was designed for use with the color-theme package. This theme adopts +;; the new built-in theme support deftheme. Additionally, this ;; theme strives to offer as many mode-specific customizations as ;; possible, with further tweaks that suit my fancy. diff --git a/packages/cython-mode-20180213.1654.el b/packages/cython-mode-20190111.2150.el similarity index 99% rename from packages/cython-mode-20180213.1654.el rename to packages/cython-mode-20190111.2150.el index ed70d91..970cfce 100644 --- a/packages/cython-mode-20180213.1654.el +++ b/packages/cython-mode-20190111.2150.el @@ -1,5 +1,5 @@ ;;; cython-mode.el --- Major mode for editing Cython files -;; Package-Version: 20180213.1654 +;; Package-Version: 20190111.2150 ;; License: Apache-2.0 @@ -104,7 +104,7 @@ (defgroup cython nil "Major mode for editing and compiling Cython files" :group 'languages :prefix "cython-" - :link '(url-link :tag "Homepage" "http://cython.org")) + :link '(url-link :tag "Homepage" "https://cython.org/")) ;;;###autoload (defcustom cython-default-compile-format "cython -a %s" diff --git a/packages/d-mode-20181011.1927.el b/packages/d-mode-20181205.607.el similarity index 99% rename from packages/d-mode-20181011.1927.el rename to packages/d-mode-20181205.607.el index e35a676..4860d73 100644 --- a/packages/d-mode-20181011.1927.el +++ b/packages/d-mode-20181205.607.el @@ -7,8 +7,8 @@ ;; Maintainer: Russel Winder ;; Vladimir Panteleev ;; Created: March 2007 -;; Version: 201810111924 -;; Package-Version: 20181011.1927 +;; Version: 201812050604 +;; Package-Version: 20181205.607 ;; Keywords: D programming language emacs cc-mode ;; Package-Requires: ((emacs "24.3")) @@ -530,6 +530,7 @@ Each list item should be a regexp matching a single identifier." ;; Pure/const etc. (zero-or-more (one-or-more (any "a-z@")) + symbol-end (zero-or-more (any " \t\n"))) (zero-or-more diff --git a/packages/dante-20180916.729.el b/packages/dante-20190818.847.el similarity index 72% rename from packages/dante-20180916.729.el rename to packages/dante-20190818.847.el index 1818052..fa70042 100644 --- a/packages/dante-20180916.729.el +++ b/packages/dante-20190818.847.el @@ -9,11 +9,11 @@ ;; Author: Jean-Philippe Bernardy ;; Maintainer: Jean-Philippe Bernardy ;; URL: https://github.com/jyp/dante -;; Package-Version: 20180916.729 +;; Package-Version: 20190818.847 ;; Created: October 2016 ;; Keywords: haskell, tools -;; Package-Requires: ((dash "2.12.0") (emacs "25.1") (f "0.19.0") (flycheck "0.30") (haskell-mode "13.14") (s "1.11.0") (lcr "1.0")) -;; Version: +;; Package-Requires: ((dash "2.12.0") (emacs "25.1") (f "0.19.0") (flycheck "0.30") (company "0.9") (haskell-mode "13.14") (s "1.11.0") (lcr "1.0")) +;; Version: 0-pre ;; 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 @@ -32,11 +32,11 @@ ;;; Commentary: -;; DANTE: Do Not Aim To Expand. +;; DANTE: Do Aim Not To Expand. -;; This is a mode for GHCi advanced "IDE" features. The mode depends -;; on GHCi only, keeping the logic simple. Additionally it aims to be -;; minimal as far as possible. +;; This is a mode to provide Emacs interface for GHCi. The mode +;; depends on GHCi only, keeping the logic simple. Additionally it +;; aims to be minimal as far as possible. ;;; Code: @@ -48,6 +48,8 @@ (require 's) (require 'xref) (require 'lcr) +(eval-when-compile + (require 'company)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Configuration @@ -89,55 +91,89 @@ will be in different GHCi sessions." (put 'dante-target 'safe-local-variable #'stringp) -(defun dante-project-root () - "Get the root directory for the project. -If `dante-project-root' is set as a variable, return that, -otherwise look for a .cabal file, or use the current dir." - (file-name-as-directory - (or dante-project-root - (set (make-local-variable 'dante-project-root) - (file-name-directory (or (dante-cabal-find-file) (dante-buffer-file-name))))))) - -(defun dante-repl-by-file (root files cmdline) - "Return if ROOT / file exists for any file in FILES, return CMDLINE." - (when (-any? (lambda (file) (file-exists-p (concat root file))) files) cmdline)) - -(defcustom dante-repl-command-line-methods-alist - `((styx . ,(lambda (root) (dante-repl-by-file root '("styx.yaml") '("styx" "repl" dante-target)))) - (nix . ,(lambda (root) (dante-repl-by-file root '("shell.nix" "default.nix") - '("nix-shell" "--pure" "--run" (concat "cabal repl " (or dante-target "") " --builddir=dist/dante"))))) - (impure-nix - . ,(lambda (root) (dante-repl-by-file root '("shell.nix" "default.nix") - '("nix-shell" "--run" (concat "cabal repl " (or dante-target "") " --builddir=dist/dante"))))) - (stack . ,(lambda (root) (dante-repl-by-file root '("stack.yaml") '("stack" "repl" dante-target)))) - (mafia . ,(lambda (root) (dante-repl-by-file root '("mafia") '("mafia" "repl" dante-target)))) - (new-build . ,(lambda (root) (when (or (directory-files root nil ".+\\.cabal$") (file-exists-p "cabal.project")) - '("cabal" "new-repl" dante-target "--builddir=dist/dante")))) - (bare . ,(lambda (_) '("cabal" "repl" dante-target "--builddir=dist/dante"))) - (bare-ghci . ,(lambda (_) '("ghci")))) -"GHCi launch command lines. -This is an alist from method name to a function taking the root -directory and returning either a command line or nil if the -method should not apply." - :type '(alist :key-type symbol :value-type function)) - -(defcustom dante-repl-command-line-methods (-map 'car dante-repl-command-line-methods-alist) - "Keys in `dante-repl-command-line-methods-alist' to try, in order. +(defun dante-cabal-new-nix (d) + "non-nil iff D contains a nix file and a cabal file." + (and (directory-files d t "shell.nix\\|default.nix") + (directory-files d t "cabal.project"))) + +(defun dante-cabal-nix (d) + "non-nil iff D contains a nix file and a cabal file." + (and (directory-files d t "shell.nix\\|default.nix") + (directory-files d t ".cabal$"))) + +(defcustom dante-methods-alist + `((styx "styx.yaml" ("styx" "repl" dante-target)) + (new-impure-nix dante-cabal-new-nix ("nix-shell" "--run" (concat "cabal new-repl " (or dante-target (dante-package-name) "") " --builddir=dist/dante"))) + (new-nix dante-cabal-new-nix ("nix-shell" "--pure" "--run" (concat "cabal new-repl " (or dante-target (dante-package-name) "") " --builddir=dist/dante"))) + (nix dante-cabal-nix ("nix-shell" "--pure" "--run" (concat "cabal repl " (or dante-target "") " --builddir=dist/dante"))) + (impure-nix dante-cabal-nix ("nix-shell" "--run" (concat "cabal repl " (or dante-target "") " --builddir=dist/dante"))) + (new-build "cabal.project" ("cabal" "new-repl" (or dante-target (dante-package-name) nil) "--builddir=dist/dante")) + (nix-ghci ,(lambda (d) (directory-files d t "shell.nix\\|default.nix")) ("nix-shell" "--pure" "--run" "ghci")) + (stack "stack.yaml" ("stack" "repl" dante-target)) + (mafia "mafia" ("mafia" "repl" dante-target)) + (bare-cabal ,(lambda (d) (directory-files d t "..cabal$")) ("cabal" "repl" dante-target "--builddir=dist/dante")) + (bare-ghci ,(lambda (_) t) ("ghci"))) +"How to automatically locate project roots and launch GHCi. +This is an alist from method name to a pair of +a `locate-dominating-file' argument and a command line." + :type '(alist :key-type symbol :value-type (list (choice (string :tag "File to locate") (function :tag "Predicate to use")) (repeat sexp)))) + +(defcustom dante-methods (-map 'car dante-methods-alist) + "Keys in `dante-methods-alist' to try, in order. Consider setting this variable as a directory variable." :group 'dante :safe t :type '(repeat symbol)) -(defvar dante-command-line "command line used to start GHCi") +(put 'dante-methods 'safe-local-variable #'listp) + +(defun dante-initialize-method () + "Initialize `dante-project-root' and `dante-repl-command-line'. +Do it according to `dante-methods' and previous values of the above variables." + (or (--first (let ((root (locate-dominating-file default-directory (nth 0 it)))) + (when root + (setq-local dante-project-root (or dante-project-root root)) + (setq-local dante-repl-command-line (or dante-repl-command-line (nth 1 it))))) + (-non-nil (--map (alist-get it dante-methods-alist) + dante-methods))) + (error "No GHCi loading method applies. Customize + `dante-methods' or + (`dante-repl-command-line' and `dante-project-root')"))) (defun dante-repl-command-line () "Return the command line for running GHCi. -If the custom variable `dante-repl-command-line' is non-nil, it -will be returned. Otherwise, use -`dante-repl-command-line-methods-alist'." +If the variable `dante-repl-command-line' is non-nil, it will be +returned. Otherwise, use `dante-initialize-method'." (or dante-repl-command-line - (let ((root (dante-project-root))) - (--some (funcall it root) - (--map (alist-get it dante-repl-command-line-methods-alist) - dante-repl-command-line-methods))))) + (progn (dante-initialize-method) dante-repl-command-line))) + +(defun dante-project-root () + "Get the root directory for the project. +If the variable `dante-project-root' is non-nil, return that, +otherwise search for project root using +`dante-initialize-method'." + (or dante-project-root + (progn (dante-initialize-method) dante-project-root))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Session-local variables. These are set *IN THE GHCi INTERACTION BUFFER* + +(defvar-local dante-command-line nil "command line used to start GHCi") +(defvar-local dante-load-message nil "load messages") +(defvar-local dante-loaded-file "") +(defvar-local dante-queue nil "List of ready GHCi queries.") +(defvar-local dante-package-name nil "The package name associated with the current buffer.") +(defvar-local dante-state nil + "nil: initial state +- deleting: The process of the buffer is being deleted. +- dead: GHCi died on its own. Do not try restarting +automatically. The user will have to manually run `dante-restart' +to destroy the buffer and create a fresh one without this variable enabled. +- other value: informative value for the user about what GHCi is doing +") + +(defun dante-get-var (symbol) + "Return the value of SYMBOL in the GHCi process buffer." + (let ((bp (dante-buffer-p))) (when bp (buffer-local-value symbol bp)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Mode @@ -153,8 +189,8 @@ will be returned. Otherwise, use (if lcr-process-callback (format "busy(%s)" (1+ (length dante-queue))) (pcase dante-state (`(ghc-err (compiling ,mod)) (format "error(%s)" mod)) - (`(loaded ,loaded-mods) (if (s-equals? dante-loaded-file fname) "loaded" (format "loaded(%s)" (file-name-base dante-loaded-file)))) - (`(,hd . ,tl) (format "%s" hd)) + (`(loaded ,_loaded-mods) (if (s-equals? dante-loaded-file fname) "loaded" (format "loaded(%s)" (file-name-base dante-loaded-file)))) + (`(,hd . ,_tl) (format "%s" hd)) (_ (format "%s" dante-state)))))))) ;;;###autoload @@ -176,36 +212,14 @@ if the argument is omitted or nil or a positive integer). :keymap dante-mode-map :group 'dante (if dante-mode - (progn (flycheck-select-checker 'haskell-dante) - (add-hook 'flymake-diagnostic-functions 'dante-flymake nil t)) - (progn (flycheck-select-checker nil) - (remove-hook 'flymake-diagnostic-functions 'dante-flymake t)))) + (add-hook 'flymake-diagnostic-functions 'dante-flymake nil t) + (remove-hook 'flymake-diagnostic-functions 'dante-flymake t))) (define-key dante-mode-map (kbd "C-c .") 'dante-type-at) (define-key dante-mode-map (kbd "C-c ,") 'dante-info) (define-key dante-mode-map (kbd "C-c /") 'attrap-attrap) ;; deprecated keybinding (define-key dante-mode-map (kbd "C-c \"") 'dante-eval-block) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Session-local variables. These are set *IN THE GHCi INTERACTION BUFFER* - -(defvar-local dante-load-message nil "load messages") -(defvar-local dante-loaded-file "") -(defvar-local dante-queue nil "List of ready GHCi queries.") -(defvar-local dante-package-name nil "The package name associated with the current buffer.") -(defvar-local dante-state nil - "nil: initial state -- deleting: The process of the buffer is being deleted. -- dead: GHCi died on its own. Do not try restarting -automatically. The user will have to manually run `dante-restart' -to destroy the buffer and create a fresh one without this variable enabled. -- other value: informative value for the user about what GHCi is doing -") - -(defun dante-get-var (symbol) - "Return the value of SYMBOL in the GHCi process buffer." - (let ((bp (dante-buffer-p))) (when bp (buffer-local-value symbol bp)))) - ;;;;;;;;;;;;;;;;;;;;;;;;; ;; Interactive utils @@ -259,12 +273,14 @@ When the universal argument INSERT is non-nil, insert the type in the buffer." (dante-fontify-expression info)) (goto-char (point-min))))))))) -;;;;;;;;;;;;;;;;;;;;; -;; Flycheck checker - (defvar-local dante-temp-epoch -1 "The value of `buffer-modified-tick' when the contents were last loaded.") +(defvar-local dante-interpreted nil) + +(defvar dante-original-buffer-map (make-hash-table :test 'equal) + "Hash table from (local) temp file names to the file they originate.") + (lcr-def dante-async-load-current-buffer (interpret) "Load and maybe INTERPRET the temp file for current buffer. Interpreting puts all symbols from the current module in @@ -272,41 +288,52 @@ scope. Compiling to avoids re-interpreting the dependencies over and over." (let* ((epoch (buffer-modified-tick)) (unchanged (equal epoch dante-temp-epoch)) - (fname (buffer-file-name (current-buffer))) + (src-fname (buffer-file-name (current-buffer))) + (fname (dante-temp-file-name (current-buffer))) (buffer (lcr-call dante-session)) - (same-buffer (s-equals? (buffer-local-value 'dante-loaded-file buffer) fname))) - (if (and unchanged same-buffer) (buffer-local-value 'dante-load-message buffer) ; see #52 + (same-target (and (or dante-interpreted (not interpret)) + (s-equals? (buffer-local-value 'dante-loaded-file buffer) src-fname)))) + (if (and unchanged same-target) ; see #52 + (buffer-local-value 'dante-load-message buffer) (setq dante-temp-epoch epoch) - (basic-save-buffer-1) ;; save without re-triggering flycheck/flymake nor any save hook + (setq dante-interpreted interpret) + (puthash (dante-local-name fname) src-fname dante-original-buffer-map) + (write-region nil nil fname nil 0) ;; GHCi will interpret the buffer iff. both -fbyte-code and :l * are used. (lcr-call dante-async-call (if interpret ":set -fbyte-code" ":set -fobject-code")) (with-current-buffer buffer - (dante-async-write (if (and (not interpret) same-buffer) ":r" + (dante-async-write (if same-target ":r" (concat ":l " (if interpret "*" "") (dante-local-name fname)))) (cl-destructuring-bind (_status err-messages _loaded-modules) (lcr-call dante-load-loop "" nil) - (setq dante-loaded-file fname) + (setq dante-loaded-file src-fname) (setq dante-load-message err-messages)))))) (defun dante-local-name (fname) "Local name of FNAME on the remote host." (string-remove-prefix (or (file-remote-p fname) "") fname)) +;;;;;;;;;;;;;;;;;;;;; +;; Flycheck checker + (defun dante-check (checker cont) "Run a check with CHECKER and pass the status onto CONT." (if (eq (dante-get-var 'dante-state) 'dead) (funcall cont 'interrupted) (lcr-cps-let ((messages (dante-async-load-current-buffer nil))) - (let* ((temp-file (dante-local-name (buffer-file-name (current-buffer))))) - (funcall cont - 'finished - (--remove (eq 'splice (flycheck-error-level it)) - (--map (dante-fly-message it checker (current-buffer) temp-file) messages))))))) + (let* ((temp-file (dante-local-name (dante-temp-file-name (current-buffer))))) + (funcall cont + 'finished + (--remove (eq 'splice (flycheck-error-level it)) + (--map (dante-fly-message it checker (current-buffer) temp-file) messages))))))) (flycheck-define-generic-checker 'haskell-dante "A syntax and type checker for Haskell using a Dante worker process." :start 'dante-check + :predicate (lambda () dante-mode) :modes '(haskell-mode literate-haskell-mode)) +(add-to-list 'flycheck-checkers 'haskell-dante) + (defun dante-fly-message (matched checker buffer temp-file) "Convert the MATCHED message to flycheck format. CHECKER and BUFFER are added if the error is in TEMP-FILE." @@ -320,8 +347,10 @@ CHECKER and BUFFER are added if the error is in TEMP-FILE." ;; FIXME: sometimes the "error type" contains the actual error too. (flycheck-error-new-at (car location) (cadr location) type (concat err-type "\n" (s-trim-right msg)) :checker checker - :buffer (when (string= temp-file file) buffer) - :filename (dante-buffer-file-name buffer))))) + :buffer buffer + :filename (if (string= temp-file file) + (dante-buffer-file-name buffer) + file))))) (defun dante-parse-error-location (string) "Parse the line/col numbers from the error in STRING." @@ -349,23 +378,29 @@ CHECKER and BUFFER are added if the error is in TEMP-FILE." (common (nth 2 (read (concat "(" (car lines) ")"))))) (--map (replace-regexp-in-string "\\\"" "" (concat common it)) (cdr lines))))) +(defun dante--in-a-comment () + "Return non-nil if point is in a comment." + (nth 4 (syntax-ppss))) + +(declare-function company-begin-backend 'company) + (defun dante-company (command &optional arg &rest _ignored) "Company backend for dante. -See ``company-backends'' for the meaning of COMMAND and _ARGS." - (let ((prefix )) ;; todo: pref len - (cl-case command - (interactive (company-begin-backend 'dante-company)) - (sorted t) - (prefix (when (and dante-mode (dante-ident-pos-at-point)) - (let* ((id-start (car (dante-ident-pos-at-point))) - (_ (save-excursion (re-search-backward "import[\t ]*" (line-beginning-position) t))) - (import-end (match-end 0)) - (import-start (match-beginning 0)) - (is-import (eq import-end id-start))) - (buffer-substring-no-properties (if is-import import-start id-start) (point))))) - (candidates - (unless (eq (dante-get-var 'dante-state) 'dead) - (cons :async (apply-partially 'dante-complete arg))))))) +See ``company-backends'' for the meaning of COMMAND, ARG and _IGNORED." + (interactive (list 'interactive)) + (cl-case command + (interactive (company-begin-backend 'dante-company)) + (sorted t) + (prefix (when (and dante-mode (not (dante--in-a-comment)) (dante-ident-pos-at-point -1)) + (let* ((id-start (car (dante-ident-pos-at-point -1))) + (_ (save-excursion (re-search-backward "import[\t ]*" (line-beginning-position) t))) + (import-end (match-end 0)) + (import-start (match-beginning 0)) + (is-import (eq import-end id-start))) + (buffer-substring-no-properties (if is-import import-start id-start) (point))))) + (candidates + (unless (eq (dante-get-var 'dante-state) 'dead) + (cons :async (apply-partially 'dante-complete arg)))))) (with-eval-after-load 'company (add-to-list 'company-backends 'dante-company)) @@ -385,38 +420,20 @@ May return a qualified name." (when reg (apply #'buffer-substring-no-properties reg)))) -(defun dante-ident-pos-at-point () - "Return the span of the identifier under point, or nil if none found. -May return a qualified name." - (save-excursion - (let ((case-fold-search nil)) - (cl-multiple-value-bind (start end) - (list - (progn (skip-syntax-backward "w_") (point)) - (progn (skip-syntax-forward "w_") (point))) - ;; If we're looking at a module ID that qualifies further IDs, add - ;; those IDs. - (goto-char start) - (while (and (looking-at "[[:upper:]]") (eq (char-after end) ?.) - ;; It's a module ID that qualifies further IDs. - (goto-char (1+ end)) - (save-excursion - (when (not (zerop (skip-syntax-forward - (if (looking-at "\\s_") "_" "w'")))) - (setq end (point)))))) - ;; If we're looking at an ID that's itself qualified by previous - ;; module IDs, add those too. - (goto-char start) - (if (eq (char-after) ?.) (forward-char 1)) ;Special case for "." - (while (and (eq (char-before) ?.) - (progn (forward-char -1) - (not (zerop (skip-syntax-backward "w'")))) - (skip-syntax-forward "'") - (looking-at "[[:upper:]]")) - (setq start (point))) - ;; This is it. - (unless (= start end) - (list start end)))))) +(defun dante-ident-pos-at-point (&optional offset) + "Return the span of the (qualified) identifier at point+OFFSET, or nil if none found." + (let* ((qualifier-regex "\\([[:upper:]][[:alnum:]]*\\.\\)") + (ident-regex (concat qualifier-regex "*\\(\\s.+\\|\\(\\sw\\|\\s_\\)+\\)"))) ; note * for many qualifiers + (save-excursion + (goto-char (+ (point) (or offset 0))) + (when (looking-at ident-regex) + (let ((end (match-end 0))) + (skip-syntax-backward (if (looking-at "\\s.") "." "w_")) ;; find start of operator/variable + (while (save-excursion + (and (re-search-backward (concat "\\b" qualifier-regex) (line-beginning-position) t) + (s-matches? (concat "^" ident-regex "$") (buffer-substring-no-properties (point) end)))) + (goto-char (match-beginning 0))) + (list (point) end)))))) (defun dante-buffer-file-name (&optional buffer) "Call function `buffer-file-name' for BUFFER and clean its result. @@ -425,6 +442,34 @@ The path returned is canonicalized and stripped of any text properties." (when name (dante-canonicalize-path (substring-no-properties name))))) +(defvar-local dante-temp-file-name nil + "The name of a temporary file to which the current buffer's content is copied.") + +(defun dante-tramp-make-tramp-temp-file (buffer) + "Create a temporary file for BUFFER, perhaps on a remote host." + (let* ((fname (buffer-file-name buffer)) + (suffix (file-name-extension fname t))) + (if (file-remote-p fname) + (with-parsed-tramp-file-name (buffer-file-name buffer) vec + (let ((prefix (concat + (expand-file-name + tramp-temp-name-prefix (tramp-get-remote-tmpdir vec)) + "dante")) + result) + (while (not result) + (setq result (concat (make-temp-name prefix) suffix)) + (if (file-exists-p result) + (setq result nil))) + ;; This creates the file by side effect. + (set-file-times result) + (set-file-modes result #o700) + result)) + (make-temp-file "dante" nil suffix)))) + +(defun dante-temp-file-name (buffer) + "Return a (possibly remote) filename suitable to store BUFFER's contents." + (with-current-buffer buffer + (or dante-temp-file-name (setq dante-temp-file-name (dante-tramp-make-tramp-temp-file buffer))))) (defun dante-canonicalize-path (path) "Return a standardized version of PATH. @@ -453,7 +498,7 @@ x:\\foo\\bar (i.e., Windows)." "Format the subexpression denoted by REG for GHCi commands." (pcase reg (`(,beg ,end) (format "%S %d %d %d %d %s" - (buffer-file-name (current-buffer)) + (dante-local-name (dante-temp-file-name (current-buffer))) (line-number-at-pos beg) (dante--ghc-column-number-at-pos beg) (line-number-at-pos end) @@ -529,6 +574,7 @@ Note that sub-sessions are not interleaved." buffer)) (defun dante-debug (category msg) + "Append a debug message MSG to the current buffer if CATEGORY is enabled in `dante-debug'." (when (memq category dante-debug) (goto-char (point-max)) (insert msg))) @@ -545,8 +591,9 @@ Must be called from GHCi process buffer." (defconst dante-ghci-prompt "\4\\(.*\\)|") -(defun dante-regexp-disjoin (&rest args) - (s-join "\\|" args)) +(defun dante-regexp-disjoin (&rest regexps) + "Return a regexp matching any of REGEXPS." + (s-join "\\|" regexps)) (lcr-def dante-load-loop (acc err-msgs) "Parse the output of load command. @@ -556,7 +603,7 @@ ACC umulate input and ERR-MSGS." "^Ok, modules loaded:[ ]*\\([^\n ]*\\)\\( (.*)\\)?\." "^Ok, .*modules loaded." ;; .* stands for a number in english (two, three, ...) (GHC 8.2) "^Ok, one module loaded.")) - (progress "^\\[\\([0-9]*\\) of \\([0-9]*\\)\\] Compiling \\([^ ]*\\).*") + (progress "^\\[\\([0-9]*\\) of \\([0-9]*\\)\\] Compiling \\([^ \n]*\\).*") (err-regexp "^\\([A-Z]?:?[^ \n:][^:\n\r]+\\):\\([0-9()-:]+\\): \\(.*\\)\n\\(\\([ ]+.*\n\\)*\\)") (result nil)) (while (not result) @@ -688,47 +735,12 @@ CABAL-FILE rather than trying to locate one." (file-name-nondirectory cabal-file)) ""))))) -(defun dante-cabal-find-file (&optional dir) - "Search for package description file upwards starting from DIR. -If DIR is nil, `default-directory' is used as starting point for -directory traversal. Upward traversal is aborted if file owner -changes. Uses `dante-cabal-find-pkg-desc' internally." - (let ((use-dir (or dir default-directory))) - (while (and use-dir (not (file-directory-p use-dir))) - (setq use-dir (file-name-directory (directory-file-name use-dir)))) - (when use-dir - (catch 'found - (let ((user (nth 2 (file-attributes use-dir))) - ;; Abbreviate, so as to stop when we cross ~/. - (root (abbreviate-file-name use-dir))) - ;; traverse current dir up to root as long as file owner doesn't change - (while (and root (equal user (nth 2 (file-attributes root)))) - (let ((cabal-file (dante-cabal-find-pkg-desc root))) - (when cabal-file - (throw 'found cabal-file))) - (let ((proot (file-name-directory (directory-file-name root)))) - (if (equal proot root) ;; fix-point reached? - (throw 'found nil) - (setq root proot)))) - nil))))) - -(defun dante-cabal-find-pkg-desc (dir &optional allow-multiple) - "Find a package description file in the directory DIR. -Returns nil if none or multiple \".cabal\" files were found. If -ALLOW-MULTIPLE is non nil, in case of multiple \".cabal\" files, -a list is returned instead of failing with a nil result." - ;; This is basically a port of Cabal's - ;; Distribution.Simple.Utils.findPackageDesc function - ;; http://hackage.haskell.org/packages/archive/Cabal/1.16.0.3/doc/html/Distribution-Simple-Utils.html - ;; but without the exception throwing. - (let* ((cabal-files - (cl-remove-if 'file-directory-p - (cl-remove-if-not 'file-exists-p - (directory-files dir t ".\\.cabal\\'"))))) - (cond - ((= (length cabal-files) 1) (car cabal-files)) ;; exactly one candidate found - (allow-multiple cabal-files) ;; pass-thru multiple candidates - (t nil)))) +(defun dante-cabal-find-file (&optional file) + "Search for directory of cabal file, upwards from FILE (or `default-directory' if nil)." + (let ((dir (locate-dominating-file (or file default-directory) + (lambda (d) (directory-files d t ".\\.cabal\\'"))))) + (when dir (car (directory-files dir t ".\\.cabal\\'"))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; xref support @@ -753,7 +765,8 @@ a list is returned instead of failing with a nil result." (line (string-to-number (match-string 2 string))) (col (string-to-number (match-string 3 string)))) (xref-make-file-location - (expand-file-name file dante-project-root) + (or (gethash file dante-original-buffer-map) + (expand-file-name file dante-project-root)) line (1- col))))) (defun dante--summarize-src-spans (spans file) @@ -788,22 +801,41 @@ a list is returned instead of failing with a nil result." (add-hook 'xref-backend-functions 'dante--xref-backend) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Idle-hook (missing bit: check for errors) - -;; (defvar dante-timer nil) -;; (defun dante-idle-function () -;; (when (bound-and-true-p dante-mode) -;; (let ((tap (dante--ghc-subexp (dante-thing-at-point)))) -;; (unless (or (nth 4 (syntax-ppss)) (nth 3 (syntax-ppss)) (s-blank? tap)) -;; (setq-local dante-idle-point (point)) -;; (lcr-cps-let ((_load_messages (dante-async-load-current-buffer t)) -;; (ty (dante-async-call (concat ":type-at " tap)))) -;; (when (eq (point) dante-idle-point) -;; (unless (current-message) -;; (message "%s" (s-collapse-whitespace (dante-fontify-expression ty))))) -;; ))))) -;; (when dante-timer (cancel-timer dante-timer)) -;; (setq dante-timer (run-with-idle-timer 1 t #'dante-idle-function)) +;; Idle-hook + +(defcustom dante-tap-type-time nil +"Delay after to display type of the thing at point, in seconds. +Use nil to disable." :type 'integer :group 'dante) +(defvar dante-timer nil) +(defvar dante-last-valid-idle-type-message nil) + +(defvar-local dante-idle-point nil "point when idler kicked in.") + +(defun dante-idle-function () + "Eldoc-like support function." + (when (and dante-mode ;; don't start GHCi if dante is not on. + (dante-buffer-p) ;; buffer exists + (with-current-buffer (dante-buffer-p) + (not (eq dante-state 'dead))) ;; GHCi alive? + (not lcr-process-callback)) ;; Is GHCi idle? + (let ((tap (dante--ghc-subexp (dante-thing-at-point)))) + (unless (or (nth 4 (syntax-ppss)) (nth 3 (syntax-ppss)) (s-blank? tap)) ;; not in a comment or string + (setq-local dante-idle-point (point)) + (lcr-cps-let ((_load_messages (dante-async-load-current-buffer t)) + (ty (dante-async-call (concat ":type-at " tap)))) + (when (and (let ((cur-msg (current-message))) + (or (not cur-msg) + (string-match-p (concat "^Wrote " (buffer-file-name)) cur-msg) + (and dante-last-valid-idle-type-message + (string-equal dante-last-valid-idle-type-message cur-msg)))) + ;; echo area is free, or the buffer was just saved from having triggered a check, or the queue had many requests for idle display and is displaying the last fulfilled idle type request + (not (s-match "^" ty)) ;; no error + (eq (point) dante-idle-point)) ;; cursor did not move + (setq dante-last-valid-idle-type-message (s-collapse-whitespace (dante-fontify-expression ty))) + (message "%s" dante-last-valid-idle-type-message))))))) +(when dante-timer (cancel-timer dante-timer)) +(when dante-tap-type-time + (setq dante-timer (run-with-idle-timer dante-tap-type-time t #'dante-idle-function))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Reploid @@ -846,11 +878,12 @@ Calls DONE when done. BLOCK-END is a marker for the end of the evaluation block "Run a check and pass the status onto REPORT-FN." (if (eq (dante-get-var 'dante-state) 'dead) (funcall report-fn :panic :explanation "Ghci is dead") (lcr-cps-let ((messages (dante-async-load-current-buffer nil))) - (let* ((temp-file (dante-local-name (buffer-file-name (current-buffer)))) + (let* ((temp-file (dante-local-name (dante-temp-file-name (current-buffer)))) (diags (-non-nil (--map (dante-fm-message it (current-buffer) temp-file) messages)))) (funcall report-fn diags))))) (defun dante-pos-at-line-col (buf l c) + "Translate line L and column C into a position within BUF." (with-current-buffer buf (save-excursion (goto-char (point-min)) diff --git a/packages/dap-mode-20190819.902.tar b/packages/dap-mode-20190819.902.tar new file mode 100644 index 0000000..1dea27a Binary files /dev/null and b/packages/dap-mode-20190819.902.tar differ diff --git a/packages/darkokai-theme-20181019.1859.el b/packages/darkokai-theme-20190603.1919.el similarity index 99% rename from packages/darkokai-theme-20181019.1859.el rename to packages/darkokai-theme-20190603.1919.el index 0c15d58..b6ff0dd 100644 --- a/packages/darkokai-theme-20181019.1859.el +++ b/packages/darkokai-theme-20190603.1919.el @@ -1,7 +1,7 @@ ;;; darkokai-theme.el --- A darker variant on Monokai. ;; URL: http://github.com/sjrmanning/darkokai -;; Package-Version: 20181019.1859 +;; Package-Version: 20190603.1919 ;; Version: 0.1.2 ;; The MIT License (MIT) @@ -116,8 +116,8 @@ Also affects 'linum-mode' background." (darkokai-green "#63de5d") (darkokai-gray "#35393b") ;; Blue tints - (darkokai-bg-blue "#1E1F28") - (darkokai-fringe-blue "#2a2b38") + (darkokai-bg-blue "#282a36") + (darkokai-fringe-blue "#323342") (darkokai-pl-ld "#38394a") (darkokai-pl-d "#323342") (darkokai-pl-dd "#292a36") @@ -148,7 +148,7 @@ Also affects 'linum-mode' background." ;; Adaptive colors (darkokai-fg "#f8fbfc") (darkokai-bg "#242728") - (darkokai-highlight-line "#424748") + (darkokai-highlight-line "#323342") (darkokai-highlight "#5D6365") (darkokai-emph "#ffffff") (darkokai-comments "#6A6D70") @@ -2980,6 +2980,49 @@ Also affects 'linum-mode' background." ((,class (:foreground ,darkokai-cyan)) (,terminal-class (:foreground ,terminal-darkokai-cyan)))) + ;; ivy + `(ivy-subdir + ((,class (:foreground ,darkokai-blue)) + (,terminal-class (:foreground ,terminal-darkokai-blue)))) + + `(ivy-minibuffer-match-face-1 + ((,class (:foreground ,darkokai-comments + :underline nil)) + (,terminal-class (:foreground ,terminal-darkokai-comments + :underline nil)))) + + `(ivy-minibuffer-match-face-2 + ((,class (:foreground ,darkokai-violet-l + :underline t)) + (,terminal-class (:foreground ,terminal-darkokai-violet-l + :underline t)))) + + `(ivy-minibuffer-match-face-3 + ((,class (:foreground ,darkokai-magenta-l + :underline t)) + (,terminal-class (:foreground ,terminal-darkokai-magenta-l + :underline t)))) + + `(ivy-minibuffer-match-face-4 + ((,class (:foreground ,darkokai-cyan-l + :underline t)) + (,terminal-class (:foreground ,terminal-darkokai-cyan-l + :underline t)))) + + `(ivy-match-required-face + ((,class (:foreground ,darkokai-red-plain)) + (,terminal-class (:foreground ,darkokai-red-plain)))) + + `(ivy-current-match + ((,class (:background ,darkokai-cyan-d + :foreground ,darkokai-cyan-l + :weight bold)) + (,terminal-class (:background ,terminal-darkokai-cyan-d + :foreground ,terminal-darkokai-cyan-l + :weight bold)))) + + ;; jabber + `(jabber-activity-face ((,class (:weight bold :foreground ,darkokai-red)) @@ -3199,6 +3242,10 @@ Also affects 'linum-mode' background." (,terminal-class (:foreground ,terminal-darkokai-red :background ,terminal-darkokai-highlight-line)))) + `(magit-section-highlight + ((,class (:background ,darkokai-highlight-line)) + (,terminal-class (:background ,terminal-darkokai-highlight-line)))) + `(magit-section-title ((,class (:foreground ,darkokai-yellow :weight bold)) diff --git a/packages/darktooth-theme-20181013.906.el b/packages/darktooth-theme-20190412.142.el similarity index 99% rename from packages/darktooth-theme-20181013.906.el rename to packages/darktooth-theme-20190412.142.el index 0191dad..78d382f 100644 --- a/packages/darktooth-theme-20181013.906.el +++ b/packages/darktooth-theme-20190412.142.el @@ -4,7 +4,7 @@ ;; Authors: Jason Milkins ;; URL: http://github.com/emacsfodder/emacs-theme-darktooth -;; Package-Version: 20181013.906 +;; Package-Version: 20190412.142 ;; Version: 0.3.10 ;; Package-Requires: ((autothemer "0.2")) @@ -155,9 +155,9 @@ ;; compilation messages (also used by several other modes) (compilation-info (:foreground darktooth-neutral_green)) (compilation-mode-line-fail (:foreground darktooth-neutral_red)) - (error (:foreground darktooth-bright_orange :bold t)) + (error (:foreground darktooth-bright_red :bold t)) (success (:foreground darktooth-neutral_green :bold t)) - (warning (:foreground darktooth-bright_red :bold t)) + (warning (:foreground darktooth-bright_yellow :bold t)) ;; Built-in syntax (font-lock-builtin-face (:foreground darktooth-bright_orange)) @@ -591,12 +591,13 @@ (ivy-remote (:foreground darktooth-neutral_blue)) ;; MODE SUPPORT: smerge - ;; TODO: smerge-base smerge-refined-changed - (smerge-mine (:background darktooth-mid_purple)) - (smerge-other (:background darktooth-mid_blue)) + (smerge-upper (:background darktooth-mid_purple)) + (smerge-lower (:background darktooth-mid_blue)) + (smerge-base (:background darktooth-dark_yellow)) (smerge-markers (:background darktooth-dark0_soft)) (smerge-refined-added (:background darktooth-dark_green)) (smerge-refined-removed (:background darktooth-dark_red)) + (smerge-refine-changed (:background nil :foreground nil)) ;; MODE SUPPORT: git-gutter (git-gutter:added (:foreground darktooth-faded_green :background darktooth-muted_green )) diff --git a/packages/dart-mode-20190808.2226.el b/packages/dart-mode-20190808.2226.el new file mode 100644 index 0000000..ff0d5a5 --- /dev/null +++ b/packages/dart-mode-20190808.2226.el @@ -0,0 +1,623 @@ +;;; dart-mode.el --- Major mode for editing Dart files -*- lexical-binding: t; -*- + +;; Author: Brady Trainor +;; URL: https://github.com/bradyt/dart-mode +;; Package-Version: 20190808.2226 +;; Version: 1.0.4 +;; Package-Requires: ((emacs "24.3")) +;; Keywords: languages + +;;; Commentary: + +;; Major mode for editing Dart files. + +;; Provides basic syntax highlighting and indentation. + +;;; Code: + +;;; Configuration + +(defvar dart-mode-map (make-sparse-keymap) + "Keymap used in dart-mode buffers.") +(define-key dart-mode-map (kbd "") 'dart-dedent-simple) +(define-key dart-mode-map (kbd "C-c C-i") 'indent-according-to-mode) + + +;;; Indentation + +(defcustom dart-indent-trigger-commands + '(indent-for-tab-command yas-expand yas/expand dart-dedent-simple) + "Commands that might trigger a `dart-indent-line' call." + :type '(repeat symbol) + :group 'dart) + +(defun dart-indent-line-function () + "`indent-line-function' for Dart mode. +When the variable `last-command' is equal to one of the symbols +inside `dart-indent-trigger-commands' it cycles possible +indentation levels from right to left." + (if (and (memq this-command dart-indent-trigger-commands) + (eq last-command this-command)) + (dart-indent-simple) + (dart-indent-line-relative))) + +(defun dart-indent-simple (&optional backwards) + (interactive) + (save-excursion + (indent-line-to + (max 0 (indent-next-tab-stop (current-indentation) backwards)))) + (when (< (current-column) (current-indentation)) + (back-to-indentation))) + +(defun dart-dedent-simple () + (interactive) + (dart-indent-simple 'backwards)) + +(defun dart-depth-of-line () + (save-excursion + (back-to-indentation) + (let ((depth (car (syntax-ppss)))) + (when (and (char-after) + (= (char-syntax (char-after)) ?\))) + (while (and (char-after) + (/= (char-syntax (char-after)) ?\() + (/= (char-after) ?\C-j)) + (when (= (char-syntax (char-after)) ?\)) + (setq depth (1- depth))) + (forward-char))) + depth))) + +(defun dart-indent-line-relative () + (let ((curr-depth (dart-depth-of-line)) + prev-line + prev-depth + prev-indent) + (save-excursion + (beginning-of-line) + (catch 'done + (while t + (when (= (point) 1) + (throw 'done t)) + (forward-line -1) + (unless (looking-at (rx (and bol (zero-or-more space) eol))) + (setq prev-line t) + (setq prev-indent (current-indentation)) + (setq prev-depth (dart-depth-of-line)) + (throw 'done t))))) + (save-excursion + (if prev-line + (indent-line-to (max 0 (+ prev-indent + (* (- curr-depth prev-depth) + tab-width)))) + (indent-line-to 0))) + (when (< (current-column) (current-indentation)) + (back-to-indentation)))) + + +;;; Fontification + +(defvar dart--file-directives + '("as" "deferred" "export" "hide" "import" "library" "of" "part" + "show")) + +(defvar dart--builtins + ;; ECMA 408; Section: Identifier Reference + ;; "Built-in identifiers" + '("abstract" "as" "covariant" "deferred" "dynamic" "export" + "external" "factory" "Function" "get" "implements" "import" + "interface" "library" "mixin" "operator" "part" "set" "static" + "typedef")) + +(defvar dart--keywords + ;; ECMA 408; Section: Reserved Words + '("assert" "break" "case" "catch" "class" "const" "continue" + "default" "do" "else" "enum" "extends" "final" "finally" "for" + "if" "in" "is" "new" "rethrow" "return" "super" "switch" "this" + "throw" "try" "var" "while" "with")) + +(defvar dart--types '("bool" "double" "int" "num" "void")) + +(defvar dart--constants '("false" "null" "true")) + +(defvar dart--async-keywords-re (rx word-start + (or "async" "await" "sync" "yield") + word-end + (zero-or-one ?*))) + +(defvar dart--number-re (rx symbol-start + (zero-or-one ?-) + (group (or (and (one-or-more digit) + (zero-or-one + (and ?. (one-or-more digit)))) + (and ?. (one-or-more digit))) + (zero-or-one (and (or ?e ?E) + (zero-or-one (or ?+ ?-)) + (one-or-more digit)))))) + +(defvar dart--hex-number-re (rx symbol-start + (zero-or-one ?-) + (group (or "0x" "0X") + (one-or-more (any (?a . ?f) + (?A . ?F) + digit))))) + +(defvar dart--operator-declaration-re (rx "operator" + (one-or-more space) + (group + (one-or-more (not (any ?\()))))) + +(eval-and-compile (defun dart--identifier (&optional case) + `(and (or word-start symbol-start) + (zero-or-more (any ?$ ?_)) + ,(if case + case + 'alpha) + (zero-or-more (or ?$ ?_ alnum))))) + +(defvar dart--metadata-re (rx ?@ (eval (dart--identifier)))) + +(defvar dart--types-re (rx (eval (dart--identifier 'upper)))) + +(defvar dart--constants-re (rx (and word-start + upper + (>= 2 (or upper ?_)) + word-end))) + +(defun dart--string-interpolation-id-func (limit) + "Font-lock matcher for string interpolation identifiers. + +These have the form $variableName. + +Can fontify entire match with group 0, or using group 1 for sigil, +group 2 for variableName." + (catch 'result + (let (data end syntax) + (while (re-search-forward (rx (group ?$) + (group (zero-or-more ?_) + lower + (zero-or-more (or ?_ alnum)))) + limit t) + (setq data (match-data)) + (setq end (match-end 2)) + (setq syntax (syntax-ppss)) + ;; Check that we are in a string and not in a raw string + (when (and (nth 3 syntax) + (or (= (nth 8 syntax) 1) + (not (eq (char-before (nth 8 syntax)) ?r)))) + (set-match-data data) + (goto-char end) + (throw 'result t)) + (when end + (goto-char end))) + (throw 'result nil)))) + +(defun dart--string-interpolation-exp-func (limit) + "Font-lock matcher for string interpolation expressions. + +These have the form ${expression}. + +Can fontify entire match with group 0, or using group 1 for sigil, +groups 2 and 4 for curly brackets, and 3 for contents." + (catch 'result + (let (sigil beg open close end depth) + ;; Loop and put point after ${ + (while (and (search-forward "${" limit t) + ;; Check that we are in a string and not in a raw string + (save-excursion + (and (nth 3 (syntax-ppss)) + (not (eq (char-before (nth 8 (syntax-ppss))) ?r))))) + ;; "a string with ${someInterpolation + aValue} inside of it." + ;; ^^^ ^^ + ;; ||| || + ;; sigil -+|+- open close -++- end + ;; +- beg + (setq open (point)) + (setq beg (- open 1)) + (setq sigil (- open 2)) + (setq depth 1) + ;; Move forward until limit, while depth is positive and we + ;; are inside string. + (while (and (> depth 0) + (< (point) limit) + (nth 3 (syntax-ppss))) + (setq depth (+ depth (pcase (char-after) + (?\{ 1) + (?\} -1) + (_ 0)))) + (forward-char)) + (setq end (point)) + ;; If depth is zero, we have found a closing } within string + ;; and before limit. Set `match-data', `point', and return `t'. + (when (= depth 0) + (setq close (1- end)) + (set-match-data (list sigil end + sigil beg + beg open + open close + close end)) + (goto-char end) + (throw 'result t)) + ;; If the candidate did not meet criteria, put point at end + ;; and search again. + (goto-char end)) + ;; When there are no more candidate "${", return nil. + (throw 'result nil)))) + +(defun dart--function-declaration-func (limit) + "Font-lock matcher function for function declarations. + +Matches function declarations before LIMIT that look like, + + \"lowercaseIdentifier([...]) [[a]sync[*], {, =>]\" + +For example, \"main\" in \"void main() async\" would be matched." + (catch 'result + (let (beg end) + (while (re-search-forward + (rx (group (eval (dart--identifier 'lower))) ?\() limit t) + (setq beg (match-beginning 1)) + (setq end (match-end 1)) + (condition-case nil + (progn + (up-list) + (when (looking-at (rx (one-or-more space) + (or "async" "async*" "sync*" "{" "=>"))) + (set-match-data (list beg end)) + (goto-char end) + (throw 'result t))) + (scan-error nil)) + (goto-char end)) + (throw 'result nil)))) + +(defun dart--abstract-method-func (limit) + "Font-lock matcher function for abstract methods. + +Matches function declarations before LIMIT that look like, + + \" [^ ][^=]* lowercaseIdentifier([...]);\" + +For example, \"compareTo\" in \" int compareTo(num other);\" would be +matched." + (catch 'result + (let (beg end) + (while (re-search-forward + (rx (and (not (any ?\.)) (group (eval (dart--identifier 'lower)))) ?\() limit t) + (setq beg (match-beginning 1)) + (setq end (match-end 1)) + (condition-case nil + (progn + (up-list) + (when (and (< (point) (point-max)) + (= (char-after (point)) ?\;)) + (goto-char beg) + (back-to-indentation) + (when (and (= (current-column) 2) + (not (looking-at "return")) + (string-match-p + " " (buffer-substring-no-properties + (point) beg)) + (not (string-match-p + "=" (buffer-substring-no-properties + (point) beg)))) + (goto-char end) + (set-match-data (list beg end)) + (throw 'result t)))) + (scan-error nil)) + (goto-char end))) + (throw 'result nil))) + +(defun dart--declared-identifier-func (limit) + "Font-lock matcher function for declared identifiers. + +Matches declared identifiers before LIMIT that look like, + + \"finalConstVarOrType lowercaseIdentifier\" + +For example, \"height\" in \"const int height\" would be matched." + (catch 'result + (let (beg end) + (while (re-search-forward + (rx + (and (group (or (or "const" "final" + "bool" "double" "dynamic" "int" "num" "void" + "var" + "get" "set") + (eval (dart--identifier 'upper))) + (zero-or-more ?>)) + (one-or-more (or space ?\C-j)) + (group (eval (dart--identifier 'lower))) + (not (any ?\( alnum ?$ ?_)))) + limit t) + (setq beg (match-beginning 2)) + (setq end (match-end 2)) + ;; Check for false positives + (when (not (member (match-string 2) + '("bool" "double" "dynamic" "int" "num" "void" + "var" + "get" "set"))) + (goto-char end) + (unless (nth 3 (syntax-ppss)) + (set-match-data (list beg end)) + (throw 'result t))) + (goto-char (match-end 1))) + (throw 'result nil)))) + +(defun dart--in-parenthesized-expression-or-formal-parameter-list-p () + "Returns `t' if `point' is in parentheses, otherwise `nil'. + +In particular, parenthesized expressions or formal parameter lists." + (save-excursion + (catch 'result + ;; Attempt to jump out of parentheses. + (condition-case nil + (backward-up-list) + (scan-error (throw 'result nil))) + ;; If we've only jumped out of optional or named section of + ;; formal parameters, try to jump again. + (when (member (char-after (point)) '(?\[ ?\{)) + (condition-case nil + (backward-up-list) + (scan-error (throw 'result nil)))) + (throw 'result (= (char-after (point)) ?\())))) + +(defun dart--declared-identifier-anchor-func (limit) + "Font-lock matcher for declared identifier. + +Uses `dart--declared-identifier-func' to find candidates before +LIMIT, and checks that they are not in parentheses. + +This matcher is an anchor to match multiple identifiers in a +single variable declaration. From ECMA-408, + + variableDeclaration: + declaredIdentifier (', ' identifier)* + ; + +After this function sets anchor, font-lock will use the function +`dart--declared-identifier-next-func' to find subsequent +identifiers." + (catch 'result + (let (data) + (while (dart--declared-identifier-func limit) + (setq data (match-data)) + (unless (dart--in-parenthesized-expression-or-formal-parameter-list-p) + (set-match-data data) + (goto-char (match-end 0)) + (throw 'result t)) + (goto-char (match-end 0))) + (throw 'result nil)))) + +(defun dart--declared-identifier-next-func (limit) + "Font-lock matcher for subsequent identifiers. + +For use after `dart--declared-identifier-anchor-func' sets +anchor, this function will look for subsequent identifers to +fontify as declared variables. From ECMA-408, + + variableDeclaration: + declaredIdentifier (', ' identifier)* + ;" + (catch 'result + (let ((depth (car (syntax-ppss)))) + (while t + (cond + ;; If point is followed by semi-colon, we are done. + ((or (> (point) limit) + (= (char-after (point)) ?\;) + (< (car (syntax-ppss)) depth)) + (throw 'result nil)) + ;; If point is followed by comma, and we are still at same + ;; depth, then attempt to match another identifier, otherwise + ;; return nil. + ((and (= (char-after (point)) ?\x2c) ; ?, + (= (car (syntax-ppss)) depth)) + (if (looking-at (rx ?\x2c + (one-or-more space) + (group (eval (dart--identifier 'lower))))) + (progn (set-match-data (list (match-beginning 1) + (match-end 1))) + (goto-char (match-end 0)) + (throw 'result t)) + (throw 'result nil))) + ;; Otherwise, if we are still before `point-max' (shouldn't + ;; this be `limit'? May be a bad attempt to deal with + ;; multiline searches. Should research how this is done with + ;; font-lock.), move forward. + ((< (point) (point-max)) + (forward-char)) + ;; Otherwise, return nil. + (t (throw 'result nil))))))) + +(defun dart--anonymous-function-matcher (limit) + "Font-lock matcher for start of anonymous functions. + +Looks for opening parenthesis, tries to jump to opening +parenthesis, ensure it is not preceded by for, while, etc. Then +tries to jump to closing parenthesis and check if followed by \" +{\" or \" =>\". + +Used with `dart--untyped-parameter-anchored-matcher' to fontify +untyped parameters. For example, in + + (untypedParameter) => untypedParameter.length" + (catch 'result + (let (beg end) + (while (search-forward "(" limit t) + (setq beg (match-beginning 0)) + (setq end (match-end 0)) + (unless (looking-back (rx (or (and (or "do" "for" "if" "switch" "while") + space) + "super") + ?\() + (point-at-bol)) + (condition-case nil + (up-list) + (scan-error (throw 'result nil))) + (when (looking-at (rx space (or ?\{ "=>"))) + (set-match-data (list beg end)) + (goto-char end) + (throw 'result t)) + (goto-char end))) + (throw 'result nil)))) + +(defun dart--untyped-parameter-anchored-matcher (limit) + "Font-lock anchored-matcher for untyped parameters. + +Searches forward for for lowercase idenitifer and ensures depth +is still same. + +Used with `dart--anonymous-function-matcher' to fontify +untyped parameters. For example, in + + (untypedParameter) => untypedParameter.length" + (let (beg end) + (catch 'result + (if (equal (char-after) ?\)) + (throw 'result nil)) + (let ((depth (car (syntax-ppss)))) + (while (re-search-forward + (rx (and (group (or (one-or-more (char ?_)) + (eval (dart--identifier 'lower)))) + (or ?, ?\))))) + (setq beg (match-beginning 1)) + (setq end (match-end 1)) + (goto-char end) + (if (or (> (point) limit) + (< (car (syntax-ppss)) depth)) + (throw 'result nil) + (set-match-data (list beg end)) + (throw 'result t)))) + (throw 'result nil)))) + +(defun dart--get-point-at-end-of-list () + (let (pt) + (save-excursion + (up-list) + (setq pt (point))) + pt)) + +(defvar dart-font-lock-defaults + '((dart-font-lock-keywords-1 dart-font-lock-keywords-1 + dart-font-lock-keywords-2 + dart-font-lock-keywords-3))) + +(defvar dart-font-lock-keywords-1 + `((,(regexp-opt dart--file-directives 'words) . font-lock-builtin-face) + (dart--function-declaration-func . font-lock-function-name-face) + (,dart--operator-declaration-re . (1 font-lock-function-name-face)) + (dart--abstract-method-func . font-lock-function-name-face))) + +(defvar dart-font-lock-keywords-2 + `(,dart--async-keywords-re + ,(regexp-opt dart--keywords 'words) + (,(regexp-opt dart--builtins 'words) . font-lock-builtin-face) + (,(regexp-opt dart--constants 'words) . font-lock-constant-face) + (,dart--hex-number-re . (1 font-lock-constant-face)) + (,dart--number-re . (1 font-lock-constant-face)) + (,dart--metadata-re . font-lock-constant-face) + (,dart--constants-re . font-lock-constant-face) + (,(regexp-opt dart--types 'words) . font-lock-type-face) + (,dart--types-re . font-lock-type-face) + (dart--function-declaration-func . font-lock-function-name-face) + (,dart--operator-declaration-re . (1 font-lock-function-name-face)) + (dart--abstract-method-func . font-lock-function-name-face))) + +(defvar dart-font-lock-keywords-3 + (append + dart-font-lock-keywords-2 + `((dart--declared-identifier-func . font-lock-variable-name-face) + (dart--declared-identifier-anchor-func + . (dart--declared-identifier-next-func + nil + nil + (0 font-lock-variable-name-face))) + (dart--anonymous-function-matcher + . (dart--untyped-parameter-anchored-matcher + (dart--get-point-at-end-of-list) + nil + (0 font-lock-variable-name-face))) + (dart--string-interpolation-id-func (0 font-lock-variable-name-face t)) + (dart--string-interpolation-exp-func (0 font-lock-variable-name-face t))))) + +(defun dart-syntax-propertize-function (beg end) + "Sets syntax-table text properties for raw and/or multiline strings. + +We use fences uniformly for consistency. + +In raw strings, we modify backslash characters to have punctuation +syntax rather than escape syntax. + +String interpolation is not handled correctly yet, but the fixes to +quote characters in multiline strings, and escape characters in raw +strings, ensures that code outside of strings is not highlighted as +strings." + (goto-char beg) + ;; We rely on syntax-propertize-extend-region-functions that `beg` + ;; will be at beginning of line, but we ensure here that we are not + ;; in a string + (while (nth 3 (syntax-ppss)) + (goto-char (nth 8 (syntax-ppss))) + (beginning-of-line)) + ;; Search for string opening + (while (re-search-forward (rx (group (optional ?r)) + (group (or (repeat 3 ?\") + (repeat 3 ?\') + ?\" + ?\'))) + end t) + (let ((bos (match-beginning 2)) + (rawp (equal (match-string-no-properties 1) "r")) + (string-delimiter (match-string-no-properties 2))) + ;; Set string fence syntax at beginning of string + (put-text-property bos (1+ bos) 'syntax-table (string-to-syntax "|") nil) + ;; Look for the end of string delimiter, depending on rawp and + ;; string-delimiter + ;; Unless rawp, ensure an even number of backslashes + (when (or (looking-at (concat (unless rawp (rx (zero-or-more ?\\ ?\\))) + string-delimiter)) + (re-search-forward (concat (unless rawp (rx (not (any ?\\)) (zero-or-more ?\\ ?\\))) + string-delimiter) + end t)) + (let ((eos (match-end 0))) + ;; Set end of string fence delimiter + (put-text-property (1- eos) eos 'syntax-table (string-to-syntax "|") nil) + ;; For all strings, remove fence property between fences + ;; For raw strings, set all backslashes to punctuation syntax + (dolist (pt (number-sequence (1+ bos) (- eos 2))) + (when (equal (get-text-property pt 'syntax-table) (string-to-syntax "|")) + (remove-text-properties pt (1+ pt) 'syntax-table)) + (when (and rawp (equal (char-after pt) ?\\)) + (put-text-property pt (1+ pt) 'syntax-table (string-to-syntax ".") nil))) + (goto-char eos)))))) + + +;;; Initialization + +;;;###autoload (add-to-list 'auto-mode-alist '("\\.dart\\'" . dart-mode)) + +;;;###autoload +(define-derived-mode dart-mode prog-mode "Dart" + "Major mode for editing Dart files. + +The hook `dart-mode-hook' is run with no args at mode +initialization. + +Key bindings: +\\{dart-mode-map}" + (modify-syntax-entry ?/ "_ 124b") + (modify-syntax-entry ?* ". 23") + (modify-syntax-entry ?\n "> b") + (modify-syntax-entry ?\' "\"") + (setq-local electric-indent-chars '(?\n ?\) ?\] ?\})) + (setq-local comment-start "//") + (setq-local comment-end "") + (setq fill-column 80) + (setq font-lock-defaults dart-font-lock-defaults) + (setq-local indent-line-function 'dart-indent-line-function) + (setq indent-tabs-mode nil) + (setq tab-width 2) + (setq-local syntax-propertize-function 'dart-syntax-propertize-function)) + +(provide 'dart-mode) + +;;; dart-mode.el ends here diff --git a/packages/dash-20180910.1856.el b/packages/dash-20190814.2006.el similarity index 97% rename from packages/dash-20180910.1856.el rename to packages/dash-20190814.2006.el index ee67456..f4b36ed 100644 --- a/packages/dash-20180910.1856.el +++ b/packages/dash-20190814.2006.el @@ -3,8 +3,8 @@ ;; Copyright (C) 2012-2016 Free Software Foundation, Inc. ;; Author: Magnar Sveen -;; Version: 2.14.1 -;; Package-Version: 20180910.1856 +;; Version: 2.16.0 +;; Package-Version: 20190814.2006 ;; Keywords: lists ;; This program is free software; you can redistribute it and/or modify @@ -87,6 +87,14 @@ the target form." forms) ,retval))) +(defmacro --doto (eval-initial-value &rest forms) + "Anaphoric form of `-doto'. +Note: `it' is not required in each form." + (declare (indent 1)) + `(let ((it ,eval-initial-value)) + ,@forms + it)) + (defun -each (list fn) "Call FN with every item in LIST. Return nil, used for side-effects only." (--each list (funcall fn it))) @@ -914,9 +922,11 @@ See also: `-drop'" "Rotate LIST N places to the right. With N negative, rotate to the left. The time complexity is O(n)." (declare (pure t) (side-effect-free t)) - (if (> n 0) - (append (last list n) (butlast list n)) - (append (-drop (- n) list) (-take (- n) list)))) + (when list + (let* ((len (length list)) + (n-mod-len (mod n len)) + (new-tail-len (- len n-mod-len))) + (append (-drop new-tail-len list) (-take new-tail-len list))))) (defun -insert-at (n x list) "Return a list with X inserted into LIST at position N. @@ -1643,6 +1653,10 @@ All returned symbols are guaranteed to be unique." (t (cons (list s source) (dash--match-cons-1 match-form s)))))) +(defun dash--get-expand-function (type) + "Get expand function name for TYPE." + (intern (format "dash-expand:%s" type))) + (defun dash--match-cons-1 (match-form source &optional props) "Match MATCH-FORM against SOURCE. @@ -1662,7 +1676,7 @@ SOURCE is a proper or improper list." ((cdr match-form) (cond ((and (symbolp (car match-form)) - (memq (car match-form) '(&keys &plist &alist &hash))) + (functionp (dash--get-expand-function (car match-form)))) (dash--match-kv (dash--match-kv-normalize-match-form match-form) (dash--match-cons-get-cdr skip-cdr source))) ((dash--match-ignore-place-p (car match-form)) (dash--match-cons-1 (cdr match-form) source @@ -1803,6 +1817,27 @@ kv can be any key-value store, such as plist, alist or hash-table." (t (cons (list s source) (dash--match-kv-1 (cdr match-form) s (car match-form))))))) +(defun dash-expand:&hash (key source) + "Generate extracting KEY from SOURCE for &hash destructuring." + `(gethash ,key ,source)) + +(defun dash-expand:&plist (key source) + "Generate extracting KEY from SOURCE for &plist destructuring." + `(plist-get ,source ,key)) + +(defun dash-expand:&alist (key source) + "Generate extracting KEY from SOURCE for &alist destructuring." + `(cdr (assoc ,key ,source))) + +(defun dash-expand:&hash? (key source) + "Generate extracting KEY from SOURCE for &hash? destructuring. +Similar to &hash but check whether the map is not nil." + (let ((src (make-symbol "src"))) + `(let ((,src ,source)) + (when ,src (gethash ,key ,src))))) + +(defalias 'dash-expand:&keys 'dash-expand:&plist) + (defun dash--match-kv-1 (match-form source type) "Match MATCH-FORM against SOURCE of type TYPE. @@ -1820,13 +1855,8 @@ Valid values are &plist, &alist and &hash." (lambda (kv) (let* ((k (car kv)) (v (cadr kv)) - (getter (cond - ((or (eq type '&plist) (eq type '&keys)) - `(plist-get ,source ,k)) - ((eq type '&alist) - `(cdr (assoc ,k ,source))) - ((eq type '&hash) - `(gethash ,k ,source))))) + (getter + (funcall (dash--get-expand-function type) k source))) (cond ((symbolp v) (list (list v getter))) @@ -1859,7 +1889,7 @@ Key-value stores are disambiguated by placing a token &plist, (let ((s (car match-form))) (cons (list s source) (dash--match (cddr match-form) s)))) - ((memq (car match-form) '(&keys &plist &alist &hash)) + ((functionp (dash--get-expand-function (car match-form))) (dash--match-kv (dash--match-kv-normalize-match-form match-form) source)) (t (dash--match-cons match-form source)))) ((vectorp match-form) @@ -2245,9 +2275,22 @@ The test for equality is done with `equal', or with `-compare-fn' if that's non-nil. Alias: `-uniq'" - (let (result) - (--each list (unless (-contains? result it) (!cons it result))) - (nreverse result))) + ;; Implementation note: The speedup gained from hash table lookup + ;; starts to outweigh its overhead for lists of length greater than + ;; 32. See discussion in PR #305. + (let* ((len (length list)) + (lut (and (> len 32) + ;; Check that `-compare-fn' is a valid hash-table + ;; lookup function or `nil'. + (memq -compare-fn '(nil equal eq eql)) + (make-hash-table :test (or -compare-fn #'equal) + :size len)))) + (if lut + (--filter (unless (gethash it lut) + (puthash it t lut)) + list) + (--each list (unless (-contains? lut it) (!cons it lut))) + (nreverse lut)))) (defalias '-uniq '-distinct) @@ -2533,11 +2576,15 @@ the new seed." (defun -cons-pair? (con) "Return non-nil if CON is true cons pair. -That is (A . B) where B is not a list." +That is (A . B) where B is not a list. + +Alias: `-cons-pair-p'" (declare (pure t) (side-effect-free t)) (and (listp con) (not (listp (cdr con))))) +(defalias '-cons-pair-p '-cons-pair?) + (defun -cons-to-list (con) "Convert a cons pair to a list with `car' and `cdr' of the pair respectively." (declare (pure t) (side-effect-free t)) @@ -2942,6 +2989,7 @@ structure such as plist or alist." "-unfold" "--unfold" "-cons-pair?" + "-cons-pair-p" "-cons-to-list" "-value-to-list" "-tree-mapreduce-from" diff --git a/packages/helm-dash-20180503.918.el b/packages/dash-docs-20190516.1702.el similarity index 50% rename from packages/helm-dash-20180503.918.el rename to packages/dash-docs-20190516.1702.el index 4dae4bf..2f798af 100644 --- a/packages/helm-dash-20180503.918.el +++ b/packages/dash-docs-20190516.1702.el @@ -1,14 +1,15 @@ -;;; helm-dash.el --- Offline documentation browser for +150 APIs using Dash docsets. -*- lexical-binding: t; -*- +;;; dash-docs.el --- Offline documentation browser using Dash docsets. -*- lexical-binding: t; -*- ;; Copyright (C) 2013-2014 Raimon Grau ;; Copyright (C) 2013-2014 Toni Reina ;; Author: Raimon Grau ;; Toni Reina +;; Bryan Gilbert ;; ;; URL: http://github.com/areina/helm-dash -;; Package-Version: 20180503.918 -;; Version: 1.3.0 -;; Package-Requires: ((helm "1.9.2") (cl-lib "0.5")) +;; Package-Version: 20190516.1702 +;; Version: 1.4.0 +;; Package-Requires: ((emacs "24.4") (cl-lib "0.5") (async "1.9.3")) ;; Keywords: docs ;; This program is free software; you can redistribute it and/or modify @@ -26,33 +27,27 @@ ;; ;;; Commentary: ;; -;; Clone the functionality of dash using helm foundation. Browse -;; documentation via dash docsets. -;; -;; M-x helm-dash -;; M-x helm-dash-at-point +;; A library that exposes functionality to work with and search dash +;; docsets. ;; ;; More info in the project site https://github.com/areina/helm-dash ;; ;;; Code: -(eval-when-compile (require 'cl)) (require 'cl-lib) -(require 'helm) -(require 'helm-multi-match) (require 'json) (require 'xml) (require 'format-spec) +(require 'async) +(require 'thingatpt) +(require 'gnutls) - -;;; Customize - -(defgroup helm-dash nil - "Search Dash docsets using helm." - :prefix "helm-dash-" +(defgroup dash-docs nil + "Search Dash docsets." + :prefix "dash-docs-" :group 'applications) -(defcustom helm-dash-docsets-path +(defcustom dash-docs-docsets-path (let ((original-dash-path (expand-file-name "~/Library/Application Support/Dash/DocSets"))) (if (and (string-equal system-type 'darwin) (file-directory-p original-dash-path)) @@ -62,41 +57,58 @@ If you're setting this option manually, set it to an absolute path. You can use `expand-file-name' function for that." :set (lambda (opt val) (set opt (expand-file-name val))) - :group 'helm-dash) + :type 'string + :group 'dash-docs) -(defcustom helm-dash-docsets-url "https://raw.github.com/Kapeli/feeds/master" - "Feeds URL for dash docsets." :group 'helm-dash) +(defcustom dash-docs-docsets-url "https://raw.github.com/Kapeli/feeds/master" + "Feeds URL for dash docsets." + :type 'string + :group 'dash-docs) -(defcustom helm-dash-min-length 3 +(defcustom dash-docs-min-length 3 "Minimum length to start searching in docsets. 0 facilitates discoverability, but may be a bit heavy when lots of docsets are active. Between 0 and 3 is sane." - :group 'helm-dash) + :type 'integer + :group 'dash-docs) -(defcustom helm-dash-candidate-format "%d %n (%t)" +(defcustom dash-docs-candidate-format "%d %n (%t)" "Format of the displayed candidates. Available formats are %d - docset name %n - name of the token %t - type of the token %f - file name" - :group 'helm-dash) + :type 'string + :group 'dash-docs) -(defcustom helm-dash-enable-debugging t +(defcustom dash-docs-enable-debugging t "When non-nil capture stderr from sql commands and display it in a buffer. Setting this to nil may speed up queries." - :group 'helm-dash) - - + :type 'boolean + :group 'dash-docs) -(defvar helm-dash-history-input nil) -(defvar helm-dash-common-docsets +(defvar dash-docs-common-docsets '() "List of Docsets to search active by default.") +(defvar dash-docs-use-workaround-for-emacs-bug + (and (< emacs-major-version 27) 'force) + "Whether to use a kludge that hopefully works around an Emacs bug. + +In Emacs versions before 27 there is a bug that causes network +connections to fail sometimes. If this variable is non-nil, then +dash-docs works around that by binding `gnutls-algorithm-priority' to +\"NORMAL:-VERS-TLS1.3\", unless we think it is unnecessary. If +`force' then always use the workaround. Currently the latter is +the default except when using Emacs 27. + +For more information see https://github.com/magit/ghub/issues/81 +and https://debbugs.gnu.org/cgi/bugreport.cgi?bug=34341.") -(defun helm-dash-docset-path (docset) + +(defun dash-docs-docset-path (docset) "Return the full path of the directory for DOCSET." - (let* ((base (helm-dash-docsets-path)) + (let* ((base (dash-docs-docsets-path)) (docdir (expand-file-name docset base))) (cl-loop for dir in (list (format "%s/%s.docset" base docset) (format "%s/%s.docset" docdir docset) @@ -105,34 +117,35 @@ Setting this to nil may speed up queries." when (and dir (file-directory-p dir)) return dir))) -(defun helm-dash-docset-db-path (docset) +(defun dash-docs-docset-db-path (docset) "Compose the path to sqlite DOCSET." - (let ((path (helm-dash-docset-path docset))) + (let ((path (dash-docs-docset-path docset))) (if path (expand-file-name "Contents/Resources/docSet.dsidx" path) - (error "Cannot find docset '%s' in `helm-dash-docsets-path'" docset)))) + (error "Cannot find docset '%s' in `dash-docs-docsets-path'" docset)))) -(defvar helm-dash-connections nil +(defvar dash-docs--connections nil "List of conses like (\"Go\" . connection).") -(defcustom helm-dash-browser-func 'browse-url +(defcustom dash-docs-browser-func 'browse-url "Default function to browse Dash's docsets. Suggested values are: * `browse-url' * `eww'" - :group 'helm-dash) + :type 'function + :group 'dash-docs) -(defun helm-dash-docsets-path () +(defun dash-docs-docsets-path () "Return the path where Dash's docsets are stored." - (expand-file-name helm-dash-docsets-path)) + (expand-file-name dash-docs-docsets-path)) -(defun helm-dash-sql (db-path sql) +(defun dash-docs-sql (db-path sql) "Run in the db located at DB-PATH the SQL command and parse the results. -If there are errors, print them in `helm-dash-debugging-buffer'" - (helm-dash-parse-sql-results +If there are errors, print them in `dash-docs-debugging-buffer'" + (dash-docs-parse-sql-results (with-output-to-string - (let ((error-file (when helm-dash-enable-debugging - (make-temp-file "helm-dash-errors-file")))) + (let ((error-file (when dash-docs-enable-debugging + (make-temp-file "dash-docs-errors-file")))) (call-process "sqlite3" nil (list standard-output error-file) nil ;; args for sqlite3: "-list" "-init" "''" db-path sql) @@ -140,7 +153,7 @@ If there are errors, print them in `helm-dash-debugging-buffer'" ;; display errors, stolen from emacs' `shell-command` function (when (and error-file (file-exists-p error-file)) (if (< 0 (nth 7 (file-attributes error-file))) - (with-current-buffer (helm-dash-debugging-buffer) + (with-current-buffer (dash-docs-debugging-buffer) (let ((pos-from-end (- (point-max) (point)))) (or (bobp) (insert "\f\n")) @@ -153,68 +166,90 @@ If there are errors, print them in `helm-dash-debugging-buffer'" (display-buffer (current-buffer)))) (delete-file error-file)))))) -(defun helm-dash-parse-sql-results (sql-result-string) +(defun dash-docs-parse-sql-results (sql-result-string) "Parse SQL-RESULT-STRING splitting it by newline and '|' chars." (mapcar (lambda (x) (split-string x "|" t)) (split-string sql-result-string "\n" t))) -(defun helm-dash-filter-connections () - "Filter connections using `helm-dash-connections-filters'." - (let ((docsets (helm-dash-buffer-local-docsets)) +(defun dash-docs-filter-connections () + "Filter connections using `dash-docs--connections-filters'." + (let ((docsets (dash-docs-buffer-local-docsets)) (connections nil)) - (setq docsets (append docsets helm-dash-common-docsets)) + (setq docsets (append docsets dash-docs-common-docsets)) (delq nil (mapcar (lambda (y) - (assoc y helm-dash-connections)) - docsets)))) + (assoc y dash-docs--connections)) + docsets)))) -(defun helm-dash-buffer-local-docsets () +(defun dash-docs-buffer-local-docsets () "Get the docsets configured for the current buffer." - (or (and (boundp 'helm-dash-docsets) helm-dash-docsets) + (or (and (boundp 'dash-docs-docsets) dash-docs-docsets) '())) -(defun helm-dash-create-common-connections () +(defun dash-docs-create-common-connections () "Create connections to sqlite docsets for common docsets." - (when (not helm-dash-connections) - (setq helm-dash-connections + (when (not dash-docs--connections) + (setq dash-docs--connections (mapcar (lambda (x) - (let ((db-path (helm-dash-docset-db-path x))) - (list x db-path (helm-dash-docset-type db-path)))) - helm-dash-common-docsets)))) + (let ((db-path (dash-docs-docset-db-path x))) + (list x db-path (dash-docs-docset-type db-path)))) + dash-docs-common-docsets)))) -(defun helm-dash-create-buffer-connections () +(defun dash-docs-create-buffer-connections () "Create connections to sqlite docsets for buffer-local docsets." - (mapc (lambda (x) (when (not (assoc x helm-dash-connections)) - (let ((connection (helm-dash-docset-db-path x))) - (setq helm-dash-connections - (cons (list x connection (helm-dash-docset-type connection)) - helm-dash-connections))))) - (helm-dash-buffer-local-docsets))) - -(defun helm-dash-reset-connections () + (mapc (lambda (x) (when (not (assoc x dash-docs--connections)) + (let ((connection (dash-docs-docset-db-path x))) + (setq dash-docs--connections + (cons (list x connection (dash-docs-docset-type connection)) + dash-docs--connections))))) + (dash-docs-buffer-local-docsets))) + +(defun dash-docs-reset-connections () "Wipe all connections to docsets." (interactive) - (setq helm-dash-connections nil)) + (setq dash-docs--connections nil)) -(defun helm-dash-docset-type (db-path) +(defun dash-docs-docset-type (db-path) "Return the type of the docset based in db schema. Possible values are \"DASH\" and \"ZDASH\". The Argument DB-PATH should be a string with the sqlite db path." (let ((type_sql "SELECT name FROM sqlite_master WHERE type = 'table' LIMIT 1")) - (if (member "searchIndex" (car (helm-dash-sql db-path type_sql))) + (if (member "searchIndex" (car (dash-docs-sql db-path type_sql))) "DASH" "ZDASH"))) -(defun helm-dash-read-json-from-url (url) +(defmacro dash-docs-with-emacs-bug-workaround (&rest body) + "Optionally apply a workaround to an Emacs bug and execute BODY. + +In Emacs versions before 27 there is a bug that causes network +connections to fail sometimes. If `dash-docs-use-workaround-for-emacs-bug' +variable is non-nil, then dash-docs works around that by binding +`gnutls-algorithm-priority' to \"NORMAL:-VERS-TLS1.3\", unless we +think it is unnecessary. If `force' then always use the workaround. +Currently the latter is the default except when using Emacs 27. + +For more information see https://github.com/magit/ghub/issues/81 +and https://debbugs.gnu.org/cgi/bugreport.cgi?bug=34341." + `(let ((gnutls-algorithm-priority + (if (and dash-docs-use-workaround-for-emacs-bug + (or (eq dash-docs-use-workaround-for-emacs-bug 'force) + (and (not gnutls-algorithm-priority) + (< emacs-major-version 27)))) + "NORMAL:-VERS-TLS1.3" + ,gnutls-algorithm-priority))) + ,@body)) + +(defun dash-docs-read-json-from-url (url) "Read and return a JSON object from URL." (with-current-buffer - (url-retrieve-synchronously url) + (dash-docs-with-emacs-bug-workaround + (url-retrieve-synchronously url)) (goto-char url-http-end-of-headers) (json-read))) -(defun helm-dash-unofficial-docsets () +(defun dash-docs-unofficial-docsets () "Return a list of lists with docsets contributed by users. The first element is the docset's name second the docset's archive url." - (let ((user-docs (helm-dash-read-json-from-url + (let ((user-docs (dash-docs-read-json-from-url "https://dashes-to-dashes.herokuapp.com/docsets/contrib"))) (mapcar (lambda (docset) (list @@ -222,27 +257,27 @@ The first element is the docset's name second the docset's archive url." (assoc-default 'archive docset))) user-docs))) -(defvar helm-dash-ignored-docsets +(defvar dash-docs-ignored-docsets '("Bootstrap" "Drupal" "Zend_Framework" "Ruby_Installed_Gems" "Man_Pages") "Return a list of ignored docsets. These docsets are not available to install. See here the reason: https://github.com/areina/helm-dash/issues/17.") -(defun helm-dash-official-docsets () +(defun dash-docs-official-docsets () "Return a list of official docsets (http://kapeli.com/docset_links)." - (let ((docsets (helm-dash-read-json-from-url + (let ((docsets (dash-docs-read-json-from-url "https://api.github.com/repos/Kapeli/feeds/contents/"))) (delq nil (mapcar (lambda (docset) (let ((name (assoc-default 'name docset))) (if (and (equal (file-name-extension name) "xml") (not - (member (file-name-sans-extension name) helm-dash-ignored-docsets))) + (member (file-name-sans-extension name) dash-docs-ignored-docsets))) (file-name-sans-extension name)))) docsets)))) -(defun helm-dash-installed-docsets () +(defun dash-docs-installed-docsets () "Return a list of installed docsets." - (let ((docset-path (helm-dash-docsets-path))) + (let ((docset-path (dash-docs-docsets-path))) (cl-loop for dir in (directory-files docset-path nil "^[^.]") for full-path = (expand-file-name dir docset-path) for subdir = (and (file-directory-p full-path) @@ -252,7 +287,7 @@ See here the reason: https://github.com/areina/helm-dash/issues/17.") (and subdir (file-directory-p subdir))) collecting (replace-regexp-in-string "\\.docset\\'" "" dir)))) -(defun helm-dash-read-docset (prompt choices) +(defun dash-docs-read-docset (prompt choices) "PROMPT user to choose one of the docsets in CHOICES. Report an error unless a valid docset is selected." (let ((completion-ignore-case t)) @@ -260,29 +295,30 @@ Report an error unless a valid docset is selected." choices nil t nil nil choices))) ;;;###autoload -(defun helm-dash-activate-docset (docset) +(defun dash-docs-activate-docset (docset) "Activate DOCSET. If called interactively prompts for the docset name." - (interactive (list (helm-dash-read-docset + (interactive (list (dash-docs-read-docset "Activate docset" - (helm-dash-installed-docsets)))) - (add-to-list 'helm-dash-common-docsets docset) - (helm-dash-reset-connections)) + (dash-docs-installed-docsets)))) + (add-to-list 'dash-docs-common-docsets docset) + (dash-docs-reset-connections)) ;;;###autoload -(defun helm-dash-deactivate-docset (docset) +(defun dash-docs-deactivate-docset (docset) "Deactivate DOCSET. If called interactively prompts for the docset name." - (interactive (list (helm-dash-read-docset + (interactive (list (dash-docs-read-docset "Deactivate docset" - helm-dash-common-docsets))) - (setq helm-dash-common-docsets (delete docset helm-dash-common-docsets))) + dash-docs-common-docsets))) + (setq dash-docs-common-docsets (delete docset dash-docs-common-docsets))) -(defun helm-dash--install-docset (url docset-name) +(defun dash-docs--install-docset (url docset-name) "Download a docset from URL and install with name DOCSET-NAME." (let ((docset-tmp-path (format "%s%s-docset.tgz" temporary-file-directory docset-name))) - (url-copy-file url docset-tmp-path t) - (helm-dash-install-docset-from-file docset-tmp-path))) + (dash-docs-with-emacs-bug-workaround + (url-copy-file url docset-tmp-path t)) + (dash-docs-install-docset-from-file docset-tmp-path))) -(defun helm-dash--ensure-created-docsets-path (docset-path) +(defun dash-docs--ensure-created-docsets-path (docset-path) "Check if DOCSET-PATH directory exists. If doesn't exist, it asks to create it." (or (file-directory-p docset-path) @@ -290,108 +326,112 @@ If doesn't exist, it asks to create it." docset-path)) (mkdir docset-path t)))) - ;;;###autoload -(defun helm-dash-install-user-docset (docset-name) +(defun dash-docs-install-user-docset (docset-name) "Download an unofficial docset with specified DOCSET-NAME and move its stuff to docsets-path." - (interactive (list (helm-dash-read-docset + (interactive (list (dash-docs-read-docset "Install docset" - (mapcar 'car (helm-dash-unofficial-docsets))))) - (when (helm-dash--ensure-created-docsets-path (helm-dash-docsets-path)) - (helm-dash--install-docset (car (assoc-default docset-name (helm-dash-unofficial-docsets))) docset-name))) - + (mapcar 'car (dash-docs-unofficial-docsets))))) + (when (dash-docs--ensure-created-docsets-path (dash-docs-docsets-path)) + (dash-docs--install-docset (car (assoc-default docset-name (dash-docs-unofficial-docsets))) docset-name))) + +(defun dash-docs-extract-and-get-folder (docset-temp-path) + "Extract DOCSET-TEMP-PATH to DASH-DOCS-DOCSETS-PATH, and return the folder that was newly extracted." + (with-temp-buffer + (let* ((call-process-args (list "tar" nil t nil)) + (process-args (list + "xfv" docset-temp-path + "-C" dash-docs-docsets-path)) + ;; On Windows, several elements need to be removed from filenames, see + ;; https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#naming-conventions. + ;; We replace with underscores on windows. This might lead to broken links. + (windows-args (list "--force-local" "--transform" "s/[<>\":?*^|]/_/g")) + (result (apply #'call-process + (append call-process-args process-args (when (eq system-type 'windows-nt) windows-args))))) + (goto-char (point-max)) + (cond + ((and (not (equal result 0)) + ;; TODO: Adjust to proper text. Also requires correct locale. + (search-backward "too long")) + (error "Failed to extract %s to %s. Filename too long. Consider changing `dash-docs-docsets-path' to a shorter value" docset-temp-path (dash-docs-docsets-path))) + ((not (equal result 0)) (error "Failed to extract %s to %s. Error: %s" docset-temp-path (dash-docs-docsets-path) result))) + (goto-char (point-max)) + (replace-regexp-in-string "^x " "" (car (split-string (thing-at-point 'line) "\\." t)))))) ;;;###autoload -(defun helm-dash-install-docset-from-file (docset-tmp-path) - "Extract the content of DOCSET-TMP-PATH, move it to `helm-dash-docsets-path` and activate the docset." +(defun dash-docs-install-docset-from-file (docset-tmp-path) + "Extract the content of DOCSET-TMP-PATH, move it to `dash-docs-docsets-path` and activate the docset." (interactive (list (car (find-file-read-args "Docset Tarball: " t)))) - (let ((docset-folder - (helm-dash-docset-folder-name - (shell-command-to-string - (format "tar xvf %s -C %s" - (shell-quote-argument (expand-file-name docset-tmp-path)) - (shell-quote-argument (helm-dash-docsets-path))))))) - (helm-dash-activate-docset docset-folder) + (let ((docset-folder (dash-docs-extract-and-get-folder docset-tmp-path))) + (dash-docs-activate-docset docset-folder) (message (format - "Docset installed. Add \"%s\" to helm-dash-common-docsets or helm-dash-docsets." + "Docset installed. Add \"%s\" to dash-docs-common-docsets or dash-docs-docsets." docset-folder)))) ;;;###autoload -(defun helm-dash-install-docset (docset-name) +(defun dash-docs-install-docset (docset-name) "Download an official docset with specified DOCSET-NAME and move its stuff to docsets-path." - (interactive (list (helm-dash-read-docset + (interactive (list (dash-docs-read-docset "Install docset" - (helm-dash-official-docsets)))) + (dash-docs-official-docsets)))) - (when (helm-dash--ensure-created-docsets-path (helm-dash-docsets-path)) - (let ((feed-url (format "%s/%s.xml" helm-dash-docsets-url docset-name)) + (when (dash-docs--ensure-created-docsets-path (dash-docs-docsets-path)) + (let ((feed-url (format "%s/%s.xml" dash-docs-docsets-url docset-name)) (feed-tmp-path (format "%s%s-feed.xml" temporary-file-directory docset-name))) - (url-copy-file feed-url feed-tmp-path t) - (helm-dash--install-docset (helm-dash-get-docset-url feed-tmp-path) docset-name)))) + (dash-docs-with-emacs-bug-workaround + (url-copy-file feed-url feed-tmp-path t)) + (dash-docs--install-docset (dash-docs-get-docset-url feed-tmp-path) docset-name)))) ;;;###autoload -(defun helm-dash-async-install-docset (docset-name) +(defun dash-docs-async-install-docset (docset-name) "Asynchronously download docset with specified DOCSET-NAME and move its stuff to docsets-path." - (interactive (list (helm-dash-read-docset "Install docset" (helm-dash-official-docsets)))) - (when (helm-dash--ensure-created-docsets-path (helm-dash-docsets-path)) - (let ((feed-url (format "%s/%s.xml" helm-dash-docsets-url docset-name))) - + (interactive (list (dash-docs-read-docset "Install docset" (dash-docs-official-docsets)))) + (when (dash-docs--ensure-created-docsets-path (dash-docs-docsets-path)) + (let ((feed-url (format "%s/%s.xml" dash-docs-docsets-url docset-name))) (message (concat "The docset \"" docset-name "\" will now be installed asynchronously.")) - (async-start ; First async call gets the docset meta data (lambda () ;; Beware! This lambda is run in it's own instance of emacs. - (url-file-local-copy feed-url)) + (dash-docs-with-emacs-bug-workaround + (url-file-local-copy feed-url))) (lambda (filename) - (let ((docset-url (helm-dash-get-docset-url filename))) + (let ((docset-url (dash-docs-get-docset-url filename))) (async-start ; Second async call gets the docset itself (lambda () ;; Beware! This lambda is run in it's own instance of emacs. - (url-file-local-copy docset-url)) + (dash-docs-with-emacs-bug-workaround + (url-file-local-copy docset-url))) (lambda (docset-tmp-path) - (helm-dash-async-install-docset-from-file docset-tmp-path))))))))) + (dash-docs-async-install-docset-from-file docset-tmp-path))))))))) ;;;###autoload -(defun helm-dash-async-install-docset-from-file (docset-tmp-path) - "Asynchronously extract the content of DOCSET-TMP-PATH, move it to `helm-dash-docsets-path` and activate the docset." +(defun dash-docs-async-install-docset-from-file (docset-tmp-path) + "Asynchronously extract the content of DOCSET-TMP-PATH, move it to `dash-docs-docsets-path` and activate the docset." (interactive (list (car (find-file-read-args "Docset Tarball: " t)))) - (let ((docset-tar-path (expand-file-name docset-tmp-path)) - (docset-out-path (helm-dash-docsets-path))) - (async-start - (lambda () - ;; Beware! This lambda is run in it's own instance of emacs. - (shell-command-to-string - (format "tar xvf %s -C %s" - (shell-quote-argument docset-tar-path) - (shell-quote-argument docset-out-path)))) - (lambda (shell-output) - (let ((docset-folder (helm-dash-docset-folder-name shell-output))) - (helm-dash-activate-docset docset-folder) - (message (format - "Docset installed. Add \"%s\" to helm-dash-common-docsets or helm-dash-docsets." - docset-folder))))))) - -(defalias 'helm-dash-update-docset 'helm-dash-install-docset) - -(defun helm-dash-docset-installed-p (docset) - "Return true if DOCSET is installed." - (member (replace-regexp-in-string "_" " " docset) (helm-dash-installed-docsets))) + (async-start + (lambda () + ;; Beware! This lambda is run in it's own instance of emacs. + (dash-docs-extract-and-get-folder docset-tmp-path)) + (lambda (docset-folder) + (dash-docs-activate-docset docset-folder) + (message (format + "Docset installed. Add \"%s\" to dash-docs-common-docsets or dash-docs-docsets." + docset-folder))))) + +(defalias 'dash-docs-update-docset 'dash-docs-install-docset) + +(defun dash-docs-docset-installed-p (docset) + "Return non-nil if DOCSET is installed." + (member (replace-regexp-in-string "_" " " docset) (dash-docs-installed-docsets))) ;;;###autoload -(defun helm-dash-ensure-docset-installed (docset) +(defun dash-docs-ensure-docset-installed (docset) "Install DOCSET if it is not currently installed." - (unless (helm-dash-docset-installed-p docset) - (helm-dash-install-docset docset))) - -(defun helm-dash-docset-folder-name (tar-output) - "Return the name of the folder where the docset has been extracted. -The argument TAR-OUTPUT should be an string with the output of a tar command." - (let ((last-line - (car (last (split-string tar-output "\n" t))))) - (replace-regexp-in-string "^x " "" (car (split-string last-line "\\." t))))) + (unless (dash-docs-docset-installed-p docset) + (dash-docs-install-docset docset))) -(defun helm-dash-get-docset-url (feed-path) +(defun dash-docs-get-docset-url (feed-path) "Parse a xml feed with docset urls and return the first url. The Argument FEED-PATH should be a string with the path of the xml file." (let* ((xml (xml-parse-file feed-path)) @@ -399,17 +439,17 @@ The Argument FEED-PATH should be a string with the path of the xml file." (url (xml-get-children urls 'url))) (cl-caddr (cl-first url)))) -(defvar helm-dash-sql-queries +(defvar dash-docs--sql-queries '((DASH . (lambda (pattern) - (let ((like (helm-dash-sql-compose-like "t.name" pattern)) + (let ((like (dash-docs-sql-compose-like "t.name" pattern)) (query "SELECT t.type, t.name, t.path FROM searchIndex t WHERE %s ORDER BY LENGTH(t.name), LOWER(t.name) LIMIT 1000")) (format query like)))) (ZDASH . (lambda (pattern) - (let ((like (helm-dash-sql-compose-like "t.ZTOKENNAME" pattern)) + (let ((like (dash-docs-sql-compose-like "t.ZTOKENNAME" pattern)) (query "SELECT ty.ZTYPENAME, t.ZTOKENNAME, f.ZPATH, m.ZANCHOR FROM ZTOKEN t, ZTOKENTYPE ty, ZFILEPATH f, ZTOKENMETAINFORMATION m WHERE ty.Z_PK = t.ZTOKENTYPE AND f.Z_PK = m.ZFILE AND m.ZTOKEN = t.Z_PK AND %s ORDER BY LENGTH(t.ZTOKENNAME), LOWER(t.ZTOKENNAME) LIMIT 1000")) (format query like)))))) -(defun helm-dash-sql-compose-like (column pattern) +(defun dash-docs-sql-compose-like (column pattern) "Return a query fragment for a sql where clause. Search in column COLUMN by multiple terms splitting the PATTERN by whitespace and using like sql operator." @@ -417,21 +457,21 @@ by whitespace and using like sql operator." (split-string pattern " ")))) (format "%s" (mapconcat 'identity conditions " AND ")))) -(defun helm-dash-sql-query (docset-type pattern) +(defun dash-docs-sql-query (docset-type pattern) "Return a SQL query to search documentation in dash docsets. A different query is returned depending on DOCSET-TYPE. PATTERN is used to compose the SQL WHERE clause." (let ((compose-select-query-func - (cdr (assoc (intern docset-type) helm-dash-sql-queries)))) + (cdr (assoc (intern docset-type) dash-docs--sql-queries)))) (when compose-select-query-func (funcall compose-select-query-func pattern)))) -(defun helm-dash-maybe-narrow-docsets (pattern) - "Return a list of helm-dash-connections. +(defun dash-docs-maybe-narrow-docsets (pattern) + "Return a list of dash-docs-connections. If PATTERN starts with the name of a docset followed by a space, narrow the used connections to just that one. We're looping on all connections, but it shouldn't be a problem as there won't be many." - (let ((conns (helm-dash-filter-connections))) + (let ((conns (dash-docs-filter-connections))) (or (cl-loop for x in conns if (string-prefix-p (concat (downcase (car x)) " ") @@ -439,7 +479,7 @@ If PATTERN starts with the name of a docset followed by a space, narrow the return (list x)) conns))) -(defun helm-dash-sub-docset-name-in-pattern (pattern docset-name) +(defun dash-docs-sub-docset-name-in-pattern (pattern docset-name) "Remove from PATTERN the DOCSET-NAME if this includes it. If the search starts with the name of the docset, ignore it. Ex: This avoids searching for redis in redis unless you type 'redis redis'" @@ -448,16 +488,7 @@ Ex: This avoids searching for redis in redis unless you type 'redis redis'" "" pattern)) -(defun helm-dash-search () - "Iterates every `helm-dash-connections' looking for the `helm-pattern'." - (let ((connections (helm-dash-maybe-narrow-docsets helm-pattern))) - (cl-loop for docset in connections - append (cl-loop for row in (helm-dash--run-query docset helm-pattern) - collect (helm-dash--candidate docset row))))) - -(make-obsolete #'helm-dash-search nil "1.3.0") - -(defun helm-dash--run-query (docset search-pattern) +(defun dash-docs--run-query (docset search-pattern) "Execute an sql query in dash docset DOCSET looking for SEARCH-PATTERN. Return a list of db results. Ex: @@ -465,27 +496,27 @@ Return a list of db results. Ex: (\"func\" \"PUBLISH\" \"commands/publish.html\") (\"func\" \"problems\" \"topics/problems.html\"))" (let ((docset-type (cl-caddr docset))) - (helm-dash-sql + (dash-docs-sql (cadr docset) - (helm-dash-sql-query docset-type - (helm-dash-sub-docset-name-in-pattern search-pattern + (dash-docs-sql-query docset-type + (dash-docs-sub-docset-name-in-pattern search-pattern (car docset)))))) -(defun helm-dash--candidate (docset row) - "Return a list extracting info from DOCSET and ROW to build a helm candidate. +(defun dash-docs--candidate (docset row) + "Return list extracting info from DOCSET and ROW to build a result candidate. First element is the display message of the candidate, rest is used to build candidate opts." - (cons (format-spec helm-dash-candidate-format - (list (cons ?d (first docset)) - (cons ?n (second row)) - (cons ?t (first row)) + (cons (format-spec dash-docs-candidate-format + (list (cons ?d (cl-first docset)) + (cons ?n (cl-second row)) + (cons ?t (cl-first row)) (cons ?f (replace-regexp-in-string "^.*/\\([^/]*\\)\\.html?#?.*" "\\1" - (third row))))) + (cl-third row))))) (list (car docset) row))) -(defun helm-dash-result-url (docset-name filename &optional anchor) +(defun dash-docs-result-url (docset-name filename &optional anchor) "Return the full, absolute URL to documentation. Either a file:/// URL joining DOCSET-NAME, FILENAME & ANCHOR with sanitization of spaces or a http(s):// URL formed as-is if FILENAME is a full HTTP(S) URL." @@ -498,97 +529,52 @@ Either a file:/// URL joining DOCSET-NAME, FILENAME & ANCHOR with sanitization "%20" (concat "file:///" - (expand-file-name "Contents/Resources/Documents/" (helm-dash-docset-path docset-name)) + (expand-file-name "Contents/Resources/Documents/" (dash-docs-docset-path docset-name)) path))))) -(defun helm-dash-browse-url (search-result) - "Call to `browse-url' with the result returned by `helm-dash-result-url'. -Get required params to call `helm-dash-result-url' from SEARCH-RESULT." +(defun dash-docs-browse-url (search-result) + "Call to `browse-url' with the result returned by `dash-docs-result-url'. +Get required params to call `dash-docs-result-url' from SEARCH-RESULT." (let ((docset-name (car search-result)) (filename (nth 2 (cadr search-result))) (anchor (nth 3 (cadr search-result)))) - (funcall helm-dash-browser-func (helm-dash-result-url docset-name filename anchor)))) + (funcall dash-docs-browser-func (dash-docs-result-url docset-name filename anchor)))) -(defun helm-dash-add-to-kill-ring (search-result) - "Add to kill ring a formatted string to call `helm-dash-browse-url' with SEARCH-RESULT." - (kill-new (format "(helm-dash-browse-url '%S)" search-result))) +(defun dash-docs-add-to-kill-ring (search-result) + "Add to kill ring a formatted string to call `dash-docs-browse-url' with SEARCH-RESULT." + (kill-new (format "(dash-docs-browse-url '%S)" search-result))) -(defun helm-dash-actions (actions doc-item) +(defun dash-docs-actions (actions doc-item) "Return an alist with the possible ACTIONS to execute with DOC-ITEM." - `(("Go to doc" . helm-dash-browse-url) - ("Copy to clipboard" . helm-dash-add-to-kill-ring))) - -(defun helm-source-dash-search () - "Return an alist with configuration options for Helm." - `((name . "Dash") - (volatile) - (delayed) - (requires-pattern . ,helm-dash-min-length) - (candidates-process . helm-dash-search) - (persistent-help . "Show this doc") - (action-transformer . helm-dash-actions))) - -(make-obsolete #'helm-source-dash-search nil "1.3.0") - -(defun helm-dash-debugging-buffer () - "Return the helm-dash debugging buffer." - (get-buffer-create "*helm-dash-errors*")) - -(defun helm-dash-initialize-debugging-buffer () + (ignore doc-item) + (ignore actions) + `(("Go to doc" . dash-docs-browse-url) + ("Copy to clipboard" . dash-docs-add-to-kill-ring))) + +(defun dash-docs-debugging-buffer () + "Return the dash-docs debugging buffer." + (get-buffer-create "*dash-docs-errors*")) + +(defun dash-docs-initialize-debugging-buffer () "Open debugging buffer and insert a header message." - (with-current-buffer (helm-dash-debugging-buffer) + (with-current-buffer (dash-docs-debugging-buffer) (erase-buffer) (insert "----------------") - (insert "\n HEY! This is helm-dash (sqlite) error logging. If you want to disable it, set `helm-dash-enable-debugging` to nil\n") + (insert "\n HEY! This is dash-docs (sqlite) error logging. If you want to disable it, set `dash-docs-enable-debugging` to nil\n") (insert "---------------- \n\n"))) -(defun helm-dash-build-source (docset) - "Build a Helm source for DOCSET." - (lexical-let ((docset docset)) - (helm-build-sync-source (car docset) - :action-transformer #'helm-dash-actions - :candidates (lambda () - (cl-loop for row in (helm-dash--run-query docset helm-pattern) - collect (helm-dash--candidate docset row))) - :volatile t - :persistent-help "View doc" - :requires-pattern helm-dash-min-length))) - -(defun helm-dash-sources--narrowed-docsets () - "Return a list of Helm sources for narrowed docsets. - -Narrowed docsets are those returned by -`helm-dash-maybe-narrow-docsets'." - (let ((connections (helm-dash-maybe-narrow-docsets helm-pattern))) - (cl-loop for docset in connections - append (list (helm-dash-build-source docset))))) - - -;;; Autoloads +(defun dash-docs-search-docset (docset pattern) + "Given a string PATTERN, query DOCSET and retrieve result." + (cl-loop for row in (dash-docs--run-query docset pattern) + collect (dash-docs--candidate docset row))) ;;;###autoload -(defun helm-dash (&optional input-pattern) - "Bring up a `helm-dash' search interface. -If INPUT-PATTERN is non-nil, use it as an initial input in helm search." - (interactive) - (helm-dash-initialize-debugging-buffer) - (helm-dash-create-common-connections) - (helm-dash-create-buffer-connections) - (helm :sources (helm-dash-sources--narrowed-docsets) - :buffer "*helm-dash*" - :prompt "Doc for: " - :history 'helm-dash-history-input - :input input-pattern - :helm-candidate-number-limit 1000)) - -;;;###autoload -(defun helm-dash-at-point () - "Bring up a `helm-dash' search interface with symbol at point." - (interactive) - (helm-dash - (substring-no-properties (or (thing-at-point 'symbol) "")))) +(defun dash-docs-search (pattern) + "Given a string PATTERN, query docsets and retrieve result." + (when (>= (length pattern) dash-docs-min-length) + (cl-loop for docset in (dash-docs-maybe-narrow-docsets pattern) + appending (dash-docs-search-docset docset pattern)))) - -(provide 'helm-dash) +(provide 'dash-docs) -;;; helm-dash.el ends here +;;; dash-docs.el ends here diff --git a/packages/ddskk-20180707.532.tar b/packages/ddskk-20190423.1234.tar similarity index 99% rename from packages/ddskk-20180707.532.tar rename to packages/ddskk-20190423.1234.tar index f91d37d..ae9c462 100644 Binary files a/packages/ddskk-20180707.532.tar and b/packages/ddskk-20190423.1234.tar differ diff --git a/packages/define-word-20180706.2029.el b/packages/define-word-20190506.1525.el similarity index 50% rename from packages/define-word-20180706.2029.el rename to packages/define-word-20190506.1525.el index 70e554f..2cfd9a6 100644 --- a/packages/define-word-20180706.2029.el +++ b/packages/define-word-20190506.1525.el @@ -4,7 +4,7 @@ ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/define-word -;; Package-Version: 20180706.2029 +;; Package-Version: 20190506.1525 ;; Version: 0.1.0 ;; Package-Requires: ((emacs "24.3")) ;; Keywords: dictionary, convenience @@ -40,6 +40,7 @@ (require 'url-parse) (require 'url-http) +(require 'nxml-mode) (defgroup define-word nil "Define word at point using an online dictionary." @@ -49,28 +50,60 @@ (defvar define-word-limit 10 "Maximum amount of results to display.") -(defcustom define-word-unpluralize t - "When non-nil, change the word to singular when appropriate. -The rule is that all definitions must contain \"Plural of\"." - :type 'boolean) +(defcustom define-word-displayfn-alist nil + "Alist for display functions per service. +By default, `message' is used." + :type '(alist + :key-type (symbol :tag "Name of service") + :value-type (function :tag "Display function"))) + +(defun define-word-displayfn (service) + "Return the display function for SERVICE." + (or (cdr (assoc service define-word-displayfn-alist)) + #'message)) (defcustom define-word-services - '((wordnik "http://wordnik.com/words/%s" define-word--parse-wordnik nil) - (openthesaurus "https://www.openthesaurus.de/synonyme/%s" - define-word--parse-openthesaurus nil)) + '((wordnik "http://wordnik.com/words/%s" define-word--parse-wordnik) + (openthesaurus "https://www.openthesaurus.de/synonyme/%s" define-word--parse-openthesaurus) + (webster "http://webstersdictionary1828.com/Dictionary/%s" define-word--parse-webster)) "Services for define-word, A list of lists of the - format (symbol url function-for-parsing [function-for-display])" - :type '(alist :key-type (symbol :tag "Name of service") + format (symbol url function-for-parsing). +Instead of an url string, url can be a custom function for retrieving results." + :type '(alist + :key-type (symbol :tag "Name of service") :value-type (group (string :tag "Url (%s denotes search word)") - (function :tag "Parsing function") - (choice (const nil) (function :tag "Display function"))))) + (function :tag "Parsing function")))) (defcustom define-word-default-service 'wordnik "The default service for define-word commands. Must be one of `define-word-services'" :type 'symbol) +(defun define-word--to-string (word service) + "Get definition of WORD from SERVICE." + (let* ((servicedata (assoc service define-word-services)) + (retriever (nth 1 servicedata)) + (parser (nth 2 servicedata))) + (if (functionp retriever) + (funcall retriever word) + (with-current-buffer (url-retrieve-synchronously + (format retriever (downcase word)) + t t) + (funcall parser))))) + +(defun define-word--expand (regex definition service) + (let ((case-fold-search nil)) + (when (string-match regex definition) + (concat + definition + "\n" (match-string 1 definition) ":\n" + (mapconcat (lambda (s) (concat " " s)) + (split-string + (define-word--to-string (match-string 1 definition) service) + "\n") + "\n"))))) + ;;;###autoload (defun define-word (word service &optional choose-service) "Define WORD using various services. @@ -82,19 +115,19 @@ lets the user choose service." (if choose-service (intern (completing-read - "Service: " (mapcar #'car define-word-services))) + "Service: " define-word-services)) define-word-default-service))) - (servicedata (assoc service define-word-services)) - (parser (nth 2 servicedata)) - (displayfn (or (nth 3 servicedata) #'message)) - (link (format (nth 1 servicedata) (downcase word))) - (results - (with-current-buffer (url-retrieve-synchronously link t t) - (funcall parser)))) - (if results - (funcall displayfn results) - (funcall displayfn "0 definitions found") - nil))) + (results (define-word--to-string word service))) + + (funcall + (define-word-displayfn service) + (cond ((not results) + "0 definitions found") + ((define-word--expand "Plural form of \\(.*\\)\\.$" results service)) + ((define-word--expand "Past participle of \\(.*\\)\\.$" results service)) + ((define-word--expand "Present participle of \\(.*\\)\\.$" results service)) + (t + results))))) ;;;###autoload (defun define-word-at-point (arg &optional service) @@ -122,6 +155,35 @@ In a non-interactive call SERVICE can be passed." '((t :inherit default)) "Face for the body of the definition") +(defun define-word--join-results (results) + (mapconcat + #'identity + (if (> (length results) define-word-limit) + (cl-subseq results 0 define-word-limit) + results) + "\n")) + +(defun define-word--regexp-to-face (regexp face) + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (let ((match (match-string 1))) + (replace-match + (propertize match 'face face))))) + +(defconst define-word--tag-faces + '(("<\\(?:em\\|i\\)>\\(.*?\\)" italic) + ("\\(.*?\\)" link) + ("\\(.*?\\)" bold) + ("\\(.*?\\)" default))) + +(defun define-word--convert-html-tag-to-face (str) + "Replace semantical HTML markup in STR with the relevant faces." + (with-temp-buffer + (insert str) + (cl-loop for (regexp face) in define-word--tag-faces do + (define-word--regexp-to-face regexp face)) + (buffer-string))) + (defun define-word--parse-wordnik () "Parse output from wordnik site and return formatted list" (save-match-data @@ -138,17 +200,33 @@ In a non-interactive call SERVICE can be passed." (buffer-substring-no-properties beg (match-beginning 0)) 'face 'define-word-face-2)) results))) - (setq results (nreverse results)) - (cond ((= 0 (length results)) - (message "0 definitions found")) - ((and define-word-unpluralize - (cl-every (lambda (x) (string-match "[Pp]\\(?:lural\\|l\\.\\).*of \\(.*\\)\\." x)) - results)) - (define-word (match-string 1 (car (last results))) 'wordnik)) - (t - (when (> (length results) define-word-limit) - (setq results (cl-subseq results 0 define-word-limit))) - (mapconcat #'identity results "\n")))))) + (when (setq results (nreverse results)) + (define-word--convert-html-tag-to-face (define-word--join-results results)))))) + +(defun define-word--parse-webster () + "Parse definition from webstersdictionary1828.com." + (save-match-data + (goto-char (point-min)) + (let (results def-type) + (while (re-search-forward "

\\(?:[[:digit:]]\\.\\)?.*\\(.*?\\)

" nil t) + (save-match-data + (save-excursion + (re-search-backward "

[A-Z'.]*, \\(.*?\\)") + (let ((match (match-string 1))) + (setq def-type + (cond + ((equal match "adjective") "adj.") + ((equal match "noun") "n.") + ((equal match "verb intransitive") "v.") + ((equal match "verb transitive") "vt.") + (t "")))))) + (push + (concat + (propertize def-type 'face 'bold) + (define-word--convert-html-tag-to-face (match-string 1))) + results)) + (when (setq results (nreverse results)) + (define-word--join-results results))))) (defun define-word--parse-openthesaurus () "Parse output from openthesaurus site and return formatted list" @@ -167,12 +245,8 @@ In a non-interactive call SERVICE can be passed." (setq part (match-string 1)) (backward-char) (push (string-trim part) results)) - (setq results (nreverse results)) - (if (= 0 (length results)) - (message "0 definitions found") - (when (> (length results) define-word-limit) - (setq results (cl-subseq results 0 define-word-limit))) - (mapconcat #'identity results "\n"))))) + (when (setq results (nreverse results)) + (define-word--join-results results))))) (provide 'define-word) diff --git a/packages/deft-20181029.213.el b/packages/deft-20181226.1534.el similarity index 98% rename from packages/deft-20181029.213.el rename to packages/deft-20181226.1534.el index 3fa5229..259f6d3 100644 --- a/packages/deft-20181029.213.el +++ b/packages/deft-20181226.1534.el @@ -27,7 +27,7 @@ ;; POSSIBILITY OF SUCH DAMAGE. ;;; Version: 0.8 -;; Package-Version: 20181029.213 +;; Package-Version: 20181226.1534 ;;; Author: Jason R. Blevins ;;; Keywords: plain text, notes, Simplenote, Notational Velocity ;;; URL: https://jblevins.org/projects/deft/ @@ -405,6 +405,12 @@ ;; properties from the standard font-lock faces defined by your current ;; color theme. +;; If you are experiencing slow performance with a large number of +;; files, you can limit the number of files displayed in the buffer by +;; seting `deft-file-limit' to a positive integer value. This limits +;; the number of file widgets that need to be rendered, making each +;; update faster. + ;; Deft also provides several hooks: `deft-mode-hook', ;; `deft-filter-hook', and `deft-open-file-hook'. See the ;; documentation for these variables for further details. @@ -746,6 +752,17 @@ For example, .tex files may be generated from `org-mode' or Pandoc." :type 'boolean :group 'deft) +(defcustom deft-file-limit nil + "Maximum number of files to list in the Deft browser. +Set this to an integer value if you have a large number of files +and are experiencing performance degradation. This is the +maximum number of files to display in the Deft buffer. When +set to nil, there is no limit." + :type '(choice (integer :tag "Limit number of files displayed") + (const :tag "No limit" nil)) + :group 'deft + :package-version '(deft . "0.9")) + ;; Faces (defgroup deft-faces nil @@ -1145,6 +1162,18 @@ Case is ignored." (deft-cache-file file) ; Cache contents (setq deft-all-files (deft-sort-files deft-all-files))) ; Sort by mtime +(defun deft-current-files () + "Return list `deft-current-files', possibly truncated. +Whether the list is truncated depends on the value of +the variable `deft-file-limit'." + (let ((len (length deft-current-files))) + (if (and (integerp deft-file-limit) + (> len 0) + (< deft-file-limit len)) + (reverse (nthcdr (- len deft-file-limit) + (reverse deft-current-files))) + deft-current-files))) + ;; Cache access (defun deft-file-contents (file) @@ -1207,7 +1236,7 @@ When REFRESH is true, attempt to restore the point afterwards." (widget-insert (deft-no-directory-message)) (if deft-current-files (progn - (mapc 'deft-file-widget deft-current-files)) + (mapc 'deft-file-widget (deft-current-files))) (widget-insert (deft-no-files-message)))) (use-local-map deft-mode-map) diff --git a/packages/devdocs-20170731.850.el b/packages/devdocs-20170731.850.el new file mode 100644 index 0000000..1edd3e9 --- /dev/null +++ b/packages/devdocs-20170731.850.el @@ -0,0 +1,117 @@ +;;; devdocs.el --- Launch DevDocs search -*- lexical-binding: t; -*- + +;; Copyright (C) 2016 Chunyang Xu + +;; Author: Chunyang Xu +;; URL: https://github.com/xuchunyang/DevDocs.el +;; Package-Version: 20170731.850 +;; Version: 0.02 + +;; 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 . + +;;; Commentary: + +;; DevDocs is API Documentation Browser. This +;; package allowing you to easily search the DevDocs Documentation. + +;; To use, type M-x devdocs-search + +;;; Code: + +(defgroup devdocs nil + "Searching in DevDocs." + :group 'external) + +(defcustom devdocs-url "https://devdocs.io" + "DevDocs URL. + +Don't change this unless you setup your own DevDocs locally." + :type 'string + :group 'devdocs) + +(defcustom devdocs-alist + '((c-mode . "c") + (c++-mode . "c++") + (clojure-mode . "clojure") + (coffee-mode . "CoffeeScript") + (common-lisp-mode . "lisp") + (cperl-mode . "perl") + (css-mode . "css") + (elixir-mode . "elixir") + (enh-ruby-mode . "ruby") + (erlang-mode . "erlang") + (gfm-mode . "markdown") + (go-mode . "go") + (groovy-mode . "groovy") + (haskell-mode . "haskell") + (html-mode . "html") + (java-mode . "java") + (js2-mode . "javascript") + (js3-mode . "javascript") + (less-css-mode . "less") + (lua-mode . "lua") + (markdown-mode . "markdown") + (perl-mode . "perl") + (php-mode . "php") + (processing-mode . "processing") + (puppet-mode . "puppet") + (python-mode . "python") + (ruby-mode . "ruby") + (sass-mode . "sass") + (scala-mode . "scala") + (tcl-mode . "tcl")) + "Alist which maps major modes to names of DevDocs documentations." + :type '(repeat (cons (symbol :tag "Major mode") + (string :tag "DevDocs documentation"))) + :group 'devdocs) + +(defcustom devdocs-build-search-pattern-function + 'devdocs-build-search-pattern-function + "A function to be called by `devdocs-search'. +It builds search pattern base on some context." + :type 'function + :group 'devdocs) + + +(defun devdocs-build-search-pattern-function () + "Build search pattern base on region/symbol-at-point and major-mode." + (let ((documentation (cdr (assoc major-mode devdocs-alist))) + (query (if (use-region-p) + (buffer-substring (region-beginning) (region-end)) + (thing-at-point 'symbol)))) + (if documentation + (concat documentation " " query) + ;; Make sure we return a string + (or query "")))) + +(defun devdocs-do-search (pattern) + (browse-url + (format "%s/#q=%s" devdocs-url (url-hexify-string pattern)))) + +(defvar devdocs-search-history '() "Search History.") + +;;;###autoload +(defun devdocs-search (&optional confirm) + "Launch Devdocs search. +CONFIRM goes with asking for confirmation." + (interactive "P") + (let ((pattern (funcall devdocs-build-search-pattern-function))) + (when confirm + (setq pattern (read-string "Searching DevDocs: " pattern))) + (devdocs-do-search pattern) + (unless (string= "" pattern) + (add-to-list 'devdocs-search-history pattern)))) + +(provide 'devdocs) +;;; devdocs.el ends here diff --git a/packages/dhall-mode-20190526.2113.el b/packages/dhall-mode-20190526.2113.el new file mode 100644 index 0000000..0951519 --- /dev/null +++ b/packages/dhall-mode-20190526.2113.el @@ -0,0 +1,336 @@ +;;; dhall-mode.el --- a major mode for dhall configuration language -*- lexical-binding: t -*- + +;; Copyright (C) 2017 Sibi Prabakaran + +;; Author: Sibi Prabakaran +;; Maintainer: Sibi Prabakaran +;; Keywords: languages +;; Package-Version: 20190526.2113 +;; Version: 0.1.3 +;; Package-Requires: ((emacs "24.4") (reformatter "0.3")) +;; URL: https://github.com/psibi/dhall-mode + +;; This file is not 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 file 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 . + +;;; Commentary: + +;; A major mode for editing Dhall configuration file (See +;; https://github.com/dhall-lang/dhall-lang to learn more) in Emacs. +;; +;; Some of its major features include: +;; +;; - syntax highlighting (font lock), +;; +;; - Basic indentation, multi line string support +;; +;; - Automatic formatting on save (configurable) +;; +;; - Error highlighting +;; +;;; Code: + +(require 'ansi-color) +(require 'comint) +(require 'reformatter) + +(defvar dhall-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-c C-b") 'dhall-repl-show) + (define-key map (kbd "C-c C-f") 'dhall-format-buffer) + (define-key map (kbd "C-c C-t") 'dhall-buffer-type) + map) + "Keymap for using `dhall-mode'.") + +(defgroup dhall nil + "Major mode for editing dhall files" + :group 'languages + :prefix "dhall-" + :link '(url-link :tag "Site" "https://github.com/psibi/dhall-mode") + :link '(url-link :tag "Repository" "https://github.com/psibi/dhall-mode")) + +;; Create the syntax table for this mode. +(defvar dhall-mode-syntax-table + (let ((st (make-syntax-table))) + ;; Taken from haskell-mode: https://stackoverflow.com/a/20845468/1651941 + (modify-syntax-entry ?\{ "(}1nb" st) + (modify-syntax-entry ?\} "){4nb" st) + (modify-syntax-entry ?- ". 123" st) + (modify-syntax-entry ?\n ">" st) + (modify-syntax-entry ?\ " " st) + (modify-syntax-entry ?\t " " st) + (modify-syntax-entry ?\[ "(]" st) + (modify-syntax-entry ?\] ")[" st) + (modify-syntax-entry ?\( "()" st) + (modify-syntax-entry ?\) ")(" st) + ;; Let us handle escapes and string + (modify-syntax-entry ?\\ "." st) + (modify-syntax-entry ?\" "." st) + ;; End + st) + "Syntax table used while in `dhall-mode'.") + +;; define several category of keywords +(defvar dhall-mode-keywords (regexp-opt '("if" "then" "else" "let" "in" "using" "as") 'symbols)) + +(defvar dhall-mode-types + (regexp-opt '("Optional" "Bool" "Natural" "Integer" "Double" "Text" "List" "Type") 'symbols)) + +(defconst dhall-mode-constants (regexp-opt '("True" "False") 'symbols)) +(defconst dhall-mode-numerals "\\_<[+\\-][1-9]+\\_>") +(defconst dhall-mode-doubles "\\_<[+\\-]?[0-9]+\.[0-9]+\\_>") +(defconst dhall-mode-operators (regexp-opt '("->" "\\[" "]" "," "++" "#" ":" "=" "==" "!=" "\\\\\(" "λ" "⫽" ")" "&&" "||" "{" "}" "("))) +(defconst dhall-mode-variables "\\([a-zA-Z_][a-zA-Z_0-9\\-]*\\)[[:space:]]*=") +(defconst dhall-mode-urls "\\_<\\(?:https?\\|file\\):[^[:space:]]+") +(defconst dhall-mode-shas "\\_") + +(defconst dhall-mode-font-lock-keywords + `( ;; Variables + (,dhall-mode-urls . font-lock-function-name-face) + (,dhall-mode-shas . font-lock-constant-face) + (,dhall-mode-types . font-lock-type-face) + (,dhall-mode-constants . font-lock-constant-face) + (,dhall-mode-operators . font-lock-builtin-face) + (,dhall-mode-variables . (1 font-lock-variable-name-face)) + (,dhall-mode-keywords . font-lock-keyword-face) + (,dhall-mode-doubles . font-lock-constant-face) + (,dhall-mode-numerals . font-lock-constant-face) + )) + +(defcustom dhall-command "dhall" + "Command used to normalize Dhall files. +Should be dhall or the complete path to your dhall executable, + e.g.: /home/sibi/.local/bin/dhall" + :type 'file + :group 'dhall + :safe 'stringp) + +(defcustom dhall-use-header-line t + "If non-nil, display the type of the file in the window's header line." + :type 'boolean + :group 'dhall + :safe 'booleanp) + +(defcustom dhall-format-command nil + "Command used to format Dhall files. +If your dhall command is old and does not support the \"format\" sub-command, +then set this to \"dhall-format\". + +If specified, this should be the complete path to your dhall-format executable, + e.g.: /home/sibi/.local/bin/dhall-format" + :type 'file + :group 'dhall + :safe 'stringp) + +(defcustom dhall-format-at-save t + "If non-nil, the Dhall buffers will be formatted after each save." + :type 'boolean + :group 'dhall + :safe 'booleanp) + +(defcustom dhall-format-arguments nil + "Provide a list of arguments for the formatter e.g. '(\"--ascii\")." + :type 'list + :group 'dhall + :safe 'listp) + +(defcustom dhall-type-check-inactivity-timeout 1 + "Wait for this period of inactivity before refreshing the buffer type. +You can try increasing this if type checking is slowing things +down. You can also disable type-checking entirely by setting +`dhall-use-header-line' to nil." + :type 'number + :group 'dhall + :safe 'numberp) + +(defun dhall-buffer-type () + "Return the type of the expression in the current buffer." + (interactive) + ;; We resolve dhall-command in the current buffer, in case + ;; dhall-command, exec-path or process-environment is local + ;; there, so that we can propagate it to the temp buffer. + (let ((cmd (executable-find dhall-command))) + (when cmd + (let ((errbuf (get-buffer-create "*dhall-buffer-type-errors*")) + (source (buffer-string))) + (with-temp-buffer + (with-current-buffer errbuf + (read-only-mode -1) + (erase-buffer)) + (insert source) + (if (zerop (shell-command-on-region (point-min) + (point-max) + (concat cmd " resolve|" cmd " type") + nil t errbuf t)) + (replace-regexp-in-string "\\(?:\\` \\| \\'\\)" "" + (replace-regexp-in-string "[[:space:]]+" " " (buffer-string))) + (prog1 + nil + (with-current-buffer errbuf + (ansi-color-apply-on-region (point-min) (point-max)) + (view-mode))))))))) + +(reformatter-define dhall-format + :program (or dhall-format-command dhall-command) + :args (append (unless dhall-format-command '("format")) dhall-format-arguments) + :group 'dhall + :lighter " DhFmt") + +(reformatter-define dhall-freeze + :program dhall-command + :args '("freeze") + :group 'dhall + :lighter " DhFreeze") + +(reformatter-define dhall-lint + :program dhall-command + :args '("lint") + :group 'dhall + :lighter " DhLint") + +(defun dhall--get-parse-state (pos) + "Get the result of `syntax-ppss' at POS." + (save-excursion (save-match-data (syntax-ppss pos)))) + +(defun dhall--get-string-type (parse-state) + "Get the type of string based on PARSE-STATE." + (let ((string-start (nth 8 parse-state))) + (and string-start (get-text-property string-start 'dhall-string-type)))) + +(defun dhall--mark-string (pos string-type) + "Mark string as a Dhall string. + +POS position of start of string +STRING-TYPE type of string based off of Emacs syntax table types" + (put-text-property pos (1+ pos) + 'syntax-table (string-to-syntax "|")) + (put-text-property pos (1+ pos) + 'dhall-string-type string-type)) + +(defun dhall--double-quotes () + "Handle Dhall double quotes." + (let* ((pos (match-beginning 0)) + (ps (dhall--get-parse-state pos)) + (string-type (dhall--get-string-type ps))) + (dhall--mark-string pos ?\"))) + +(defun dhall--single-quotes () + "Handle Dhall single quotes." + (let* ((pos (match-beginning 0)) + (ps (dhall--get-parse-state pos)) + (string-type (dhall--get-string-type ps))) + (dhall--mark-string pos ?\"))) + +(defun dhall-syntax-propertize (start end) + "Special syntax properties for Dhall from START to END." + (goto-char start) + (remove-text-properties start end '(syntax-table nil dhall-string-type nil)) + (funcall + (syntax-propertize-rules + ("'\\{2,\\}" + (0 (ignore (dhall--single-quotes)))) + ("\"" + (0 (ignore (dhall--double-quotes))))) + start end)) + +(defvar-local dhall-buffer-type nil) +(defvar-local dhall-buffer-type-compute-timer nil) + +(defun dhall-buffer-type-compute (buffer) + "Recompute `dhall-buffer-type' in BUFFER." + (with-current-buffer buffer + (let ((type (dhall-buffer-type))) + (setq dhall-buffer-type + (if type + (if (<= (length type) (window-width)) + type + (concat + (substring type 0 + (- (window-width) 10)) + "...")) + (propertize "Error determining type." 'face 'error)))))) + +(defun dhall-after-change (&optional _beg _end _length) + "Called after any change in the buffer." + (when dhall-use-header-line + (when dhall-buffer-type-compute-timer + (cancel-timer dhall-buffer-type-compute-timer)) + (setq dhall-buffer-type-compute-timer + (run-at-time dhall-type-check-inactivity-timeout + nil + (apply-partially 'dhall-buffer-type-compute (current-buffer)))))) + +;; The main mode functions +;;;###autoload +(define-derived-mode dhall-mode prog-mode + "Dhall" + "Major mode for editing Dhall files." + :group 'dhall + :keymap dhall-mode-map + :syntax-table dhall-mode-syntax-table + (when dhall-use-header-line + (setq header-line-format + '((:eval dhall-buffer-type))) + (dhall-after-change)) + (setq font-lock-defaults '(dhall-mode-font-lock-keywords)) + (setq-local indent-tabs-mode t) + (setq-local tab-width 4) + (setq-local comment-start "-- ") + (setq-local comment-end "") + ;; Special syntax properties for Dhall + (setq-local syntax-propertize-function 'dhall-syntax-propertize) + (add-hook 'after-change-functions 'dhall-after-change nil t) + (when dhall-format-at-save + (dhall-format-on-save-mode))) + +;; Automatically use dhall-mode for .dhall files. +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.dhall\\'" . dhall-mode)) + + +;; REPL +(defcustom dhall-repl-executable "dhall-repl" + "Location of dhall-repl command." + :type 'string) + +(defconst dhall-prompt-regexp "⊢ ") + +(define-derived-mode dhall-repl-mode comint-mode "Dhall-REPL" + "Interactive prompt for Dhall." + (setq-local comint-prompt-regexp dhall-prompt-regexp) + (setq-local comint-prompt-read-only t)) + +(defun dhall-repl-show () + "Load the Dhall-REPL." + (interactive) + (pop-to-buffer-same-window + (get-buffer-create "*Dhall-REPL*")) + (unless (comint-check-proc (current-buffer)) + (dhall--make-repl-in-buffer (current-buffer)) + (dhall-repl-mode))) + +(defun dhall--make-repl-in-buffer (buffer) + "Make Dhall Repl in BUFFER." + (make-comint-in-buffer "Dhall-REPL" buffer dhall-repl-executable)) + + +;; Provide ourselves: +(provide 'dhall-mode) + +;; Local Variables: +;; coding: utf-8 +;; End: + +;;; dhall-mode.el ends here diff --git a/packages/diff-hl-20180201.1155.tar b/packages/diff-hl-20190707.2243.tar similarity index 90% rename from packages/diff-hl-20180201.1155.tar rename to packages/diff-hl-20190707.2243.tar index 79fa282..dd4751c 100644 Binary files a/packages/diff-hl-20180201.1155.tar and b/packages/diff-hl-20190707.2243.tar differ diff --git a/packages/docker-20181101.504.tar b/packages/docker-20190813.1431.tar similarity index 93% rename from packages/docker-20181101.504.tar rename to packages/docker-20190813.1431.tar index ed9326f..578c45d 100644 Binary files a/packages/docker-20181101.504.tar and b/packages/docker-20190813.1431.tar differ diff --git a/packages/docker-tramp-20170207.325.tar b/packages/docker-tramp-20170207.325.tar index a3d4999..b950da6 100644 Binary files a/packages/docker-tramp-20170207.325.tar and b/packages/docker-tramp-20170207.325.tar differ diff --git a/packages/dockerfile-mode-20181104.1800.el b/packages/dockerfile-mode-20190505.1807.el similarity index 97% rename from packages/dockerfile-mode-20181104.1800.el rename to packages/dockerfile-mode-20190505.1807.el index 32d5a08..036fc87 100644 --- a/packages/dockerfile-mode-20181104.1800.el +++ b/packages/dockerfile-mode-20190505.1807.el @@ -2,7 +2,7 @@ ;; Copyright (c) 2013 Spotify AB ;; Package-Requires: ((emacs "24") (s "1.12")) -;; Package-Version: 20181104.1800 +;; Package-Version: 20190505.1807 ;; Homepage: https://github.com/spotify/dockerfile-mode ;; ;; Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -43,6 +43,11 @@ :type 'hook :group 'dockerfile) +(defcustom dockerfile-mode-command "docker" + "Which binary to use to build images" + :group 'dockerfile + :type 'string) + (defcustom dockerfile-use-sudo nil "Runs docker builder command with sudo." :type 'boolean @@ -166,8 +171,9 @@ If prefix arg NO-CACHE is set, don't cache the image." (if (stringp image-name) (compilation-start (format - "%sdocker build %s -t %s %s -f %s %s" + "%s%s build %s -t %s %s -f %s %s" (if dockerfile-use-sudo "sudo " "") + dockerfile-mode-command (if no-cache "--no-cache" "") (shell-quote-argument image-name) (dockerfile-build-arg-string) diff --git a/packages/doom-modeline-20181117.2008.el b/packages/doom-modeline-20181117.2008.el deleted file mode 100644 index 986636d..0000000 --- a/packages/doom-modeline-20181117.2008.el +++ /dev/null @@ -1,1305 +0,0 @@ -;;; doom-modeline.el --- A minimal and modern modeline -*- lexical-binding: t; -*- - -;; Copyright (C) 2018 Vincent Zhang - -;; Author: Vincent Zhang -;; Homepage: https://github.com/seagle0128/doom-modeline -;; Version: 0.8.0 -;; Package-Version: 20181117.2008 -;; Package-Requires: ((emacs "25.1") (all-the-icons "1.0.0") (shrink-path "0.2.0") (eldoc-eval "0.1") (dash "2.11.0")) -;; Keywords: faces mode-line - -;; This file is not part of GNU Emacs. - -;; -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2, 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; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth -;; Floor, Boston, MA 02110-1301, USA. -;; - -;;; Commentary: -;; -;; This package offers a modern modeline them which is extraced from DOOM Emacs -;; (https://github.com/hlissner/doom-emacs/tree/master/modules/ui/doom-modeline). -;; It's also the part of Centaur Emacs (https://github.com/seagle0128/.emacs.d). -;; -;; The DOOM modeline was designed for minimalism, and offers: -;; 1. A match count panel (for evil-search, iedit and evil-substitute) -;; 2. An indicator for recording a macro -;; 3. Local python/ruby version in the major-mode -;; 4. A customizable mode-line height (see doom-modeline-height) -;; 5. An error/warning count segment for flycheck -;; 6. A workspace number segment for eyebrowse -;; 7. A window number segment for winum and window-numbering -;; 8. An indicator for evil state -;; -;; Installation: -;; From melpa, `M-x package-install RET doom-modeline RET`. -;; In `init.el`, -;; (require 'doom-modeline) -;; (doom-modeline-init) -;; or -;; (use-package doom-modeline -;; :ensure t -;; :defer t -;; :hook (after-init . doom-modeline-init)) -;; - -;;; Code: - -(require 'all-the-icons) -(require 'eldoc-eval) -(require 'shrink-path) -(require 'subr-x) -(when (>= emacs-major-version 26) - (require 'project)) - -;; -;; Variables -;; - -(defvar doom-modeline-height 25 - "How tall the mode-line should be (only respected in GUI Emacs).") - -(defvar doom-modeline-bar-width 3 - "How wide the mode-line bar should be (only respected in GUI Emacs).") - -(defvar doom-modeline-buffer-file-name-style 'truncate-with-project - "Determines the style used by `doom-modeline-buffer-file-name'. - -Given ~/Projects/FOSS/emacs/lisp/comint.el - truncate-upto-project => ~/P/F/emacs/lisp/comint.el - truncate-with-project => emacs/l/comint.el - truncate-upto-root => ~/P/F/e/lisp/comint.el - truncate-all => ~/P/F/e/l/comint.el - relative-from-project => emacs/lisp/comint.el - relative-to-project => lisp/comint.el - file-name => comint.el") - -(defvar doom-modeline-python-executable "python" - "What executable of Python will be used (if nil nothing will be showed).") - -(defvar doom-modeline-icon t - "Whether show `all-the-icons' or not (if nil nothing will be showed). -The icons may not be showed correctly on Windows. Disable to make it work.") - -;; -;; externals -;; - -(defvar anzu--current-position) -(defvar anzu--overflow-p) -(defvar anzu--state) -(defvar anzu--total-matched) -(defvar anzu-cons-mode-line-p) -(defvar aw-keys) -(defvar evil-ex-active-highlights-alist) -(defvar evil-ex-argument) -(defvar evil-ex-range) -(defvar evil-local-mode) -(defvar evil-state) -(defvar evil-visual-beginning) -(defvar evil-visual-end) -(defvar evil-visual-selection) -(defvar flycheck-current-errors) -(defvar iedit-mode) -(defvar iedit-occurrences-overlays) -(defvar projectile-dynamic-mode-line) -(defvar text-scale-mode-amount) -(defvar winum-auto-setup-mode-line) -(defvar mc/mode-line) - -(declare-function anzu--reset-status 'anzu) -(declare-function anzu--where-is-here 'anzu) -(declare-function avy-traverse 'avy) -(declare-function avy-tree 'avy) -(declare-function aw-update 'ace-window) -(declare-function aw-window-list 'ace-window) -(declare-function eldoc-in-minibuffer-mode 'eldoc-eval) -(declare-function evil-delimited-arguments 'evil-common) -(declare-function evil-emacs-state-p 'evil-states) -(declare-function evil-force-normal-state 'evil-commands) -(declare-function evil-insert-state-p 'evil-states) -(declare-function evil-motion-state-p 'evil-states) -(declare-function evil-normal-state-p 'evil-states) -(declare-function evil-operator-state-p 'evil-states) -(declare-function evil-replace-state-p 'evil-states) -(declare-function evil-state-property 'evil-common) -(declare-function evil-visual-state-p 'evil-states) -(declare-function eyebrowse--get 'eyebrowse) -(declare-function face-remap-remove-relative 'face-remap) -(declare-function flycheck-count-errors 'flycheck) -(declare-function iedit-find-current-occurrence-overlay 'iedit-lib) -(declare-function iedit-prev-occurrence 'iedit-lib) -(declare-function image-get-display-property 'image-mode) -(declare-function magit-toplevel 'magit-git) -(declare-function project-current 'project) -(declare-function project-roots 'project) -(declare-function projectile-ensure-project 'projectile) -(declare-function projectile-project-root 'projectile) -(declare-function window-numbering-clear-mode-line 'window-numbering) -(declare-function window-numbering-get-number-string 'window-numbering) -(declare-function window-numbering-install-mode-line 'window-numbering) -(declare-function winum--clear-mode-line 'winum) -(declare-function winum--install-mode-line 'winum) -(declare-function winum-get-number-string 'winum) - -;; -;; Custom faces -;; - -(defgroup doom-modeline nil - "Doom mode-line faces." - :group 'faces) - -(defface doom-modeline-buffer-path - '((t (:inherit (mode-line-emphasis bold)))) - "Face used for the dirname part of the buffer path.") - -(defface doom-modeline-buffer-file - '((t (:inherit (mode-line-buffer-id bold)))) - "Face used for the filename part of the mode-line buffer path.") - -(defface doom-modeline-buffer-modified - '((t (:inherit (error bold) :background nil))) - "Face used for the 'unsaved' symbol in the mode-line.") - -(defface doom-modeline-buffer-major-mode - '((t (:inherit (mode-line-emphasis bold)))) - "Face used for the major-mode segment in the mode-line.") - -(defface doom-modeline-project-root-dir - '((t (:inherit (mode-line-emphasis bold)))) - "Face used for the project part of the mode-line buffer path.") - -(defface doom-modeline-highlight - '((t (:inherit mode-line-emphasis))) - "Face for bright segments of the mode-line.") - -(defface doom-modeline-panel - '((t (:inherit mode-line-highlight))) - "Face for 'X out of Y' segments, such as `doom-modeline--anzu', `doom-modeline--evil-substitute' and -`iedit'") - -(defface doom-modeline-info - `((t (:inherit (success bold)))) - "Face for info-level messages in the modeline. Used by `*vc'.") - -(defface doom-modeline-warning - `((t (:inherit (warning bold)))) - "Face for warnings in the modeline. Used by `*flycheck'") - -(defface doom-modeline-urgent - `((t (:inherit (error bold)))) - "Face for errors in the modeline. Used by `*flycheck'") - -;; Bar -(defface doom-modeline-bar '((t (:inherit highlight))) - "The face used for the left-most bar on the mode-line of an active window.") - -(defface doom-modeline-eldoc-bar '((t (:inherit shadow))) - "The face used for the left-most bar on the mode-line when eldoc-eval is -active.") - -(defface doom-modeline-inactive-bar `((t (:background - ,(face-foreground 'mode-line-inactive) - :foreground - ,(face-background 'mode-line-inactive)))) - "The face used for the left-most bar on the mode-line of an inactive window.") - -(defface doom-modeline-evil-emacs-state '((t (:inherit doom-modeline-warning))) - "Face for the Emacs state tag in evil state indicator.") - -(defface doom-modeline-evil-insert-state'((t (:inherit doom-modeline-urgent))) - "Face for the insert state tag in evil state indicator.") - -(defface doom-modeline-evil-motion-state'((t :inherit doom-modeline-buffer-path)) - "Face for the motion state tag in evil state indicator.") - -(defface doom-modeline-evil-normal-state'((t (:inherit doom-modeline-info))) - "Face for the normal state tag in evil state indicator.") - -(defface doom-modeline-evil-operator-state'((t (:inherit doom-modeline-buffer-path))) - "Face for the operator state tag in evil state indicator.") - -(defface doom-modeline-evil-visual-state'((t (:inherit doom-modeline-buffer-file))) - "Face for the visual state tag in evil state indicator.") - -(defface doom-modeline-evil-replace-state'((t (:inherit doom-modeline-buffer-modified))) - "Face for the replace state tag in evil state indicator.") - -;; -;; Modeline library -;; - -(eval-and-compile - (defvar doom-modeline-fn-alist ()) - (defvar doom-modeline-var-alist ())) - -(defmacro doom-modeline-def-segment (name &rest body) - "Defines a modeline segment NAME with BODY and byte compiles it." - (declare (indent defun) (doc-string 2)) - (let ((sym (intern (format "doom-modeline-segment--%s" name))) - (docstring (if (stringp (car body)) - (pop body) - (format "%s modeline segment" name)))) - (cond ((and (symbolp (car body)) - (not (cdr body))) - (add-to-list 'doom-modeline-var-alist (cons name (car body))) - `(add-to-list 'doom-modeline-var-alist (cons ',name ',(car body)))) - (t - (add-to-list 'doom-modeline-fn-alist (cons name sym)) - `(progn - (fset ',sym (lambda () ,docstring ,@body)) - (add-to-list 'doom-modeline-fn-alist (cons ',name ',sym)) - ,(unless (bound-and-true-p byte-compile-current-file) - `(let (byte-compile-warnings) - (byte-compile #',sym)))))))) - -(defun doom-modeline--prepare-segments (segments) - "Prepare mode-line `SEGMENTS'." - (let (forms it) - (dolist (seg segments) - (cond ((stringp seg) - (push seg forms)) - ((symbolp seg) - (cond ((setq it (cdr (assq seg doom-modeline-fn-alist))) - (push (list :eval (list it)) forms)) - ((setq it (cdr (assq seg doom-modeline-var-alist))) - (push it forms)) - ((error "%s is not a defined segment" seg)))) - ((error "%s is not a valid segment" seg)))) - (nreverse forms))) - -(defun doom-modeline-def-modeline (name lhs &optional rhs) - "Defines a modeline format and byte-compiles it. - - NAME is a symbol to identify it (used by `doom-modeline' for retrieval). - LHS and RHS are lists of symbols of modeline segments defined with - `doom-modeline-def-segment'. - - Example: - (doom-modeline-def-modeline 'minimal - '(bar matches \" \" buffer-info) - '(media-info major-mode)) - (doom-modeline-set-modeline 'minimal t)" - (let ((sym (intern (format "doom-modeline-format--%s" name))) - (lhs-forms (doom-modeline--prepare-segments lhs)) - (rhs-forms (doom-modeline--prepare-segments rhs))) - (defalias sym - (lambda () - (let ((rhs-str (format-mode-line (cons "" rhs-forms)))) - (list lhs-forms - (propertize - " " 'display - `((space :align-to (- (+ right right-fringe right-margin) - ,(+ 1 (string-width rhs-str)))))) - rhs-str))) - (concat "Modeline:\n" - (format " %s\n %s" - (prin1-to-string lhs) - (prin1-to-string rhs)))))) - -(defun doom-modeline (key) - "Return a mode-line configuration associated with KEY (a symbol). - - Throws an error if it doesn't exist." - (let ((fn (intern-soft (format "doom-modeline-format--%s" key)))) - (when (functionp fn) - `(:eval (,fn))))) - -(defun doom-modeline-set-modeline (key &optional default) - "Set the modeline format. Does nothing if the modeline KEY doesn't exist. - - If DEFAULT is non-nil, set the default mode-line for all buffers." - (when-let ((modeline (doom-modeline key))) - (setf (if default - (default-value 'mode-line-format) - (buffer-local-value 'mode-line-format (current-buffer))) - (list "%e" modeline)))) - -(defvar-local doom-modeline-project-root nil) -(defun doom-modeline-project-root () - "Get the path to the root of your project. - - Return `default-directory' if no project was found." - (if doom-modeline-project-root - doom-modeline-project-root - (setq doom-modeline-project-root - (or - (when (featurep 'projectile) (projectile-project-root)) - (when (featurep 'project) - (when-let ((project (project-current))) - (car (project-roots project)))) - default-directory)))) - -;; Disable projectile mode-line segment -(setq projectile-dynamic-mode-line nil) - -;; -;; Plugins -;; - -(defun doom-modeline-eldoc (text) - "Get eldoc TEXT for mode-line." - (concat (when (display-graphic-p) - (doom-modeline--make-xpm 'doom-modeline-eldoc-bar - doom-modeline-height - doom-modeline-bar-width)) - text)) - -;; Show eldoc in the mode-line with `eval-expression' -(defun doom-modeline--show-eldoc (input) - "Display string INPUT in the mode-line next to minibuffer." - (with-current-buffer (eldoc-current-buffer) - (let* ((str (and (stringp input) input)) - (mode-line-format (or (and str (or (doom-modeline-eldoc str) str)) - mode-line-format)) - mode-line-in-non-selected-windows) - (force-mode-line-update) - (sit-for eldoc-show-in-mode-line-delay)))) -(setq eldoc-in-minibuffer-show-fn #'doom-modeline--show-eldoc) - -(eldoc-in-minibuffer-mode 1) - -;; anzu and evil-anzu expose current/total state that can be displayed in the -;; mode-line. -(defun doom-modeline-fix-anzu-count (positions here) - "Calulate anzu counts via POSITIONS and HERE." - (cl-loop for (start . end) in positions - collect t into before - when (and (>= here start) (<= here end)) - return (length before) - finally return 0)) - -(advice-add #'anzu--where-is-here :override #'doom-modeline-fix-anzu-count) - -;; Avoid anzu conflicts across buffers -;; (mapc #'make-variable-buffer-local -;; '(anzu--total-matched anzu--current-position anzu--state -;; anzu--cached-count anzu--cached-positions anzu--last-command -;; anzu--last-isearch-string anzu--overflow-p)) - -;; Ensure anzu state is cleared when searches & iedit are done -(with-eval-after-load 'anzu - (add-hook 'isearch-mode-end-hook #'anzu--reset-status t) - (add-hook 'iedit-mode-end-hook #'anzu--reset-status) - (advice-add #'evil-force-normal-state :after #'anzu--reset-status)) - -;; Keep `doom-modeline-current-window' up-to-date -(defvar doom-modeline-current-window (frame-selected-window)) -(defun doom-modeline-set-selected-window (&rest _) - "Set `doom-modeline-current-window' appropriately." - (when-let ((win (frame-selected-window))) - (unless (minibuffer-window-active-p win) - (setq doom-modeline-current-window win) - (force-mode-line-update)))) - -(defun doom-modeline-unset-selected-window () - "Unset `doom-modeline-current-window' appropriately." - (setq doom-modeline-current-window nil) - (force-mode-line-update)) - -(add-hook 'window-configuration-change-hook #'doom-modeline-set-selected-window) -(advice-add #'handle-switch-frame :after #'doom-modeline-set-selected-window) -(advice-add #'select-window :after #'doom-modeline-set-selected-window) -(advice-add #'make-frame :after #'doom-modeline-set-selected-window) -(advice-add #'delete-frame :after #'doom-modeline-set-selected-window) -(with-no-warnings - (cond ((not (boundp 'after-focus-change-function)) - (add-hook 'focus-in-hook #'doom-modeline-set-selected-window) - (add-hook 'focus-out-hook #'doom-modeline-unset-selected-window)) - ((defun doom-modeline-refresh-frame () - (setq doom-modeline-current-window nil) - (cl-loop for frame in (frame-list) - if (eq (frame-focus-state frame) t) - return (setq doom-modeline-current-window (frame-selected-window frame))) - (force-mode-line-update)) - (add-function :after after-focus-change-function #'doom-modeline-refresh-frame)))) - -;; Show version string for multi-version managers like rvm, rbenv, pyenv, etc. -(defvar-local doom-modeline-env-version nil) -(defvar-local doom-modeline-env-command nil) -(add-hook 'find-file-hook #'doom-modeline-update-env) -(with-no-warnings - (if (boundp 'after-focus-change-function) - (add-function :after after-focus-change-function #'doom-modeline-update-env) - (add-hook 'focus-in-hook #'doom-modeline-update-env))) -(defun doom-modeline-update-env () - "Update environment info on mode-line." - (when doom-modeline-env-command - (let ((default-directory (doom-modeline-project-root)) - (s (shell-command-to-string doom-modeline-env-command))) - (setq doom-modeline-env-version (if (string-match "[ \t\n\r]+\\'" s) - (replace-match "" t t s) - s))))) - - -;; -;; Modeline helpers -;; - -(defun doom-modeline-icon-octicon (&rest args) - "Display octicon via `ARGS'." - (when doom-modeline-icon - (apply 'all-the-icons-octicon args))) - -(defun doom-modeline-icon-faicon (&rest args) - "Display font awesome icon via `ARGS'." - (when doom-modeline-icon - (apply 'all-the-icons-faicon args))) - -(defun doom-modeline-icon-material (&rest args) - "Display material icon via `ARGS'." - (when doom-modeline-icon - (apply 'all-the-icons-material args))) - -(defun doom-modeline--active () - "Whether is an active window." - (eq (selected-window) doom-modeline-current-window)) - -(defun doom-modeline--make-xpm (face width height) - "Create an XPM bitmap via FACE, WIDTH and HEIGHT. Inspired by `powerline''s `pl/make-xpm'." - (propertize - " " 'display - (let ((data (make-list height (make-list width 1))) - (color (or (face-background face nil t) "None"))) - (ignore-errors - (create-image - (concat - (format "/* XPM */\nstatic char * percent[] = {\n\"%i %i 2 1\",\n\". c %s\",\n\" c %s\"," - (length (car data)) - (length data) - color - color) - (apply #'concat - (cl-loop with idx = 0 - with len = (length data) - for dl in data - do (cl-incf idx) - collect - (concat "\"" - (cl-loop for d in dl - if (= d 0) collect (string-to-char " ") - else collect (string-to-char ".")) - (if (eq idx len) "\"};" "\",\n"))))) - 'xpm t :ascent 'center))))) - -(defun doom-modeline-buffer-file-name () - "Propertized variable `buffer-file-name' based on `doom-modeline-buffer-file-name-style'." - (let ((buffer-file-name (or (buffer-file-name (buffer-base-buffer)) ""))) - (unless buffer-file-truename - (setq buffer-file-truename (file-truename buffer-file-name))) - (propertize - (pcase doom-modeline-buffer-file-name-style - (`truncate-upto-project - (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink)) - (`truncate-with-project - ( doom-modeline--buffer-file-name-truncate-with-project buffer-file-name buffer-file-truename)) - (`truncate-upto-root - (doom-modeline--buffer-file-name-truncate buffer-file-name buffer-file-truename)) - (`truncate-all - (doom-modeline--buffer-file-name-truncate buffer-file-name buffer-file-truename t)) - (`relative-to-project - (doom-modeline--buffer-file-name-relative buffer-file-name buffer-file-truename)) - (`relative-from-project - (doom-modeline--buffer-file-name-relative buffer-file-name buffer-file-truename 'include-project)) - (`file-name - (propertize (file-name-nondirectory buffer-file-name) - 'face - (let ((face (or (and (buffer-modified-p) - 'doom-modeline-buffer-modified) - (and (doom-modeline--active) - 'doom-modeline-buffer-file)))) - (when face `(:inherit ,face)))))) - 'help-echo buffer-file-truename))) - -(defun doom-modeline--buffer-file-name-truncate (file-path true-file-path &optional truncate-tail) - "Propertized variable `buffer-file-name' that truncates every dir along path. -If TRUNCATE-TAIL is t also truncate the parent directory of the file." - (let ((dirs (shrink-path-prompt (file-name-directory true-file-path))) - (active (doom-modeline--active))) - (if (null dirs) - (propertize "%b" 'face (if active 'doom-modeline-buffer-file)) - (let ((modified-faces (if (buffer-modified-p) 'doom-modeline-buffer-modified))) - (let ((dirname (car dirs)) - (basename (cdr dirs)) - (dir-faces (or modified-faces (if active 'doom-modeline-project-root-dir))) - (file-faces (or modified-faces (if active 'doom-modeline-buffer-file)))) - (concat (propertize (concat dirname - (if truncate-tail (substring basename 0 1) basename) - "/") - 'face (if dir-faces `(:inherit ,dir-faces))) - (propertize (file-name-nondirectory file-path) - 'face (if file-faces `(:inherit ,file-faces))))))))) - -(defun doom-modeline--buffer-file-name-truncate-with-project (file-path _true-file-path) - "Propertized variable `buffer-file-name' based on FILE-PATH. - -Show relative path to the project and truncate it. -Example: - ~/Projects/FOSS/emacs/lisp/comint.el => emacs/l/comint.el" - (let* ((project-root (doom-modeline-project-root)) - (relative-path (file-relative-name (or (file-name-directory file-path) "./") - (file-truename project-root)))) - (let ((active (doom-modeline--active)) - (modified-faces (if (buffer-modified-p) 'doom-modeline-buffer-modified))) - (let ((project-faces (or modified-faces (if active 'font-lock-string-face))) - (relative-faces (or modified-faces (if active 'doom-modeline-buffer-path))) - (file-faces (or modified-faces (if active 'doom-modeline-buffer-file)))) - (let ((project-props `(,@(if project-faces `(:inherit ,project-faces)) ,@(if active '(:weight bold)))) - (relative-props `(,@(if relative-faces `(:inherit ,relative-faces)))) - (file-props `(,@(if file-faces `(:inherit ,file-faces))))) - (concat (propertize - (concat (file-name-nondirectory (directory-file-name (doom-modeline-project-root))) "/") - 'face project-props) - (unless (string-equal relative-path "./") - (propertize (shrink-path--dirs-internal relative-path t) 'face relative-props)) - (propertize (file-name-nondirectory file-path) 'face file-props))))))) - -(defun doom-modeline--buffer-file-name-relative (_file-path true-file-path &optional include-project) - "Propertized variable `buffer-file-name' showing directories relative to project's root only." - (let ((root (doom-modeline-project-root)) - (active (doom-modeline--active))) - (if (null root) - (propertize "%b" 'face (if active 'doom-modeline-buffer-file)) - (let* ((modified-faces (if (buffer-modified-p) 'doom-modeline-buffer-modified)) - (relative-dirs (file-relative-name (file-name-directory true-file-path) - (if include-project (concat root "../") root))) - (relative-faces (or modified-faces (if active 'doom-modeline-buffer-path))) - (file-faces (or modified-faces (if active 'doom-modeline-buffer-file)))) - (if (equal "./" relative-dirs) (setq relative-dirs "")) - (concat (propertize relative-dirs 'face (if relative-faces `(:inherit ,relative-faces))) - (propertize (file-name-nondirectory true-file-path) - 'face (if file-faces `(:inherit ,file-faces)))))))) - -(defun doom-modeline--buffer-file-name (file-path _true-file-path &optional truncate-project-root-parent) - "Propertized variable `buffer-file-name'. - -If TRUNCATE-PROJECT-ROOT-PARENT is t space will be saved by truncating it down -fish-shell style. - -Example: - ~/Projects/FOSS/emacs/lisp/comint.el => ~/P/F/emacs/lisp/comint.el" - (let* ((project-root (doom-modeline-project-root)) - (file-name-split (shrink-path-file-mixed project-root - (or (file-name-directory file-path) "./") - file-path)) - (active (doom-modeline--active))) - (if (null file-name-split) - (propertize "%b" 'face (if active 'doom-modeline-buffer-file)) - (pcase-let ((`(,root-path-parent ,project ,relative-path ,file-path) file-name-split)) - (let ((modified-faces (if (buffer-modified-p) 'doom-modeline-buffer-modified))) - (let ((sp-faces (or modified-faces (if active 'font-lock-comment-face))) - (project-faces (or modified-faces (if active 'font-lock-string-face))) - (relative-faces (or modified-faces (if active 'doom-modeline-buffer-path))) - (file-faces (or modified-faces (if active 'doom-modeline-buffer-file)))) - (let ((sp-props `(,@(if sp-faces `(:inherit ,sp-faces)) ,@(if active '(:weight bold)))) - (project-props `(,@(if project-faces `(:inherit ,project-faces)) ,@(if active '(:weight bold)))) - (relative-props `(,@(if relative-faces `(:inherit ,relative-faces)))) - (file-props `(,@(if file-faces `(:inherit ,file-faces))))) - (concat (propertize (if truncate-project-root-parent - root-path-parent - (abbreviate-file-name project-root)) - 'face sp-props) - (propertize (concat project "/") 'face project-props) - (if relative-path (propertize relative-path 'face relative-props)) - (propertize file-path 'face file-props))))))))) - - -;; -;; buffer information -;; - -(doom-modeline-def-segment buffer-default-directory - "Displays `default-directory'. This is for special buffers like the scratch -buffer where knowing the current project directory is important." - (let ((face (if (doom-modeline--active) 'doom-modeline-buffer-path))) - (concat (if (display-graphic-p) " ") - (doom-modeline-icon-octicon - "file-directory" - :face face - :v-adjust -0.05 - :height 1.25) - (propertize (concat " " (abbreviate-file-name default-directory)) - 'face face)))) - -;; -(defun doom-modeline-update-buffer-file-name () - "Update buffer file name in mode-line. - - Show buffer name if it doesn't equal the file name. - Format: \"buffer-file-name[buffer-name]\". - Except the same buffer names in different directories." - (when-let ((file-name (doom-modeline-buffer-file-name)) - (buffer-name (buffer-name)) - (buffer-file-name buffer-file-name)) - (if (or (not (file-exists-p buffer-file-name)) - (string-equal - (file-name-nondirectory buffer-file-name) - (replace-regexp-in-string "<.+>$" "" buffer-name))) - file-name - (format "%s[%s]" file-name buffer-name)))) - -(doom-modeline-def-segment buffer-info - "Combined information about the current buffer, including the current working -directory, the file name, and its state (modified, read-only or non-existent)." - (let ((active (doom-modeline--active))) - (concat - (if active - (cond (buffer-read-only - (concat (doom-modeline-icon-octicon - "lock" - :face 'doom-modeline-warning - :v-adjust -0.05) - " ")) - ((buffer-modified-p) - (concat (doom-modeline-icon-faicon - "floppy-o" - :face 'doom-modeline-buffer-modified - :v-adjust -0.0575) - " ")) - ((and buffer-file-name - (not (file-exists-p buffer-file-name))) - (concat (doom-modeline-icon-octicon - "circle-slash" - :face 'doom-modeline-urgent - :v-adjust -0.05) - " ")) - ((buffer-narrowed-p) - (concat (doom-modeline-icon-octicon - "fold" - :face 'doom-modeline-warning - :v-adjust -0.05) - " ")))) - (if buffer-file-name - (doom-modeline-update-buffer-file-name) - (propertize "%b" 'face (if active 'doom-modeline-buffer-file)))))) - -(doom-modeline-def-segment buffer-info-simple - "Display only the current buffer's name, but with fontification." - (propertize - "%b" - 'face (cond ((and buffer-file-name (buffer-modified-p)) - 'doom-modeline-buffer-modified) - ((doom-modeline--active) 'doom-modeline-buffer-file)))) - -;; -(doom-modeline-def-segment buffer-encoding - "Displays the encoding and eol style of the buffer the same way Atom does." - (concat (pcase (coding-system-eol-type buffer-file-coding-system) - (0 "LF ") - (1 "CRLF ") - (2 "CR ")) - (let ((sys (coding-system-plist buffer-file-coding-system))) - (cond ((memq (plist-get sys :category) '(coding-category-undecided coding-category-utf-8)) - "UTF-8") - (t (upcase (symbol-name (plist-get sys :name)))))) - " ")) - - -;; -;; major-mode -;; - -(doom-modeline-def-segment major-mode - "The major mode, including environment and text-scale info." - (propertize - (concat (format-mode-line - `(:propertize ("" mode-name) - help-echo "Major mode\n\ -mouse-1: Display major mode menu\n\ -mouse-2: Show help for major mode\n\ -mouse-3: Toggle minor modes" - mouse-face mode-line-highlight - local-map ,mode-line-major-mode-keymap)) - (when doom-modeline-env-version - (format " %s" doom-modeline-env-version)) - (and (boundp 'text-scale-mode-amount) - (/= text-scale-mode-amount 0) - (format - (if (> text-scale-mode-amount 0) - " (%+d)" - " (%-d)") - text-scale-mode-amount))) - 'face (if (doom-modeline--active) 'doom-modeline-buffer-major-mode))) - - -;; -;; process -;; - -(doom-modeline-def-segment process - "The process info." - mode-line-process) - -;; -;; vcs -;; - -(defvar-local doom-modeline--vcs nil) -(defun doom-modeline--update-vcs (&rest _) - "Update vsc state in mode-line." - (setq doom-modeline--vcs - (when (and vc-mode buffer-file-name) - (let* ((backend (vc-backend buffer-file-name)) - (state (vc-state buffer-file-name backend))) - (let ((face 'mode-line-inactive) - (active (doom-modeline--active)) - (all-the-icons-default-adjust -0.1)) - (concat " " - (cond ((memq state '(edited added)) - (if active (setq face 'doom-modeline-info)) - (doom-modeline-icon-octicon - "git-compare" - :face face - :v-adjust -0.05)) - ((eq state 'needs-merge) - (if active (setq face 'doom-modeline-info)) - (doom-modeline-icon-octicon "git-merge" :face face)) - ((eq state 'needs-update) - (if active (setq face 'doom-modeline-warning)) - (doom-modeline-icon-octicon "arrow-down" :face face)) - ((memq state '(removed conflict unregistered)) - (if active (setq face 'doom-modeline-urgent)) - (doom-modeline-icon-octicon "alert" :face face)) - (t - (if active (setq face 'font-lock-doc-face)) - (doom-modeline-icon-octicon - "git-branch" - :face face - :v-adjust -0.05))) - " " - (propertize (substring vc-mode (+ (if (eq backend 'Hg) 2 3) 2)) - 'face (if active face)) - " ")))))) -(add-hook 'after-revert-hook #'doom-modeline--update-vcs) -(add-hook 'after-save-hook #'doom-modeline--update-vcs) -(add-hook 'find-file-hook #'doom-modeline--update-vcs t) -(advice-add #'select-window :after #'doom-modeline--update-vcs) - -(doom-modeline-def-segment vcs - "Displays the current branch, colored based on its state." - (if (doom-modeline--active) - doom-modeline--vcs - "")) - - -;; -;; flycheck -;; - -(defvar doom-modeline-vspc - (propertize " " 'face 'variable-pitch) - "Text style with icons in mode-line.") - -(defun doom-modeline-icon (icon &optional text face voffset) - "Displays an ICON with FACE, followed by TEXT. -Uses `all-the-icons-material' to fetch the icon." - (concat (if vc-mode " " " ") - (when icon - (concat - (doom-modeline-icon-material icon :face face :height 0.95 :v-adjust (or voffset -0.2)) - (if text doom-modeline-vspc))) - (if text (propertize text 'face face)) - (if vc-mode " " " "))) - -(defvar-local doom-modeline--flycheck nil) -(add-hook 'flycheck-status-changed-functions #'doom-modeline-update-flycheck-segment) -(add-hook 'flycheck-mode-hook #'doom-modeline-update-flycheck-segment) - -(defun doom-modeline-update-flycheck-segment (&optional status) - "Update flycheck segment via STATUS." - (setq doom-modeline--flycheck - (pcase status - (`finished (if flycheck-current-errors - (let-alist (flycheck-count-errors flycheck-current-errors) - (let ((sum (+ (or .error 0) (or .warning 0)))) - (doom-modeline-icon "do_not_disturb_alt" - (number-to-string sum) - (if .error 'doom-modeline-urgent 'doom-modeline-warning) - -0.15))) - (doom-modeline-icon "check" nil 'doom-modeline-info))) - (`running (doom-modeline-icon "access_time" nil 'font-lock-doc-face -0.25)) - (`no-checker (doom-modeline-icon "sim_card_alert" "-" 'font-lock-doc-face)) - (`errored (doom-modeline-icon "sim_card_alert" "Error" 'doom-modeline-urgent)) - (`interrupted (doom-modeline-icon "pause" "Interrupted" 'font-lock-doc-face))))) - -(doom-modeline-def-segment flycheck - "Displays color-coded flycheck error status in the current buffer with pretty -icons." - (if (doom-modeline--active) - doom-modeline--flycheck - "")) - - -;; -;; selection-info -;; - -(defsubst doom-modeline-column (pos) - "Get the column of the position `POS'." - (save-excursion (goto-char pos) - (current-column))) - -(defvar-local doom-modeline-enable-word-count nil - "If non-nil, a word count will be added to the selection-info modeline -segment.") - -(doom-modeline-def-segment selection-info - "Information about the current selection, such as how many characters and -lines are selected, or the NxM dimensions of a block selection." - (when (and (or mark-active (and (bound-and-true-p evil-local-mode) - (eq evil-state 'visual))) - (doom-modeline--active)) - (cl-destructuring-bind (beg . end) - (if (and (bound-and-true-p evil-local-mode) (eq evil-state 'visual)) - (cons evil-visual-beginning evil-visual-end) - (cons (region-beginning) (region-end))) - (propertize - (let ((lines (count-lines beg (min end (point-max))))) - (concat (cond ((or (bound-and-true-p rectangle-mark-mode) - (and (bound-and-true-p evil-visual-selection) - (eq 'block evil-visual-selection))) - (let ((cols (abs (- (doom-modeline-column end) - (doom-modeline-column beg))))) - (format "%dx%dB" lines cols))) - ((and (bound-and-true-p evil-visual-selection) - (eq evil-visual-selection 'line)) - (format "%dL" lines)) - ((> lines 1) - (format "%dC %dL" (- end beg) lines)) - ((format "%dC" (- end beg)))) - (when doom-modeline-enable-word-count - (format " %dW" (count-words beg end))))) - 'face 'doom-modeline-highlight)))) - - -;; -;; matches (anzu, evil-substitute, iedit, macro) -;; - -(defun doom-modeline--macro-recording () - "Display current Emacs or evil macro being recorded." - (when (and (doom-modeline--active) (or defining-kbd-macro executing-kbd-macro)) - (let ((sep (propertize " " 'face 'doom-modeline-panel))) - (concat sep - (propertize (if (bound-and-true-p evil-this-macro) - (char-to-string evil-this-macro) - "Macro") - 'face 'doom-modeline-panel) - sep - (doom-modeline-icon-octicon "triangle-right" - :face 'doom-modeline-panel - :v-adjust -0.05) - sep)))) - -(defsubst doom-modeline--anzu () - "Show the match index and total number thereof. - -Requires `anzu', also `evil-anzu' if using `evil-mode' for compatibility with -`evil-search'." - (setq anzu-cons-mode-line-p nil) - (when (and (bound-and-true-p anzu--state) - (not (bound-and-true-p iedit-mode))) - (propertize - (let ((here anzu--current-position) - (total anzu--total-matched)) - (cond ((eq anzu--state 'replace-query) - (format " %d replace " total)) - ((eq anzu--state 'replace) - (format " %d/%d " here total)) - (anzu--overflow-p - (format " %s+ " total)) - (t - (format " %s/%d " here total)))) - 'face (if (doom-modeline--active) 'doom-modeline-panel)))) - -(defsubst doom-modeline--evil-substitute () - "Show number of matches for evil-ex substitutions and highlights in real time." - (when (and (bound-and-true-p evil-local-mode) - (or (assq 'evil-ex-substitute evil-ex-active-highlights-alist) - (assq 'evil-ex-global-match evil-ex-active-highlights-alist) - (assq 'evil-ex-buffer-match evil-ex-active-highlights-alist))) - (propertize - (let ((range (if evil-ex-range - (cons (car evil-ex-range) (cadr evil-ex-range)) - (cons (line-beginning-position) (line-end-position)))) - (pattern (car-safe (evil-delimited-arguments evil-ex-argument 2)))) - (if pattern - (format " %s matches " (how-many pattern (car range) (cdr range))) - " - ")) - 'face (if (doom-modeline--active) 'doom-modeline-panel)))) - -(defun doom-modeline-themes--overlay-sort (a b) - "Sort overlay A and B." - (< (overlay-start a) (overlay-start b))) - -(defsubst doom-modeline--iedit () - "Show the number of iedit regions matches + what match you're on." - (when (and (bound-and-true-p iedit-mode) - (bound-and-true-p iedit-occurrences-overlays)) - (propertize - (let ((this-oc (or (let ((inhibit-message t)) - (iedit-find-current-occurrence-overlay)) - (progn (iedit-prev-occurrence) - (iedit-find-current-occurrence-overlay)))) - (length (length iedit-occurrences-overlays))) - (format " %s/%d " - (if this-oc - (- length - (length (memq this-oc (sort (append iedit-occurrences-overlays nil) - #'doom-modeline-themes--overlay-sort))) - -1) - "-") - length)) - 'face (if (doom-modeline--active) 'doom-modeline-panel)))) - -(defsubst doom-modeline--multiple-cursors () - "Show the number of multiple cursors." - (when (bound-and-true-p multiple-cursors-mode) - (propertize - (concat (car mc/mode-line) - (eval (cadadr mc/mode-line)) - " ") - 'face (if (doom-modeline--active) 'doom-modeline-panel)))) - -(doom-modeline-def-segment matches - "Displays: 1. the currently recording macro, 2. A current/total for the -current search term (with anzu), 3. The number of substitutions being conducted -with `evil-ex-substitute', and/or 4. The number of active `iedit' regions." - (let ((meta (concat (doom-modeline--macro-recording) - (doom-modeline--anzu) - (doom-modeline--evil-substitute) - (doom-modeline--iedit) - (doom-modeline--multiple-cursors)))) - (or (and (not (equal meta "")) meta) - (if buffer-file-name " %I ")))) - - -;; -;; media-info -;; - -(doom-modeline-def-segment media-info - "Metadata regarding the current file, such as dimensions for images." - ;; TODO Include other information - (cond ((eq major-mode 'image-mode) - (cl-destructuring-bind (width . height) - (when (fboundp 'image-size) - (image-size (image-get-display-property) :pixels)) - (format " %dx%d " width height))))) - - -;; -;; bar -;; - -(defvar doom-modeline--bar-active nil) -(defvar doom-modeline--bar-inactive nil) -(doom-modeline-def-segment bar - "The bar regulates the height of the mode-line in GUI Emacs. - Returns \"\" to not break --no-window-system." - (if (display-graphic-p) - (if (doom-modeline--active) - doom-modeline--bar-active - doom-modeline--bar-inactive) - "")) - -(when (>= emacs-major-version 26) - (add-variable-watcher - 'doom-modeline-height - (lambda (_sym val op _where) - (when (and (eq op 'set) (integerp val)) - (doom-modeline-refresh-bars doom-modeline-bar-width val)))) - - (add-variable-watcher - 'doom-modeline-bar-width - (lambda (_sym val op _where) - (when (and (eq op 'set) (integerp val)) - (doom-modeline-refresh-bars val doom-modeline-height))))) - -(add-hook 'after-setting-font-hook - '(lambda () - (doom-modeline-refresh-bars))) - - -;; -;; window number -;; - -;; HACK: `ace-window-display-mode' should respect the ignore buffers. -(defun doom-modeline-aw-update () - "Update ace-window-path window parameter for all windows. - -Ensure all windows are labeled so the user can select a specific -one. The ignored buffers are excluded unless `aw-ignore-on' is nil." - (let ((ignore-window-parameters t)) - (avy-traverse - (avy-tree (aw-window-list) aw-keys) - (lambda (path leaf) - (set-window-parameter - leaf 'ace-window-path - (propertize - (apply #'string (reverse path)) - 'face 'aw-mode-line-face)))))) -(advice-add #'aw-update :override #'doom-modeline-aw-update) - -(advice-add #'window-numbering-install-mode-line :override #'ignore) -(advice-add #'window-numbering-clear-mode-line :override #'ignore) -(advice-add #'winum--install-mode-line :override #'ignore) -(advice-add #'winum--clear-mode-line :override #'ignore) - -(doom-modeline-def-segment window-number - (let ((num (cond - ((bound-and-true-p ace-window-display-mode) - (setq mode-line-format - (assq-delete-all 'ace-window-display-mode - (default-value 'mode-line-format))) - (setq-default mode-line-format mode-line-format) - (aw-update) - (window-parameter (selected-window) 'ace-window-path)) - ((bound-and-true-p winum-mode) - (setq winum-auto-setup-mode-line nil) - (winum-get-number-string)) - ((bound-and-true-p window-numbering-mode) - (window-numbering-get-number-string)) - (t "")))) - (if (< 0 (length num)) - (propertize (format " %s " num) - 'face (if (doom-modeline--active) - 'doom-modeline-buffer-major-mode)) - ""))) - - -;; -;; workspace number -;; - -(doom-modeline-def-segment workspace-number - "The current workspace name or number. Requires `eyebrowse-mode' to be -enabled." - (if (and (bound-and-true-p eyebrowse-mode) - (< 1 (length (eyebrowse--get 'window-configs)))) - (let* ((num (eyebrowse--get 'current-slot)) - (tag (when num (nth 2 (assoc num (eyebrowse--get 'window-configs))))) - (str (if (and tag (< 0 (length tag))) - tag - (when num (int-to-string num))))) - (propertize (format " %s " str) 'face - (if (doom-modeline--active) 'doom-modeline-buffer-major-mode))) - "")) - - -;; -;; global -;; - -(doom-modeline-def-segment global - "For the time string and whatever uses global-mode-string." - (if (< 0 (length global-mode-string)) - '(" " global-mode-string " ") - "")) - - -;; -;; position -;; - -;; Be compatible with Emacs 25. -(defvar-local doom-modeline-column-zero-based - (or (bound-and-true-p column-number-indicator-zero-based) t) - "When non-nil, mode line displays column numbers zero-based. -See `column-number-indicator-zero-based'.") - -(defvar-local doom-modeline-percent-position - (or (bound-and-true-p mode-line-percent-position) '(-3 "%p")) - "Specification of \"percentage offset\" of window through buffer. -See `mode-line-percent-position'.") - -(setq-default mode-line-position - '((line-number-mode - (column-number-mode - (doom-modeline-column-zero-based " %l:%c" " %l:%C") - " %l") - (column-number-mode (doom-modeline-column-zero-based " :%c" " :%C"))) - (if doom-modeline-percent-position (" " doom-modeline-percent-position)) - (:eval (when (or line-number-mode column-number-mode doom-modeline-percent-position) " ")))) - -(doom-modeline-def-segment buffer-position - "The buffer position information." - '(" " mode-line-position)) - - -;; -;; evil-state -;; - -(doom-modeline-def-segment evil-state - "The current evil state. Requires `evil-mode' to be enabled." - (when (bound-and-true-p evil-local-mode) - (let ((tag (evil-state-property evil-state :tag t))) - (propertize tag 'face - (if (doom-modeline--active) - (cond ((evil-normal-state-p) 'doom-modeline-evil-normal-state) - ((evil-emacs-state-p) 'doom-modeline-evil-emacs-state) - ((evil-insert-state-p) 'doom-modeline-evil-insert-state) - ((evil-motion-state-p) 'doom-modeline-evil-motion-state) - ((evil-visual-state-p) 'doom-modeline-evil-visual-state) - ((evil-operator-state-p) 'doom-modeline-evil-operator-state) - ((evil-replace-state-p) 'doom-modeline-evil-replace-state))))))) - - -;; -;; input method -;; - -(doom-modeline-def-segment input-method - "The current input method." - (cond - (current-input-method - (concat current-input-method-title " ")) - ((and (bound-and-true-p evil-local-mode) - (bound-and-true-p evil-input-method)) - (concat - (nth 3 (assoc default-input-method input-method-alist)) - " ")))) - -;; -;; Mode lines -;; - -(doom-modeline-def-modeline 'main - '(bar workspace-number window-number evil-state matches " " buffer-info buffer-position " " selection-info) - '(global input-method buffer-encoding major-mode process vcs flycheck)) - -(doom-modeline-def-modeline 'minimal - '(bar matches " " buffer-info) - '(media-info major-mode)) - -(doom-modeline-def-modeline 'special - '(bar window-number evil-state matches " " buffer-info-simple buffer-position " " selection-info) - '(global input-method buffer-encoding major-mode process flycheck)) - -(doom-modeline-def-modeline 'project - '(bar window-number buffer-default-directory) - '(global major-mode)) - -(doom-modeline-def-modeline 'media - '(bar window-number " %b ") - '(global media-info major-mode)) - -;; -;; Hooks -;; - -(defun doom-modeline-refresh-bars (&optional width height) - "Refresh mode-line bars with `WIDTH' and `HEIGHT'." - (setq doom-modeline--bar-active - (doom-modeline--make-xpm 'doom-modeline-bar - (or width doom-modeline-bar-width) - (max (or height doom-modeline-height) - (frame-char-height))) - doom-modeline--bar-inactive - (doom-modeline--make-xpm 'doom-modeline-inactive-bar - (or width doom-modeline-bar-width) - (max (or height doom-modeline-height) - (frame-char-height))))) - -;;;###autoload -(defun doom-modeline-init () - "Initialize doom mode-line." - ;; Create bars - (doom-modeline-refresh-bars) - (unless after-init-time - ;; These buffers are already created and don't get modelines. For the love - ;; of Emacs, someone give the man a modeline! - (dolist (bname '("*scratch*" "*Messages*")) - (with-current-buffer bname - (doom-modeline-set-modeline 'main))))) - -;;;###autoload -(defun doom-modeline-set-special-modeline () - "Set sepcial mode-line." - (doom-modeline-set-modeline 'special)) - -;;;###autoload -(defun doom-modeline-set-media-modeline () - "Set media mode-line." - (doom-modeline-set-modeline 'media)) - -;;;###autoload -(defun doom-modeline-set-project-modeline () - "Set project mode-line." - (doom-modeline-set-modeline 'project)) - -;; -;; Bootstrap -;; - -(doom-modeline-set-modeline 'main t) ; set default modeline - -(add-hook 'image-mode-hook #'doom-modeline-set-media-modeline) -(add-hook 'org-src-mode-hook #'doom-modeline-set-special-modeline) -(add-hook 'circe-mode-hook #'doom-modeline-set-special-modeline) - -;; Versions, support Python, Ruby, Perl and Golang, etc. -(add-hook 'python-mode-hook - (lambda () - (when (and doom-modeline-python-executable (executable-find doom-modeline-python-executable) (executable-find "cut") (executable-find "sed")) - (setq doom-modeline-env-command (concat doom-modeline-python-executable " --version 2>&1 | cut -d' ' -f2 | sed -n '1p'"))))) -(add-hook 'ruby-mode-hook - (lambda () - (when (and (executable-find "ruby") (executable-find "cut") (executable-find "sed")) - (setq doom-modeline-env-command "ruby --version 2>&1 | cut -d' ' -f2 | sed -n '1p'")))) -(add-hook 'perl-mode-hook - (lambda () - (when (and (executable-find "perl") (executable-find "cut") (executable-find "tr") (executable-find "sed")) - (setq doom-modeline-env-command "perl --version 2>&1 | cut -d'(' -f2 | cut -d')' -f1 | tr -d 'v' | sed -n '2p'")))) -(add-hook 'go-mode-hook - (lambda () - (when (and (executable-find "go") (executable-find "cut") (executable-find "tr") (executable-find "sed")) - (setq doom-modeline-env-command "go version 2>&1 | cut -d' ' -f3 | tr -d 'go' | sed -n '1p'")))) -(add-hook 'elixir-mode-hook - (lambda () - (when (and (executable-find "iex") (executable-find "cut") (executable-find "sed")) - (setq doom-modeline-env-command "iex --version 2>&1 | cut -d' ' -f2 | sed -n '1p'")))) - - -;; Ensure modeline is inactive when Emacs is unfocused (and active otherwise) -(defvar doom-modeline-remap-face-cookie nil) -(defun doom-modeline-focus () - "Focus mode-line." - (when doom-modeline-remap-face-cookie - (require 'face-remap) - (face-remap-remove-relative doom-modeline-remap-face-cookie))) -(defun doom-modeline-unfocus () - "Unfocus mode-line." - (setq doom-modeline-remap-face-cookie (face-remap-add-relative 'mode-line 'mode-line-inactive))) - -(with-no-warnings - (if (boundp 'after-focus-change-function) - (progn - (defun doom-modeline-focus-change () - (if (frame-focus-state) - (doom-modeline-focus) - (doom-modeline-unfocus))) - (add-function :after after-focus-change-function #'doom-modeline-focus-change)) - (progn - (add-hook 'focus-in-hook #'doom-modeline-focus) - (add-hook 'focus-out-hook #'doom-modeline-unfocus)))) - -(provide 'doom-modeline) - -;;; doom-modeline.el ends here diff --git a/packages/doom-modeline-20190820.1749.tar b/packages/doom-modeline-20190820.1749.tar new file mode 100644 index 0000000..bdf7789 Binary files /dev/null and b/packages/doom-modeline-20190820.1749.tar differ diff --git a/packages/doom-themes-20181101.218.tar b/packages/doom-themes-20190819.1549.tar similarity index 67% rename from packages/doom-themes-20181101.218.tar rename to packages/doom-themes-20190819.1549.tar index a2eca0b..dbdbd14 100644 Binary files a/packages/doom-themes-20181101.218.tar and b/packages/doom-themes-20190819.1549.tar differ diff --git a/packages/dotnet-20190415.1237.el b/packages/dotnet-20190415.1237.el new file mode 100644 index 0000000..b49cc45 --- /dev/null +++ b/packages/dotnet-20190415.1237.el @@ -0,0 +1,257 @@ +;;; dotnet.el --- Interact with dotnet CLI tool + +;; Copyright (C) 2019 by Julien Blanchard + +;; Author: Julien BLANCHARD +;; URL: https://github.com/julienXX/dotnet.el +;; Package-Version: 20190415.1237 +;; Version: 0.5 +;; Keywords: .net, tools + +;; 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 . + +;;; Commentary: +;; +;; dotnet CLI minor mode. + +;; Provides some key combinations to interact with dotnet CLI. + +;;; Code: + +(defgroup dotnet nil + "dotnet group." + :prefix "dotnet-" + :group 'tools) + +(defcustom dotnet-mode-keymap-prefix (kbd "C-c C-n") + "Dotnet minor mode keymap prefix." + :group 'dotnet + :type 'string) + +;;;###autoload +(defun dotnet-add-package (package-name) + "Add package reference from PACKAGE-NAME." + (interactive "sPackage name: ") + (dotnet-command (concat "dotnet add package " package-name))) + +;;;###autoload +(defun dotnet-add-reference (reference project) + "Add a REFERENCE to a PROJECT." + (interactive (list (read-file-name "Reference file: ") + (read-file-name "In Project: "))) + (dotnet-command (concat "dotnet add " project " reference " reference))) + +;;;###autoload +(defun dotnet-build () + "Build a .NET project." + (interactive) + (let* ((target (dotnet-select-project-or-solution)) + (command "dotnet build -v n \"%s\"")) + (compile (format command target)))) + +;;;###autoload +(defun dotnet-clean () + "Clean build output." + (interactive) + (dotnet-command "dotnet clean -v n")) + +(defvar dotnet-langs '("c#" "f#")) +(defvar dotnet-templates '("console" "classlib" "mstest" "xunit" "web" "mvc" "webapi")) + +;;;###autoload +(defun dotnet-new (project-path template lang) + "Initialize a new console .NET project. +PROJECT-PATH is the path to the new project, TEMPLATE is a +template (see `dotnet-templates'), and LANG is a supported +language (see `dotnet-langs')." + (interactive (list (read-directory-name "Project path: ") + (completing-read "Choose a template: " dotnet-templates) + (completing-read "Choose a language: " dotnet-langs))) + (dotnet-command (concat "dotnet " + (mapconcat 'shell-quote-argument + (list "new" template "-o" project-path "-lang" lang) + " ")))) + +;;;###autoload +(defun dotnet-publish () + "Publish a .NET project for deployment." + (interactive) + (dotnet-command "dotnet publish -v n")) + +;;;###autoload +(defun dotnet-restore () + "Restore dependencies specified in the .NET project." + (interactive) + (dotnet-command "dotnet restore")) + +(defvar dotnet-run-last-proj-dir nil + "Last project directory executed by `dotnet-run'.") + +;;;###autoload +(defun dotnet-run (arg) + "Compile and execute a .NET project. With ARG, query for project path again." + (interactive "P") + (when (or (not dotnet-run-last-proj-dir) arg) + (setq dotnet-run-last-proj-dir (read-directory-name "Run project in directory: "))) + (let ((default-directory dotnet-run-last-proj-dir)) + (dotnet-command (concat "dotnet run " dotnet-run-last-proj-dir)))) + +;;;###autoload +(defun dotnet-run-with-args (args) + "Compile and execute a .NET project with ARGS." + (interactive "Arguments: ") + (dotnet-command (concat "dotnet run " args))) + +;;;###autoload +(defun dotnet-sln-add () + "Add a project to a Solution." + (interactive) + (let ((solution-file (read-file-name "Solution file: "))) + (let ((to-add (read-file-name "Project/Pattern to add to the solution: "))) + (dotnet-command (concat "dotnet sln " solution-file " add " to-add))))) + +;;;###autoload +(defun dotnet-sln-remove () + "Remove a project from a Solution." + (interactive) + (let ((solution-file (read-file-name "Solution file: "))) + (let ((to-remove (read-file-name "Project/Pattern to remove from the solution: "))) + (dotnet-command (concat "dotnet sln " solution-file " remove " to-remove))))) + +;;;###autoload +(defun dotnet-sln-list () + "List all projects in a Solution." + (interactive) + (let ((solution-file (read-file-name "Solution file: "))) + (dotnet-command (concat "dotnet sln " solution-file " list")))) + +;;;###autoload +(defun dotnet-sln-new () + "Create a new Solution." + (interactive) + (let ((solution-path (read-directory-name "Solution path: "))) + (dotnet-command (concat "dotnet new sln -o " solution-path)))) + +(defvar dotnet-test-last-test-proj nil + "Last unit test project file executed by `dotnet-test'.") + +;;;###autoload +(defun dotnet-test (arg) + "Launch project unit-tests, querying for a project on first call. With ARG, query for project path again." + (interactive "P") + (when (or (not dotnet-test-last-test-proj) arg) + (setq dotnet-test-last-test-proj (read-file-name "Launch tests for Project file: "))) + (dotnet-command (concat "dotnet test " dotnet-test-last-test-proj))) + +(defun dotnet-command (cmd) + "Run CMD in an async buffer." + (async-shell-command cmd "*dotnet*")) + +(defun dotnet-find (extension) + "Search for a EXTENSION file in any enclosing folders relative to current directory." + (dotnet-search-upwards (rx-to-string extension) + (file-name-directory buffer-file-name))) + +(defun dotnet-goto (extension) + "Open file with EXTENSION in any enclosing folders relative to current directory." + (let ((file (dotnet-find extension))) + (if file + (find-file file) + (error "Could not find any %s file" extension)))) + +(defun dotnet-goto-sln () + "Search for a solution file in any enclosing folders relative to current directory." + (interactive) + (dotnet-goto ".sln")) + +(defun dotnet-goto-csproj () + "Search for a C# project file in any enclosing folders relative to current directory." + (interactive) + (dotnet-goto ".csproj")) + +(defun dotnet-goto-fsproj () + "Search for a F# project file in any enclosing folders relative to current directory." + (interactive) + (dotnet-goto ".fsproj")) + +(defun dotnet-search-upwards (regex dir) + "Search for REGEX in DIR." + (when dir + (or (car-safe (directory-files dir 'full regex)) + (dotnet-search-upwards regex (dotnet-parent-dir dir))))) + +(defun dotnet-parent-dir (dir) + "Find parent DIR." + (let ((p (file-name-directory (directory-file-name dir)))) + (unless (equal p dir) + p))) + +(defun dotnet-select-project-or-solution () + "Prompt for the project/solution file or directory. Try projectile root first, else use current buffer's directory." + (let ((default-dir-prompt "?")) + (ignore-errors + (when (fboundp 'projectile-project-root) + (setq default-dir-prompt (projectile-project-root)))) + (when (string= default-dir-prompt "?") + (setq default-dir-prompt default-directory)) + (expand-file-name (read-file-name "Project or solution: " default-dir-prompt nil t)))) + +(defun dotnet-valid-project-solutions (path) + "Predicate to validate project/solution paths. PATH is passed by `'read-file-name`." + ;; file-attributes returns t for directories + ;; if not a dir, then check the common extensions + (let ((extension (file-name-extension path)) + (valid-projects (list "sln" "csproj" "fsproj"))) + (or (member extension valid-projects) + (car (file-attributes path))))) + +(defvar dotnet-mode-command-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "a p") #'dotnet-add-package) + (define-key map (kbd "a r") #'dotnet-add-reference) + (define-key map (kbd "b") #'dotnet-build) + (define-key map (kbd "c") #'dotnet-clean) + (define-key map (kbd "g c") #'dotnet-goto-csproj) + (define-key map (kbd "g f") #'dotnet-goto-fsproj) + (define-key map (kbd "g s") #'dotnet-goto-sln) + (define-key map (kbd "n") #'dotnet-new) + (define-key map (kbd "p") #'dotnet-publish) + (define-key map (kbd "r") #'dotnet-restore) + (define-key map (kbd "e") #'dotnet-run) + (define-key map (kbd "C-e") #'dotnet-run-with-args) + (define-key map (kbd "s a") #'dotnet-sln-add) + (define-key map (kbd "s l") #'dotnet-sln-list) + (define-key map (kbd "s n") #'dotnet-sln-new) + (define-key map (kbd "s r") #'dotnet-sln-remove) + (define-key map (kbd "t") #'dotnet-test) + map) + "Keymap for dotnet-mode commands after `dotnet-mode-keymap-prefix'.") + +(defvar dotnet-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd dotnet-mode-keymap-prefix) dotnet-mode-command-map) + map) + "Keymap for dotnet-mode.") + +;;;###autoload +(define-minor-mode dotnet-mode + "dotnet CLI minor mode." + nil + " dotnet" + dotnet-mode-map + :group 'dotnet) + + +(provide 'dotnet) +;;; dotnet.el ends here diff --git a/packages/dracula-theme-20180710.1324.el b/packages/dracula-theme-20190107.2016.el similarity index 99% rename from packages/dracula-theme-20180710.1324.el rename to packages/dracula-theme-20190107.2016.el index c113242..c02f978 100644 --- a/packages/dracula-theme-20180710.1324.el +++ b/packages/dracula-theme-20190107.2016.el @@ -5,8 +5,8 @@ ;; Code licensed under the MIT license ;; Author: film42 -;; Version: 1.5.0 -;; Package-Version: 20180710.1324 +;; Version: 1.5.1 +;; Package-Version: 20190107.2016 ;; Package-Requires: ((emacs "24")) ;; URL: https://github.com/dracula/emacs @@ -178,6 +178,8 @@ (helm-time-zone-current :foreground ,builtin :background ,bg1) (helm-time-zone-home :foreground ,type :background ,bg1) (helm-visible-mark :foreground ,bg1 :background ,bg3) + ;; highlight-indentation minor mode + (highlight-indentation-face :background ,bg2) ;; icomplete (icompletep-determined :foreground ,builtin) ;; ido diff --git a/packages/drupal-mode-20171120.2309.tar b/packages/drupal-mode-20171120.2309.tar index 7cf6fcd..5fc7d38 100644 Binary files a/packages/drupal-mode-20171120.2309.tar and b/packages/drupal-mode-20171120.2309.tar differ diff --git a/packages/dumb-jump-20181022.2224.el b/packages/dumb-jump-20190804.533.el similarity index 93% rename from packages/dumb-jump-20181022.2224.el rename to packages/dumb-jump-20190804.533.el index b2bfb8f..f6091e5 100644 --- a/packages/dumb-jump-20181022.2224.el +++ b/packages/dumb-jump-20190804.533.el @@ -2,7 +2,7 @@ ;; Copyright (C) 2015-2018 jack angers ;; Author: jack angers ;; Version: 0.5.2 -;; Package-Version: 20181022.2224 +;; Package-Version: 20190804.533 ;; Package-Requires: ((emacs "24.3") (f "0.20.0") (s "1.11.0") (dash "2.9.0") (popup "0.5.3")) ;; Keywords: programming @@ -80,7 +80,8 @@ If nil then the most optimal searcher will be chosen at runtime." (const :tag "ag" ag) (const :tag "rg" rg) (const :tag "grep" gnu-grep) - (const :tag "git grep" git-grep))) + (const :tag "git grep" git-grep) + (const :tag "git grep + ag" git-grep-plus-ag))) (defcustom dumb-jump-force-searcher @@ -93,7 +94,8 @@ or most optimal searcher." (const :tag "ag" ag) (const :tag "rg" rg) (const :tag "grep" gnu-grep) - (const :tag "git grep" git-grep))) + (const :tag "git grep" git-grep) + (const :tag "git grep + ag" git-grep-plus-ag))) (defcustom dumb-jump-grep-prefix "LANG=C" @@ -213,6 +215,25 @@ or most optimal searcher." :group 'dumb-jump :type 'boolean) +(defcustom dumb-jump-git-grep-search-args + "" + "Appends the passed arguments to the git-grep search function. Default: \"\"" + :group 'dumb-jump + :type 'string) + +(defcustom dumb-jump-ag-search-args + "" + "Appends the passed arguments to the ag search function. Default: \"\"" + :group 'dumb-jump + :type 'string) + +(defcustom dumb-jump-rg-search-args + "--pcre2" + "Appends the passed arguments to the rg search function. Default: \"--pcre2\"" + :group 'dumb-jump + :type 'string) + + (defcustom dumb-jump-find-rules '((:type "function" :supports ("ag" "grep" "rg" "git-grep") :language "elisp" :regex "\\\((defun|cl-defun)\\s+JJJ\\j" @@ -244,6 +265,19 @@ or most optimal searcher." :tests ("(defun blah (test)" "(defun blah (test blah)" "(defun (blah test)") :not ("(defun blah (test-1)" "(defun blah (test-2 blah)" "(defun (blah test-3)")) + ;; common lisp + (:type "function" :supports ("ag" "grep" "rg" "git-grep") :language "commonlisp" + :regex "\\\(defun\\s+JJJ\\j" + ;; \\j usage see `dumb-jump-ag-word-boundary` + :tests ("(defun test (blah)" "(defun test\n") + :not ("(defun test-asdf (blah)" "(defun test-blah\n" + "(defun tester (blah)" "(defun test? (blah)" "(defun test- (blah)")) + + (:type "variable" :supports ("ag" "grep" "rg" "git-grep") :language "commonlisp" + :regex "\\\(defparameter\\b\\s*JJJ\\j" + :tests ("(defparameter test " "(defparameter test\n") + :not ("(defparameter tester" "(defparameter test?" "(defparameter test-")) + ;; scheme (:type "function" :supports ("ag" "grep" "rg" "git-grep") :language "scheme" :regex "\\\(define\\s+\\(\\s*JJJ\\j" @@ -290,7 +324,7 @@ or most optimal searcher." ;; :regex "(\\b\\w+|[,>])([*&]|\\s)+JJJ\\s*(\\[([0-9]|\\s)*\\])*\\s*([=,){;]|:\\s*[0-9])|#define\\s+JJJ\\b" ;; :tests ("int test=2;" "char *test;" "int x = 1, test = 2" "int test[20];" "#define test" "unsigned int test:2;")) - (:type "variable" :supports ("ag") :language "c++" + (:type "variable" :supports ("ag" "rg") :language "c++" :regex "\\b(?!(class\\b|struct\\b|return\\b|else\\b|delete\\b))(\\w+|[,>])([*&]|\\s)+JJJ\\s*(\\[(\\d|\\s)*\\])*\\s*([=,(){;]|:\\s*\\d)|#define\\s+JJJ\\b" :tests ("int test=2;" "char *test;" "int x = 1, test = 2" "int test[20];" "#define test" "typedef int test;" "unsigned int test:2") :not ("return test;" "#define NOT test" "else test=2;")) @@ -509,6 +543,12 @@ or most optimal searcher." :tests ("type test = object" "type test {.pure.} = enum") :not ("type testnot = object")) + ;; nix + (:type "variable" :supports ("ag" "grep" "rg" "git-grep") :language "nix" + :regex "\\b\\s*JJJ\\s*=[^=;]+" + :tests ("test = 1234;" "test = 123;" "test=123") + :not ("testNot = 1234;" "Nottest = 1234;" "AtestNot = 1234;")) + ;; ruby (:type "variable" :supports ("ag" "rg" "git-grep") :language "ruby" :regex "^\\s*((\\w+[.])*\\w+,\\s*)*JJJ(,\\s*(\\w+[.])*\\w+)*\\s*=([^=>~]|$)" @@ -538,7 +578,7 @@ or most optimal searcher." :regex "(^|\\W)alias(_method)?\\W+JJJ(\\W|$)" :tests ("alias test some_method" "alias_method :test, :some_method" - "alias_method ’test’ ’some_method’" + "alias_method 'test' 'some_method'" "some_class.send(:alias_method, :test, :some_method)") :not ("alias some_method test" "alias_method :some_method, :test" @@ -625,8 +665,8 @@ or most optimal searcher." ;; perl (:type "function" :supports ("ag" "grep" "rg" "git-grep") :language "perl" - :regex "sub\\s*JJJ\\s*\\\{" - :tests ("sub test{" "sub test {")) + :regex "sub\\s*JJJ\\s*(\\{|\\()" + :tests ("sub test{" "sub test {" "sub test(" "sub test (")) (:type "variable" :supports ("ag" "grep" "rg" "git-grep") :language "perl" :regex "JJJ\\s*=\\s*" @@ -675,6 +715,15 @@ or most optimal searcher." :regex "class\\s*JJJ\\s*(extends|implements|\\\{)" :tests ("class test{" "class test {" "class test extends foo" "class test implements foo")) + ;; dart + (:type "function" :supports ("ag" "grep" "rg" "git-grep") :language "dart" + :regex "\\bJJJ\\s*\\([^()]*\\)\\s*[{]" + :tests ("test(foo) {" "test (foo){" "test(foo){")) + + (:type "function" :supports ("ag" "grep" "rg" "git-grep") :language "dart" + :regex "class\\s*JJJ\\s*[\\\(\\\{]" + :tests ("class test(object) {" "class test{")) + ;; faust (:type "function" :supports ("ag" "grep" "rg" "git-grep") :language "faust" :regex "\\bJJJ\(\\\(.+\\\)\)*\\s*=" @@ -687,19 +736,23 @@ or most optimal searcher." :not ("if (test == 1234)")) (:type "function" :supports ("ag" "grep" "rg" "git-grep") :language "fortran" - :regex "\\b(function|subroutine)\\s+JJJ\\b\\s*\\\(" - :tests ("function test (foo)" "integer function test(foo)" "subroutine test (foo, bar)") - :not ("end function test" "end subroutine test")) + :regex "\\b(function|subroutine|FUNCTION|SUBROUTINE)\\s+JJJ\\b\\s*\\\(" + :tests ("function test (foo)" "integer function test(foo)" + "subroutine test (foo, bar)" "FUNCTION test (foo)" + "INTEGER FUNCTION test(foo)" "SUBROUTINE test (foo, bar)") + :not ("end function test" "end subroutine test" "END FUNCTION test" + "END SUBROUTINE test")) (:type "function" :supports ("ag" "grep" "rg" "git-grep") :language "fortran" - :regex "^\\s*interface\\s+JJJ\\b" - :tests ("interface test") - :not ("interface test2" "end interface test")) + :regex "^\\s*(interface|INTERFACE)\\s+JJJ\\b" + :tests ("interface test" "INTERFACE test") + :not ("interface test2" "end interface test" "INTERFACE test2" + "END INTERFACE test")) (:type "type" :supports ("ag" "grep" "rg" "git-grep") :language "fortran" - :regex "^\\s*module\\s+JJJ\\s*" - :tests ("module test") - :not ("end module test")) + :regex "^\\s*(module|MODULE)\\s+JJJ\\s*" + :tests ("module test" "MODULE test") + :not ("end module test" "END MODULE test")) ;; go (:type "variable" :supports ("ag" "grep" "rg" "git-grep") :language "go" @@ -783,11 +836,11 @@ or most optimal searcher." :regex "const\\s+JJJ\\b" :tests ("const test = ")) - (:type "type" :supports ("ag","rg") :language "julia" + (:type "type" :supports ("ag" "rg") :language "julia" :regex "(mutable)?\\s*struct\\s*JJJ" :tests ("struct test")) - (:type "type" :supports ("ag","rg") :language "julia" + (:type "type" :supports ("ag" "rg") :language "julia" :regex "(type|immutable|abstract)\\s*JJJ" :tests ("type test" "immutable test" "abstract test <:Testable" )) @@ -1130,7 +1183,7 @@ or most optimal searcher." (:type "type" :supports ("ag" "grep" "rg" "git-grep") :language "systemverilog" :regex "\\s*class\\s+\\bJJJ\\b" :tests ("virtual class test;" "class test;" "class test extends some_class") - :not ("virtual class testing;" "class test2;")) + :not ("virtual class testing;" "class test2;" "class some_test" "class some_class extends test")) (:type "type" :supports ("ag" "grep" "rg" "git-grep") :language "systemverilog" :regex "\\s*task\\s+\\bJJJ\\b" @@ -1147,6 +1200,12 @@ or most optimal searcher." :tests ("function Matrix test ;" "function Matrix test;") :not ("function test blah")) + ;; matches SV class handle declarations + (:type "function" :supports ("ag" "rg" "git-grep") :language "systemverilog" + :regex "^\\s*[^\\s]*\\s*[^\\s]+\\s+\\bJJJ\\b" + :tests ("some_class_name test" " another_class_name test ;" "some_class test[];" "some_class #(1) test") + :not ("test some_class_name" "class some_class extends test")) + ;; vhdl (:type "type" :supports ("ag" "grep" "rg" "git-grep") :language "vhdl" :regex "\\s*type\\s+\\bJJJ\\b" @@ -1232,6 +1291,8 @@ or most optimal searcher." (defcustom dumb-jump-language-file-exts '((:language "elisp" :ext "el" :agtype "elisp" :rgtype "elisp") (:language "elisp" :ext "el.gz" :agtype "elisp" :rgtype "elisp") + (:language "commonlisp" :ext "lisp" :agtype "lisp" :rgtype "lisp") + (:language "commonlisp" :ext "lsp" :agtype "lisp" :rgtype "lisp") (:language "c++" :ext "c" :agtype "cc" :rgtype "c") (:language "c++" :ext "h" :agtype "cc" :rgtype "c") (:language "c++" :ext "C" :agtype "cpp" :rgtype "cpp") @@ -1272,6 +1333,9 @@ or most optimal searcher." (:language "fortran" :ext "f77" :agtype "fortran" :rgtype "fortran") (:language "fortran" :ext "f90" :agtype "fortran" :rgtype "fortran") (:language "fortran" :ext "f95" :agtype "fortran" :rgtype "fortran") + (:language "fortran" :ext "F77" :agtype "fortran" :rgtype "fortran") + (:language "fortran" :ext "F90" :agtype "fortran" :rgtype "fortran") + (:language "fortran" :ext "F95" :agtype "fortran" :rgtype "fortran") (:language "fortran" :ext "f03" :agtype "fortran" :rgtype "fortran") (:language "fortran" :ext "for" :agtype "fortran" :rgtype "fortran") (:language "fortran" :ext "ftn" :agtype "fortran" :rgtype "fortran") @@ -1282,10 +1346,10 @@ or most optimal searcher." (:language "javascript" :ext "vue" :agtype "js" :rgtype "js") (:language "javascript" :ext "html" :agtype "html" :rgtype "html") (:language "javascript" :ext "css" :agtype "css" :rgtype "css") - (:language "lisp" :ext "lisp" :agtype "lisp" :rgtype "lisp") - (:language "lisp" :ext "lsp" :agtype "lisp" :rgtype "lisp") + (:language "dart" :ext "dart" :agtype nil :rgtype "dart") (:language "lua" :ext "lua" :agtype "lua" :rgtype "lua") (:language "nim" :ext "nim" :agtype "nim" :rgtype "nim") + (:language "nix" :ext "nix" :agtype "nix" :rgtype "nix") (:language "org" :ext "org" :agtype nil :rgtype "org") (:language "perl" :ext "pl" :agtype "perl" :rgtype "perl") (:language "perl" :ext "pm" :agtype "perl" :rgtype "perl") @@ -1432,12 +1496,27 @@ If `nil` always show list of more than 1 match." (s-contains? "ag version" (shell-command-to-string (concat dumb-jump-ag-cmd " --version")))) dumb-jump--ag-installed?)) +(defvar dumb-jump--git-grep-plus-ag-installed? 'unset) +(defun dumb-jump-git-grep-plus-ag-installed? () + "Return t if git grep and ag is installed." + (if (eq dumb-jump--git-grep-plus-ag-installed? 'unset) + (setq dumb-jump--git-grep-plus-ag-installed? + (and (dumb-jump-git-grep-installed?) (dumb-jump-ag-installed?))) + dumb-jump--git-grep-plus-ag-installed?)) + (defvar dumb-jump--rg-installed? 'unset) (defun dumb-jump-rg-installed? () "Return t if rg is installed." (if (eq dumb-jump--rg-installed? 'unset) (setq dumb-jump--rg-installed? - (s-contains? "ripgrep" (shell-command-to-string (concat dumb-jump-rg-cmd " --version")))) + (let ((result (s-match "ripgrep \\([0-9]+\\)\\.\\([0-9]+\\).*" + (shell-command-to-string (concat dumb-jump-rg-cmd " --version"))))) + (when (equal (length result) 3) + (let ((major (string-to-number (nth 1 result))) + (minor (string-to-number (nth 2 result)))) + (or + (and (= major 0) (>= minor 10)) + (>= major 1)))))) dumb-jump--rg-installed?)) (defvar dumb-jump--git-grep-installed? 'unset) @@ -1548,7 +1627,7 @@ Optionally pass t for RUN-NOT-TESTS to see a list of all failed rules" (lambda (rule) (-mapcat (lambda (test) - (let* ((cmd (concat "rg --color never --no-heading " + (let* ((cmd (concat "rg --color never --no-heading -U --pcre2 " (shell-quote-argument (dumb-jump-populate-regex (plist-get rule :regex) "test" 'rg)))) (resp (dumb-jump-run-test test cmd))) (when (or @@ -1635,9 +1714,7 @@ Ignore PROJ" (defun dumb-jump-prompt-user-for-choice (proj results) "Put a PROJ's list of RESULTS in a 'popup-menu' (or helm/ivy) for user to select. Filters PROJ path from files for display." - (let* ((choices (-map (lambda (result) - (dumb-jump--format-result proj result)) - results))) + (let ((choices (--map (dumb-jump--format-result proj it) results))) (cond ((and (eq dumb-jump-selector 'ivy) (fboundp 'ivy-read)) (funcall dumb-jump-ivy-jump-to-selected-function results choices proj)) @@ -1745,8 +1822,12 @@ to keep looking for another root." (cond ((and (string= lang "clojure") (s-contains? "/" look-for)) (nth 1 (s-split "/" look-for))) + ((and (string= lang "ruby") (s-contains? "::" look-for)) + (-last-item (s-split "::" look-for))) ((and (or (string= lang "ruby") (string= lang "crystal")) (s-starts-with? ":" look-for)) (s-chop-prefix ":" look-for)) + ((and (string= lang "systemverilog") (s-starts-with? "`" look-for)) + (s-chop-prefix "`" look-for)) (t look-for))) @@ -1813,7 +1894,7 @@ of project configuraiton." cur-line-num parse-fn generate-fn) search-paths)) - (results (--map (plist-put it :target look-for) raw-results))) + (results (delete-dups (--map (plist-put it :target look-for) raw-results)))) `(:results ,results :lang ,(if (null lang) "" lang) :symbol ,look-for :ctx-type ,(if (null ctx-type) "" ctx-type) :file ,cur-file :root ,proj-root))) @@ -1905,7 +1986,9 @@ current file." (defcustom dumb-jump-language-comments '((:comment "//" :language "c++") (:comment ";" :language "elisp") + (:comment ";" :language "commonlisp") (:comment "//" :language "javascript") + (:comment "//" :language "dart") (:comment "--" :language "haskell") (:comment "--" :language "lua") (:comment "//" :language "rust") @@ -1918,7 +2001,6 @@ current file." (:comment "//" :language "faust") (:comment "!" :language "fortran") (:comment "//" :language "go") - (:comment ";" :language "lisp") (:comment "#" :language "perl") (:comment "//" :language "php") (:comment "#" :language "python") @@ -1926,6 +2008,7 @@ current file." (:comment "#" :language "ruby") (:comment "#" :language "crystal") (:comment "#" :language "nim") + (:comment "#" :language "nix") (:comment "//" :language "scala") (:comment ";" :language "scheme") (:comment "#" :language "shell") @@ -2049,9 +2132,13 @@ PREFER-EXTERNAL will sort current file last." (dumb-jump-message "-----\nDUMB JUMP DEBUG `dumb-jump-handle-results` START\n----- \n\nlook for: \n\t%s\n\ntype: \n\t%s \n\njump? \n\t%s \n\nmatches: \n\t%s \n\nresults: \n\t%s \n\nprefer external: \n\t%s\n\nmatch-cur-file-front: \n\t%s\n\nproj-root: \n\t%s\n\ncur-file: \n\t%s\n\nreal-cur-file: \n\t%s \n\n-----\nDUMB JUMP DEBUG `dumb-jump-handle-results` END\n-----\n" look-for ctx-type var-to-jump (pp-to-string match-cur-file-front) (pp-to-string results) prefer-external match-cur-file-front proj-root cur-file rel-cur-file)) - (if do-var-jump - (dumb-jump-result-follow var-to-jump use-tooltip proj-root) - (dumb-jump-prompt-user-for-choice proj-root match-cur-file-front)))) + (cond + (use-tooltip ;; quick-look mode + (popup-menu* (--map (dumb-jump--format-result proj-root it) results))) + (do-var-jump + (dumb-jump-result-follow var-to-jump use-tooltip proj-root)) + (t + (dumb-jump-prompt-user-for-choice proj-root match-cur-file-front))))) (defun dumb-jump-read-config (root config-file) "Load and return options (exclusions, inclusions, etc). @@ -2171,6 +2258,11 @@ searcher symbol." :generate ,'dumb-jump-generate-ag-command :installed ,'dumb-jump-ag-installed? :searcher ,searcher)) + ((equal 'git-grep-plus-ag searcher) + `(:parse ,'dumb-jump-parse-ag-response + :generate ,'dumb-jump-generate-git-grep-plus-ag-command + :installed ,'dumb-jump-git-grep-plus-ag-installed? + :searcher ,searcher)) ((equal 'rg searcher) `(:parse ,'dumb-jump-parse-rg-response :generate ,'dumb-jump-generate-rg-command @@ -2371,6 +2463,7 @@ searcher symbol." "Populate IT regex template with LOOK-FOR." (let ((boundary (cond ((eq variant 'rg) dumb-jump-rg-word-boundary) ((eq variant 'ag) dumb-jump-ag-word-boundary) + ((eq variant 'git-grep-plus-ag) dumb-jump-ag-word-boundary) ((eq variant 'git-grep) dumb-jump-git-grep-word-boundary) (t dumb-jump-grep-word-boundary)))) (let ((text it)) @@ -2397,6 +2490,8 @@ searcher symbol." (if (s-ends-with? ".gz" cur-file) " --search-zip" "") + (when (not (s-blank? dumb-jump-ag-search-args)) + (concat " " dumb-jump-ag-search-args)) (s-join "" (--map (format " --%s" it) agtypes)))) (exclude-args (dumb-jump-arg-joiner "--ignore-dir" (--map (shell-quote-argument (s-replace proj-dir "" it)) exclude-paths))) @@ -2405,13 +2500,54 @@ searcher symbol." "" (dumb-jump-concat-command cmd exclude-args regex-args proj)))) +(defun dumb-jump-get-git-grep-files-matching-symbol (symbol proj-root) + "Search for the literal SYMBOL in the PROJ-ROOT via git grep for a list of file matches." + (let* ((cmd (format "git grep --full-name -F -c %s %s" (shell-quote-argument symbol) proj-root)) + (result (s-trim (shell-command-to-string cmd))) + (matched-files (--map (first (s-split ":" it)) + (s-split "\n" result)))) + matched-files)) + +(defun dumb-jump-format-files-as-ag-arg (files proj-root) + "Take a list of FILES and their PROJ-ROOT and return a `ag -G` argument." + (format "'(%s)'" (s-join "|" (--map (f-join proj-root it) files)))) + +(defun dumb-jump-get-git-grep-files-matching-symbol-as-ag-arg (symbol proj-root) + "Get the files matching the SYMBOL via `git grep` in the PROJ-ROOT and return them formatted for `ag -G`." + (dumb-jump-format-files-as-ag-arg + (dumb-jump-get-git-grep-files-matching-symbol symbol proj-root) + proj-root)) + +;; git-grep plus ag only recommended for huge repos like the linux kernel +(defun dumb-jump-generate-git-grep-plus-ag-command (look-for cur-file proj regexes lang exclude-paths) + "Generate the ag response based on the needle LOOK-FOR in the directory PROJ. +Using ag to search only the files found via git-grep literal symbol search." + (let* ((filled-regexes (dumb-jump-populate-regexes look-for regexes 'ag)) + (proj-dir (file-name-as-directory proj)) + (ag-files-arg (dumb-jump-get-git-grep-files-matching-symbol-as-ag-arg look-for proj-dir)) + (cmd (concat dumb-jump-ag-cmd + " --nocolor --nogroup" + (if (s-ends-with? ".gz" cur-file) + " --search-zip" + "") + " -G " ag-files-arg + " ")) + (exclude-args (dumb-jump-arg-joiner + "--ignore-dir" (--map (shell-quote-argument (s-replace proj-dir "" it)) exclude-paths))) + (regex-args (shell-quote-argument (s-join "|" filled-regexes)))) + (if (= (length regexes) 0) + "" + (dumb-jump-concat-command cmd exclude-args regex-args proj)))) + (defun dumb-jump-generate-rg-command (look-for cur-file proj regexes lang exclude-paths) "Generate the rg response based on the needle LOOK-FOR in the directory PROJ." (let* ((filled-regexes (dumb-jump-populate-regexes look-for regexes 'rg)) (rgtypes (dumb-jump-get-rg-type-by-language lang)) (proj-dir (file-name-as-directory proj)) (cmd (concat dumb-jump-rg-cmd - " --color never --no-heading --line-number" + " --color never --no-heading --line-number -U" + (when (not (s-blank? dumb-jump-rg-search-args)) + (concat " " dumb-jump-rg-search-args)) (s-join "" (--map (format " --type %s" it) rgtypes)))) (exclude-args (dumb-jump-arg-joiner "-g" (--map (shell-quote-argument (concat "!" (s-replace proj-dir "" it))) exclude-paths))) @@ -2426,9 +2562,10 @@ searcher symbol." (ggtypes (when (f-ext cur-file) (dumb-jump-get-git-grep-type-by-language lang))) (cmd (concat dumb-jump-git-grep-cmd " --color=never --line-number" - (if dumb-jump-git-grep-search-untracked - " --untracked" - "") + (when dumb-jump-git-grep-search-untracked + " --untracked") + (when (not (s-blank? dumb-jump-git-grep-search-args)) + (concat " " dumb-jump-git-grep-search-args)) " -E")) (fileexps (s-join " " (--map (shell-quote-argument (format "%s/*.%s" proj it)) ggtypes))) (exclude-args (s-join " " @@ -2509,6 +2646,7 @@ searcher symbol." (let* ((searcher-str (cond ((eq 'git-grep searcher) "git-grep") ((eq 'rg searcher) "rg") ((eq 'ag searcher) "ag") + ((eq 'git-grep-plus-ag searcher) "ag") (t "grep"))) (results (--filter (and (string= (plist-get it ':language) language) diff --git a/packages/dune-20190808.345.tar b/packages/dune-20190808.345.tar new file mode 100644 index 0000000..ac3664e Binary files /dev/null and b/packages/dune-20190808.345.tar differ diff --git a/packages/eclim-20181108.1134.tar b/packages/eclim-20181108.1134.tar index 66a4f35..fd4589c 100644 Binary files a/packages/eclim-20181108.1134.tar and b/packages/eclim-20181108.1134.tar differ diff --git a/packages/ediprolog-1.2.el b/packages/ediprolog-1.2.el new file mode 100644 index 0000000..504bb0f --- /dev/null +++ b/packages/ediprolog-1.2.el @@ -0,0 +1,652 @@ +;;; ediprolog.el --- Emacs Does Interactive Prolog + +;; Copyright (C) 2006-2009, 2012-2013, 2016-2017 Free Software Foundation, Inc. + +;; Author: Markus Triska +;; Keywords: languages, processes +;; Version: 1.2 +;; Homepage: https://www.metalevel.at/ediprolog/ + +;; 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 file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; These definitions let you interact with SWI-Prolog in all buffers. +;; You can consult Prolog programs and evaluate embedded queries. + +;; Installation +;; ============ +;; +;; Copy ediprolog.el to your load-path and add to your .emacs: +;; +;; (require 'ediprolog) +;; (global-set-key [f10] 'ediprolog-dwim) +;; +;; Restart Emacs and customize ediprolog with +;; +;; M-x customize-group RET ediprolog RET +;; + +;; Usage +;; ===== +;; +;; The central function is `ediprolog-dwim' (Do What I Mean), which is +;; bound to F10 by the snippet above. Depending on the content at +;; point, `ediprolog-dwim' does the "appropriate" thing: If point is +;; on a query, F10 sends the query to a Prolog process, and you +;; interact with the process in the current buffer as on a terminal. +;; Queries start with "?-" or ":-", possibly preceded by "%" and +;; whitespace. An example of a query is (without leading ";;"): +;; +;; %?- member(X, [a,b,c]). +;; +;; If you press F10 when point is on that query, you get: +;; +;; %?- member(X, [a,b,c]). +;; %@ X = a ; +;; %@ X = b ; +;; %@ X = c ; +;; %@ false. +;; +;; When waiting for output of the Prolog process, you can press C-g to +;; unblock Emacs and continue with other work. To resume interaction +;; with the Prolog process, use M-x ediprolog-toplevel RET. + +;; If you press F10 when point is *not* on a query, the buffer content +;; is consulted in the Prolog process, and point is moved to the first +;; error (if any). In transient mark mode, if the region is active, +;; only the text in the region is consulted. + +;; For convenience, the most recent interactions with the Prolog +;; process are logged in the buffer "*ediprolog-history*". + +;; Use M-x ediprolog-localize RET to make any Prolog process started +;; in the current buffer buffer-local. This way, you can run distinct +;; processes simultaneously. Revert with M-x ediprolog-unlocalize RET. + +;; `ediprolog-dwim' with prefix arguments has special meanings: +;; +;; C-0 F10 kill Prolog process +;; C-1 F10 always consult buffer (even when point is on a query) +;; C-2 F10 always consult buffer, using a new process +;; C-7 F10 equivalent to `ediprolog-toplevel' +;; C-u F10 first consult buffer, then evaluate query (if any) +;; C-u C-u F10 like C-u F10, with a new process + +;; Tested with SWI-Prolog 7.3.21 + Emacs 22.1, 23.4, 24.5, 25.1 and 26.0 + +;;; Code: + +(defconst ediprolog-version "1.2") + +(defgroup ediprolog nil + "Transparent interaction with SWI-Prolog." + :group 'languages + :group 'processes) + +(defcustom ediprolog-program + (or (executable-find "swipl") (executable-find "pl") "swipl") + "Program name of the Prolog executable." + :group 'ediprolog + :type 'string) + +(defcustom ediprolog-program-switches nil + "List of switches passed to the Prolog process. Example: +'(\"-G128M\" \"-O\")" + :group 'ediprolog + :type '(repeat string)) + +(defcustom ediprolog-prefix "%@ " + "String to prepend when inserting output from the Prolog +process into the buffer." + :group 'ediprolog + :type 'string) + +(defcustom ediprolog-max-history 80000 + "Maximal size of history buffers storing recent interactions, or +nil to never truncate the history." + :group 'ediprolog + :type 'sexp) + +(defvar ediprolog-process nil "A Prolog process.") + +(defvar ediprolog-temp-buffer nil + "Buffer that temporarily saves process output ") + +(defvar ediprolog-seen-prompt nil + "Whether a prompt was (recently) emitted by the Prolog process.") + +(defvar ediprolog-read-term nil + "Whether the Prolog process waits for the user to enter a term.") + +(defvar ediprolog-indent-prefix "" + "Any whitespace occurring before the most recently executed query.") + +(defvar ediprolog-temp-file nil + "File name of a temporary file used for consulting the buffer.") + +(defvar ediprolog-prompt "?ediprolog- " + "Prompt used in the Prolog session. It must differ from the +default Prolog prompt.") + +(defvar ediprolog-consult-buffer "*ediprolog-consult*" + "Buffer used to display consult output.") + +(defvar ediprolog-consult-window nil + "Window used to show consult output.") + +(defvar ediprolog-history-buffer nil + "Buffer that stores recent interactions.") + +(defvar ediprolog-interrupted nil + "True iff waiting for the previous query was interrupted with C-g.") + +(defmacro ediprolog-wait-for-prompt-after (&rest forms) + "Evaluate FORMS and wait for prompt." + `(progn + (setq ediprolog-seen-prompt nil) + (ediprolog-ensure-buffer "temp") + (with-current-buffer ediprolog-temp-buffer + (let (buffer-read-only) + (erase-buffer))) + ;; execute forms with default-directory etc. from invocation buffer + ,@forms + (while (not ediprolog-seen-prompt) + ;; Wait for output/sentinel and update consult window, if any. + ;; As `accept-process-output' does not run the sentinel in + ;; Emacs <= 23.1, we use `sit-for' to do both. However, + ;; `sit-for' returns immediately if keyboard input is + ;; available, so we must discard input. + (discard-input) + (sit-for 0.1)))) + +(defmacro ediprolog-remember-interruption (form) + "Set `ediprolog-interrupted' if evaluation of FORM was interrupted." + `(condition-case nil + ,form + (quit (setq ediprolog-interrupted t)))) + +;; Only the sentinel can reliably detect if no more output follows - +;; even if process-status is 'exit, further output can still follow. +(defun ediprolog-sentinel (proc str) + (when (buffer-live-p (process-buffer proc)) + (with-current-buffer (process-buffer proc) + (let ((status (with-temp-buffer + (insert str) + (while (search-backward "\n" nil t) + (replace-match "")) + (buffer-string)))) + (ediprolog-log + (format "%s: %s.\n" + (substring (current-time-string) 4 -5) status) "green" t)) + (when (string-match "^\\(?:finished\n\\|exited abnormally\\|killed\n\\)" + str) + (setq ediprolog-seen-prompt t))))) + +(defun ediprolog-ensure-buffer (name) + (let ((str (format "*ediprolog-%s*" name)) + (var (intern (format "ediprolog-%s-buffer" name)))) + (unless (buffer-live-p (symbol-value var)) + (set var (generate-new-buffer str)) + (with-current-buffer (symbol-value var) + (buffer-disable-undo) + (setq buffer-read-only t))))) + +(defun ediprolog-log (str &optional col nl) + (ediprolog-ensure-buffer "history") + (with-current-buffer ediprolog-history-buffer + (let (buffer-read-only) + (goto-char (point-max)) + (let ((s (format "%s%s" (if (and nl (not (bolp))) "\n" "") str))) + (insert (if col (propertize s 'face `(:background ,col)) s))) + (let ((size (- (point-max) (point-min)))) + (when (and ediprolog-max-history + (> size ediprolog-max-history)) + ;; delete older half of the (possibly narrowed) history + (delete-region (point-min) (+ (point-min) (/ size 2)))))))) + +(defun ediprolog-run-prolog () + "Start a Prolog process." + (let ((args (cons ediprolog-program ediprolog-program-switches))) + (ediprolog-log (format "%s: starting: %S\n" + (substring (current-time-string) 4 -5) args) + "green" t) + (condition-case nil + (ediprolog-wait-for-prompt-after + (setq ediprolog-process + (apply #'start-process "ediprolog" (current-buffer) args)) + (set-process-sentinel ediprolog-process 'ediprolog-sentinel) + (set-process-filter ediprolog-process + 'ediprolog-wait-for-prompt-filter) + (ediprolog-send-string + (format "set_prolog_flag(color_term, false),\ + '$set_prompt'('%s').\n" ediprolog-prompt))) + ((error quit) + (ediprolog-log "No prompt found." "red" t) + (error "No prompt from: %s" ediprolog-program))))) + +(defun ediprolog-kill-prolog () + "Kill the Prolog process and run the process sentinel." + (when (ediprolog-running) + (delete-process ediprolog-process))) + +(defun ediprolog-show-consult-output (str) + (with-current-buffer (get-buffer-create ediprolog-consult-buffer) + (setq buffer-read-only t) + (let (buffer-read-only) + (erase-buffer) + (insert str) + (goto-char (point-min)) + ;; remove normal consult status lines, which start with "%" + (while (re-search-forward "^[\t ]*%.*\n" nil t) + (delete-region (match-beginning 0) (match-end 0)))) + (setq str (buffer-string))) + ;; show consult output in a separate window unless it is a prefix of + ;; success (i.e., consulted without errors), or still an incomplete + ;; line that starts with a comment character + (unless (or (string-match "^[\t ]*\\(?:%.*\\)?\\'" str) + (let ((success "true.")) + (and (<= (length str) (length success)) + (string= str (substring success 0 (length str)))))) + (setq ediprolog-consult-window (display-buffer ediprolog-consult-buffer)) + (set-window-dedicated-p ediprolog-consult-window t) + (fit-window-to-buffer ediprolog-consult-window (/ (frame-height) 2)))) + +(defun ediprolog-consult-filter (proc str) + "Filter used when consulting a file, showing consult output." + (with-current-buffer (ediprolog-temp-buffer proc) + (goto-char (point-max)) + (let (buffer-read-only) + (insert str)) + (with-current-buffer (process-buffer proc) + (ediprolog-log str)) + (when (re-search-backward + (format "^%s" (regexp-quote ediprolog-prompt)) nil t) + (with-current-buffer (process-buffer proc) + (setq ediprolog-seen-prompt t))) + (skip-chars-backward "\n") + (ediprolog-show-consult-output (buffer-substring (point-min) (point))))) + +(defun ediprolog-wait-for-prompt-filter (proc str) + "Filter that only waits until prompt appears." + (with-current-buffer (ediprolog-temp-buffer proc) + (goto-char (point-max)) + (let (buffer-read-only) + (insert str)) + (with-current-buffer (process-buffer proc) + (ediprolog-log str)) + (when (re-search-backward + (format "^%s" (regexp-quote ediprolog-prompt)) nil t) + (with-current-buffer (process-buffer proc) + (setq ediprolog-seen-prompt t))))) + + +;;;###autoload +(defun ediprolog-dwim (&optional arg) + "Load current buffer into Prolog or post query (Do What I Mean). +If invoked on a line starting with `:-' or `?-', possibly +preceded by `%' and whitespace, call `ediprolog-interact' with +the query as argument. Otherwise, call `ediprolog-consult'. + +With prefix argument 0, kill the Prolog process. With prefix 1, +equivalent to `ediprolog-consult'. With prefix 2, equivalent to +`ediprolog-consult' with a new Prolog process. With prefix 7, +equivalent to `ediprolog-toplevel'. With just C-u, first call +`ediprolog-consult' and then, if point is on a query, call +`ediprolog-interact' with it as argument. Analogously, C-u C-u +for `ediprolog-consult' with a new process. With other prefix +arguments, equivalent to `ediprolog-remove-interactions'." + (interactive "P") + (cond ((eq arg 0) + (unless (ediprolog-running) + (error "No Prolog process running")) + (ediprolog-kill-prolog) + (message "Prolog process killed.")) + ((eq arg 1) (ediprolog-consult)) + ((eq arg 2) (ediprolog-consult t)) + ((eq arg 7) + (unless (ediprolog-more-solutions) + (error "No query in progress")) + (ediprolog-toplevel)) + ((equal arg '(4)) (ediprolog-consult) (ediprolog-query)) + ((equal arg '(16)) (ediprolog-consult t) (ediprolog-query)) + ((null arg) (unless (ediprolog-query) (ediprolog-consult))) + (t (ediprolog-remove-interactions)))) + +(defun ediprolog-process-ready () + "Error if the previous query is still in progress." + (when (and ediprolog-interrupted + (ediprolog-running) + (ediprolog-more-solutions)) + (error "Previous query still in progress, see `ediprolog-toplevel'")) + (setq ediprolog-interrupted nil)) + +(defun ediprolog-query () + "If point is on a query, send it to the process and start interaction." + (ediprolog-process-ready) + (when (and (not (and transient-mark-mode mark-active)) + (save-excursion + (beginning-of-line) + (looking-at "\\([\t ]*\\)%*[\t ]*[:?]-"))) + ;; whitespace preceding the query is the indentation level + (setq ediprolog-indent-prefix (match-string 1)) + (let* ((from (goto-char (match-end 0))) + (to (if (re-search-forward "\\.[\t ]*\\(?:%.*\\)?$" nil t) + ;; omit trailing whitespace + (+ (point) (skip-chars-backward "\t ")) + (error "Missing `.' at the end of this query"))) + (query (buffer-substring-no-properties from to)) + (handle (and (fboundp 'prepare-change-group) + (fboundp 'undo-amalgamate-change-group) + (cons t (prepare-change-group))))) + (end-of-line) + (insert "\n" ediprolog-indent-prefix ediprolog-prefix) + (ediprolog-interact + (format "%s\n" (mapconcat #'identity + ;; `%' can precede each query line + (split-string query "\n[ \t%]*") " "))) + (when handle + (undo-amalgamate-change-group (cdr handle)))) + t)) + +;;;###autoload +(defun ediprolog-interact (query) + "Send QUERY to Prolog process and interact as on a terminal. + +You can use \\[keyboard-quit] to unblock Emacs in the case of +longer-running queries. When the query completes and the toplevel +asks for input, use \\[ediprolog-toplevel] to resume interaction +with the Prolog process." + (unless (ediprolog-running) + (ediprolog-run-prolog)) + (set-marker (process-mark ediprolog-process) (point)) + (set-process-buffer ediprolog-process (current-buffer)) + (set-process-filter ediprolog-process 'ediprolog-interact-filter) + (ediprolog-ensure-buffer "temp") + (with-current-buffer ediprolog-temp-buffer + (let (buffer-read-only) + (erase-buffer))) + (setq ediprolog-seen-prompt nil + ediprolog-read-term nil) + (ediprolog-send-string query) + (ediprolog-toplevel)) + +(defun ediprolog-send-string (str) + "Send string to Prolog process and log it." + (ediprolog-log str "cyan") + (process-send-string ediprolog-process str)) + +(defun ediprolog-toplevel () + "Start or resume Prolog toplevel interaction in the buffer. + +You can use this function if you have previously quit (with +\\[keyboard-quit]) waiting for a longer-running query and now +want to resume interaction with the toplevel." + (interactive) + (when ediprolog-process + (select-window (display-buffer (process-buffer ediprolog-process)))) + (ediprolog-remember-interruption + (while (ediprolog-more-solutions) + (let (str + char) + ;; poll for user input; meanwhile, process output can arrive + (while (and (ediprolog-more-solutions) (null str)) + (goto-char (process-mark ediprolog-process)) + (if ediprolog-read-term + (progn + (setq str (concat (read-string "Input: ") "\n")) + (ediprolog-insert-at-marker + str ediprolog-indent-prefix ediprolog-prefix) + (setq ediprolog-read-term nil)) + (condition-case nil + (when (setq char (if (>= emacs-major-version 22) + (read-char nil nil 0.1) + (with-timeout (0.1 nil) + (read-char)))) + ;; char-to-string might still yield an error (C-0 etc.) + (setq str (char-to-string char))) + (error + (message "Non-character key") + ;; non-character keys must not remain in the input + ;; buffer, lest `read-char' return immediately + (discard-input))))) + (when (ediprolog-more-solutions) + (if (eq char ?\C-c) ; char can be nil too + ;; sending C-c directly yields strange SWI buffering + (interrupt-process ediprolog-process) + (ediprolog-send-string str))))))) + +;;;###autoload +(defun ediprolog-remove-interactions () + "Remove all lines starting with `ediprolog-prefix' from buffer. + +In transient mark mode, if the region is active, the function +operates on the region." + (interactive) + (save-excursion + (save-restriction + (when (and transient-mark-mode mark-active) + (narrow-to-region (region-beginning) (region-end))) + (goto-char (point-min)) + (flush-lines (concat "^[\t ]*" (regexp-quote ediprolog-prefix))))) + (message "Interactions removed.")) + + +;;;###autoload +(defun ediprolog-consult (&optional new-process) + "Buffer is loaded into a Prolog process. If NEW-PROCESS is +non-nil, start a new process. Otherwise use the existing process, +if any. In case of errors, point is moved to the position of the +first error, and the mark is left at the previous position. + +In transient mark mode, if the region is active, the function +operates on the region." + (interactive) + (when (string= (buffer-name) ediprolog-consult-buffer) + (error "Cannot consult the consult buffer")) + (when (window-live-p ediprolog-consult-window) + (condition-case nil + ;; deleting the window can still raise an error, if the window + ;; was the only window in the frame and the consult buffer was + ;; killed (and it thus displays a different buffer now) + (delete-window ediprolog-consult-window) + (error nil))) + (when (buffer-live-p ediprolog-consult-buffer) + (bury-buffer ediprolog-consult-buffer)) + (when new-process + (ediprolog-kill-prolog)) + (unless (ediprolog-running) + (ediprolog-run-prolog)) + (ediprolog-process-ready) + (set-process-buffer ediprolog-process (current-buffer)) + (unless ediprolog-temp-file + (setq ediprolog-temp-file (make-temp-file "ediprolog"))) + (let ((start (if (and transient-mark-mode mark-active) + (region-beginning) (point-min))) + (end (if (and transient-mark-mode mark-active) + (region-end) (point-max)))) + (write-region start end ediprolog-temp-file nil 'silent)) + (set-process-filter ediprolog-process 'ediprolog-consult-filter) + (ediprolog-remember-interruption + (ediprolog-wait-for-prompt-after + (ediprolog-send-string (format "['%s'].\n" ediprolog-temp-file)))) + (message "%s consulted." (if (and transient-mark-mode mark-active) + "Region" "Buffer")) + ;; go to line of the first error, if any + (let ((line (with-current-buffer ediprolog-temp-buffer + (when (save-excursion + (goto-char (point-min)) + (re-search-forward "^ERROR.*?:\\([0-9]+\\)" nil t)) + (string-to-number (match-string 1)))))) + (when line + (if (and transient-mark-mode mark-active) + (when (fboundp 'line-number-at-pos) + (goto-line (+ (line-number-at-pos (region-beginning)) line -1))) + (goto-line line))))) + +(defun ediprolog-running () + "True iff `ediprolog-process' is a running process." + (and (processp ediprolog-process) + (eq (process-status ediprolog-process) 'run))) + +(defun ediprolog-more-solutions () + "True iff there could be more solutions from the process." + (not ediprolog-seen-prompt)) + +(defun ediprolog-interact-filter (proc string) + "Insert output from the process and update the state." + (when (and (buffer-live-p (ediprolog-temp-buffer proc)) + (buffer-live-p (process-buffer proc))) + (let (str) + (with-current-buffer (ediprolog-temp-buffer proc) + (goto-char (point-max)) + (let (buffer-read-only) + (insert string)) + (with-current-buffer (process-buffer proc) + (ediprolog-log string)) + ;; read a term from the user? + (when (re-search-backward "^|: $" nil t) + (with-current-buffer (process-buffer proc) + (setq ediprolog-read-term t)) + (setq str (buffer-string)) + (let (buffer-read-only) + (erase-buffer))) + ;; check for prompt + (goto-char (point-max)) + (when (re-search-backward + (format "^%s" (regexp-quote ediprolog-prompt)) nil t) + (with-current-buffer (process-buffer proc) + (setq ediprolog-seen-prompt t)) + ;; ignore further output due to accidental user input (C-j, + ;; C-m, etc.) while the query was running + (set-process-filter proc 'ediprolog-ignore-filter) + (skip-chars-backward "\n") + (setq str (buffer-substring (point-min) (point)))) + (unless str + (goto-char (point-max)) + ;; delay final line if it can still be completed to prompt + (let ((l (buffer-substring (line-beginning-position) (point)))) + (when (and (<= (length l) (length ediprolog-prompt)) + (string= l (substring ediprolog-prompt 0 (length l)))) + (goto-char (line-beginning-position)))) + ;; delay emitting newlines until we are sure no prompt + ;; follows; one or two newlines can precede a prompt + (let ((d (abs (skip-chars-backward "\n")))) + (when (> d 2) + (forward-char (- d 2)))) + (setq str (buffer-substring (point-min) (point))) + (let (buffer-read-only) + (delete-region (point-min) (point)))) + (when str + (with-temp-buffer + ;; precede each line with ediprolog prefices + (insert str) + (goto-char (point-min)) + (while (search-forward "\n" nil t) + (replace-match + (format "\n%s%s" (with-current-buffer (process-buffer proc) + ediprolog-indent-prefix) ediprolog-prefix))) + (setq str (buffer-string))) + (with-current-buffer (process-buffer proc) + (let ((near (<= (abs (- (point) (process-mark proc))) 1))) + (ediprolog-insert-at-marker str) + (when near + ;; catch up with output if point was reasonably close + (goto-char (process-mark proc)))))))))) + + +(defun ediprolog-insert-at-marker (&rest args) + "Insert strings ARGS at marker and update the marker." + (save-excursion + (goto-char (process-mark ediprolog-process)) + (end-of-line) + (apply #'insert args) + (set-marker (process-mark ediprolog-process) (point)))) + +(defun ediprolog-ignore-filter (proc str) + "Log and then ignore all process output." + (with-current-buffer (process-buffer proc) + (ediprolog-log str "gray"))) + +(defun ediprolog-temp-buffer (proc) + (with-current-buffer (process-buffer proc) + ;; temp buffer can be buffer local + ediprolog-temp-buffer)) + +(defun ediprolog-map-variables (func) + "Call FUNC with all ediprolog variables that can become buffer-local." + (mapc func '(ediprolog-process + ediprolog-program + ediprolog-program-switches + ediprolog-temp-buffer + ediprolog-history-buffer + ediprolog-seen-prompt + ediprolog-interrupted + ediprolog-read-term + ediprolog-indent-prefix + ediprolog-temp-file))) + +;;;###autoload +(defun ediprolog-localize () + "After `ediprolog-localize', any Prolog process started from +this buffer becomes buffer-local." + (interactive) + (unless (local-variable-p 'ediprolog-process) + (ediprolog-map-variables #'make-local-variable) + (setq ediprolog-temp-file nil + ediprolog-process nil + ediprolog-history-buffer nil + ediprolog-temp-buffer nil))) + +(defun ediprolog-unlocalize () + "Revert the effect of `ediprolog-localize'." + (interactive) + (when (local-variable-p 'ediprolog-process) + (ediprolog-kill-prolog) + (ediprolog-map-variables #'kill-local-variable))) + +;;;; ChangeLog: + +;; 2017-06-11 Markus Triska +;; +;; * ediprolog/ediprolog.el (ediprolog-version): Bump to 1.2 +;; +;; (ediprolog-query): Use undo-amalgamate-change-group when available. +;; (ediprolog-remove-interactions, ediprolog-consult): Improve docstring. +;; +;; 2016-07-11 Paul Eggert +;; +;; Fix some quoting problems in doc strings +;; +;; Most of these are minor issues involving, e.g., quoting `like this' +;; instead of 'like this'. A few involve escaping ` and ' with a preceding +;; \= when the characters should not be turned into curved single quotes. +;; +;; 2015-09-23 Dmitry Gutov +;; +;; ediprolog: Don't autoload variables +;; +;; 2015-09-23 Dmitry Gutov +;; +;; Update ediprolog to the latest release +;; +;; 2011-12-22 Stefan Monnier +;; +;; Add new package "ediprolog". +;; + + +(provide 'ediprolog) + +;;; ediprolog.el ends here diff --git a/packages/editorconfig-20181115.709.tar b/packages/editorconfig-20190703.336.tar similarity index 81% rename from packages/editorconfig-20181115.709.tar rename to packages/editorconfig-20190703.336.tar index dc28c40..539f82a 100644 Binary files a/packages/editorconfig-20181115.709.tar and b/packages/editorconfig-20190703.336.tar differ diff --git a/packages/ein-20181113.2117.tar b/packages/ein-20190813.2156.tar similarity index 79% rename from packages/ein-20181113.2117.tar rename to packages/ein-20190813.2156.tar index e38dff9..af84723 100644 Binary files a/packages/ein-20181113.2117.tar and b/packages/ein-20190813.2156.tar differ diff --git a/packages/eldoc-eval-20180607.1157.el b/packages/eldoc-eval-20180607.1157.el deleted file mode 100644 index 34f7d1f..0000000 --- a/packages/eldoc-eval-20180607.1157.el +++ /dev/null @@ -1,246 +0,0 @@ -;;; eldoc-eval.el --- Enable eldoc support when minibuffer is in use. -*- lexical-binding: t -*- - -;; Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. - -;; Author: Thierry Volpiatto -;; Version: 0.1 -;; Package-Version: 20180607.1157 - -;; This file is part of GNU Emacs. - -;; GNU Emacs 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. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . - -;;; Commentary: -;; -;; This package enables eldoc support when minibuffer is in use. -;; -;; Eldoc info is shown by default in mode-line, -;; but you can have eldoc info somewhere else by setting -;; `eldoc-in-minibuffer-show-fn' to another function (e.g `tooltip-show'). -;; -;; By default with this package `M-:' will use `pp-eval-expression' -;; instead of `eval-expression'; you can change that by setting -;; `eldoc-eval-preferred-function'. -;; -;; It also provides a convenient macro to enable eldoc support -;; in your own functions using minibuffer or in your defadvices, -;; that is `with-eldoc-in-minibuffer'. -;; -;; Users of own minibuffer frame will have to set -;; `eldoc-in-minibuffer-own-frame-p' to non-nil. -;; -;; You can turn On/Off eldoc support in minibuffer any time -;; with `eldoc-in-minibuffer-mode'. -;; -;;; Install: -;; Add to .emacs: -;; -;; (autoload 'eldoc-in-minibuffer-mode "eldoc-eval") -;; (eldoc-in-minibuffer-mode 1) - - -;;; Code: -(require 'eldoc) -(when (require 'elisp-mode nil t) ; emacs-25 - (defalias 'eldoc-current-symbol 'elisp--current-symbol) - (defalias 'eldoc-fnsym-in-current-sexp 'elisp--fnsym-in-current-sexp) - (defalias 'eldoc-get-fnsym-args-string 'elisp-get-fnsym-args-string) - (defalias 'eldoc-get-var-docstring 'elisp-get-var-docstring)) - -;;; Minibuffer support. -;; Enable displaying eldoc info in something else -;; Than minibuffer when this one is in use. -;; -(defgroup eldoc-eval nil - "Show eldoc infos in mode line while minibuffer is in use." - :group 'eldoc) - -(defcustom eldoc-in-minibuffer-show-fn 'eldoc-show-in-mode-line - "A function to display eldoc info. -Should take one arg: the string to display" - :type 'function) - -(defcustom eldoc-show-in-mode-line-delay 12 - "The time we show eldoc when Emacs is idle." - :type 'number) - -(defcustom eldoc-eval-preferred-function 'pp-eval-expression - "Preferred function to use with `M-:'." - :type 'function) - -(defcustom eldoc-in-minibuffer-own-frame-p nil - "Whether minibuffer has its own frame or not." - :type 'boolean) - -(defcustom eldoc-in-minibuffer-mode-lighter " Eldoc-eval" - "String displayed in mode-line when `eldoc-in-minibuffer-mode' is enabled." - :type 'string) - -(defcustom eldoc-mode-line-stop-rolling-on-input t - "When rolling mode-line is enabled, stop rolling on input when non--nil." - :type 'boolean) - -;;; Compatibility with Emacs-24.4 -;; New implementation of eldoc in minibuffer that come -;; with Emacs-24.4 show the eldoc info of current-buffer while -;; minibuffer is in use, disable this and inline old Emacs behavior. -;; -(defconst eldoc-eval--old-message-function - (and (boundp 'eldoc-message-function) eldoc-message-function)) - -(defadvice eldoc-display-message-no-interference-p - (after eldoc-eval activate) - (when eldoc-in-minibuffer-mode - (setq ad-return-value - (and ad-return-value - ;; Having this mode operate in an active minibuffer/echo area - ;; causes interference with what's going on there. - (not cursor-in-echo-area) - (not (eq (selected-window) (minibuffer-window))))))) - -;; Internal. -(defvar eldoc-active-minibuffers-list nil - "List of active minibuffers with eldoc enabled.") -(defvar eldoc-mode-line-rolling-flag nil) - -(defun eldoc-store-minibuffer () - "Store minibuffer buffer name in `eldoc-active-minibuffers-list'. -This function is called by each minibuffer started with eldoc support. -See `with-eldoc-in-minibuffer'." - (with-selected-window (minibuffer-window) - (push (current-buffer) eldoc-active-minibuffers-list))) - -(defmacro with-eldoc-in-minibuffer (&rest body) - "Enable eldoc support for minibuffer input that runs in BODY." - (declare (indent 0) (debug t)) - (let ((timer (make-symbol "eldoc-eval--timer"))) - `(let ((,timer (and eldoc-in-minibuffer-mode - (run-with-idle-timer - eldoc-idle-delay - 'repeat #'eldoc-run-in-minibuffer)))) - (unwind-protect - (minibuffer-with-setup-hook - ;; When minibuffer is activated in body, store it. - #'eldoc-store-minibuffer - ,@body) - (and ,timer (cancel-timer ,timer)) - ;; Each time a minibuffer exits or aborts - ;; its buffer is removed from stack, - ;; assuming we can only exit the active minibuffer - ;; on top of stack. - (setq eldoc-active-minibuffers-list - (cdr eldoc-active-minibuffers-list)))))) - -(defun eldoc-current-buffer () - "Return the current buffer prior to activating the minibuffer." - (with-selected-frame (last-nonminibuffer-frame) - (window-buffer - (cond (eldoc-in-minibuffer-own-frame-p - (selected-window)) - ((fboundp 'window-in-direction) - (window-in-direction - 'above (minibuffer-window))) - (t (minibuffer-selected-window)))))) - -(defun eldoc-show-in-mode-line (input) - "Display string STR in the mode-line next to minibuffer." - (with-current-buffer (eldoc-current-buffer) - (let* ((max (window-width (selected-window))) - (str (and (stringp input) (concat " " input))) - (len (length str)) - (tmp-str str) - (mode-line-format (or str mode-line-format)) - roll mode-line-in-non-selected-windows) - (catch 'break - (if (and (> len max) eldoc-mode-line-rolling-flag) - (progn - (while (setq roll (sit-for 0.3)) - (setq tmp-str (substring tmp-str 2) - mode-line-format (concat tmp-str " [<]" str)) - (force-mode-line-update) - (when (< (length tmp-str) 2) (setq tmp-str str))) - (unless roll - (when eldoc-mode-line-stop-rolling-on-input - (setq eldoc-mode-line-rolling-flag nil)) - (throw 'break nil))) - (force-mode-line-update) - (sit-for eldoc-show-in-mode-line-delay)))) - (force-mode-line-update))) - -(defun eldoc-mode-line-toggle-rolling () - (interactive) - (if (and eldoc-in-minibuffer-mode - (minibuffer-window-active-p (selected-window))) - (setq eldoc-mode-line-rolling-flag (not eldoc-mode-line-rolling-flag)) - (error "No active minibuffer found"))) - -(defvar eldoc-in-minibuffer-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [remap eval-expression] 'eldoc-eval-expression) - map)) - -;;;###autoload -(define-minor-mode eldoc-in-minibuffer-mode - "Show eldoc for current minibuffer input." - :global t - :group 'eldoc-eval - (if eldoc-in-minibuffer-mode - (progn - (add-hook 'minibuffer-exit-hook - (lambda () - (setq eldoc-mode-line-rolling-flag nil))) - (when (boundp 'eldoc-post-insert-mode) - (setq eldoc-message-function 'message) - (remove-hook 'eval-expression-minibuffer-setup-hook - 'eldoc-post-insert-mode)) - (define-key minibuffer-local-map (kbd "C-@") - 'eldoc-mode-line-toggle-rolling) - (setq eldoc-minor-mode-string eldoc-in-minibuffer-mode-lighter)) - (setq eldoc-minor-mode-string " Eldoc") - (when (boundp 'eldoc-post-insert-mode) - (setq eldoc-message-function eldoc-eval--old-message-function) - (add-hook 'eval-expression-minibuffer-setup-hook - 'eldoc-post-insert-mode)) - (define-key minibuffer-local-map (kbd "C-@") 'set-mark-command))) - -(defun eldoc-run-in-minibuffer () - (let ((buf (window-buffer (active-minibuffer-window)))) - ;; If this minibuffer have been started with - ;;`with-eldoc-in-minibuffer' give it eldoc support - ;; and update mode-line, otherwise do nothing. - (condition-case _err - (when (member buf eldoc-active-minibuffers-list) - (with-current-buffer buf - (let* ((sym (save-excursion - (unless (looking-back ")\\|\"" (1- (point))) - (forward-char -1)) - (eldoc-current-symbol))) - (info-fn (eldoc-fnsym-in-current-sexp)) - (doc (or (eldoc-get-var-docstring sym) - (eldoc-get-fnsym-args-string - (car info-fn) (cadr info-fn))))) - (funcall eldoc-in-minibuffer-show-fn (or doc 1))))) - (scan-error nil) - (beginning-of-buffer nil)))) - -;;;###autoload -(defun eldoc-eval-expression () - "Eval expression with eldoc support in mode-line." - (interactive) - (with-eldoc-in-minibuffer - (call-interactively eldoc-eval-preferred-function))) - - -(provide 'eldoc-eval) -;;; eldoc-eval.el ends here diff --git a/packages/elfeed-20180916.1338.tar b/packages/elfeed-20190809.1358.tar similarity index 91% rename from packages/elfeed-20180916.1338.tar rename to packages/elfeed-20190809.1358.tar index 245708c..ac7cf2d 100644 Binary files a/packages/elfeed-20180916.1338.tar and b/packages/elfeed-20190809.1358.tar differ diff --git a/packages/elfeed-goodies-20171127.651.tar b/packages/elfeed-goodies-20190128.1631.tar similarity index 90% rename from packages/elfeed-goodies-20171127.651.tar rename to packages/elfeed-goodies-20190128.1631.tar index dc62826..194b74a 100644 Binary files a/packages/elfeed-goodies-20171127.651.tar and b/packages/elfeed-goodies-20190128.1631.tar differ diff --git a/packages/elfeed-web-20180829.1716.tar b/packages/elfeed-web-20180829.1716.tar index 3a5ec97..e7c2d87 100644 Binary files a/packages/elfeed-web-20180829.1716.tar and b/packages/elfeed-web-20180829.1716.tar differ diff --git a/packages/elixir-mode-20180711.1245.tar b/packages/elixir-mode-20190422.155.tar similarity index 95% rename from packages/elixir-mode-20180711.1245.tar rename to packages/elixir-mode-20190422.155.tar index ad3931b..6aa37d3 100644 Binary files a/packages/elixir-mode-20180711.1245.tar and b/packages/elixir-mode-20190422.155.tar differ diff --git a/packages/elm-mode-20181114.2235.tar b/packages/elm-mode-20190815.555.tar similarity index 94% rename from packages/elm-mode-20181114.2235.tar rename to packages/elm-mode-20190815.555.tar index b53b678..1498d11 100644 Binary files a/packages/elm-mode-20181114.2235.tar and b/packages/elm-mode-20190815.555.tar differ diff --git a/packages/elm-test-runner-20180918.2255.el b/packages/elm-test-runner-20190105.1923.el similarity index 94% rename from packages/elm-test-runner-20180918.2255.el rename to packages/elm-test-runner-20190105.1923.el index 2cc46fd..7754330 100644 --- a/packages/elm-test-runner-20180918.2255.el +++ b/packages/elm-test-runner-20190105.1923.el @@ -4,7 +4,7 @@ ;; Author: Juan Edi ;; Version: 0.0.1 -;; Package-Version: 20180918.2255 +;; Package-Version: 20190105.1923 ;; URL: https://github.com/juanedi/elm-test-runner ;; Package-Requires: ((emacs "24.4")) @@ -60,9 +60,9 @@ If nil,will try to use a locally installed node runner and fallback to a globall (define-compilation-mode elm-test-runner-compilation-mode "Elm Test Compilation" "Compilation mode for elm-test output." - (add-hook 'compilation-filter-hook 'elm-test-runner--colorize-compilation-buffer nil t) - ) + (add-hook 'compilation-filter-hook 'elm-test-runner--colorize-compilation-buffer nil t)) +;;;###autoload (defun elm-test-runner-run () "Run elm-test on the current buffer's file." (interactive) @@ -70,6 +70,7 @@ If nil,will try to use a locally installed node runner and fallback to a globall (buffer-file-name) elm-test-runner-command-options)) +;;;###autoload (defun elm-test-runner-run-project () "Run elm-test on the whole project." (interactive) @@ -77,6 +78,7 @@ If nil,will try to use a locally installed node runner and fallback to a globall (elm-test-runner--test-directory (buffer-file-name)) elm-test-runner-command-options)) +;;;###autoload (defun elm-test-runner-run-directory () "Prompt for a directory on which to run specs." (interactive) @@ -86,6 +88,7 @@ If nil,will try to use a locally installed node runner and fallback to a globall selected-dir elm-test-runner-command-options)))) +;;;###autoload (defun elm-test-runner-watch () "Run elm-test on the current buffer's file in watch mode." (interactive) @@ -93,6 +96,7 @@ If nil,will try to use a locally installed node runner and fallback to a globall (buffer-file-name) (concat elm-test-runner-command-options " --watch"))) +;;;###autoload (defun elm-test-runner-rerun () "Re-run the last elm-test invocation." (interactive) @@ -101,6 +105,7 @@ If nil,will try to use a locally installed node runner and fallback to a globall (let ((default-directory elm-test-runner--last-directory)) (apply #'elm-test-runner--compile elm-test-runner--last-arguments)))) +;;;###autoload (defun elm-test-runner-toggle-test-and-target () "Switch to the test or the target file for the current buffer. If the current buffer is visiting a test file, switches to the @@ -321,7 +326,7 @@ Optional argument CURRENT-FILE-NAME the file name of whose project we'll run tes (defun elm-test-runner--project-root (&optional current-file-name) "The root directory of CURRENT-FILE-NAME's elm project. -That is, the one with the main elm-package.json. The result of this function +That is, the one with the elm.json file. The result of this function depends on the value of ‘elm-test-runner-project-root-for-file’." (let* ((starting-point (or current-file-name (buffer-file-name))) @@ -334,6 +339,18 @@ depends on the value of ‘elm-test-runner-project-root-for-file’." This function assumes a standard layout as described in elm-test's documentation: the root directory should contain a 'tests' directory for elm-test stuff. +Argument CURRENT-FILE-NAME the file whose Elm project's root we're looking for." + (or + (elm-test-runner--standard-elm-19-project-root-for-file current-file-name) + (elm-test-runner--standard-elm-18-project-root-for-file current-file-name))) + +(defun elm-test-runner--standard-elm-19-project-root-for-file (current-file-name) + "Detect project root for a standard elm 19 project. +Argument CURRENT-FILE-NAME the file whose Elm project's root we're looking for." + (locate-dominating-file current-file-name "elm.json")) + +(defun elm-test-runner--standard-elm-18-project-root-for-file (current-file-name) + "Detect project root for a standard elm 18 project. Argument CURRENT-FILE-NAME the file whose Elm project's root we're looking for." ;; If we are on a target file, return the first directory we see with an elm-package.json ;; If we are on a test file, it's the one above. @@ -344,7 +361,7 @@ Argument CURRENT-FILE-NAME the file whose Elm project's root we're looking for." (if parent-dir-elm-package parent-dir - first-elm-package-dir))) + first-elm-package-dir))) (defun elm-test-runner--compile-command (target &optional opts) "Composes the compilation command to run specs for TARGET. diff --git a/packages/emacsql-20190625.1859.tar b/packages/emacsql-20190625.1859.tar new file mode 100644 index 0000000..9a2ebfb Binary files /dev/null and b/packages/emacsql-20190625.1859.tar differ diff --git a/packages/emacsql-sqlite-20190727.1710.tar b/packages/emacsql-sqlite-20190727.1710.tar new file mode 100644 index 0000000..7acd0e1 Binary files /dev/null and b/packages/emacsql-sqlite-20190727.1710.tar differ diff --git a/packages/ember-mode-20181001.936.el b/packages/ember-mode-20190403.1652.el similarity index 94% rename from packages/ember-mode-20181001.936.el rename to packages/ember-mode-20190403.1652.el index 359868c..79906d7 100644 --- a/packages/ember-mode-20181001.936.el +++ b/packages/ember-mode-20190403.1652.el @@ -29,7 +29,7 @@ ;;;; Accounting ;; Version: 0.3.1 -;; Package-Version: 20181001.936 +;; Package-Version: 20190403.1652 ;; Author: Aad Versteden ;; Keywords: ember ember.js emberjs ;; License: MIT @@ -67,6 +67,26 @@ :prefix "ember-" :group 'tools) +;;;;;;;;;;;;;;;;;;; +;;;; Debug printing + +(defvar ember--debug-ember-mode nil) + +(defvar ember--debug-output-buffer (generate-new-buffer "*ember-mode-debug*")) + +(defun ember--debug-princ (&rest args) + "Prints content to the ember debug output using princ" + (when ember--debug-ember-mode + (princ args ember--debug-output-buffer) + (princ "\n" ember--debug-output-buffer))) + +(defun ember--debug-print (&rest args) + "Prints content to the ember debug output using print" + (when ember--debug-ember-mode + (print args ember--debug-output-buffer))) + +(ember--debug-princ "*This buffer contains debug s-expressions from ember-mode*") + ;;;;;;;;;;;; ;;;; plurals ;; @@ -160,25 +180,41 @@ The first item in this list is used as the 'default', used when creating files." (defvar ember-use-pods 'unset "Default to not using the POD structure for now.") +(defun ember--dot-ember-cli-has-pods-p () + "Returns non-nil iff the .ember-cli file in the root sets +usePods to true. Very basic detection is performed to see if the +line with usePods is commented out." + (let ((ember-cli-filename (concat (ember--current-project-root) + "/.ember-cli"))) + (when (file-exists-p ember-cli-filename) + (with-temp-buffer + (insert-file-contents ember-cli-filename) + (re-search-forward "^[^/]*\"usePods\".*:.*true" nil t))))) + + +;;;;;;;;;;;;;;;;;;;;;;;; +;;; MU structure support + +(defvar ember-use-mu 'unset + "Defaults to not using the MU structure for now.") + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Shared support for MU and PODs + (defun ember--get-matcher-map-name () "Returns the name of the map for the current matcher. Returns either 'pod and 'no-pod." (cond + ((eq ember-use-mu t) 'mu) ((eq ember-use-pods t) 'pod) ((eq ember-use-pods nil) 'no-pod) (t (if (ember--dot-ember-cli-has-pods-p) 'pod 'no-pod)))) -(defun ember--dot-ember-cli-has-pods-p () - "Returns non-nil iff the .ember-cli file in the root sets -usePods to true. Very basic detection is performed to see if the -line with usePods is commented out." - (let ((ember-cli-filename (concat (ember--current-project-root) - "/.ember-cli"))) - (with-temp-buffer - (insert-file-contents ember-cli-filename) - (re-search-forward "^[^/]*\"usePods\".*:.*true" nil t)))) +(defun base-prefixes () + '("app" "src" "addon")) ;;;;;;;;;;;;;; ;;; Navigation @@ -198,6 +234,8 @@ assumption. From the string base, a type can be built.") +(setf *ember--matcher-templates* (make-hash-table)) + (cl-defun ember--define-matcher (map-name base-type-regex target-kind base-location &optional (base-type base-type-regex)) "Adds a matcher to the end of the list of *EMBER--MATCHER-TEMPLATES* for map-name" (setf (gethash map-name *ember--matcher-templates*) @@ -253,6 +291,26 @@ From the string base, a type can be built.") ;; END contains the definition of each matcher ) +(ember--define-matchers mu + ;; BEGIN contains the definition for each matcher + ;; the first two columns are a regexp, the rest is executed as code + ;; base-type | target-kind | concatenation lambda body | override base-type + ("router" ".*" (:prefix "/router" "." :jsext)) + ("^route$" "source" (:prefix "/ui/routes/" :class "/route" "." :jsext) "route") + ("model" "source" (:prefix "/data/models/" :class "/model" "." :jsext)) + ("controller" "source" (:prefix "/controllers/" :class "." :jsext)) + ("service" "source" (:prefix "/services/" :class "." :jsext)) + ("component" "source" (:prefix "/ui/components/" :class "/component" "." :jsext)) + ("mixin" "source" (:prefix "/mixins/" :class "." :jsext)) + ("initializer" "source" (:prefix "/init/initializers/" :class "." :jsext)) + ("util" "source" (:prefix "/utils/" :class "." :jsext)) + ("service" "source" (:prefix "/services/" :class "." :jsext)) + ("component" "template" (:prefix "/ui/components/" :class "/template" "." :hbext)) + ("template" "source" (:prefix "/ui/routes/" :class "/template" "." :hbext)) + (".*" "template" (:prefix "/ui/routes/" :class "/template" "." :hbext) "template") + ;; END contains the definition of each matcher + ) + (defun ember--current-matcher-templates () "Returns the contents of the matcher templates given the current POD setting." @@ -332,7 +390,8 @@ the matcher-template" (defun ember--matcher-template-map-prefixes (matcher-template) "Returns a new matcher-template for each prefix" (list (ember--matcher-partial-fill matcher-template :prefix "app") - (ember--matcher-partial-fill matcher-template :prefix "addon"))) + (ember--matcher-partial-fill matcher-template :prefix "addon") + (ember--matcher-partial-fill matcher-template :prefix "src"))) (defun ember--regex-escape-matcher-template (matcher-template) "Returns the same matcher but in which the components can be used in @@ -434,7 +493,8 @@ Sources are specified in ember by a few orthogonal factors: (ember--file-project-root (or load-file-name buffer-file-name default-directory))) (defun ember--file-project-root (file) - (locate-dominating-file file ".ember-cli")) + (or (locate-dominating-file file ".ember-cli") + (locate-dominating-file file ".ember-cli.js"))) (defun ember--relative-file-components (file) "Returns a list containing the components which make up this ember source @@ -458,7 +518,8 @@ file." "source") ((cl-find (cl-getf components :hbext) ember-template-file-types :test #'equal) "template")))) - (list base-prefix base-class base-type target-kind)))))) + (let ((response (list base-prefix base-class base-type target-kind))) + response)))))) (defun ember--file-relative-to-root (file) "Returns the pathname of FILE relative to the current project's @@ -469,8 +530,8 @@ root." "Returns a list containing the components which make up this ember source file." (or (ember--relative-file-components - (ember--file-relative-to-root (or load-file-name buffer-file-name default-directory))) - (list nil nil nil nil))) + (ember--file-relative-to-root (or load-file-name buffer-file-name default-directory))) + (list nil nil nil nil))) (cl-defun ember-open-file-by-type (type &optional (assume-js t)) "Opens an ember file for TYPE with all base values assumed from @@ -513,7 +574,7 @@ files and directories that match IGNORE (IGNORE is tested before MATCH. Recurse only to depth MAXDEPTH. Does not recurse if MAXDEPTH is zero or negative." (let ((matchers (ember--matchers-for base-type target-kind)) - (walk-dirs (cl-loop for prefix in '("app" "addon") + (walk-dirs (cl-loop for prefix in '("app" "addon" "src") for dir = (concat (ember--current-project-root) prefix) if (file-directory-p dir) collect dir)) @@ -576,25 +637,33 @@ This replacement uses a completion system according to "Tries to open the ember file specified by BASE-CLASS, BASE-TYPE and TARGET-KIND. If no such file was found, it tries to find related files or requests the user if the file should be created." - (unless base-class - (setf base-class "")) - (let ((ember-root (ember--current-project-root)) - (file-list - ;; pick the files and their alternatives, so we have a good list - ;; to search for an existing file. - (append (ember--relative-ember-source-path base-prefix base-class base-type target-kind) - (ember--relative-ember-source-path base-prefix (ember--pluralize-noun base-class) base-type target-kind) - (ember--relative-ember-source-path base-prefix (ember--singularize-noun base-class) base-type target-kind)))) - (cl-block found-file - (cl-loop for relative-file in file-list - for absolute-file = (concat ember-root relative-file) - if (file-exists-p absolute-file) - do - (find-file absolute-file) - (cl-return-from found-file absolute-file)) - (when (string= target-kind "template") - (setf base-type "template")) - (ember--select-file-by-type-and-kind "Not found, alternatives: " base-type target-kind)))) + (let ((prefix-list + (cond ((equal base-prefix "src") + '("src" "app")) + ((and (equal base-prefix "app") ember-use-mu) + '("app" "src")) + (t + (list base-prefix))))) + (unless base-class + (setf base-class "")) + (let ((ember-root (ember--current-project-root)) + (file-list + ;; pick the files and their alternatives, so we have a good list + ;; to search for an existing file. + (cl-loop for prefix in prefix-list append + (append (ember--relative-ember-source-path prefix base-class base-type target-kind) + (ember--relative-ember-source-path prefix (ember--pluralize-noun base-class) base-type target-kind) + (ember--relative-ember-source-path prefix (ember--singularize-noun base-class) base-type target-kind))))) + (cl-block found-file + (cl-loop for relative-file in file-list + for absolute-file = (concat ember-root relative-file) + if (file-exists-p absolute-file) + do + (find-file absolute-file) + (cl-return-from found-file absolute-file)) + (when (string= target-kind "template") + (setf base-type "template")) + (ember--select-file-by-type-and-kind "Not found, alternatives: " base-type target-kind))))) (defun ember-open-component () "Opens a component file based on the currently opened file." @@ -662,6 +731,7 @@ the corresponding source." (defun ember-toggle-addon () "Toggles between the native view and the ember addon view." (interactive) + ;; TODO fix for mu (cl-destructuring-bind (base-prefix base-class base-type target-kind) (ember--current-file-components) (let ((new-base-prefix (cond ((string= base-prefix "app") diff --git a/packages/ember-yasnippets-20160526.1658.tar b/packages/ember-yasnippets-20160526.1658.tar index 4a72e48..217948b 100644 Binary files a/packages/ember-yasnippets-20160526.1658.tar and b/packages/ember-yasnippets-20160526.1658.tar differ diff --git a/packages/emoji-cheat-sheet-plus-20150617.1331.tar b/packages/emoji-cheat-sheet-plus-20150617.1331.tar index 7d8fad3..4fbc622 100644 Binary files a/packages/emoji-cheat-sheet-plus-20150617.1331.tar and b/packages/emoji-cheat-sheet-plus-20150617.1331.tar differ diff --git a/packages/emojify-20180611.1538.tar b/packages/emojify-20190809.959.tar similarity index 98% rename from packages/emojify-20180611.1538.tar rename to packages/emojify-20190809.959.tar index 25be6b8..4b18c77 100644 Binary files a/packages/emojify-20180611.1538.tar and b/packages/emojify-20190809.959.tar differ diff --git a/packages/engine-mode-20180401.1646.el b/packages/engine-mode-20181222.2027.el similarity index 98% rename from packages/engine-mode-20180401.1646.el rename to packages/engine-mode-20181222.2027.el index 7342ad2..4612b0a 100644 --- a/packages/engine-mode-20180401.1646.el +++ b/packages/engine-mode-20181222.2027.el @@ -2,7 +2,7 @@ ;; Author: Harry R. Schwartz ;; Version: 2.1.0 -;; Package-Version: 20180401.1646 +;; Package-Version: 20181222.2027 ;; URL: https://github.com/hrs/engine-mode ;; Package-Requires: ((cl-lib "0.5")) @@ -123,7 +123,7 @@ Defaults to `nil' which means to go with `browse-url-browser-function'." (defun engine/bind-key (engine-name keybinding) (when keybinding - `(define-key engine-mode-prefixed-map ,keybinding + `(define-key engine-mode-prefixed-map (kbd ,keybinding) (quote ,(engine/function-name engine-name))))) ;;;###autoload diff --git a/packages/enh-ruby-mode-20180730.2309.tar b/packages/enh-ruby-mode-20190513.254.tar similarity index 73% rename from packages/enh-ruby-mode-20180730.2309.tar rename to packages/enh-ruby-mode-20190513.254.tar index 7cd71c6..d678c80 100644 Binary files a/packages/enh-ruby-mode-20180730.2309.tar and b/packages/enh-ruby-mode-20190513.254.tar differ diff --git a/packages/ensime-20180615.1330.tar b/packages/ensime-20180615.1330.tar index c8035a0..1e03256 100644 Binary files a/packages/ensime-20180615.1330.tar and b/packages/ensime-20180615.1330.tar differ diff --git a/packages/epc-20140610.534.tar b/packages/epc-20140610.534.tar index 82ba252..6a87b7e 100644 Binary files a/packages/epc-20140610.534.tar and b/packages/epc-20140610.534.tar differ diff --git a/packages/erc-tweet-20150920.1258.el b/packages/erc-tweet-20150920.1258.el new file mode 100644 index 0000000..2cc5ce6 --- /dev/null +++ b/packages/erc-tweet-20150920.1258.el @@ -0,0 +1,140 @@ +;;; erc-tweet.el --- shows text of a tweet when an url is posted in erc buffers + +;; Copyright (C) 2012 Raimon Grau + +;; Author: Raimon Grau +;; Version: 0.9 +;; Package-Version: 20150920.1258 +;; Keywords: extensions + +;; 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 . + +;;; Commentary: +;; +;; Show inlined tweets in erc buffers. +;; +;;; Installation: +;; +;; usage: +;; +;; (require 'erc-tweet) +;; (add-to-list 'erc-modules 'tweet) +;; (erc-update-modules) +;; +;; Or `(require 'erc-tweet)` and `M-x customize-option erc-modules RET` +;; +;; This plugin subscribes to hooks `erc-insert-modify-hook` and +;; `erc-send-modify-hook` to download and show tweets. + +;;; Code: + +(require 'erc) +(require 'url-queue) + +(defgroup erc-tweet nil + "Enable tweet." + :group 'erc) + +(defcustom erc-tweet-regex "https?://\\(?:[^/]*\\)?twitter.com/.+/status/[0-9]+" + "Regex to mach URLs to be downloaded" + :group 'erc-tweet + :type '(regexp :tag "Regex")) + +(defun erc-tweet-strip-tags (str) + "Strip tags in a regex. Naive, I know." + (replace-regexp-in-string "<.+?>" "" str)) + +(defun erc-tweet-text () + "Extract the tweet text from the retrieved HTML" + (goto-char (point-min)) + (search-forward-regexp "js-tweet-text tweet-text[^>]*>") + (let ((pt-before (point))) + (search-forward " + +") + (backward-char) + (string-as-multibyte (buffer-substring-no-properties pt-before (point))))) + +(defvar erc-tweet-cleanup-text 'erc-tweet-strip-tags) + + +(defun erc-tweet-decode-entities (html) + (with-temp-buffer + (save-excursion (insert html)) + (xml-parse-string))) + +(defun erc-tweet-insert (msg marker) + "Insert MSG before MARKER." + (with-current-buffer (marker-buffer marker) + (save-excursion + (let ((inhibit-read-only t)) + (goto-char (marker-position marker)) + (let ((pt-before (point))) + (insert-before-markers (erc-tweet-decode-entities msg)) + (put-text-property pt-before (point) 'read-only t)))))) + +(defun erc-tweet-error (error-info marker) + "Insert error text from ERROR-INFO before MARKER." + (let* ((name (car error-info)) + (data (cadr error-info)) + (msg (format "[tweet/%s] - %s\n" name data))) + (erc-tweet-insert msg marker))) + +(defun erc-tweet-callback (status marker) + "Callback function for url-queue-retrieve." + (interactive) + (let ((error-info (plist-get status :error))) + (cond (error-info + (erc-tweet-error error-info marker)) + (t (erc-tweet marker))))) + +(defun erc-tweet (marker) + "Extract the tweet text and insert before MARKER." + (let* ((tweet-text (erc-tweet-text)) + (msg (concat "[tweet] - " + (funcall erc-tweet-cleanup-text tweet-text)))) + (erc-tweet-insert msg marker))) + +(defun erc-tweet-correct-url (url) + "Change the url to go to the non-mobile site." + (when (and url (string-match erc-tweet-regex url)) + ;; go to the non-mobile tweet + (replace-regexp-in-string "mobile\." "" url))) + +(defun erc-tweet-show-tweet () + (interactive) + (goto-char (point-min)) + (search-forward "http" nil t) + (let ((url (erc-tweet-correct-url (thing-at-point 'url)))) + (when url + (url-queue-retrieve url + 'erc-tweet-callback + (list + (point-max-marker)) + t)))) + +;;;###autoload +(eval-after-load 'erc + '(define-erc-module tweet nil + "Display inlined twits in ERC buffer" + ((add-hook 'erc-insert-modify-hook 'erc-tweet-show-tweet t) + (add-hook 'erc-send-modify-hook 'erc-tweet-show-tweet t)) + ((remove-hook 'erc-insert-modify-hook 'erc-tweet-show-tweet) + (remove-hook 'erc-send-modify-hook 'erc-tweet-show-tweet)) + t)) + +;;; Code: + +(provide 'erc-tweet) +;;; erc-tweet.el ends here diff --git a/packages/erlang-20181011.1236.tar b/packages/erlang-20190404.928.tar similarity index 94% rename from packages/erlang-20181011.1236.tar rename to packages/erlang-20190404.928.tar index 96f2617..715bce0 100644 Binary files a/packages/erlang-20181011.1236.tar and b/packages/erlang-20190404.928.tar differ diff --git a/packages/eshell-prompt-extras-20180110.634.el b/packages/eshell-prompt-extras-20181229.1418.el similarity index 94% rename from packages/eshell-prompt-extras-20180110.634.el rename to packages/eshell-prompt-extras-20181229.1418.el index 1fa97ac..9ec830a 100644 --- a/packages/eshell-prompt-extras-20180110.634.el +++ b/packages/eshell-prompt-extras-20181229.1418.el @@ -1,12 +1,12 @@ ;;; eshell-prompt-extras.el --- Display extra information for your eshell prompt. -;; Copyright (C) 2014-2016 Wei Zhao +;; Copyright (C) 2014-2019 Wei Zhao -;; Author: Wei Zhao +;; Author: zwild ;; Contributors: Lee Hinman ;; Maintainer: Chunyang Xu -;; URL: https://github.com/hiddenlotus/eshell-prompt-extras -;; Package-Version: 20180110.634 +;; URL: https://github.com/zwild/eshell-prompt-extras +;; Package-Version: 20181229.1418 ;; Version: 0.96 ;; Created: 2014-08-16 ;; Keywords: eshell, prompt @@ -414,27 +414,24 @@ length of PATH (sans directory slashes) down to MAX-LEN." (concat (if (epe-remote-p) (progn - (concat - (epe-colorize-with-face "┌─[" 'epe-pipeline-delimiter-face) - (epe-colorize-with-face (epe-remote-user) 'epe-pipeline-user-face) - (epe-colorize-with-face "@" 'epe-pipeline-delimiter-face) - (epe-colorize-with-face (epe-remote-host) 'epe-pipeline-host-face)) - ) + (concat + (epe-colorize-with-face "┌─[" 'epe-pipeline-delimiter-face) + (epe-colorize-with-face (epe-remote-user) 'epe-pipeline-user-face) + (epe-colorize-with-face "@" 'epe-pipeline-delimiter-face) + (epe-colorize-with-face (epe-remote-host) 'epe-pipeline-host-face))) (progn (concat - (epe-colorize-with-face "┌─[" 'epe-pipeline-delimiter-face) - (epe-colorize-with-face (user-login-name) 'epe-pipeline-user-face) - (epe-colorize-with-face "@" 'epe-pipeline-delimiter-face) - (epe-colorize-with-face (system-name) 'epe-pipeline-host-face))) - ) + (epe-colorize-with-face "┌─[" 'epe-pipeline-delimiter-face) + (epe-colorize-with-face (user-login-name) 'epe-pipeline-user-face) + (epe-colorize-with-face "@" 'epe-pipeline-delimiter-face) + (epe-colorize-with-face (system-name) 'epe-pipeline-host-face)))) (concat (epe-colorize-with-face "]──[" 'epe-pipeline-delimiter-face) (epe-colorize-with-face (format-time-string "%H:%M" (current-time)) 'epe-pipeline-time-face) (epe-colorize-with-face "]──[" 'epe-pipeline-delimiter-face) (epe-colorize-with-face (concat (eshell/pwd)) 'epe-dir-face) (epe-colorize-with-face "]\n" 'epe-pipeline-delimiter-face) - (epe-colorize-with-face "└─>" 'epe-pipeline-delimiter-face) - ) + (epe-colorize-with-face "└─>" 'epe-pipeline-delimiter-face)) (when (and epe-show-python-info (bound-and-true-p venv-current-name)) (epe-colorize-with-face (concat "(" venv-current-name ") ") 'epe-venv-face)) (when (epe-git-p) @@ -442,15 +439,16 @@ length of PATH (sans directory slashes) down to MAX-LEN." (epe-colorize-with-face ":" 'epe-dir-face) (epe-colorize-with-face (concat (epe-git-branch) - (epe-git-dirty) - (epe-git-untracked) - (let ((unpushed (epe-git-unpushed-number))) - (unless (= unpushed 0) - (concat ":" (number-to-string unpushed))))) + (epe-git-dirty) + (epe-git-untracked) + (let ((unpushed (epe-git-unpushed-number))) + (unless (= unpushed 0) + (concat ":" (number-to-string unpushed))))) 'epe-git-face))) (epe-colorize-with-face " λ" 'epe-symbol-face) (epe-colorize-with-face (if (= (user-uid) 0) "#" "") 'epe-sudo-symbol-face) " ")) + (provide 'eshell-prompt-extras) ;;; eshell-prompt-extras.el ends here diff --git a/packages/ess-20181117.1705.tar b/packages/ess-20190814.1054.tar similarity index 75% rename from packages/ess-20181117.1705.tar rename to packages/ess-20190814.1054.tar index ef41a34..2dc6d6e 100644 Binary files a/packages/ess-20181117.1705.tar and b/packages/ess-20190814.1054.tar differ diff --git a/packages/ess-smart-equals-20150202.601.el b/packages/ess-smart-equals-20150202.601.el deleted file mode 100644 index 0d20e69..0000000 --- a/packages/ess-smart-equals-20150202.601.el +++ /dev/null @@ -1,240 +0,0 @@ -;;; ess-smart-equals.el --- better smart-assignment with =-key in R and S -*- lexical-binding: t; -*- - -;; Copyright (C) 2010-2015 Christopher R. Genovese, all rights reserved. - -;; Author: Christopher R. Genovese -;; Maintainer: Christopher R. Genovese -;; Keywords: R, S, ESS, convenience -;; URL: https://github.com/genovese/ess-smart-equals -;; Version: 0.2.1 -;; Package-Version: 20150202.601 -;; Package-X-Original-Version: 0.2.1 -;; Package-Requires: ((emacs "24") (ess "5.00")) - - -;;; License: -;; -;; 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; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth -;; Floor, Boston, MA 02110-1301, USA. -;; - - -;;; Commentary: -;; -;; Assignment in R is syntactically complicated by three features: 1. the -;; historical role of '_' (underscore) as an assignment character in -;; the S language (SPlus may still allow this); 2. the somewhat -;; inconvenient-to-type, if conceptually pure, '<-' operator as the -;; preferred assignment operator; and 3. the ability to use either -;; an '=' or an '<-' for assignment. -;; -;; ESS uses '_' as a (default) smart assignment character which expands -;; to the '<-' with one invokation and gives an underscore on two. -;; This makes it rather painful to use underscores in variable, field, -;; and function names. Moreover, _ no longer has any association with -;; assignment in R, so the mnemonic is strained. -;; -;; It is possible to reassign the special underscore to another character, -;; such as '=', but that raises other inconviences because of the multiple -;; roles that '=' can play (assignment and default argument setting). -;; -;; This package gives an alternative smart assignment for R and S code -;; that is tied to the '=' key instead of the '_' key. It intelligently -;; handles the various ways that '=' is used in R (and S) by examining -;; the preceding context. It works under the assumption that '=' used -;; for default arguments to functions *will not* be surrounded by -;; spaces but that binary operators involving '=' /should be/. When -;; this is enabled, underscore is completely divorced from assignment -;; and thus can be used directly in names. -;; -;; This package defines a global minor mode `ess-smart-equals-mode', that -;; when enabled for S-language modes causes the '=' key to use the -;; preceding character to determine the intended construct (assignment, -;; comparison, default argument). Loosely speaking, an '=' preceded by a -;; space is converted to an assignment, an '=' preceded by a comparison -;; character (<>!=) becomes a space-padded comparison operator, and -;; otherwise just an '=' is inserted. The specific rules are as follows: -;; -;; 1. In a string or comment or with a non-S language, just insert '='. -;; 2. If a space (or tab) preceeds the '=', insert a version of `ess-S-assign' -;; with no leading space (e.g., "<- "). (Other preceeding spaces are -;; left alone.) -;; 3. If any of =<>! preceed the current '=', insert an '= ', but -;; if no space preceeds the preceeding character, insert a space -;; so that the resulting binary operator is surrounded by spaces. -;; 4. If the `ess-S-assign' string (e.g., "<- ") precedes point, -;; insert '== ' (a double *not* a single equals). -;; 5. Otherwise, just insert an '='. -;; -;; With a prefix argument, '=' always just inserts an '='. -;; -;; These insertions ensure that binary operators have a space on either -;; end but they do not otherwise adjust spacing on either side. Note that -;; in #4 above, the second '=' key is assumed to be intended as an equality -;; comparison because the assignment would have been produced by an '=' -;; following a space. -;; -;; Examples: In the left column below, ^ marks the location at which an '=' -;; key is pressed, and in the right column it marks the resulting -;; position of point. -;; -;; Before '=' After '=' -;; ---------- --------- -;; foo ^ foo <- ^ -;; foo ^ foo <- ^ -;; foo(a^ foo(a=^ -;; foo=^ foo == ^ -;; foo<^ foo <= ^ -;; "foo ^ "foo =^ -;; #...foo ^ #...foo =^ -;; foo <- ^ foo == ^ -;; -;; -;; Installation -;; ------------ -;; Either put this file on your load path -;; Disabling the minor mode restores (as well as possible) the previous -;; ESS assignment setup. -;; - -;;; Change Log: - - -;;; Code: - -(require 'ess-site) - -(defvar ess-smart-equals--last-assign-key - ess-smart-S-assign-key - "Cached value of previous smart assignment key.") - -(defvar ess-smart-equals--last-assign-str - ess-S-assign - "Cached value of previous assignment string.") - -(defun ess-smart-equals--strip-leading-space (string) - "Strip one leading space from STRING, if present." - (replace-regexp-in-string "\\` " "" string)) - -(defun ess-smart-equals--restore-leading-space (string) - "Add one leading space to STRING, if none are present." - (replace-regexp-in-string "\\`\\(\\S-\\)" " \\1" string)) - -(defun ess-smart-equals--maybe-narrow () - "Narrow to relevant part of buffer in various ess-related modes." - (ignore-errors - (when (and (eq major-mode 'inferior-ess-mode) - (> (point) (process-mark (get-buffer-process (current-buffer))))) - (narrow-to-region (process-mark (ess-get-process)) (point-max))) - (and ess-noweb-mode - (ess-noweb-in-code-chunk) - (ess-noweb-narrow-to-chunk)) - (and (fboundp 'pm/narrow-to-span) - polymode-mode - (pm/narrow-to-span)))) - -(defun ess-smart-equals--after-assign-p () - "Are we looking backward at `ess-S-assign'? -If so, return number of characters to its beginning; otherwise, nil." - (let ((ess-assign-len (length ess-S-assign))) - (when (and (>= (point) (+ ess-assign-len (point-min))) ; enough room back - (save-excursion - (backward-char ess-assign-len) - (looking-at-p ess-S-assign))) - ess-assign-len))) - -;;;###autoload -(defun ess-smart-equals (&optional raw) - "Insert an R assignment for equal signs preceded by spaces. -For equal signs not preceded by spaces, as in argument lists, -just use equals. This can effectively distinguish the two uses -of equals in every case. When RAW is non-nil, the equals sign -is always inserted as is." - (interactive "P") - (save-restriction - (ess-smart-equals--maybe-narrow) - (let ((prev-char (preceding-char))) - (cond - ((or raw - (not (equal ess-language "S")) - (not (string-match-p "[ \t=<>!]" (string prev-char))) - (ess-inside-string-or-comment-p (point))) - (insert "=")) - ((string-match-p "[=<>!]" (string prev-char)) - (when (save-excursion - (goto-char (- (point) 2)) ; OK if we go past beginning (ignore-errors (backward-char 2)) - (not (looking-at-p "[ \t]"))) - (delete-char -1) - (insert " " prev-char)) - (insert "= ")) - (t - (let ((back-by (ess-smart-equals--after-assign-p))) - (if (not back-by) - (insert ess-S-assign) - (delete-char (- back-by)) - (insert "== ")))))))) - -;;;###autoload -(define-minor-mode ess-smart-equals-mode - "Minor mode for setting the '=' key to intelligently handle assignment. - -When enabled for S-language modes, an '=' key uses the preceding character -to determine the intended construct (assignment, comparison, default argument). -Loosely, an '=' preceded by a space is converted to an assignment, an '=' -preceded by a comparison (<>!=) becomes a space-padded comparison operator, -and otherwise just an '=' is inserted. The specific rules are as follows: - - 1. In a string or comment or with a non-S language, just insert '='. - 2. If a space (or tab) preceeds the '=', insert a version of `ess-S-assign' - with no leading space (e.g., '<- ') so that assignment is surrounded - by at least one space. (Other preceeding spaces are left alone.) - 3. If any of '=<>!' preceed the current '=', insert an '= ', but - if no space preceeds the preceeding character, insert a space - so that the resulting binary operator is surrounded by spaces. - 4. If the `ess-S-assign' string (e.g., '<- ') precedes point, - insert '== ' (a double *not* a single equals). - 5. Otherwise, just insert an '='. - -With a prefix argument, '=' always just inserts an '='. - -This is a global minor mode that will affect the use of '=' in -all ess-mode and inferior-ess-mode buffers. A local mode -may be included in a future version. - -Do not set the variable `ess-smart-equals-mode' directly; use the -function of the same name instead. Also any changes to -`ess-smart-S-assign-key' while this mode is enabled will have no -effect and will be lost when the mode is disabled." - :lighter nil - :require 'ess-site - (if (not ess-smart-equals-mode) - (progn ; reset to default with previous assign key - (setq ess-S-assign ess-smart-equals--last-assign-str) - (ess-toggle-S-assign nil) ; clear smart assignment - (setq ess-smart-S-assign-key ess-smart-equals--last-assign-key) - (ess-toggle-S-assign t)) - (setq ess-smart-equals--last-assign-key ess-smart-S-assign-key) - (setq ess-smart-equals--last-assign-str ess-S-assign) - (setq ess-S-assign (ess-smart-equals--strip-leading-space ess-S-assign)) - (setq ess-smart-S-assign-key "=") - (ess-toggle-S-assign nil) ;; reset ess map bindings - (define-key ess-mode-map ess-smart-S-assign-key 'ess-smart-equals) - (define-key inferior-ess-mode-map ess-smart-S-assign-key - 'ess-smart-equals))) - - -(provide 'ess-smart-equals) - -;;; ess-smart-equals.el ends here diff --git a/packages/esxml-20171129.807.tar b/packages/esxml-20171129.807.tar index 02899bd..5ecb146 100644 Binary files a/packages/esxml-20171129.807.tar and b/packages/esxml-20171129.807.tar differ diff --git a/packages/eval-sexp-fu-20180510.203.el b/packages/eval-sexp-fu-20190109.809.el similarity index 96% rename from packages/eval-sexp-fu-20180510.203.el rename to packages/eval-sexp-fu-20190109.809.el index 94def65..ba51459 100644 --- a/packages/eval-sexp-fu-20180510.203.el +++ b/packages/eval-sexp-fu-20190109.809.el @@ -2,10 +2,10 @@ ;; Copyright (C) 2009-2013 Takeshi Banse ;; Author: Takeshi Banse -;; Version: 0.4.2 -;; Package-Version: 20180510.203 +;; Version: 0.5.0 +;; Package-Version: 20190109.809 ;; Keywords: lisp, highlight, convenience -;; Package-Requires: ((cl-lib "0") (highlight "0")) +;; Package-Requires: ((cl-lib "0")) ;; 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 @@ -31,8 +31,7 @@ ;;; Installation: ;; -;; Put the highlight.el to your load-path. -;; Then require this package. +;; Require this package using (require 'eval-sexp-fu) ;;; Commands: ;; @@ -66,6 +65,9 @@ ;; `eval-sexp-fu-flash-function' ;; *Function to be used to create all of the actual flashing implementations. ;; default = (quote eval-sexp-fu-flash-default) +;; `eval-sexp-fu-overlay-priority' +;; Priority of the overlays created by esf-hl-highlight-bounds. +;; default = 0 ;; `eval-sexp-fu-flash-doit-function' ;; *Function to use for flashing the sexps. ;; default = (quote eval-sexp-fu-flash-doit-simple) @@ -81,6 +83,10 @@ ;;; History: +;; v0.5.0 +;; Remove dependency on highlight.el +;; Thank you very much, yuhan0. + ;; v0.4.2 ;; rename missing multiple-value-bind to cl-multiple-value-bind ;; Thank you very much, Hlöðver Sigurðsson @@ -111,7 +117,6 @@ (eval-when-compile (require 'cl)) (require 'cl-lib) -(require 'highlight) (defgroup eval-sexp-fu nil "Tiny functionality enhancements for evaluating sexps." @@ -151,6 +156,9 @@ :type '(choice (function-item eval-sexp-fu-flash-default) (function-item eval-sexp-fu-flash-paren-only)) :group 'eval-sexp-fu) +(defcustom eval-sexp-fu-overlay-priority 0 + "Priority of the overlays created by esf-hl-highlight-bounds." + :type 'integer :group 'eval-sexp-fu) ;;; Tools (defmacro esf-konstantly (v) @@ -167,10 +175,15 @@ (defun esf-hl-highlight-bounds (bounds face buf) (with-current-buffer buf - (hlt-highlight-region (car bounds) (cdr bounds) face))) + (let ((ov (make-overlay (car bounds) (cdr bounds)))) + (overlay-put ov 'face face) + (overlay-put ov 'esf-highlight t) + (overlay-put ov 'priority eval-sexp-fu-overlay-priority)))) (defun esf-hl-unhighlight-bounds (bounds buf) (with-current-buffer buf - (hlt-unhighlight-region (car bounds) (cdr bounds)))) + (dolist (ov (overlays-in (car bounds) (cdr bounds))) + (when (overlay-get ov 'esf-highlight) + (delete-overlay ov))))) (defun esf-flash-error-bounds (bounds buf face) (when face (let ((flash-error diff --git a/packages/evil-20181107.1016.tar b/packages/evil-20190729.704.tar similarity index 98% rename from packages/evil-20181107.1016.tar rename to packages/evil-20190729.704.tar index 4b5d005..5708d03 100644 Binary files a/packages/evil-20181107.1016.tar and b/packages/evil-20190729.704.tar differ diff --git a/packages/evil-cleverparens-20170718.413.tar b/packages/evil-cleverparens-20170718.413.tar index 63f980f..9df4059 100644 Binary files a/packages/evil-cleverparens-20170718.413.tar and b/packages/evil-cleverparens-20170718.413.tar differ diff --git a/packages/evil-commentary-20170413.1451.tar b/packages/evil-commentary-20170413.1451.tar index e2f53cb..adf2452 100644 Binary files a/packages/evil-commentary-20170413.1451.tar and b/packages/evil-commentary-20170413.1451.tar differ diff --git a/packages/evil-goggles-20180725.952.el b/packages/evil-goggles-20181123.1946.el similarity index 99% rename from packages/evil-goggles-20180725.952.el rename to packages/evil-goggles-20181123.1946.el index 69c5341..db1a7ff 100644 --- a/packages/evil-goggles-20180725.952.el +++ b/packages/evil-goggles-20181123.1946.el @@ -4,7 +4,7 @@ ;; Author: edkolev ;; URL: http://github.com/edkolev/evil-goggles -;; Package-Version: 20180725.952 +;; Package-Version: 20181123.1946 ;; Package-Requires: ((emacs "24.4") (evil "1.0.0")) ;; Version: 0.0.1 ;; Keywords: emulations, evil, vim, visual @@ -137,7 +137,7 @@ background of 'evil-goggles-default-face, then 'region." (numberp end) ;; don't show overlay if the region is a single char on a single line (not (and (<= (- end beg) 1) - (= (line-number-at-pos beg) (line-number-at-pos end)))) + (<= (count-lines beg end) 1))) (<= (point-min) beg end) (>= (point-max) end beg) (not (evil-visual-state-p)) @@ -416,7 +416,7 @@ BEG and END are the argumenets to the original functions." (when (and (called-interactively-p 'interactive) (evil-goggles--show-p beg end) ;; don't show goggles for single lines ("J"/"gJ" without count) - (< 1 (- (line-number-at-pos end) (line-number-at-pos beg)))) + (< 1 (count-lines beg end))) (evil-goggles--show-blocking-hint beg end))) ;;; fill diff --git a/packages/evil-magit-20180702.1553.el b/packages/evil-magit-20190620.153.el similarity index 87% rename from packages/evil-magit-20180702.1553.el rename to packages/evil-magit-20190620.153.el index 9062d85..91f0bcb 100644 --- a/packages/evil-magit-20180702.1553.el +++ b/packages/evil-magit-20190620.153.el @@ -4,7 +4,7 @@ ;; Author: Justin Burkett ;; Package-Requires: ((evil "1.2.3") (magit "2.6.0")) -;; Package-Version: 20180702.1553 +;; Package-Version: 20190620.153 ;; Homepage: https://github.com/justbur/evil-magit ;; Version: 0.4.1 @@ -146,12 +146,11 @@ should be a string suitable for `kbd'." "Modes that switch from default state to `evil-magit-state'") (defvar evil-magit-untouched-modes + ;; TODO do something here '(git-popup-mode magit-blame-mode magit-blame-read-only-mode - magit-file-mode - magit-popup-mode - magit-popup-sequence-mode) + magit-file-mode) "Modes whose evil states are unchanged") (defvar evil-magit-ignored-modes @@ -160,7 +159,7 @@ should be a string suitable for `kbd'." magit-blame-put-keymap-before-view-mode magit-diff-mode magit-merge-preview-mode - magit-popup-help-mode + transient-resume-mode magit-rebase-mode magit-file-mode-major-mode magit-wip-after-save-mode @@ -168,6 +167,8 @@ should be a string suitable for `kbd'." magit-wip-after-save-local-mode magit-wip-after-apply-mode magit-wip-before-change-mode + magit-wip-initial-backup-mode + magit-wip-mode ;; gh magit-gh-pulls-mode ;; git-gutter @@ -222,6 +223,9 @@ evil-magit was loaded." magit-diffstat-section-map magit-headers-section-map magit-message-section-map + ;; FIXME: deal with new bindings in this one + magit-module-section-map + magit-modules-section-map magit-processbuf-section-map magit-process-section-map magit-pulls-section-map @@ -281,14 +285,15 @@ moment.") (,states magit-mode-map "x" magit-delete-thing "k") (,states magit-mode-map "X" magit-file-untrack "K") (,states magit-mode-map "-" magit-revert-no-commit "v") - (,states magit-mode-map "_" magit-revert-popup "V") - (,states magit-mode-map "p" magit-push-popup "P") - (,states magit-mode-map "o" magit-reset "x") - (,states magit-mode-map "O" magit-reset-popup "X") + (,states magit-mode-map "_" magit-revert "V") + (,states magit-mode-map "p" magit-push "P") + (,states magit-mode-map "o" magit-reset-quickly "x") + (,states magit-mode-map "O" magit-reset "X") (,states magit-mode-map "|" magit-git-command ":") - (,states magit-mode-map "'" magit-submodule-popup "o") - (,states magit-mode-map "\"" magit-subtree-popup "O") + (,states magit-mode-map "'" magit-submodule "o") + (,states magit-mode-map "\"" magit-subtree "O") (,states magit-mode-map "=" magit-diff-less-context "-") + (,states magit-mode-map "@" forge-dispatch) (,states magit-mode-map "j" evil-next-visual-line) (,states magit-mode-map "k" evil-previous-visual-line) (,states magit-mode-map "gg" evil-goto-first-line) @@ -326,14 +331,17 @@ moment.") (,states magit-status-mode-map "gfp" magit-jump-to-unpulled-from-pushremote "jfp") (,states magit-status-mode-map "gpu" magit-jump-to-unpushed-to-upstream "jpu") (,states magit-status-mode-map "gpp" magit-jump-to-unpushed-to-pushremote "jpp") + (,states magit-status-mode-map "gh" magit-section-up "^") (,states magit-diff-mode-map "gj" magit-section-forward) (,states magit-diff-mode-map "gd" magit-jump-to-diffstat-or-diff "j") - ((emacs) magit-popup-mode-map "" "q")) + ;; NOTE This is now transient-map and the binding is C-g. + ;; ((emacs) magit-popup-mode-map "" "q") + ) (when evil-magit-want-horizontal-movement - `((,states magit-mode-map "H" magit-dispatch-popup "h") - (,states magit-mode-map "L" magit-log-popup "l") - (,states magit-mode-map "C-l" magit-log-refresh-popup "L") + `((,states magit-mode-map "H" magit-dispatch "h") + (,states magit-mode-map "L" magit-log "l") + (,states magit-mode-map "C-l" magit-log-refresh "L") (,states magit-mode-map "h" evil-backward-char) (,states magit-mode-map "l" evil-forward-char))) @@ -346,7 +354,7 @@ moment.") (,states magit-mode-map "C-w" evil-window-map) (,states magit-mode-map "y") (,states magit-mode-map "yy" evil-yank-line) - (,states magit-mode-map "yr" magit-show-refs-popup "y") + (,states magit-mode-map "yr" magit-show-refs "y") (,states magit-mode-map "ys" magit-copy-section-value "C-w") (,states magit-mode-map "yb" magit-copy-buffer-revision "M-w") ((visual) magit-mode-map "y" evil-yank)) @@ -501,6 +509,14 @@ denotes the original magit key for this command.") ;; section maps: evil's auxiliary maps don't work here, because these maps are ;; text overlays +(defun evil-magit-stage-untracked-file-with-intent () + "Call `magit-stage-untracked' with optional arg." + (interactive) + (when (and (derived-mode-p 'magit-mode) + (magit-apply--get-selection) + (eq (magit-diff-type) 'untracked)) + (magit-stage-untracked t))) + (defvar evil-magit-original-section-bindings `((,(copy-keymap magit-file-section-map) "\C-j" magit-diff-visit-file-worktree) (,(copy-keymap magit-hunk-section-map) "\C-j" magit-diff-visit-file-worktree)) @@ -509,64 +525,76 @@ evil-magit affects.") (defun evil-magit-adjust-section-bindings () "Revert changed bindings in section maps generated by evil-magit" + (define-key magit-file-section-map "I" + 'evil-magit-stage-untracked-file-with-intent) (define-key magit-file-section-map "\C-j" nil) ; breaking change (define-key magit-hunk-section-map "\C-j" nil)) ; breaking change (defun evil-magit-revert-section-bindings () "Revert changed bindings in section maps generated by evil-magit" + (define-key magit-file-section-map "I" nil) (define-key magit-file-section-map "\C-j" 'magit-diff-visit-file-worktree) (define-key magit-hunk-section-map "\C-j" 'magit-diff-visit-file-worktree)) ;; Popups -(defvar evil-magit-dispatch-popup-backup (copy-sequence magit-dispatch-popup)) +(defvar evil-magit-dispatch-popup-backup + (copy-tree (get 'magit-dispatch 'transient--layout) t)) (defvar evil-magit-popup-keys-changed nil) (defvar evil-magit-popup-changes (append (when evil-magit-use-z-for-folds - '((magit-dispatch-popup :actions "z" "Z" magit-stash-popup))) + '((magit-dispatch "z" "Z" magit-stash))) (when evil-magit-want-horizontal-movement - '((magit-dispatch-popup :actions "L" "\C-l" magit-log-refresh-popup) - (magit-dispatch-popup :actions "l" "L" magit-log-popup))) - '((magit-branch-popup :actions "x" "X" magit-branch-reset) - (magit-branch-popup :actions "k" "x" magit-branch-delete) - (magit-dispatch-popup :actions "o" "'" magit-submodule-popup) - (magit-dispatch-popup :actions "O" "\"" magit-subtree-popup) - (magit-dispatch-popup :actions "V" "_" magit-revert-popup) - (magit-dispatch-popup :actions "X" "O" magit-reset-popup) - (magit-dispatch-popup :actions "v" "-" magit-reverse) - (magit-dispatch-popup :actions "k" "x" magit-discard) - (magit-remote-popup :actions "k" "x" magit-remote-remove) - (magit-revert-popup :actions "v" "o" magit-revert-no-commit) - (magit-revert-popup :actions "V" "O" magit-revert) - (magit-revert-popup :sequence-actions "V" "O" magit-sequencer-continue) - (magit-tag-popup :actions "k" "x" magit-tag-delete))) + '((magit-dispatch "L" "\C-l" magit-log-refresh) + (magit-dispatch "l" "L" magit-log))) + '((magit-branch "x" "X" magit-branch-reset) + (magit-branch "k" "x" magit-branch-delete) + (magit-dispatch "o" "'" magit-submodule) + (magit-dispatch "O" "\"" magit-subtree) + (magit-dispatch "V" "_" magit-revert) + (magit-dispatch "X" "O" magit-reset) + (magit-dispatch "v" "-" magit-reverse) + (magit-dispatch "k" "x" magit-discard) + (magit-remote "k" "x" magit-remote-remove) + (magit-revert "v" "o" magit-revert-no-commit) + ;; FIXME: how to properly handle a popup with a key that appears twice (in + ;; `define-transient-command' definition)? Currently we rely on: + ;; 1. first call to `evil-magit-change-popup-key' changes the first "V" + ;; entry of `magit-revert' (the first entry in `define-transient-command' + ;; definition of `magit-revert'), second call changes the second "V". + ;; 2. the remapping here are in the same order as in `magit-revert' + ;; definition + (magit-revert "V" "O" magit-revert-and-commit) + (magit-revert "V" "O" magit-sequencer-continue) + (magit-tag "k" "x" magit-tag-delete))) "Changes to popup keys") -(defun evil-magit-change-popup-key (popup type from to _) +(defun evil-magit-change-popup-key (popup from to &rest _args) "Wrap `magit-change-popup-key'." - (magit-change-popup-key popup type (string-to-char from) (string-to-char to)) - ;; Support C-a -- C-z - (when (and (>= (string-to-char to) 1) - (<= (string-to-char to) 26)) - (define-key magit-popup-mode-map to #'magit-invoke-popup-action))) + (transient-suffix-put popup from :key to)) (defun evil-magit-adjust-popups () "Adjust popup keys to match evil-magit." (unless evil-magit-popup-keys-changed (dolist (change evil-magit-popup-changes) (apply #'evil-magit-change-popup-key change)) + (with-eval-after-load 'forge + (transient-remove-suffix 'magit-dispatch 'forge-dispatch) + (transient-append-suffix 'magit-dispatch "!" + '("@" "Forge" forge-dispatch))) (setq evil-magit-popup-keys-changed t))) (defun evil-magit-revert-popups () "Revert popup keys changed by evil-magit." - (setq magit-dispatch-popup evil-magit-dispatch-popup-backup) + (put 'magit-dispatch 'transient--layout evil-magit-dispatch-popup-backup) (when evil-magit-popup-keys-changed (dolist (change evil-magit-popup-changes) - (magit-change-popup-key - (nth 0 change) (nth 1 change) - (string-to-char (nth 3 change)) (string-to-char (nth 2 change)))) + (evil-magit-change-popup-key + (nth 0 change) (nth 2 change) (nth 1 change))) + (with-eval-after-load 'forge + (transient-suffix-put 'magit-dispatch "@" :key "'")) (setq evil-magit-popup-keys-changed nil))) ;;;###autoload diff --git a/packages/evil-matchit-20181111.604.tar b/packages/evil-matchit-20190808.1056.tar similarity index 89% rename from packages/evil-matchit-20181111.604.tar rename to packages/evil-matchit-20190808.1056.tar index 7e0b5b0..056aaba 100644 Binary files a/packages/evil-matchit-20181111.604.tar and b/packages/evil-matchit-20190808.1056.tar differ diff --git a/packages/evil-mc-20180921.1727.tar b/packages/evil-mc-20190321.1606.tar similarity index 94% rename from packages/evil-mc-20180921.1727.tar rename to packages/evil-mc-20190321.1606.tar index 8e1019b..c4af4f2 100644 Binary files a/packages/evil-mc-20180921.1727.tar and b/packages/evil-mc-20190321.1606.tar differ diff --git a/packages/evil-nerd-commenter-20180722.2325.tar b/packages/evil-nerd-commenter-20190801.148.tar similarity index 71% rename from packages/evil-nerd-commenter-20180722.2325.tar rename to packages/evil-nerd-commenter-20190801.148.tar index 0f2b746..1997b93 100644 Binary files a/packages/evil-nerd-commenter-20180722.2325.tar and b/packages/evil-nerd-commenter-20190801.148.tar differ diff --git a/packages/evil-org-20180323.2306.tar b/packages/evil-org-20180323.2306.tar index f3a1a09..1331870 100644 Binary files a/packages/evil-org-20180323.2306.tar and b/packages/evil-org-20180323.2306.tar differ diff --git a/packages/evil-surround-20181020.1248.el b/packages/evil-surround-20190403.418.el similarity index 87% rename from packages/evil-surround-20181020.1248.el rename to packages/evil-surround-20190403.418.el index 2c00199..23fab02 100644 --- a/packages/evil-surround-20181020.1248.el +++ b/packages/evil-surround-20190403.418.el @@ -1,16 +1,17 @@ ;;; evil-surround.el --- emulate surround.vim from Vim ;; Copyright (C) 2010 - 2017 Tim Harper +;; Copyright (C) 2018 - 2019 The evil-surround.el Contributors ;; Licensed under the same terms as Emacs (GPLv3) ;; ;; Author: Tim Harper -;; Vegard Øye +;; Vegard Øye ;; Current Maintainer: ninrod (github.com/ninrod) ;; Created: July 23 2011 -;; Version: 0.1 -;; Package-Version: 20181020.1248 +;; Version: 1.0.3 +;; Package-Version: 20190403.418 ;; Package-Requires: ((evil "1.2.12")) ;; Mailing list: ;; Subscribe: http://tinyurl.com/implementations-list @@ -88,13 +89,23 @@ Each item is of the form (OPERATOR . OPERATION)." (defvar evil-surround-read-tag-map (let ((map (copy-keymap minibuffer-local-map))) - (define-key map ">" 'exit-minibuffer) + (define-key map ">" (lambda () + (interactive) + (call-interactively 'self-insert-command) + (run-at-time nil nil + (lambda () + (when (active-minibuffer-window) + (select-window (active-minibuffer-window)) + (exit-minibuffer)))))) map) "Keymap used by `evil-surround-read-tag'.") (defvar evil-surround-record-repeat nil "Flag to indicate we're manually recording repeat info.") +(defvar evil-surround-last-deleted-left "" + "The previously deleted LEFT region.") + (defun evil-surround-read-from-minibuffer (&rest args) (when evil-surround-record-repeat (evil-repeat-keystrokes 'post)) @@ -124,19 +135,40 @@ Each item is of the form (OPERATOR . OPERATION)." (cons (format "%s(" (or fname "")) ")"))) +(defconst evil-surround-tag-name-re "\\([0-9a-z-]+\\)" + "Regexp matching an XML tag name.") + +(defun evil-surround-tag-p (string) + "Return t if `STRING' looks like a tag." + (string-match-p evil-surround-tag-name-re string)) + (defun evil-surround-read-tag () "Read a XML tag from the minibuffer." (let* ((input (evil-surround-read-from-minibuffer "<" "" evil-surround-read-tag-map)) - (match (string-match "\\([0-9a-z-]+\\)\\(.*?\\)[>]*$" input)) + (match (string-match (concat evil-surround-tag-name-re "\\(.*?\\)\\([>]*\\)$") input)) (tag (match-string 1 input)) - (rest (match-string 2 input))) - (cons (format "<%s%s>" (or tag "") (or rest "")) + (rest (match-string 2 input)) + (keep-attributes (not (string-match-p ">" input))) + (original-tag (when (evil-surround-tag-p evil-surround-last-deleted-left) + (substring evil-surround-last-deleted-left + (string-match (concat "<" evil-surround-tag-name-re) evil-surround-last-deleted-left) + (match-end 0)))) + (original-attributes (when (and keep-attributes original-tag) + (substring evil-surround-last-deleted-left (length original-tag))))) + (cons (format "<%s%s%s" (or tag "") (or rest "") (or original-attributes ">")) (format "" (or tag ""))))) (defun evil-surround-valid-char-p (char) "Returns whether CHAR is a valid surround char or not." (not (memq char '(?\C-\[ ?\C-?)))) +(defun evil-surround-delete-char-noop-p (char) + "Returns whether CHAR is a noop when used with surround delete." + (memq char (list (string-to-char "w") + (string-to-char "W") + (string-to-char "s") + (string-to-char "p")))) + (defun evil-surround-pair (char) "Return the evil-surround pair of char. This is a cons cell (LEFT . RIGHT), both strings." @@ -210,7 +242,8 @@ between these overlays is what is deleted." (interactive (evil-surround-input-char)) (cond ((and outer inner) - (delete-region (overlay-start outer) (overlay-start inner)) + (setq evil-surround-last-deleted-left + (delete-and-extract-region (overlay-start outer) (overlay-start inner))) (delete-region (overlay-end inner) (overlay-end outer)) (goto-char (overlay-start outer))) (t @@ -232,7 +265,8 @@ overlays OUTER and INNER, which are passed to `evil-surround-delete'." (interactive (evil-surround-input-char)) (cond ((and outer inner) - (evil-surround-delete char outer inner) + (unless (evil-surround-delete-char-noop-p char) + (evil-surround-delete char outer inner)) (let ((key (evil-surround-read-char))) (evil-surround-region (overlay-start outer) (overlay-end outer) diff --git a/packages/evil-textobj-line-20150729.1522.el b/packages/evil-textobj-line-20150729.1522.el new file mode 100644 index 0000000..955f78f --- /dev/null +++ b/packages/evil-textobj-line-20150729.1522.el @@ -0,0 +1,68 @@ +;;; evil-textobj-line.el --- evil textobj line + +;; Copyright (C) 2015 by Syohei YOSHIDA + +;; Author: Syohei YOSHIDA +;; URL: https://github.com/syohex/emacs-evil-textobj-line +;; Package-Version: 20150729.1522 +;; Version: 0.01 +;; Package-Requires: ((evil "1.0.0")) + +;; 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 . + +;;; Commentary: + +;;; Code: + +(require 'evil) + +(defgroup evil-textobj-line nil + "Text object line for Evil" + :group 'evil) + +(defcustom evil-textobj-line-i-key "l" + "Keys for evil-inner-line" + :type 'string + :group 'evil-textobj-line) + +(defcustom evil-textobj-line-a-key "l" + "Keys for evil-a-line" + :type 'string + :group 'evil-textobj-line) + +(defun evil-line-range (count beg end type &optional inclusive) + (if inclusive + (evil-range (line-beginning-position) (line-end-position)) + (let ((start (save-excursion + (back-to-indentation) + (point))) + (end (save-excursion + (goto-char (line-end-position)) + (skip-syntax-backward " " (line-beginning-position)) + (point)))) + (evil-range start end)))) + +(evil-define-text-object evil-a-line (count &optional beg end type) + "Select range between a character by which the command is followed." + (evil-line-range count beg end type t)) +(evil-define-text-object evil-inner-line (count &optional beg end type) + "Select inner range between a character by which the command is followed." + (evil-line-range count beg end type)) + +(define-key evil-outer-text-objects-map evil-textobj-line-a-key 'evil-a-line) +(define-key evil-inner-text-objects-map evil-textobj-line-i-key 'evil-inner-line) + +(provide 'evil-textobj-line) + +;;; evil-textobj-line.el ends here diff --git a/packages/evil-tutor-20150103.650.tar b/packages/evil-tutor-20150103.650.tar index 58058b6..761194a 100644 Binary files a/packages/evil-tutor-20150103.650.tar and b/packages/evil-tutor-20150103.650.tar differ diff --git a/packages/evil-tutor-ja-20160917.132.tar b/packages/evil-tutor-ja-20160917.132.tar index e61150d..0e59b30 100644 Binary files a/packages/evil-tutor-ja-20160917.132.tar and b/packages/evil-tutor-ja-20160917.132.tar differ diff --git a/packages/evil-visual-mark-mode-20150202.1800.el b/packages/evil-visual-mark-mode-20190116.1557.el similarity index 88% rename from packages/evil-visual-mark-mode-20150202.1800.el rename to packages/evil-visual-mark-mode-20190116.1557.el index ad3ff56..1d4082d 100644 --- a/packages/evil-visual-mark-mode-20150202.1800.el +++ b/packages/evil-visual-mark-mode-20190116.1557.el @@ -5,7 +5,7 @@ ;; Author: Roman Gonzalez ;; Maintainer: Roman Gonzalez ;; Version: 0.0.3 -;; Package-Version: 20150202.1800 +;; Package-Version: 20190116.1557 ;; Package-Requires: ((evil "1.0.9") (dash "2.10")) ;; Keywords: evil @@ -87,11 +87,12 @@ This function is called when enabling the evil-visual-marker-mode." (-map (lambda (it) (let* ((letter (car it)) + (buffer (evil-marker-get-buffer letter)) (marker (cdr it)) (new-item (list nil nil)) (new-overlay (evil-visual-mark-make-overlay marker))) - (setf (car new-item) letter) + (setf (car new-item) (cons letter buffer)) (setf (cdr new-item) new-overlay) @@ -112,7 +113,7 @@ This function is called on `evil-normal-state-exit-hook.'" This function is called on `evil-normal-state-entry-hook'." (--each evil-visual-mark-overlay-alist - (evil-visual-mark-overlay-put (car it) (cdr it)))) + (evil-visual-mark-overlay-put (car (car it)) (cdr it)))) (defun evil-visual-mark-render () "Render for the first time the evil mark list. @@ -122,7 +123,7 @@ This function is called on the initialization of (evil-visual-mark-populate-overlay-alist) (when (evil-normal-state-p) (--each evil-visual-mark-overlay-alist - (evil-visual-mark-overlay-put (car it) + (evil-visual-mark-overlay-put (car (car it)) (cdr it))))) (defun evil-visual-mark-cleanup () @@ -133,6 +134,18 @@ This function is called when disabling `evil-visual-mark-mode'" (lambda (it) (delete-overlay (cdr it)))) (setq evil-visual-mark-overlay-alist '())) +(defun evil-global-marker-char? (char) + (and (>= char ?A) (<= char ?Z))) + +(defun evil-marker-get-buffer (char) + (if (evil-global-marker-char? char) + 'global + (current-buffer))) + +(defun evil-marker-get-item (char) + (let* ((buffer (evil-marker-get-buffer char))) + (assoc (cons char buffer) evil-visual-mark-overlay-alist))) + (defun evil-visual-mark-update-mark (char marker) "Update overlay value for CHAR. @@ -142,14 +155,15 @@ the result of calling that function." (markerp marker)) (let* ((new-overlay (evil-visual-mark-make-overlay marker)) - (old-item (assoc char evil-visual-mark-overlay-alist)) + (buffer (evil-marker-get-buffer char)) + (old-item (evil-marker-get-item char)) (old-overlay (and old-item (cdr old-item)))) ;; update overlay state for given char (if old-item (setf (cdr old-item) new-overlay) (let ((new-item (list nil nil))) - (setf (car new-item) char) + (setf (car new-item) (cons char buffer)) (setf (cdr new-item) new-overlay) (add-to-list 'evil-visual-mark-overlay-alist new-item))) diff --git a/packages/ewal-20190820.1702.tar b/packages/ewal-20190820.1702.tar new file mode 100644 index 0000000..792eae9 Binary files /dev/null and b/packages/ewal-20190820.1702.tar differ diff --git a/packages/ewal-spacemacs-themes-20190821.451.tar b/packages/ewal-spacemacs-themes-20190821.451.tar new file mode 100644 index 0000000..a89f564 Binary files /dev/null and b/packages/ewal-spacemacs-themes-20190821.451.tar differ diff --git a/packages/exec-path-from-shell-20180324.204.el b/packages/exec-path-from-shell-20190426.2227.el similarity index 96% rename from packages/exec-path-from-shell-20180324.204.el rename to packages/exec-path-from-shell-20190426.2227.el index 6877253..712a9a2 100644 --- a/packages/exec-path-from-shell-20180324.204.el +++ b/packages/exec-path-from-shell-20190426.2227.el @@ -5,7 +5,7 @@ ;; Author: Steve Purcell ;; Keywords: unix, environment ;; URL: https://github.com/purcell/exec-path-from-shell -;; Package-Version: 20180324.204 +;; Package-Version: 20190426.2227 ;; Package-X-Original-Version: 0 ;; This file is not part of GNU Emacs. @@ -120,9 +120,12 @@ See documentation for `exec-path-from-shell-shell-name'." (error "SHELL environment variable is unset"))) (defcustom exec-path-from-shell-arguments - (if (string-match-p "t?csh$" (exec-path-from-shell--shell)) - (list "-d") - (list "-l" "-i")) + (let ((shell (exec-path-from-shell--shell))) + (if (string-match-p "t?csh$" shell) + (list "-d") + (if (string-match-p "fish" shell) + (list "-l") + (list "-l" "-i")))) "Additional arguments to pass to the shell. The default value denotes an interactive login shell." @@ -178,6 +181,8 @@ shell-escaped, so they may contain $ etc." Execute the shell according to `exec-path-from-shell-arguments'. The result is a list of (NAME . VALUE) pairs." + (when (file-remote-p default-directory) + (error "You cannot run exec-path-from-shell from a remote buffer (Tramp, etc.)")) (let* ((random-default (md5 (format "%s%s%s" (emacs-pid) (random) (current-time)))) (dollar-names (mapcar (lambda (n) (format "${%s-%s}" n random-default)) names)) (values (split-string (exec-path-from-shell-printf diff --git a/packages/expand-region-20180817.1134.tar b/packages/expand-region-20190416.538.tar similarity index 92% rename from packages/expand-region-20180817.1134.tar rename to packages/expand-region-20190416.538.tar index b4d4be4..0fe9567 100644 Binary files a/packages/expand-region-20180817.1134.tar and b/packages/expand-region-20190416.538.tar differ diff --git a/packages/eyebrowse-20180514.1919.el b/packages/eyebrowse-20190322.933.el similarity index 97% rename from packages/eyebrowse-20180514.1919.el rename to packages/eyebrowse-20190322.933.el index c6554c5..d1c9cd7 100644 --- a/packages/eyebrowse-20180514.1919.el +++ b/packages/eyebrowse-20190322.933.el @@ -4,7 +4,7 @@ ;; Author: Vasilij Schneidermann ;; URL: https://github.com/wasamasa/eyebrowse -;; Package-Version: 20180514.1919 +;; Package-Version: 20190322.933 ;; Version: 0.7.7 ;; Package-Requires: ((dash "2.7.0") (emacs "24.3.1")) ;; Keywords: convenience @@ -96,10 +96,13 @@ nil, 'hide: Don't show at all. 'smart: Hide when only one window config. +'current: Only show current config. + t, 'always: Always show." :type '(choice (const :tag "Hide" hide) (const :tag "Smart" smart) - (const :tag "Always" always)) + (const :tag "Always" always) + (const :tag "Current" current)) :group 'eyebrowse) (defcustom eyebrowse-wrap-around nil @@ -560,14 +563,15 @@ Currently only gt, gT, gc and zx are supported." (define-key evil-motion-state-map (kbd "zx") 'eyebrowse-last-window-config)) ;;;###autoload -(defun eyebrowse-setup-opinionated-keys () +(defun eyebrowse-setup-opinionated-keys (&optional ignore-evil) "Set up more opinionated key bindings for using eyebrowse. -M-0..M-9, C-< / C->, C-'and C-\" are used for switching. If Evil -is detected, extra key bindings will be set up with -`eyebrowse-setup-evil-keys' as well." +M-0..M-9, C-< / C->, C-'and C-\" are used for switching. If +IGNORE-EVIL isn't set and Evil is detected, extra key bindings +will be set up with `eyebrowse-setup-evil-keys' as well." (let ((map eyebrowse-mode-map)) - (when (bound-and-true-p evil-mode) + (when (and (not ignore-evil) + (bound-and-true-p evil-mode)) (eyebrowse-setup-evil-keys)) (define-key map (kbd "C-<") 'eyebrowse-prev-window-config) (define-key map (kbd "C->") 'eyebrowse-next-window-config) @@ -607,7 +611,9 @@ is detected, extra key bindings will be set up with (separator (propertize eyebrowse-mode-line-separator 'face 'eyebrowse-mode-line-separator)) (current-slot (eyebrowse--get 'current-slot)) - (window-configs (eyebrowse--get 'window-configs))) + (window-configs (if (eq eyebrowse-mode-line-style 'current) + (list (assoc current-slot (eyebrowse--get 'window-configs))) + (eyebrowse--get 'window-configs)))) (if (and eyebrowse-mode-line-style (not (eq eyebrowse-mode-line-style 'hide)) (or (and (not (eq eyebrowse-mode-line-style 'smart)) diff --git a/packages/eziam-theme-20180414.1029.tar b/packages/eziam-theme-20190720.1720.tar similarity index 84% rename from packages/eziam-theme-20180414.1029.tar rename to packages/eziam-theme-20190720.1720.tar index 3da20f8..64868df 100644 Binary files a/packages/eziam-theme-20180414.1029.tar and b/packages/eziam-theme-20190720.1720.tar differ diff --git a/packages/f-20180106.922.el b/packages/f-20190109.906.el similarity index 97% rename from packages/f-20180106.922.el rename to packages/f-20190109.906.el index 7124deb..c6f0ac3 100644 --- a/packages/f-20180106.922.el +++ b/packages/f-20190109.906.el @@ -5,7 +5,7 @@ ;; Author: Johan Andersson ;; Maintainer: Johan Andersson ;; Version: 0.20.0 -;; Package-Version: 20180106.922 +;; Package-Version: 20190109.906 ;; Keywords: files, directories ;; URL: http://github.com/rejeep/f.el ;; Package-Requires: ((s "1.7.0") (dash "2.2.0")) @@ -236,15 +236,7 @@ TEXT with. PATH is a file name to write to." "Write binary DATA to PATH. DATA is a unibyte string. PATH is a file name to write to." - (f--destructive path - (unless (f-unibyte-string-p data) - (signal 'wrong-type-argument (list 'f-unibyte-string-p data))) - (let ((file-coding-system-alist nil) - (coding-system-for-write 'binary)) - (with-temp-file path - (setq buffer-file-coding-system 'binary) - (set-buffer-multibyte nil) - (insert data))))) + (f--write-bytes data path nil)) (defalias 'f-append 'f-append-text) (defun f-append-text (text coding path) @@ -257,11 +249,19 @@ If PATH does not exist, it is created." "Append binary DATA to PATH. If PATH does not exist, it is created." - (let ((content - (if (f-file? path) - (f-read-bytes path) - ""))) - (f-write-bytes (concat content data) path))) + (f--write-bytes data path :append)) + +(defun f--write-bytes (data filename append) + "Write binary DATA to FILENAME. +If APPEND is non-nil, append the DATA to the existing contents." + (f--destructive filename + (unless (f-unibyte-string-p data) + (signal 'wrong-type-argument (list 'f-unibyte-string-p data))) + (let ((coding-system-for-write 'binary) + (write-region-annotate-functions nil) + (write-region-post-annotation-function nil)) + (write-region data nil filename append :silent) + nil))) ;;;; Destructive diff --git a/packages/farmhouse-theme-20160713.2244.tar b/packages/farmhouse-theme-20160713.2244.tar index 7465552..115335a 100644 Binary files a/packages/farmhouse-theme-20160713.2244.tar and b/packages/farmhouse-theme-20160713.2244.tar differ diff --git a/packages/fcitx-20170914.200.el b/packages/fcitx-20190806.1923.el similarity index 98% rename from packages/fcitx-20170914.200.el rename to packages/fcitx-20190806.1923.el index 9a20da0..db593a4 100644 --- a/packages/fcitx-20170914.200.el +++ b/packages/fcitx-20190806.1923.el @@ -4,7 +4,7 @@ ;; Author: Junpeng Qiu ;; Keywords: extensions -;; Package-Version: 20170914.200 +;; Package-Version: 20190806.1923 ;; URL: https://github.com/cute-jumper/fcitx.el ;; This program is free software; you can redistribute it and/or modify @@ -506,14 +506,18 @@ Default value is nil.") (defvar fcitx--aggressive-p nil "Whether we should disable fcitx whenever we're in the minibuffer.") +(defvar fcitx-remote-command "fcitx-remote" + "use fcitx (fcitx-remote) or fcitx5 (fcitx5-remote)") + + ;;;###autoload (defun fcitx-check-status () (not - (if (executable-find "fcitx-remote") + (if (executable-find fcitx-remote-command) (let ((output (let (deactivate-mark) (with-temp-buffer - (call-process "fcitx-remote" nil t) + (call-process fcitx-remote-command nil t) (buffer-string))))) (and (stringp output) (> (length output) 0) @@ -538,16 +542,16 @@ Re-run the setup function after `fcitx' is started."))) (fcitx--defun-dbus-or-proc active-p) (defun fcitx--activate-proc () - (call-process "fcitx-remote" nil nil nil "-o")) + (call-process fcitx-remote-command nil nil nil "-o")) (defun fcitx--deactivate-proc () - (call-process "fcitx-remote" nil nil nil "-c")) + (call-process fcitx-remote-command nil nil nil "-c")) (defun fcitx--active-p-proc () (let ((output (let (deactivate-mark) (with-temp-buffer - (call-process "fcitx-remote" nil t) + (call-process fcitx-remote-command nil t) (buffer-string))))) (char-equal (aref output 0) ?2))) diff --git a/packages/feature-mode-20170907.1448.tar b/packages/feature-mode-20190801.1137.tar similarity index 95% rename from packages/feature-mode-20170907.1448.tar rename to packages/feature-mode-20190801.1137.tar index df939e1..352c37b 100644 Binary files a/packages/feature-mode-20170907.1448.tar and b/packages/feature-mode-20190801.1137.tar differ diff --git a/packages/floobits-20180801.524.tar b/packages/floobits-20180801.524.tar index e7e80ab..ef40696 100644 Binary files a/packages/floobits-20180801.524.tar and b/packages/floobits-20180801.524.tar differ diff --git a/packages/flycheck-20181018.1021.tar b/packages/flycheck-20190821.926.tar similarity index 92% rename from packages/flycheck-20181018.1021.tar rename to packages/flycheck-20190821.926.tar index 8afde69..3efa8a4 100644 Binary files a/packages/flycheck-20181018.1021.tar and b/packages/flycheck-20190821.926.tar differ diff --git a/packages/flycheck-clojure-20190611.2351.el b/packages/flycheck-clojure-20190611.2351.el new file mode 100644 index 0000000..afc9cb3 --- /dev/null +++ b/packages/flycheck-clojure-20190611.2351.el @@ -0,0 +1,223 @@ +;;; flycheck-clojure.el --- Flycheck: Clojure support -*- lexical-binding: t; -*- + +;; Copyright © 2014 Peter Fraenkel +;; Copyright (C) 2014 Sebastian Wiesner +;; +;; Author: Peter Fraenkel +;; Sebastian Wiesner +;; Maintainer: Peter Fraenkel +;; URL: https://github.com/clojure-emacs/squiggly-clojure +;; Package-Version: 20190611.2351 +;; Version: 1.8.0 +;; Package-Requires: ((cider "0.22.0") (flycheck "32-cvs") (let-alist "1.0.1") (emacs "25")) + +;; This file is not part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 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 . + +;;; Commentary: + +;; Add Clojure support to Flycheck. +;; +;; Provide syntax checkers to check Clojure code using a running Cider repl. +;; +;; Installation: +;; +;; (eval-after-load 'flycheck '(flycheck-clojure-setup)) + +;;; Code: + +(require 'cider-client) +(require 'flycheck) +(require 'json) +(require 'url-parse) +(eval-when-compile (require 'let-alist)) + +(defcustom flycheck-clojure-inject-dependencies-at-jack-in t + "When nil, do not inject repl dependencies (i.e. the linters/checkers) at `cider-jack-in' time." + :group 'flycheck-clojure + :type 'boolean) + +(defvar flycheck-clojure-dep-version "0.1.9-SNAPSHOT" + "Version of `acyclic/squiggly-clojure' compatible with this version of flycheck-clojure.") + +;;;###autoload +(defun flycheck-clojure-parse-cider-errors (value checker) + "Parse cider errors from JSON VALUE from CHECKER. + +Return a list of parsed `flycheck-error' objects." + ;; Parse the nested JSON from Cider. The outer JSON contains the return value + ;; from Cider, and the inner JSON the errors returned by the individual + ;; checker. + (let ((error-objects (json-read-from-string (json-read-from-string value)))) + (mapcar (lambda (o) + (let-alist o + ;; Use the file name reported by the syntax checker, but only if + ;; its absolute, because typed reports relative file names that + ;; are hard to expand correctly, since they are relative to the + ;; source directory (not the project directory). + (let* ((parsed-file (when .file + (url-filename + (url-generic-parse-url .file)))) + (filename (if (and parsed-file + (file-name-absolute-p parsed-file) + (not (string-prefix-p (expand-file-name "~/.boot/cache") parsed-file))) + parsed-file + (buffer-file-name)))) + (flycheck-error-new-at .line .column (intern .level) .msg + :checker checker + :filename filename)))) + error-objects))) + +(defun cider-flycheck-eval (input callback) + "Send the request INPUT and register the CALLBACK as the response handler. +Uses the tooling session, with no specified namespace." + (cider-tooling-eval input callback)) + +(defun flycheck-clojure-may-use-cider-checker () + "Determine whether a cider checker may be used. + +Checks for `cider-mode', and a current nREPL connection. + +Standard predicate for cider checkers." + (let ((connection-buffer (cider-current-repl))) + (and (bound-and-true-p cider-mode) + connection-buffer + (buffer-live-p (get-buffer connection-buffer)) + (clojure-find-ns)))) + +(defun flycheck-clojure-start-cider (checker callback) + "Start a cider syntax CHECKER with CALLBACK." + (let ((ns (clojure-find-ns)) + (form (get checker 'flycheck-clojure-form))) + (cider-flycheck-eval + (funcall form ns) + (nrepl-make-response-handler + (current-buffer) + (lambda (buffer value) + (funcall callback 'finished + (with-current-buffer buffer + (flycheck-clojure-parse-cider-errors value checker)))) + nil ; stdout + nil ; stderr + (lambda (_) + ;; If the evaluation completes without returning any value, there has + ;; gone something wrong. Ideally, we'd report *what* was wrong, but + ;; `nrepl-make-response-handler' is close to useless for this :(, + ;; because it just `message's for many status codes that are errors for + ;; us :( + (funcall callback 'errored "Done with no errors")) + (lambda (_buffer ex _rootex _sess) + (funcall callback 'errored + (format "Form %s of checker %s failed: %s" + form checker ex)))))) +) + +(defun flycheck-clojure-define-cider-checker (name docstring &rest properties) + "Define a Cider syntax checker with NAME, DOCSTRING and PROPERTIES. + +NAME, DOCSTRING, and PROPERTIES are like for +`flycheck-define-generic-checker', except that `:start' and +`:modes' are invalid PROPERTIES. A syntax checker defined with +this function will always check in `clojure-mode', and only if +`cider-mode' is enabled. + +Instead of `:start', this syntax checker requires a `:form +FUNCTION' property. FUNCTION takes the current Clojure namespace +as single argument, and shall return a string containing a +Clojure form to be sent to Cider to check the current buffer." + (declare (indent 1) + (doc-string 2)) + (let* ((form (plist-get properties :form)) + (orig-predicate (plist-get properties :predicate))) + + (when (plist-get :start properties) + (error "Checker %s may not have :start" name)) + (when (plist-get :modes properties) + (error "Checker %s may not have :modes" name)) + (unless (functionp form) + (error ":form %s of %s not a valid function" form name)) + (apply #'flycheck-define-generic-checker + name docstring + :start #'flycheck-clojure-start-cider + :modes '(clojure-mode) + :predicate (if orig-predicate + (lambda () + (and (flycheck-clojure-may-use-cider-checker) + (funcall orig-predicate))) + #'flycheck-clojure-may-use-cider-checker) + properties) + + (put name 'flycheck-clojure-form form))) + +(flycheck-clojure-define-cider-checker 'clojure-cider-eastwood + "A syntax checker for Clojure, using Eastwood in Cider. + +See URL `https://github.com/jonase/eastwood' and URL +`https://github.com/clojure-emacs/cider/' for more information." + :form (lambda (ns) + (format "(do (require 'squiggly-clojure.core) (squiggly-clojure.core/check-ew '%s))" + ns)) + :next-checkers '(clojure-cider-kibit clojure-cider-typed)) + +(flycheck-clojure-define-cider-checker 'clojure-cider-kibit + "A syntax checker for Clojure, using Kibit in Cider. + +See URL `https://github.com/jonase/kibit' and URL +`https://github.com/clojure-emacs/cider/' for more information." + :form (lambda (ns) + (format + "(do (require 'squiggly-clojure.core) (squiggly-clojure.core/check-kb '%s %s))" + ns + ;; Escape file name for Clojure + (flycheck-sexp-to-string (buffer-file-name)))) + :predicate (lambda () (buffer-file-name)) + :next-checkers '(clojure-cider-typed)) + +(flycheck-clojure-define-cider-checker 'clojure-cider-typed + "A syntax checker for Clojure, using Typed Clojure in Cider. + +See URL `https://github.com/clojure-emacs/cider/' and URL +`https://github.com/clojure/core.typed' for more information." + :form (lambda (ns) + (format + "(do (require 'squiggly-clojure.core) (squiggly-clojure.core/check-tc '%s))" + ns))) + +(defun flycheck-clojure-inject-jack-in-dependencies () + "Inject the REPL dependencies of flycheck-clojure at `cider-jack-in'. +If injecting the dependencies is not preferred set `flycheck-clojure-inject-dependencies-at-jack-in' to nil." + (when (and flycheck-clojure-inject-dependencies-at-jack-in + (boundp 'cider-jack-in-dependencies)) + (cider-add-to-alist 'cider-jack-in-dependencies "acyclic/squiggly-clojure" flycheck-clojure-dep-version) + (cider-add-to-alist 'cider-jack-in-dependencies-exclusions "acyclic/squiggly-clojure" '("org.clojure/tools.reader")))) + +;;;###autoload +(defun flycheck-clojure-setup () + "Setup Flycheck for Clojure." + (interactive) + ;; Add checkers in reverse order, because `add-to-list' adds to front. + (dolist (checker '(clojure-cider-typed + clojure-cider-kibit + clojure-cider-eastwood)) + (add-to-list 'flycheck-checkers checker)) + (flycheck-clojure-inject-jack-in-dependencies)) + +(provide 'flycheck-clojure) + +;; Local Variables: +;; indent-tabs-mode: nil +;; End: + +;;; flycheck-clojure.el ends here diff --git a/packages/flycheck-golangci-lint-20180711.817.el b/packages/flycheck-golangci-lint-20190330.1412.el similarity index 67% rename from packages/flycheck-golangci-lint-20180711.817.el rename to packages/flycheck-golangci-lint-20190330.1412.el index d0fbec6..03c6e49 100644 --- a/packages/flycheck-golangci-lint-20180711.817.el +++ b/packages/flycheck-golangci-lint-20190330.1412.el @@ -4,7 +4,7 @@ ;; Author: Wei Jian Gan ;; Keywords: convenience, tools, go -;; Package-Version: 20180711.817 +;; Package-Version: 20190330.1412 ;; URL: https://github.com/weijiangan/flycheck-golangci-lint ;; Version: 0.1.0 ;; Package-Requires: ((emacs "24") (flycheck "0.22")) @@ -53,16 +53,40 @@ :safe #'booleanp :type 'boolean) +(flycheck-def-option-var flycheck-golangci-lint-disable-all nil golangci-lint + "Disable all linters" + :safe #'booleanp + :type 'boolean) + +(flycheck-def-option-var flycheck-golangci-lint-enable-all nil golangci-lint + "Enable all linters" + :safe #'booleanp + :type 'boolean) + +(flycheck-def-option-var flycheck-golangci-lint-enable-linters nil golangci-lint + "Enable specific linters" + :type '(repeat (string :tag "linter")) + :safe #'flycheck-string-list-p) + +(flycheck-def-option-var flycheck-golangci-lint-disable-linters nil golangci-lint + "Disable specific linters" + :type '(repeat (string :tag "linter")) + :safe #'flycheck-string-list-p) + (flycheck-define-checker golangci-lint "A Go syntax checker using golangci-lint that's 5x faster than gometalinter See URL `https://github.com/golangci/golangci-lint'." :command ("golangci-lint" "run" "--print-issued-lines=false" "--out-format=line-number" - (option "--config=" flycheck-golangci-lint-config concat) - (option "--deadline=" flycheck-golangci-lint-deadline concat) - (option-flag "--tests" flycheck-golangci-lint-tests) - (option-flag "--fast" flycheck-golangci-lint-fast) - ".") + (option "--config=" flycheck-golangci-lint-config concat) + (option "--deadline=" flycheck-golangci-lint-deadline concat) + (option-flag "--tests" flycheck-golangci-lint-tests) + (option-flag "--fast" flycheck-golangci-lint-fast) + (option-flag "--disable-all" flycheck-golangci-lint-disable-all) + (option-flag "--enable-all" flycheck-golangci-lint-enable-all) + (option-list "--disable=" flycheck-golangci-lint-disable-linters concat) + (option-list "--enable=" flycheck-golangci-lint-enable-linters concat) + ".") :error-patterns ((error line-start (file-name) ":" line ":" column ": " (message) line-end) (error line-start (file-name) ":" line ":" (message) line-end)) diff --git a/packages/flycheck-haskell-20181117.1001.tar b/packages/flycheck-haskell-20181207.1646.tar similarity index 97% rename from packages/flycheck-haskell-20181117.1001.tar rename to packages/flycheck-haskell-20181207.1646.tar index 67d0ea5..7c16e38 100644 Binary files a/packages/flycheck-haskell-20181117.1001.tar and b/packages/flycheck-haskell-20181207.1646.tar differ diff --git a/packages/flycheck-kotlin-20170122.1137.el b/packages/flycheck-kotlin-20190808.630.el similarity index 90% rename from packages/flycheck-kotlin-20170122.1137.el rename to packages/flycheck-kotlin-20190808.630.el index bde4946..d59c37e 100644 --- a/packages/flycheck-kotlin-20170122.1137.el +++ b/packages/flycheck-kotlin-20190808.630.el @@ -5,8 +5,8 @@ ;; Author: Elric Milon ;; Created: 20 January 2017 ;; Version: 0.1 -;; Package-Version: 20170122.1137 -;; Package-Requires: ((flycheck "0.18")) +;; Package-Version: 20190808.630 +;; Package-Requires: ((flycheck "0.20")) ;;; Commentary: @@ -42,10 +42,11 @@ (flycheck-define-checker kotlin-ktlint "A Kotlin syntax and style checker using the ktlint utility. See URL `https://github.com/shyiko/ktlint'." - :command ("ktlint" source-inplace) + :command ("ktlint" source-original) :error-patterns ((error line-start (file-name) ":" line ":" column ": " (message) line-end)) - :modes kotlin-mode) + :modes kotlin-mode + :predicate flycheck-buffer-saved-p) ;;;###autoload diff --git a/packages/flycheck-mix-20170118.1430.el b/packages/flycheck-mix-20190714.958.el similarity index 86% rename from packages/flycheck-mix-20170118.1430.el rename to packages/flycheck-mix-20190714.958.el index 5d3f2e4..043a9a7 100644 --- a/packages/flycheck-mix-20170118.1430.el +++ b/packages/flycheck-mix-20190714.958.el @@ -4,7 +4,7 @@ ;; Author: Tomasz Kowal ;; Version: 1.0.0 -;; Package-Version: 20170118.1430 +;; Package-Version: 20190714.958 ;; Package-Requires: ((flycheck "27") (elixir-mode "1.8.0")) ;; Keywords: Elixir flycheck mix ;; URL: https://github.com/tomekowal/flycheck-mix @@ -36,17 +36,13 @@ ;;; Code: (require 'flycheck) -;; :command uses source-original, source-inplace copies the file -;; which makes mix throw errors (flycheck-define-checker elixir-mix "Defines a checker for elixir with mix compile. - There are to conditions that must be true to fulfil the predicate. - 1. The project must be valid mix project with =mix.exs= file - 2. The variable =flycheck-mix-enable-checking= must be set to =t=" + The project must be valid mix project with =mix.exs= file" :command ("elixir" "-e" - (eval (flycheck-mix-cd-option)) + (eval (flycheck-mix-cd-and-set-mix-env)) "-S" "mix" "compile") @@ -86,9 +82,9 @@ "Return directory where =mix.exs= is located." (locate-dominating-file buffer-file-name "mix.exs")) -(defun flycheck-mix-cd-option () +(defun flycheck-mix-cd-and-set-mix-env () "Generate change directory command for elixir executable." - (format "IEx.Helpers.cd(\"%s\")" + (format "IEx.Helpers.cd(\"%s\"); Mix.start(); Mix.env(:test)" (shell-quote-argument (flycheck-mix-project-root)) )) diff --git a/packages/flycheck-package-20161111.2251.el b/packages/flycheck-package-20161111.2251.el new file mode 100644 index 0000000..b25934f --- /dev/null +++ b/packages/flycheck-package-20161111.2251.el @@ -0,0 +1,74 @@ +;;; flycheck-package.el --- A Flycheck checker for elisp package authors + +;; Copyright (C) 2014-2016 Steve Purcell, Fanael Linithien + +;; Author: Steve Purcell +;; Fanael Linithien +;; Keywords: lisp +;; Package-Version: 20161111.2251 +;; Version: 0 +;; Package-Requires: ((flycheck "0.22") (package-lint "0.2")) + +;; 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 . + +;;; Commentary: + +;; Provides feedback via flycheck about issues with the package metadata +;; of a file, e.g. the package dependencies it requires. + +;; To enable, use something like this: + +;; (eval-after-load 'flycheck +;; '(flycheck-package-setup)) + +;; Checks will currently be enabled only if a "Package-Requires:" or +;; "Package-Version:" header is present in the file. + +;;; Code: + +(require 'flycheck) +(require 'package-lint) + +(defun flycheck-package--start (checker callback) + "Flycheck start function for CHECKER, invoking CALLBACK." + (funcall callback + 'finished + (mapcar (lambda (x) + (apply #'flycheck-error-new-at `(,@x :checker ,checker))) + (condition-case err + (when (package-lint-looks-like-a-package-p) + (package-lint-buffer (current-buffer))) + (error + (funcall callback 'errored (error-message-string err)) + (signal (car err) (cdr err))))))) + + +;;; Checker definition + +(flycheck-define-generic-checker 'emacs-lisp-package + "A checker for \"Package-Requires\" headers and other packaging issues." + :start #'flycheck-package--start + :modes '(emacs-lisp-mode)) + +;;;###autoload +(defun flycheck-package-setup () + "Setup flycheck-package. +Add `flycheck-emacs-lisp-package' to `flycheck-checkers'." + (interactive) + (add-to-list 'flycheck-checkers 'emacs-lisp-package t) + (flycheck-add-next-checker 'emacs-lisp 'emacs-lisp-package t) + (flycheck-add-next-checker 'emacs-lisp-checkdoc 'emacs-lisp-package t)) + +(provide 'flycheck-package) +;;; flycheck-package.el ends here diff --git a/packages/flycheck-rust-20180904.1117.el b/packages/flycheck-rust-20190319.1546.el similarity index 99% rename from packages/flycheck-rust-20180904.1117.el rename to packages/flycheck-rust-20190319.1546.el index 0867818..c057beb 100644 --- a/packages/flycheck-rust-20180904.1117.el +++ b/packages/flycheck-rust-20190319.1546.el @@ -5,9 +5,9 @@ ;; Author: Sebastian Wiesner ;; URL: https://github.com/flycheck/flycheck-rust -;; Package-Version: 20180904.1117 +;; Package-Version: 20190319.1546 ;; Keywords: tools, convenience -;; Version: 0.1-cvs +;; Version: 1.1 ;; Package-Requires: ((emacs "24.1") (flycheck "28") (dash "2.13.0") (seq "2.3") (let-alist "1.0.4")) ;; This file is not part of GNU Emacs. diff --git a/packages/flymd-20160617.1214.tar b/packages/flymd-20160617.1214.tar index 2103392..30c4fa4 100644 Binary files a/packages/flymd-20160617.1214.tar and b/packages/flymd-20160617.1214.tar differ diff --git a/packages/flyspell-correct-20181106.801.tar b/packages/flyspell-correct-20190408.1010.tar similarity index 85% rename from packages/flyspell-correct-20181106.801.tar rename to packages/flyspell-correct-20190408.1010.tar index 7590538..056535d 100644 Binary files a/packages/flyspell-correct-20181106.801.tar and b/packages/flyspell-correct-20190408.1010.tar differ diff --git a/packages/flyspell-correct-helm-20180928.504.el b/packages/flyspell-correct-helm-20181205.1932.el similarity index 93% rename from packages/flyspell-correct-helm-20180928.504.el rename to packages/flyspell-correct-helm-20181205.1932.el index b768429..19fe940 100644 --- a/packages/flyspell-correct-helm-20180928.504.el +++ b/packages/flyspell-correct-helm-20181205.1932.el @@ -4,7 +4,7 @@ ;; ;; Author: Boris Buliga ;; URL: https://github.com/d12frosted/flyspell-correct -;; Package-Version: 20180928.504 +;; Package-Version: 20181205.1932 ;; Package-X-Original-Version: 0.5.0 ;; Package-Requires: ((flyspell-correct "0.5.0") (helm "1.9.0")) ;; @@ -23,6 +23,13 @@ ;; (require 'flyspell-correct-helm) ;; (define-key flyspell-mode-map (kbd "C-;") 'flyspell-correct-wrapper) ;; +;; Or via use-package: +;; +;; (use-package flyspell-correct-helm +;; :bind ("C-M-;" . flyspell-correct-wrapper) +;; :init +;; (setq flyspell-correct-interface #'flyspell-correct-helm)) +;; ;;; Code: ;; @@ -33,6 +40,7 @@ ;; Interface implementation +;;;###autoload (defun flyspell-correct--helm-always-match (_) "Return non-nil for any CANDIDATE." t) diff --git a/packages/flyspell-correct-ivy-20180929.1331.el b/packages/flyspell-correct-ivy-20181205.1932.el similarity index 90% rename from packages/flyspell-correct-ivy-20180929.1331.el rename to packages/flyspell-correct-ivy-20181205.1932.el index 123e20e..162533b 100644 --- a/packages/flyspell-correct-ivy-20180929.1331.el +++ b/packages/flyspell-correct-ivy-20181205.1932.el @@ -4,7 +4,7 @@ ;; ;; Author: Boris Buliga ;; URL: https://github.com/d12frosted/flyspell-correct -;; Package-Version: 20180929.1331 +;; Package-Version: 20181205.1932 ;; Package-X-Original-Version: 0.5.0 ;; Package-Requires: ((flyspell-correct "0.5.0") (ivy "0.8.0")) ;; @@ -23,6 +23,13 @@ ;; (require 'flyspell-correct-ivy) ;; (define-key flyspell-mode-map (kbd "C-;") 'flyspell-correct-wrapper) ;; +;; Or via use-package: +;; +;; (use-package flyspell-correct-ivy +;; :bind ("C-M-;" . flyspell-correct-wrapper) +;; :init +;; (setq flyspell-correct-interface #'flyspell-correct-ivy)) +;; ;;; Code: ;; @@ -33,6 +40,7 @@ ;; Interface implementation +;;;###autoload (defun flyspell-correct-ivy (candidates word) "Run `ivy-read' for the given CANDIDATES. diff --git a/packages/flyspell-correct-popup-20180928.504.el b/packages/flyspell-correct-popup-20181205.1932.el similarity index 87% rename from packages/flyspell-correct-popup-20180928.504.el rename to packages/flyspell-correct-popup-20181205.1932.el index e73d4f9..8213fe0 100644 --- a/packages/flyspell-correct-popup-20180928.504.el +++ b/packages/flyspell-correct-popup-20181205.1932.el @@ -4,7 +4,7 @@ ;; ;; Author: Boris Buliga ;; URL: https://github.com/d12frosted/flyspell-correct -;; Package-Version: 20180928.504 +;; Package-Version: 20181205.1932 ;; Package-X-Original-Version: 0.5.0 ;; Package-Requires: ((flyspell-correct "0.5.0") (popup "0.5.3")) ;; @@ -23,6 +23,13 @@ ;; (require 'flyspell-correct-popup) ;; (define-key flyspell-mode-map (kbd "C-;") 'flyspell-correct-wrapper) ;; +;; Or via use-package: +;; +;; (use-package flyspell-correct-popup +;; :bind ("C-M-;" . flyspell-correct-wrapper) +;; :init +;; (setq flyspell-correct-interface #'flyspell-correct-popup)) +;; ;;; Code: ;; @@ -33,6 +40,7 @@ ;; Interface implementation +;;;###autoload (defun flyspell-correct-popup (candidates word) "Run `popup-menu*' for the given CANDIDATES. diff --git a/packages/forge-20190820.826.tar b/packages/forge-20190820.826.tar new file mode 100644 index 0000000..8eb5cdc Binary files /dev/null and b/packages/forge-20190820.826.tar differ diff --git a/packages/forth-mode-20170527.1930.tar b/packages/forth-mode-20170527.1930.tar index 9a06583..b7c662c 100644 Binary files a/packages/forth-mode-20170527.1930.tar and b/packages/forth-mode-20170527.1930.tar differ diff --git a/packages/fsharp-mode-20180518.1820.tar b/packages/fsharp-mode-20190609.1317.tar similarity index 57% rename from packages/fsharp-mode-20180518.1820.tar rename to packages/fsharp-mode-20190609.1317.tar index 31192f8..cd02a78 100644 Binary files a/packages/fsharp-mode-20180518.1820.tar and b/packages/fsharp-mode-20190609.1317.tar differ diff --git a/packages/fuel-20190611.1350.tar b/packages/fuel-20190611.1350.tar new file mode 100644 index 0000000..6511b9a Binary files /dev/null and b/packages/fuel-20190611.1350.tar differ diff --git a/packages/geiser-20181117.650.tar b/packages/geiser-20190820.1931.tar similarity index 76% rename from packages/geiser-20181117.650.tar rename to packages/geiser-20190820.1931.tar index 480b6d1..577a986 100644 Binary files a/packages/geiser-20181117.650.tar and b/packages/geiser-20190820.1931.tar differ diff --git a/packages/ggtags-20181031.1803.el b/packages/ggtags-20190320.2208.el similarity index 95% rename from packages/ggtags-20181031.1803.el rename to packages/ggtags-20190320.2208.el index 221d14d..bc476af 100644 --- a/packages/ggtags-20181031.1803.el +++ b/packages/ggtags-20190320.2208.el @@ -1,10 +1,10 @@ ;;; ggtags.el --- emacs frontend to GNU Global source code tagging system -*- lexical-binding: t; -*- -;; Copyright (C) 2013-2018 Free Software Foundation, Inc. +;; Copyright (C) 2013-2019 Free Software Foundation, Inc. ;; Author: Leo Liu ;; Version: 0.9.0 -;; Package-Version: 20181031.1803 +;; Package-Version: 20190320.2208 ;; Keywords: tools, convenience ;; Created: 2013-01-29 ;; URL: https://github.com/leoliu/ggtags @@ -864,9 +864,11 @@ blocking emacs." (default (substring-no-properties default)) (t (ggtags-read-tag type t prompt require-match default)))))) -(defun ggtags-sort-by-nearness-p () +(defun ggtags-sort-by-nearness-p (&optional start-location) (and ggtags-sort-by-nearness - (ggtags-process-succeed-p "global" "--nearness=." "--help"))) + (ggtags-process-succeed-p "global" "--nearness=." "--help") + (concat "--nearness=" + (or start-location buffer-file-name default-directory)))) (defun ggtags-global-build-command (cmd &rest args) ;; CMD can be definition, reference, symbol, grep, idutils @@ -878,7 +880,6 @@ blocking emacs." (ggtags-find-project) (ggtags-project-has-color (ggtags-find-project)) "--color=always") - (and (ggtags-sort-by-nearness-p) "--nearness=.") (and (ggtags-find-project) (ggtags-project-has-path-style (ggtags-find-project)) "--path-style=shorter") @@ -941,7 +942,11 @@ blocking emacs." (defun ggtags-find-tag (cmd &rest args) (ggtags-check-project) - (ggtags-global-start (apply #'ggtags-global-build-command cmd args))) + (let ((nearness (ggtags-sort-by-nearness-p + (ggtags-project-relative-file + (or buffer-file-name default-directory))))) + (ggtags-global-start + (apply #'ggtags-global-build-command cmd nearness args)))) (defun ggtags-include-file () "Calculate the include file based on `ggtags-include-pattern'." @@ -2038,7 +2043,10 @@ If SYNC is non-nil, synchronously run CMDS and call CALLBACK." (let* ((re (cadr (assq 'grep ggtags-global-error-regexp-alist-alist))) (current (current-buffer)) (buffer (get-buffer-create " *ggtags-definition*")) - (args (list "--result=grep" "--path-style=absolute" name)) + ;; `.' works here because ggtags-global-output doesn't set + ;; default-directory to project root. + (args (delq nil (list (ggtags-sort-by-nearness-p ".") + "--result=grep" "--path-style=absolute" name))) ;; Need these bindings so that let-binding ;; `ggtags-print-definition-function' can work see ;; `ggtags-eldoc-function'. @@ -2057,11 +2065,8 @@ If SYNC is non-nil, synchronously run CMDS and call CALLBACK." (with-current-buffer current (funcall print-fn (funcall get-fn defs))))))) (ggtags-with-current-project - (ggtags-global-output - buffer - (cons (ggtags-program-path "global") - (if (ggtags-sort-by-nearness-p) (cons "--nearness=." args) args)) - show 100)))) + (ggtags-global-output buffer (cons (ggtags-program-path "global") args) + show 100)))) (defvar ggtags-mode-prefix-map (let ((m (make-sparse-keymap))) @@ -2202,6 +2207,7 @@ to nil disables displaying this information.") (if ggtags-mode (progn (add-hook 'after-save-hook 'ggtags-after-save-function nil t) + (add-hook 'xref-backend-functions 'ggtags--xref-backend nil t) ;; Append to serve as a fallback method. (add-hook 'completion-at-point-functions #'ggtags-completion-at-point t t) @@ -2217,6 +2223,7 @@ to nil disables displaying this information.") (append mode-line-buffer-identification '(ggtags-mode-line-project-name))))) (remove-hook 'after-save-hook 'ggtags-after-save-function t) + (remove-hook 'xref-backend-functions 'ggtags--xref-backend t) (remove-hook 'completion-at-point-functions #'ggtags-completion-at-point t) (remove-function (local 'eldoc-documentation-function) 'ggtags-eldoc-function) (setq mode-line-buffer-identification @@ -2359,6 +2366,97 @@ Function `ggtags-eldoc-function' disabled for eldoc in current buffer: %S" err)) (setq he-expand-list (cdr he-expand-list)) t)) +;;; Xref + +(defconst ggtags--xref-limit 1000) + +(defclass ggtags-xref-location (xref-file-location) + ((project-root :type string :initarg :project-root))) + +(cl-defmethod xref-location-group ((l ggtags-xref-location)) + (with-slots (file project-root) l + (file-relative-name file project-root))) + +(defun ggtags--xref-backend () + (and (ggtags-find-project) + (let ((tag (ggtags-tag-at-point))) + ;; Try to use this backend if there is no tag at + ;; point, since we may still want to when asking + ;; the user for a tag. + (or (null tag) + (test-completion tag ggtags-completion-table))) + 'ggtags)) + +(cl-defmethod xref-backend-identifier-at-point ((_backend (eql ggtags))) + (ggtags-tag-at-point)) + +(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql ggtags))) + ggtags-completion-table) + +(defun ggtags--xref-collect-tags (tag root colored) + "Collect xrefs for TAG from Global output in the `current-buffer'. +Return the list of xrefs for TAG. Global output is assumed to +have grep format. + +ROOT is the project root directory to associate with the xrefs. + +If COLORED is non-nil, convert ANSI color codes to font lock text +properties in the summary text of each xref." + (cl-loop + with re = (cadr (assq 'grep ggtags-global-error-regexp-alist-alist)) + while (re-search-forward re nil t) + for summary = (buffer-substring (1+ (match-end 2)) (line-end-position)) + for file = (expand-file-name (match-string 1)) + for line = (string-to-number (match-string 2)) + for column = (string-match-p tag summary) + if colored do (setq summary (ansi-color-apply summary)) end + ;; Sometimes there are false positives, depending on the + ;; parser used so only collect lines that actually + ;; contain TAG. + and when column + collect (xref-make + summary + (make-instance + 'ggtags-xref-location + :file file + :line line + :column column + :project-root root)))) + +(defun ggtags--xref-find-tags (tag cmd) + "Find xrefs of TAG using Global CMD. +CMD has the same meaning as in `ggtags-global-build-command'. +Return the list of xrefs for TAG." + (let* ((ggtags-global-output-format 'grep) + (project (ggtags-find-project)) + (xrefs nil) + (collect + (lambda (_status) + (goto-char (point-min)) + (setq xrefs (ggtags--xref-collect-tags + tag + (ggtags-project-root project) + (and ggtags-global-use-color + (ggtags-project-has-color project)))) + (kill-buffer (current-buffer))))) + (ggtags-with-current-project + (ggtags-global-output + (get-buffer-create " *ggtags-xref*") + (append + (split-string (ggtags-global-build-command cmd)) + (list "--" (shell-quote-argument tag))) + collect ggtags--xref-limit 'sync) + xrefs))) + +(cl-defmethod xref-backend-definitions ((_backend (eql ggtags)) tag) + (ggtags--xref-find-tags tag 'definition)) + +(cl-defmethod xref-backend-references ((_backend (eql ggtags)) tag) + (ggtags--xref-find-tags tag 'reference)) + +(cl-defmethod xref-backend-apropos ((_backend (eql ggtags)) tag) + (ggtags--xref-find-tags tag 'grep)) + (defun ggtags-reload (&optional force) (interactive "P") (unload-feature 'ggtags force) diff --git a/packages/gh-20180308.2138.tar b/packages/gh-20180308.2138.tar index b9de462..b479905 100644 Binary files a/packages/gh-20180308.2138.tar and b/packages/gh-20180308.2138.tar differ diff --git a/packages/ghc-20180121.1218.tar b/packages/ghc-20180121.1218.tar index 8e65faf..f300fff 100644 Binary files a/packages/ghc-20180121.1218.tar and b/packages/ghc-20180121.1218.tar differ diff --git a/packages/ghub+-20181113.32.el b/packages/ghub+-20181113.32.el deleted file mode 100644 index f681e9d..0000000 --- a/packages/ghub+-20181113.32.el +++ /dev/null @@ -1,1085 +0,0 @@ -;;; ghub+.el --- a thick GitHub API client built on ghub -*- lexical-binding: t; -*- - -;; Copyright (C) 2017-2018 Sean Allred - -;; Author: Sean Allred -;; Keywords: extensions, multimedia, tools -;; Homepage: https://github.com/vermiculus/ghub-plus -;; Package-Requires: ((emacs "25") (ghub "2.0") (apiwrap "0.5")) -;; Package-Version: 20181113.32 -;; Package-X-Original-Version: 0.4 - -;; 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 . - -;;; Commentary: - -;; Provides some sugar for `ghub'. See package `apiwrap' for -;; generated function usage instructions. - -;;; Code: - -(require 'url) -(require 'cl-lib) -(require 'subr-x) -(require 'ghub) -(require 'apiwrap) - -(eval-and-compile - (defun ghubp--make-link (alist) - "Create a link from an ALIST of API endpoint properties." - (format "https://developer.github.com/v3/%s" (alist-get 'link alist))) - - (defun ghubp--stringify-params (params) - "Process PARAMS from textual data to Lisp structures." - (mapcar (lambda (p) - (if (listp p) - (let ((k (car p)) (v (cdr p))) - (cons k (alist-get v '((t . "true") (nil . "false")) v))) - p)) - params)) - - (defun ghubp--pre-process-params (params) - (ghubp--stringify-params params)) - - (defvar ghubp-contextualize-function nil - "Function to contextualize `ghub' requests. -Can return an alist with any of the following properties: - -* `auth' -* `headers' -* `host' -* `unpaginate' -* `username' - -If (and only if) these properties are non-nil, they will provide -values for the eponymous `ghub-request' keyword arguments. - -The function should be callable with no arguments. - -See also `ghubp-get-context'.") - - (defvar ghubp-request-override-function nil - "Function to use instead of `ghub-request' for base calls. -It is expected to have the same signature as `ghub-request'.") - - (defun ghubp-get-context () - "Get the current context with `ghubp-contextualize-function'." - (when (functionp ghubp-contextualize-function) - (funcall ghubp-contextualize-function))) - - (defun ghubp-get-in-all (props object-list) - "Follow property-path PROPS in OBJECT-LIST. -Returns a list of the property-values." - (declare (indent 1)) - (if (or (null props) (not (consp props))) - object-list - (ghubp-get-in-all (cdr props) - (mapcar (lambda (o) (alist-get (car props) o)) - object-list)))) - - (defun ghubp-request (method resource params data) - "Using METHOD, get RESOURCE with PARAMS and DATA. - -`ghubp-contextualize-function' is used to contextualize this -request. - -If non-nil, `ghubp-request-override-function' is used instead of -`ghub-request'. - -METHOD is one of `get', `put', `post', `head', `patch', and -`delete'. - -RESOURCE is a string. - -PARAMS is a plist. - -DATA is an alist." - (let-alist (ghubp-get-context) - (let ((method (encode-coding-string (upcase (symbol-name method)) 'utf-8)) - (params (apiwrap-plist->alist params))) - (funcall (or ghubp-request-override-function - #'ghub-request) - method resource nil - :query params - :payload data - :unpaginate .unpaginate - :headers .headers - :username .username - :auth .auth - :host .host)))) - - ;; If ghub-404 is not defined as an error, define it. - ;; This will be necessary until Ghub releases v2. - ;; See also #8. - (unless (get 'ghub-404 'error-conditions) - (define-error 'ghub-404 "Not Found" 'ghub-http-error)) - - (defun ghubp--catch (error-symbol &rest handlers) - "Catch some Ghub signals as ERROR-SYMBOL with HANDLERS. -Each element of HANDLERS should be a list of - - (HTTP-CODE HANDLER) - -where HTTP-CODE is an error code like 404. - -For use inside `:condition-case' endpoint configurations. - -See also `ghubp-catch' and `ghubp-catch*'." - `((ghub-http-error - (pcase (cadr ,error-symbol) - ,@handlers - (_ (signal (car ,error-symbol) (cdr ,error-symbol))))))) - - (defmacro ghubp-catch* (&rest handlers) - "Catch some Ghub signals with HANDLERS. -For use inside `:condition-case' endpoint configurations. - -For advanced error handling, the error is bound to the symbol `it'. - -See `ghubp--catch'." - (apply #'ghubp--catch 'it handlers)) - - (defmacro ghubp-catch (error-symbol form &rest handlers) - "Catch some Ghub signals as ERROR_SYMBOL in FORM with HANDLERS. -For general use. - -See `ghubp--catch'" - (declare (indent 2)) - (when (eq error-symbol '_) - (setq error-symbol (cl-gensym))) - `(condition-case ,error-symbol ,form - ,@(apply #'ghubp--catch error-symbol handlers))) - - (apiwrap-new-backend "GitHub" "ghubp" - '((repo . "REPO is a repository alist of the form returned by `ghubp-get-user-repos'.") - (branch . "BRANCH is a branch object of the form returned by `ghubp-get-repos-owner-repo-branches-branch'.") - (org . "ORG is an organization alist of the form returned by `ghubp-get-user-orgs'.") - (thread . "THREAD is a thread object of the form returned by `ghubp-get-repos-owner-repo-comments'.") - (issue . "ISSUE is an issue object of the form returned by `ghubp-get-issues'.") - (pull-request . "PULL-REQUEST is a pull request object of the form returned by `ghubp-get-repos-owner-repo-pulls'.") - (review . "REVIEW is a review object of the form returned by `ghubp-get-repos-owner-repo-pulls-number-reviews'.") - (label . "LABEL is a label object of the form returned by `ghubp-get-repos-owner-repo-issues-number-labels'.") - (ref . "REF is a string and can be a SHA, a branch name, or a tag name.") - (milestone . "MILESTONE is a milestone object.") - (user . "USER is a user object.") - (user-1 . "USER-1 is a user object.") - (user-2 . "USER-2 is a user object.") - (key . "KEY is a key object.")) - :request #'ghubp-request - :link #'ghubp--make-link - :pre-process-params #'ghubp--pre-process-params)) - - -;;; Utilities: - -(defmacro ghubp-unpaginate (&rest body) - "Unpaginate API responses while executing BODY." - `(ghubp-override-context unpaginate t ,@body)) - -(defmacro ghubp-override-context (context new-value &rest body) - "Execute BODY while manually overriding CONTEXT with NEW-VALUE. -NEW-VALUE takes precedence over anything that -`ghubp-contextualize-function' provides for CONTEXT, but -`ghubp-contextualize-function' is otherwise respected." - (declare (indent 2)) - (unless (memq context '(host auth username unpaginate headers)) - (error (concat "`ghubp-override-context' should only override one " - "of the symbols from `ghubp-contextualize-function'."))) - (let ((sym-other-context (cl-gensym))) - `(let ((,sym-other-context (ghubp-get-context)) - ghubp-contextualize-function) - ;; override any existing value for CONTEXT - (push (cons ',context ,new-value) ,sym-other-context) - ;; and box the whole thing back into the var - (setq ghubp-contextualize-function (lambda () ,sym-other-context)) - ,@body))) - -(defun ghubp-keep-only (structure object) - "Keep a specific STRUCTURE in OBJECT. -See URL `http://emacs.stackexchange.com/a/31050/2264'." - (declare (indent 1)) - (if (and (consp object) (consp (car object)) (consp (caar object))) - (mapcar (apply-partially #'ghubp-keep-only structure) object) - (mapcar (lambda (el) - (if (consp el) - (cons (car el) - (ghubp-keep-only (cdr el) (alist-get (car el) object))) - (cons el (alist-get el object)))) - structure))) - -(defun ghubp-header (header) - "Get the value of HEADER from the last request as a string." - (cdr (assoc-string header ghub-response-headers))) - -(defun ghubp-ratelimit-reset-time () - "Get the reset time for the rate-limit as a time object." - (declare (obsolete 'ghubp-ratelimit "2017-10-17")) - (alist-get 'reset (ghubp-ratelimit))) - -(defun ghubp-ratelimit-remaining () - "Get the remaining number of requests available." - (declare (obsolete 'ghubp-ratelimit "2017-10-17")) - (alist-get 'remaining (ghubp-ratelimit))) - -(defun ghubp-ratelimit (&optional no-headers) - "Get `/rate_limit.rate'. -Returns nil if the service is not rate-limited. Otherwise, -returns an alist with the following properties: - - `.limit' - number of requests we're allowed to make per hour. - - `.remaining' - number of requests remaining for this hour. - - `.reset' - time value of instant `.remaining' resets to `.limit'. - -Unless NO-HEADERS is non-nil, tries to use response headers -instead of actually hitting /rate_limit." - ;; todo: bug when headers are from other host - (if (and (not no-headers) - ghub-response-headers - (assoc-string "X-RateLimit-Limit" ghub-response-headers)) - (let* ((headers (list "X-RateLimit-Limit" "X-RateLimit-Remaining" "X-RateLimit-Reset")) - (headers (mapcar (lambda (x) (string-to-number (ghubp-header x))) headers))) - `((limit . ,(nth 0 headers)) - (remaining . ,(nth 1 headers)) - (reset . ,(seconds-to-time - (nth 2 headers))))) - (ghubp-catch _ - (let-alist (ghubp-request 'get "/rate_limit" nil nil) - .resources.core) - ;; Enterprise returns 404 if rate limiting is disabled - (404 nil)))) - -(defun ghubp--follow (method resource &optional params data) - "Using METHOD, follow the RESOURCE link with PARAMS and DATA. -This method is intended for use with callbacks." - (let ((url (url-generic-parse-url resource))) - (when (fboundp 'ghub--host) - (unless (string-equal (url-host url) (ghub--host)) - (error "Bad link"))) - (ghubp-request method (url-filename url) params data))) - -(defun ghubp-follow-get (resource &optional params data) - "GET wrapper for `ghubp-follow'. -See that documentation for RESOURCE, PARAMS, and DATA." - (ghubp--follow 'get resource params data)) -(defun ghubp-follow-put (resource &optional params data) - "PUT wrapper for `ghubp-follow'. -See that documentation for RESOURCE, PARAMS, and DATA." - (ghubp--follow 'put resource params data)) -(defun ghubp-follow-head (resource &optional params data) - "HEAD wrapper for `ghubp-follow'. -See that documentation for RESOURCE, PARAMS, and DATA." - (ghubp--follow 'head resource params data)) -(defun ghubp-follow-post (resource &optional params data) - "POST wrapper for `ghubp-follow'. -See that documentation for RESOURCE, PARAMS, and DATA." - (ghubp--follow 'post resource params data)) -(defun ghubp-follow-patch (resource &optional params data) - "PATCH wrapper for `ghubp-follow'. -See that documentation for RESOURCE, PARAMS, and DATA." - (ghubp--follow 'patch resource params data)) -(defun ghubp-follow-delete (resource &optional params data) - "DELETE wrapper for `ghubp-follow'. -See that documentation for RESOURCE, PARAMS, and DATA." - (ghubp--follow 'delete resource params data)) - -(defun ghubp-base-html-url () - "Get the base HTML URL from `ghub-default-host'." - (if-let ((host (car (ignore-errors - (process-lines "git" "config" "github.host"))))) - (and (string-match (rx bos (group (* any)) "/api/v3" eos) host) - (match-string 1 host)) - "https://github.com")) - -(defun ghubp-host () - "Exposes `ghub--host'." - (ghub--host)) - -(defun ghubp-username () - "Exposes `ghub--username'." - (ghub--username (ghub--host))) - -(defun ghubp-token (package) - "Exposes `ghub--token' for PACKAGE in a friendly way." - (let* ((host (ghub--host)) - (user (ghub--username host))) - (ghub--token host user package t))) - - -;;; Errors: -(define-error 'ghubp-error "Ghub+ error" 'ghub-error) -(define-error 'ghubp-error-review-is-active "This review is active" 'ghubp-error) - - -;;; Issues: - -(defapiget-ghubp "/issues" - "List all issues assigned to the authenticated user across all -visible repositories including owned repositories, member -repositories, and organization repositories." - "issues/#list-issues") - -(defapiget-ghubp "/user/issues" - "List all issues across owned and member repositories assigned -to the authenticated user." - "issues/#list-issues") - -(defapiget-ghubp "/orgs/:org/issues" - "List all issues for a given organization assigned to the -authenticated user." - "issues/#list-issues" - (org) "/org/:org.login/issues") - -(defapiget-ghubp "/repos/:owner/:repo/issues" - "List issues for a repository." - "issues/#list-issues-for-a-repository" - (repo) "/repos/:repo.owner.login/:repo.name/issues") - -(defapiget-ghubp "/repos/:owner/:repo/issues/:number" - "Get a single issue." - "issues/#get-a-single-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number") - -(defapipost-ghubp "/repos/:owner/:repo/issues" - "Create an issue. -Any user with pull access to a repository can create an issue." - "issues/#create-an-issue" - (repo) "/repos/:repo.owner.login/:repo.name/issues") - -(defapipatch-ghubp "/repos/:owner/:repo/issues/:number" - "Edit an issue. -Issue owners and users with push access can edit an issue." - "issues/#edit-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number") - -(defapiput-ghubp "/repos/:owner/:repo/issues/:number/lock" - "Lock an issue. -Users with push access can lock an issue's conversation." - "issues/#lock-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number") - -(defapidelete-ghubp "/repos/:owner/:repo/issues/:number/lock" - "Unlock an issue -Users with push access can unlock an issue's conversation." - "issues/#unlock-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number") - - -;;; Issue Assignees: - -(defapiget-ghubp "/repos/:owner/:repo/assignees" - "List assignees. -This call lists all the available assignees to which issues may -be assigned." - "issues/assignees/#list-assignees" - (repo) "/repos/:repo.owner.login/:repo.name/assignees") - -(defapiget-ghubp "/repos/:owner/:repo/assignees/:assignee" - ;; todo: sugar to handle valid 404 response - "Check assignee. -You may also check to see if a particular user is an assignee for -a repository." - "issues/assignees/#check-assignee" - (repo user) "/repos/:repo.owner.login/:repo.name/assignees/:user.login") - -(defapipost-ghubp "/repos/:owner/:repo/issues/:number/assignees" - "Add assignees to an Issue. -This call adds the users passed in the assignees key (as their -logins) to the issue." - "issues/assignees/#add-assignees-to-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/assignees" - :pre-process-data - (lambda (users) - `((assignees . ,(ghubp-get-in-all '(login) users))))) - -(defapidelete-ghubp "/repos/:owner/:repo/issues/:number/assignees" - "Remove assignees from an Issue. -This call removes the users passed in the assignees key (as their -logins) from the issue." - "issues/assignees/#remove-assignees-from-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/assignees" - :pre-process-data - (lambda (users) - `((assignees . ,(ghubp-get-in-all '(login) users))))) - - -;;; Issue Comments: - -(defapiget-ghubp "/repos/:owner/:repo/issues/:number/comments" - "List comments on an issue. -Issue Comments are ordered by ascending ID." - "issues/comments/#list-comments-on-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/comments") - -(defapiget-ghubp "/repos/:owner/:repo/issues/comments" - "List comments in a repository. -By default, Issue Comments are ordered by ascending ID." - "issues/comments/#list-comments-in-a-repository" - (repo) "/repos/:repo.owner.login/:repo.name/issues/comments") - -(defapiget-ghubp "/repos/:owner/:repo/issues/comments/:id" - "Get a single comment." - "issues/comments/#get-a-single-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/issues/comments/:thread.id") - -(defapipatch-ghubp "/repos/:owner/:repo/issues/:number/comments" - "Create a comment." - "issues/comments/#create-a-comment" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/comments") - -(defapipatch-ghubp "/repos/:owner/:repo/issues/comments/:id" - "Edit a comment." - "issues/comments/#edit-a-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/issues/comments/:thread.id") - -(defapidelete-ghubp "/repos/:owner/:repo/issues/comments/:id" - "Delete a comment." - "issues/comments/#delete-a-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/issues/comments/:thread.id") - - -;;; Issue Events: - -(defapiget-ghubp "/repos/:owner/:repo/issues/:number/events" - ;; note: :number changed from :issue_number for consistency - "List events for an issue." - "issues/events/#list-events-for-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/events") - -(defapiget-ghubp "/repos/:owner/:repo/issues/events" - "List events for a repository." - "issues/events/#list-events-for-a-repository" - (repo) "/repos/:repo.owner.login/:repo.name/issues/events") - -(defapiget-ghubp "/repos/:owner/:repo/issues/events/:id" - "Get a single event." - "issues/events/#get-a-single-event" - (repo thread) "/repos/:repo.owner.login/:repo.name/issues/events/:thread.id") - - -;;; Issue Labels: - -(defapiget-ghubp "/repos/:owner/:repo/labels" - "List all labels for this repository." - "issues/labels/#list-all-labels-for-this-repository" - (repo) "/repos/:repo.owner.login/:repo.name/labels") - -(defapiget-ghubp "/repos/:owner/:repo/labels/:name" - "Get a single label." - "issues/labels/#get-a-single-label" - (repo label) "/repos/:repo.owner.login/:repo.name/labels/:label.name") - -(defapipost-ghubp "/repos/:owner/:repo/labels" - "Create a label." - "issues/labels/#create-a-label" - (repo) "/repos/:repo.owner.login/:repo.name/labels") - -(defapipatch-ghubp "/repos/:owner/:repo/labels/:name" - "Update a label." - "issues/labels/#update-a-label" - (repo label) "/repos/:repo.owner.login/:repo.name/labels/:label.name") - -(defapidelete-ghubp "/repos/:owner/:repo/labels/:name" - "Delete a label." - "issues/labels/#deleted-a-label" - (repo label) "/repos/:repo.owner.login/:repo.name/labels/:label.name") - -(defapiget-ghubp "/repos/:owner/:repo/issues/:number/labels" - "List labels on an issue." - "issues/labels/#list-labels-on-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/labels") - -(defapipost-ghubp "/repos/:owner/:repo/issues/:number/labels" - "Add labels to an issue." - "issues/labels/#add-labels-to-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/labels" - :pre-process-data (apply-partially #'ghubp-get-in-all '(name))) - -(defapidelete-ghubp "/repos/:owner/:repo/issues/:number/labels/:name" - "Remove a label from an issue." - "issues/labels/#remove-a-label-from-an-issue" - (repo issue label) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/labels/:label.name") - -(defapipatch-ghubp "/repos/:owner/:repo/issues/:number/labels" - "Replace all labels for an issue." - "issues/labels/#replace-all-labels-for-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/labels" - :pre-process-data (apply-partially #'ghubp-get-in-all '(name))) - -(defapidelete-ghubp "/repos/:owner/:repo/issues/:number/labels" - "Remove all labels from an issue." - "issues/labels/#remove-all-labels-from-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/labels") - -(defapiget-ghubp "/repos/:owner/:repo/milestones/:number/labels" - "Get labels for every issue in a milestone." - "issues/labels/#get-labels-for-every-issue-in-a-milestone" - (repo milestone) "/repos/:repo.owner.login/:repo.name/milestones/:milestone.number/labels") - - -;;; Issue Milestones: - -(defapiget-ghubp "/repos/:owner/:repo/milestones" - "List milestones for a repository." - "issues/milestones/#list-milestones-for-a-repository" - (repo) "/repos/:repo.owner.login/:repo.name/milestones") - -(defapiget-ghubp "/repos/:owner/:repo/milestones/:number" - "Get a single milestone." - "issues/milestones/#get-a-single-milestone" - (repo milestone) "/repos/:repo.owner.login/:repo.name/milestones/:milestone.number") - -(defapipost-ghubp "/repos/:owner/:repo/milestones" - "Create a milestone." - "issues/milestones/#create-a-milestone" - (repo) "/repos/:repo.owner.login/:repo.name/milestones") - -(defapipatch-ghubp "/repos/:owner/:repo/milestones/:number" - "Update a milestone." - "issues/milestones/#create-a-milestone" - (repo milestone) "/repos/:repo.owner.login/:repo.name/milestones/:milestone.number") - -(defapidelete-ghubp "/repos/:owner/:repo/milestones/:number" - "Delete a milestone." - "issues/milestones/#delete-a-milestone" - (repo milestone) "/repos/:repo.owner.login/:repo.name/milestones/:milestone.number") - - -;;; Organizations: - -(defapiget-ghubp "/user/orgs" - "List organizations for the authenticated user." - "orgs/#list-your-organizations") - -(defapiget-ghubp "/organizations" - "Lists all organizations in the order that they were created on GitHub." - "orgs/#list-all-organizations") - -(defapiget-ghubp "/users/:username/orgs" - "List public organization memberships for the specified user." - "orgs/#list-user-organizations" - (user) "/users/:user.login/orgs") - -(defapiget-ghubp "/orgs/:org" - "Get an organization." - "orgs/#get-an-organization" - (org) "/orgs/:org.login") - -(defapipatch-ghubp "/orgs/:org" - "Edit an organization." - "orgs/#edit-an-organization" - (org) "/orgs/:org.login") - - -;;; Pull Request: - -(defapiget-ghubp "/repos/:owner/:repo/pulls" - "List pull requests." - "pulls/#list-pull-requests" - (repo) "/repos/:repo.owner.login/:repo.name/pulls") - -(defapiget-ghubp "/repos/:owner/:repo/pulls/:number" - "Get a single pull request." - "pulls/#get-a-single-pull-request" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number") - -(defapipost-ghubp "/repos/:owner/:repo/pulls" - "Create a pull request." - "pulls/#create-a-pull-request" - (repo) "/repos/:repo.owner.login/:repo.name/pulls") - -(defapipatch-ghubp "/repos/:owner/:repo/pulls/:number" - "Update a pull request." - "pulls/#update-a-pull-request" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number") - -(defapiget-ghubp "/repos/:owner/:repo/pulls/:number/commits" - "List commits on a pull request." - "pulls/#list-commits-on-a-pull-request" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/commits") - -(defapiget-ghubp "/repos/:owner/:repo/pulls/:number/files" - "List pull request files." - "pulls/#list-pull-requests-files" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/files") - -(defapiget-ghubp "/repos/:owner/:repo/pulls/:number/merge" - "Get if a pull request has been merged." - "pulls/#get-if-a-pull-request-has-been-merged" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/merge") - -(defapiput-ghubp "/repos/:owner/:repo/pulls/:number/merge" - "Merge a pull request (Merge Button)" - "pulls/#merge-a-pull-request-merge-button" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/merge") - - -;;; Pull Request Reviews: - -(defapiget-ghubp "/repos/:owner/:repo/collaborators" - "List collaborators. -This call lists all the repo's collaborators." - "repos/collaborators/#list-collaborators" - (repo) "/repos/:repo.owner.login/:repo.name/collaborators") - -(defapiget-ghubp "/repos/:owner/:repo/pulls/:number/reviews" - "List reviews on a pull request." - "pulls/reviews/#list-reviews-on-a-pull-request" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/reviews") - -(defapiget-ghubp "/repos/:owner/:repo/pulls/:number/reviews/:id" - "Get a single review." - "pulls/reviews/#list-reviews-on-a-pull-request" - (repo pull-request review) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/reviews/:review.id") - -(defapidelete-ghubp "/repos/:owner/:repo/pulls/:number/reviews/:id" - "Delete a pending review." - "pulls/reviews/#delete-a-pending-review" - (repo pull-request review) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/reviews/:review.id" - :condition-case - (ghubp-catch* - (422 (signal 'ghubp-error-review-is-active nil)))) - -(defapiget-ghubp "/repos/:owner/:repo/pulls/:number/reviews/:id/comments" - "Get comments for a single review." - "pulls/reviews/#get-comments-for-a-single-review" - (repo pull-request review) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/reviews/:review.id/comments") - -(defapipost-ghubp "/repos/:owner/:repo/pulls/:number/reviews" - "Create a pull request review." - "pulls/reviews/#create-a-pull-request-review" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/reviews") - -(defapipost-ghubp "/repos/:owner/:repo/pulls/:number/reviews/:id/events" - "Submit a pull request review." - "pulls/reviews/#submit-a-pull-request-review" - (repo pull-request review) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/reviews/:review.id/events") - -(defapiput-ghubp "/repos/:owner/:repo/pulls/:number/reviews/:id/dismissals" - "Dismiss a pull request review." - "pulls/reviews/#dismiss-a-pull-request-review" - (repo pull-request review) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/reviews/:review.id/dismissals") - - -;;; Pull Request Review Comments: - -(defapiget-ghubp "/repos/:owner/:repo/pulls/:number/comments" - "List comments on a pull request." - "pulls/comments/#list-comments-on-a-pull-request" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/comments") - -(defapiget-ghubp "/repos/:owner/:repo/pulls/comments" - "List comments in a repository." - "pulls/comments/#list-comments-in-a-repository" - (repo) "/repos/:repo.owner.login/:repo.name/pulls/comments") - -(defapiget-ghubp "/repos/:owner/:repo/pulls/comments/:id" - "Get a single comment." - "pulls/comments/#get-a-single-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/pulls/comments/:thread.id") - -(defapipost-ghubp "/repos/:owner/:repo/pulls/:number/comments" - "Create a comment." - "pulls/comments/#create-a-comment" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/comments") - -(defapipatch-ghubp "/repos/:owner/:repo/pulls/comments/:id" - "Edit a comment." - "pulls/comments/#edit-a-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/pulls/comments/:thread.id") - -(defapidelete-ghubp "/repos/:owner/:repo/pulls/comments/:id" - "Delete a comment." - "pulls/comments/#delete-a-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/pulls/comments/:thread.id") - - -;;; Pull Request Review Requests: - -(defapiget-ghubp "/repos/:owner/:repo/pulls/:number/requested_reviewers" - "List review requests." - "pulls/review_requests/#list-review-requests" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/requested_reviewers") - -(defapipost-ghubp "/repos/:owner/:repo/pulls/:number/requested_reviewers" - "Create a review request." - "pulls/review_requests/#create-a-review-request" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/requested_reviewers" - :pre-process-data - (lambda (users) - `((reviewers . ,(ghubp-get-in-all '(login) users))))) - -(defapidelete-ghubp "/repos/:owner/:repo/pulls/:number/requested_reviewers" - "Delete a review request." - "pulls/review_requests/#delete-a-review-request" - (repo pull-request) "/repos/:repo.owner.login/:repo.name/pulls/:pull-request.number/requested_reviewers") - - -;;; Reactions: - -(defapiget-ghubp "/repos/:owner/:repo/comments/:id/reactions" - "List reactions for a commit comment." - "reactions/#list-reactions-for-a-commit-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/comments/:thread.id/reactions") - -(defapipost-ghubp "/repos/:owner/:repo/comments/:id/reactions" - "Create reaction for a commit comment." - "reactions/#create-reaction-for-a-commit-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/comments/:thread.id/reactions") - -(defapiget-ghubp "/repos/:owner/:repo/issues/:number/reactions" - "List reactions for an issue." - "reactions/#list-reactions-for-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/reactions") - -(defapipost-ghubp "/repos/:owner/:repo/issues/:number/reactions" - "Create reaction for an issue." - "reactions/#create-reaction-for-an-issue" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/reactions") - -(defapiget-ghubp "/repos/:owner/:repo/issues/comments/:id/reactions" - "List reactions for an issue comment." - "reactions/#list-reactions-for-an-issue-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/issues/comments/:thread.id/reactions") - -(defapipost-ghubp "/repos/:owner/:repo/issues/comments/:id/reactions" - "Create reaction for an issue comment." - "reactions/#create-reaction-for-an-issue-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/issues/comments/:thread.id/reactions") - -(defapiget-ghubp "/repos/:owner/:repo/pulls/comments/:id/reactions" - "List reactions for a pull request review comment." - "reactions/#list-reactions-for-a-pull-request-review-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/pulls/comments/:thread.id/reactions") - -(defapipost-ghubp "/repos/:owner/:repo/pulls/comments/:id/reactions" - "Create reaction for a pull request review comment." - "reactions/#create-reaction-for-a-pull-request-review-comment" - (repo thread) "/repos/:repo.owner.login/:repo.name/pulls/comments/:thread.id/reactions") - -(defapidelete-ghubp "/reactions/:id" - "Delete a reaction." - "reactions/#delete-a-reaction" - (thread) "/reactions/:thread.id") - - -;;; Repositories: - -(defapiget-ghubp "/user/repos" - "List your repositories. -List repositories that are accessible to the authenticated user. - -This includes repositories owned by the authenticated user, -repositories where the authenticated user is a collaborator, and -repositories that the authenticated user has access to through an -organization membership." - "repos/#list-your-repositories") - -(defapiget-ghubp "/users/:username/repos" - "List user repositories. -List public repositories for the specified user." - "repos/#list-user-repositories" - (user) "/users/:user.login/repos") - -(defapiget-ghubp "/orgs/:org/repos" - "List organization repositories. -List repositories for the specified org." - "repos/#list-organization-repositories" - (org) "/orgs/:org.login/repos") - -(defapiget-ghubp "/repositories" - "List all public repositories. -This provides a dump of every public repository, in the order -that they were created." - "repos/#list-all-public-repositories") - -(defapipost-ghubp "/user/repos" - "Create. -Create a new repository for the authenticated user. (Currently -not enabled for Integrations)." - "repos/#create") - -(defapipost-ghubp "/orgs/:org/repos" - "Create a new repository in this organization. -The authenticated user must be a member of the specified -organization." - "repos/#create" - (org) "/orgs/:org.login/repos") - -(defapiget-ghubp "/repos/:owner/:repo" - "Get a specific repository object." - "repos/#get" - (repo) "/repos/:repo.owner.login/:repo.name" - :condition-case - (ghubp-catch* - (404 nil))) - - -;;; Branches: - -(defapiget-ghubp "/repos/:owner/:repo/branches/:branch" - "Get branch" - "repos/branches/#get-branch" - (repo branch) "/repos/:repo.owner.login/:repo.name/branches/:branch.name" - :condition-case - (ghubp-catch* - (404 nil))) - - -;;; Users: -(defapiget-ghubp "/users/:username" - "Get a single user." - "users/#get-a-single-user" - (user) "/users/:user.login" - :condition-case - (ghubp-catch* - (404 nil))) - -(defapiget-ghubp "/user" - "Get the authenticated user." - "users/#get-the-authenticated-user") - -(defapipatch-ghubp "/user" - "Update the authenticated user." - "users/#update-the-authenticated-user") - -(defapiget-ghubp "/users" - "Get all users. -Lists all users, in the order that they signed up on GitHub. This -list includes personal user accounts and organization accounts." - "users/#get-all-users") - - ;; Users - Emails - -(defapiget-ghubp "/user/emails" - "List email addresses for a user." - "users/emails/#list-email-addresses-for-a-user") - -(defapiget-ghubp "/user/public_emails" - "List public email addresses for a user." - "users/emails/#list-public-email-addresses-for-a-user") - -(defapipost-ghubp "/user/emails" - "Add email address(es). -You can post a single email address or an array of addresses." - "users/emails/#add-email-addresses") - -(defapidelete-ghubp "/user/emails" - "Delete email address(es). -You can post a single email address or an array of addresses." - "users/emails/#add-email-addresses") - -(defapipatch-ghubp "/user/email/visibility" - "Toggle primary email visibility." - "users/emails/#toggle-primary-email-visibility") - - ;; Users - Followers - -(defapiget-ghubp "/users/:username/followers" - "List a user's followers." - "users/followers/#list-followers-of-a-user" - (user) "/users/:user.login/followers") - -(defapiget-ghubp "/user/followers" - "List the authenticated user's followers." - "users/followers/#list-followers-of-a-user") - -(defapiget-ghubp "/users/:username/following" - "List who USER is following." - "users/followers/#list-users-followed-by-another-user" - (user) "/users/:user.login/following") - -(defapiget-ghubp "/user/following" - "List who the authenticated user is following." - "users/followers/#list-users-followed-by-another-user") - -(defapiget-ghubp "/user/following/:username" - "Check if you are following USER." - "users/followers/#check-if-you-are-following-a-user" - (user) "/user/following/:user.login") - -(defapiget-ghubp "/users/:username/following/:target_user" - "Check if USER-1 follows USER-2." - "users/followers/#check-if-you-are-following-a-user" - (user-1 user-2) "/users/:user-1.login/following/:user-2.login") - -(defapiput-ghubp "/user/following/:username" - "Follow USER." - "users/followers/#follow-a-user" - (user) "/user/following/:user.login") - -(defapidelete-ghubp "/user/following/:username" - "Unfollow USER." - "users/followers/#unfollow-a-user" - (user) "/user/following/:user.login") - - ;; Users - Git SSH Keys - -(defapiget-ghubp "/users/:username/keys" - "Lists the verified public keys for a user. -This is accessible by anyone." - "users/keys/#list-public-keys-for-a-user" - (user) "/users/:user.login/keys") - -(defapiget-ghubp "/user/keys" - "List your public keys." - "users/keys/#list-your-public-keys") - -(defapiget-ghubp "/user/keys/:id" - "Get a single public key." - "users/keys/#get-a-single-public-key" - (key) "/user/keys/:key.id") - -(defapiput-ghubp "/user/keys" - "Create a public key." - "users/keys/#create-a-public-key") - -(defapidelete-ghubp "/user/keys/:id" - "Delete a single public key." - "users/keys/#get-a-single-public-key" - (key) "/user/keys/:key.id") - - ;; Users - GPG Keys - -;; TODO: Currently in preview. - -;; https://developer.github.com/v3/users/gpg_keys/ - - ;; Users - Blocking - -;; TODO: Currently in preview. - -;; https://developer.github.com/v3/users/blocking/ - - ;; Activity - Notifications - -;; TODO: It would be nice if ghub+ could offer 'smart' polling for -;; notifications to trim down on API requests. This smart polling is -;; supported by GitHub for notifications in particular. If done -;; right, we could offer a 'push'-type interface to handle when new -;; notifications are received. - -;; (ghubp-notifications-{start,stop}-polling) -;; ghubp-notifications-received-hook - -(defapiget-ghubp "/notifications" - "Get the user's notifications." - "activity/notifications/#list-your-notifications") - -(defapiget-ghubp "/repos/:owner/:repo/notifications" - "List your notifications in a repository." - "activity/notifications/#list-your-notifications-in-a-repository" - (repo) "/repos/:repo.owner.login/:repo.name/notifications") - -(defapiput-ghubp "/notifications" - "Mark as read. -Marking a notification as \"read\" removes it from the default -view on GitHub." - "activity/notifications/#mark-as-read") - -(defapiput-ghubp "/repos/:owner/:repo/notifications" - "Mark notifications as read in a repository. -Marking all notifications in a repository as \"read\" removes -them from the default view on GitHub." - "activity/notifications/#mark-notifications-as-read-in-a-repository" - (repo) "/repos/:repo.owner.login/:repo.name/notifications") - -(defapiget-ghubp "/notifications/threads/:id" - "View a single thread." - "activity/notifications/#view-a-single-thread" - (thread) "/notifications/threads/:thread.id") - -(defapipatch-ghubp "/notifications/threads/:id" - "Mark a thread as read." - "activity/notifications/#mark-a-thread-as-read" - (thread) "/notifications/threads/:thread.id") - -(defapiget-ghubp "/notifications/threads/:id/subscription" - "Get a thread subscription. -This checks to see if the current user is subscribed to a -thread." - "activity/notifications/#get-a-thread-subscription" - (thread) "/notifications/threads/:thread.id/subscription") - -(defapiput-ghubp "/notifications/threads/:id/subscription" - "Set a thread subscription. -This lets you subscribe or unsubscribe from a conversation. -Unsubscribing from a conversation mutes all future -notifications (until you comment or get @mentioned once more)." - "activity/notifications/#set-a-thread-subscription" - (thread) "/notifications/threads/:thread.id/subscription") - -(defapidelete-ghubp "/notifications/threads/:id/subscription" - "Delete a thread subscription." - "activity/notifications/#delete-a-thread-subscription" - (thread) "/notifications/threads/:thread.id/subscription") - - -;;; Unfiled: - -(defapiget-ghubp "/repos/:owner/:repo/commits/:ref/statuses" - "List statuses for a specific ref" - "repos/statuses/#list-statuses-for-a-specific-ref" - (repo ref) "/repos/:repo.owner.login/:repo.name/commits/:ref/statuses") - -(defapiget-ghubp "/repos/:owner/:repo/commits/:ref/status" - "Get the combined status for a specific ref" - "repos/statuses/#get-the-combined-status-for-a-specific-ref" - (repo ref) "/repos/:repo.owner.login/:repo.name/commits/:ref/status" - :condition-case - (ghubp-catch* - (404 nil))) - -(defapipost-ghubp "/repos/:owner/:repo/forks" - "Create a fork for the authenticated user." - "repos/forks/#create-a-fork" - (repo) "/repos/:repo.owner.login/:repo.name/forks") - -(defapipost-ghubp "/repos/:owner/:repo/issues/:number/comments" - "Post a comment to an issue" - "issues/comments/#create-a-comment" - (repo issue) "/repos/:repo.owner.login/:repo.name/issues/:issue.number/comments") - -(defapiget-ghubp "/repos/:owner/:repo/commits" - "List commits on a repository" - "repos/commits/#list-commits-on-a-repository" - (repo) "/repos/:repo.owner.login/:repo.name/commits") - -(defun ghubp-url-parse (url) - "Parse URL for its type and API callback. - -A cons cell is returned. The car is one of - - - `issue' - - `pull-request' - -and the cdr is a callback suitable for `ghub-get', etc." - (let ((callback (url-filename (url-generic-parse-url url)))) - (cons - (cond - ((string-match-p (rx bol "/repos/" (+? any) "/" (+? any) "/issues/" (+ digit) eol) - callback) - 'issue) - ((string-match-p (rx bol "/repos/" (+? any) "/" (+? any) "/pulls/" (+ digit) eol) - callback) - 'pull-request) - (t 'unknown)) - callback))) - -(provide 'ghub+) -;;; ghub+.el ends here diff --git a/packages/ghub-20181112.1755.tar b/packages/ghub-20190806.959.tar similarity index 87% rename from packages/ghub-20181112.1755.tar rename to packages/ghub-20190806.959.tar index de1fd6f..71fece4 100644 Binary files a/packages/ghub-20181112.1755.tar and b/packages/ghub-20190806.959.tar differ diff --git a/packages/git-commit-20181116.1408.el b/packages/git-commit-20190717.29.el similarity index 92% rename from packages/git-commit-20181116.1408.el rename to packages/git-commit-20190717.29.el index 6b5c6d0..076ebb1 100644 --- a/packages/git-commit-20181116.1408.el +++ b/packages/git-commit-20190717.29.el @@ -1,6 +1,6 @@ ;;; git-commit.el --- Edit Git commit messages -*- lexical-binding: t; -*- -;; Copyright (C) 2010-2018 The Magit Project Contributors +;; Copyright (C) 2010-2019 The Magit Project Contributors ;; ;; You should have received a copy of the AUTHORS.md file which ;; lists all contributors. If not, see http://magit.vc/authors. @@ -12,7 +12,7 @@ ;; Maintainer: Jonas Bernoulli ;; Package-Requires: ((emacs "25.1") (dash "20180910") (with-editor "20181103")) -;; Package-Version: 20181116.1408 +;; Package-Version: 20190717.29 ;; Keywords: git tools vc ;; Homepage: https://github.com/magit/magit @@ -204,6 +204,8 @@ run at all. For certain commands such as `magit-rebase-continue' this hook is never run because doing so would lead to a race condition. +This hook is only run if `magit' is available. + Also see `magit-post-commit-hook'." :group 'git-commit :type 'hook @@ -297,11 +299,15 @@ already using it, then you probably shouldn't start doing so." "Face used for non-whitespace on the second line of commit messages." :group 'git-commit-faces) -(defface git-commit-note +(defface git-commit-keyword '((t :inherit font-lock-string-face)) - "Face used for notes in commit messages." + "Face used for keywords in commit messages. +In this context a \"keyword\" is text surrounded be brackets." :group 'git-commit-faces) +(define-obsolete-face-alias 'git-commit-note + 'git-commit-keyword "Git-Commit 2.91.0") + (defface git-commit-pseudo-header '((t :inherit font-lock-string-face)) "Face used for pseudo headers in commit messages." @@ -415,7 +421,7 @@ This is only used if Magit is available." ;;;###autoload (defconst git-commit-filename-regexp "/\\(\ -\\(\\(COMMIT\\|NOTES\\|PULLREQ\\|TAG\\)_EDIT\\|MERGE_\\|\\)MSG\ +\\(\\(COMMIT\\|NOTES\\|PULLREQ\\|MERGEREQ\\|TAG\\)_EDIT\\|MERGE_\\|\\)MSG\ \\|\\(BRANCH\\|EDIT\\)_DESCRIPTION\\)\\'") (eval-after-load 'recentf @@ -464,21 +470,31 @@ This is only used if Magit is available." (when (eq system-type 'windows-nt) (add-hook 'find-file-not-found-functions #'git-commit-file-not-found)) +(defconst git-commit-usage-message "\ +Type \\[with-editor-finish] to finish, \ +\\[with-editor-cancel] to cancel, and \ +\\[git-commit-prev-message] and \\[git-commit-next-message] \ +to recover older messages") + ;;;###autoload (defun git-commit-setup () + (when (fboundp 'magit-toplevel) + ;; `magit-toplevel' is autoloaded and defined in magit-git.el, + ;; That library declares this functions without loading + ;; magit-process.el, which defines it. + (require 'magit-process nil t)) ;; Pretend that git-commit-mode is a major-mode, ;; so that directory-local settings can be used. (let ((default-directory - (if (or (file-exists-p ".dir-locals.el") - (not (fboundp 'magit-toplevel))) - default-directory - ;; When $GIT_DIR/.dir-locals.el doesn't exist, - ;; fallback to $GIT_WORK_TREE/.dir-locals.el, - ;; because the maintainer can use the latter - ;; to enforce conventions, while s/he has no - ;; control over the former. - (and (fboundp 'magit-toplevel) ; silence byte-compiler - (magit-toplevel))))) + (or (and (not (file-exists-p ".dir-locals.el")) + ;; When $GIT_DIR/.dir-locals.el doesn't exist, + ;; fallback to $GIT_WORK_TREE/.dir-locals.el, + ;; because the maintainer can use the latter + ;; to enforce conventions, while s/he has no + ;; control over the former. + (fboundp 'magit-toplevel) ; silence byte-compiler + (magit-toplevel)) + default-directory))) (let ((buffer-file-name nil) ; trick hack-dir-local-variables (major-mode 'git-commit-mode)) ; trick dir-locals-collect-variables (hack-dir-local-variables) @@ -494,7 +510,9 @@ This is only used if Magit is available." (git-commit-mode t) (with-editor-mode t)) (normal-mode t))) + ;; Show our own message using our hook. (setq with-editor-show-usage nil) + (setq with-editor-usage-message git-commit-usage-message) (unless with-editor-mode ;; Maybe already enabled when using `shell-command' or an Emacs shell. (with-editor-mode 1)) @@ -529,11 +547,14 @@ This is only used if Magit is available." (goto-char (point-min)) (when (looking-at "\\`\\(\\'\\|\n[^\n]\\)") (open-line 1))) - (run-hooks 'git-commit-setup-hook) + (with-demoted-errors "Error running git-commit-setup-hook: %S" + (run-hooks 'git-commit-setup-hook)) (set-buffer-modified-p nil)) (defun git-commit-run-post-finish-hook (previous) - (when git-commit-post-finish-hook + (when (and git-commit-post-finish-hook + (require 'magit nil t) + (fboundp 'magit-rev-parse)) (cl-block nil (let ((break (time-add (current-time) (seconds-to-time 1)))) @@ -554,7 +575,8 @@ Don't use it directly, instead enable `global-git-commit-mode'." (put 'git-commit-mode 'permanent-local t) (defun git-commit-setup-changelog-support () - "Treat ChangeLog entries as paragraphs." + "Treat ChangeLog entries as unindented paragraphs." + (setq-local fill-indent-according-to-mode t) (setq-local paragraph-start (concat paragraph-start "\\|\\*\\|("))) (defun git-commit-turn-on-auto-fill () @@ -751,14 +773,30 @@ With a numeric prefix ARG, go forward ARG comments." ;;; Font-Lock +(defvar-local git-commit-need-summary-line t + "Whether the text should have a heading that is separated from the body. + +For commit messages that is a convention that should not +be violated. For notes it is up to the user. If you do +not want to insist on an empty second line here, then use +something like: + + (add-hook \\='git-commit-setup-hook + (lambda () + (when (equal (file-name-nondirectory (buffer-file-name)) + \"NOTES_EDITMSG\") + (setq git-commit-need-summary-line nil))))") + (defun git-commit-summary-regexp () - (concat - ;; Leading empty lines and comments - (format "\\`\\(?:^\\(?:\\s-*\\|%s.*\\)\n\\)*" comment-start) - ;; Summary line - (format "\\(.\\{0,%d\\}\\)\\(.*\\)" git-commit-summary-max-length) - ;; Non-empty non-comment second line - (format "\\(?:\n%s\\|\n\\(.+\\)\\)?" comment-start))) + (if git-commit-need-summary-line + (concat + ;; Leading empty lines and comments + (format "\\`\\(?:^\\(?:\\s-*\\|%s.*\\)\n\\)*" comment-start) + ;; Summary line + (format "\\(.\\{0,%d\\}\\)\\(.*\\)" git-commit-summary-max-length) + ;; Non-empty non-comment second line + (format "\\(?:\n%s\\|\n\\(.+\\)\\)?" comment-start)) + "\\(EASTER\\) \\(EGG\\)")) (defun git-commit-extend-region-summary-line () "Identify the multiline summary-regexp construct. @@ -796,9 +834,9 @@ Added to `font-lock-extend-region-functions'." ;; Summary (eval . `(,(git-commit-summary-regexp) (1 'git-commit-summary))) - ;; - Note (overrides summary) + ;; - Keyword [aka "text in brackets"] (overrides summary) ("\\[.+?\\]" - (0 'git-commit-note t)) + (0 'git-commit-keyword t)) ;; - Non-empty second line (overrides summary and note) (eval . `(,(git-commit-summary-regexp) (2 'git-commit-overlong-summary t t) @@ -893,7 +931,7 @@ Added to `font-lock-extend-region-functions'." (add-hook 'font-lock-extend-region-functions #'git-commit-extend-region-summary-line t t) - (font-lock-add-keywords nil git-commit-font-lock-keywords t)) + (font-lock-add-keywords nil git-commit-font-lock-keywords)) (defun git-commit-propertize-diff () (require 'diff-mode) @@ -935,8 +973,7 @@ Elisp doc-strings, including this one. Unlike in doc-strings, (setq font-lock-defaults '(git-commit-elisp-text-mode-keywords))) (defvar git-commit-elisp-text-mode-keywords - `((,(concat "[`‘]\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)" - lisp-mode-symbol-regexp "\\)['’]") + `((,(concat "[`‘]\\(" lisp-mode-symbol-regexp "\\)['’]") (1 font-lock-constant-face prepend)) ("\"[^\"]*\"" (0 font-lock-string-face prepend)))) diff --git a/packages/git-link-20181031.259.el b/packages/git-link-20190817.302.el similarity index 93% rename from packages/git-link-20181031.259.el rename to packages/git-link-20190817.302.el index 4f61655..41312cb 100644 --- a/packages/git-link-20181031.259.el +++ b/packages/git-link-20190817.302.el @@ -1,10 +1,10 @@ ;;; git-link.el --- Get the GitHub/Bitbucket/GitLab URL for a buffer location -*- lexical-binding: t -*- -;; Copyright (C) 2013-2017 Skye Shaw and others +;; Copyright (C) 2013-2019 Skye Shaw and others ;; Author: Skye Shaw -;; Version: 0.7.2 -;; Package-Version: 20181031.259 -;; Keywords: git, vc, github, bitbucket, gitlab, convenience +;; Version: 0.7.4 +;; Package-Version: 20190817.302 +;; Keywords: git, vc, github, bitbucket, gitlab, sourcehut, convenience ;; URL: http://github.com/sshaw/git-link ;; Package-Requires: ((emacs "24.3")) @@ -36,6 +36,12 @@ ;;; Change Log: +;; 2019-08-16 - v0.7.4 +;; * Add support for Magit-Blob buffers (Issue #61, thanks Miciah Dashiel Butler Masters) +;; +;; 2019-03-09 - v0.7.3 +;; * Add support for sourcehut +;; ;; 2018-10-30 - v0.7.2 ;; * Fix suffix stripping on remote path only if it ends in .git (Issue #58, thanks Marko Crnic) ;; @@ -157,7 +163,8 @@ :group 'git-link) (defcustom git-link-remote-alist - '(("github" git-link-github) + '(("git.sr.ht" git-link-sourcehut) + ("github" git-link-github) ("bitbucket" git-link-bitbucket) ("gitorious" git-link-gitorious) ("gitlab" git-link-gitlab)) @@ -172,7 +179,8 @@ As an example, \"gitlab\" will match with both \"gitlab.com\" and :group 'git-link) (defcustom git-link-commit-remote-alist - '(("github" git-link-commit-github) + '(("git.sr.ht" git-link-commit-github) + ("github" git-link-commit-github) ("bitbucket" git-link-commit-bitbucket) ("gitorious" git-link-commit-gitorious) ("gitlab" git-link-commit-github)) @@ -207,9 +215,12 @@ As an example, \"gitlab\" will match with both \"gitlab.com\" and (car (git-link--exec "--no-pager" "log" "-n1" "--pretty=format:%H"))) (defun git-link--commit () - (if (git-link--using-git-timemachine) - (car git-timemachine-revision) - (git-link--last-commit))) + (cond + ((git-link--using-git-timemachine) + (car git-timemachine-revision)) + ((git-link--using-magit-blob-mode) + magit-buffer-revision) + (t (git-link--last-commit)))) (defun git-link--current-branch () (car (git-link--exec "symbolic-ref" "--short" "HEAD"))) @@ -229,6 +240,8 @@ As an example, \"gitlab\" will match with both \"gitlab.com\" and (defun git-link--branch () (or (git-link--get-config "git-link.branch") git-link-default-branch + (when (git-link--using-magit-blob-mode) + (magit-rev-branch magit-buffer-revision)) (git-link--current-branch))) (defun git-link--remote () @@ -252,7 +265,7 @@ As an example, \"gitlab\" will match with both \"gitlab.com\" and "For an ALIST whose `car' (a regexp) matches STR, return cadr. The ALIST consists of (REGEXP FN) list elements. -Valid ALISTs are `git-link-commit-remote-alist',`git-link-commit-alist'. +Valid ALISTs are `git-link-remote-alist',`git-link-commit-remote-alist'. For the first ALIST element whose REGEXP matches with STR, FN is returned. @@ -281,6 +294,8 @@ return (FILENAME . REVISION) otherwise nil." (cond ((eq major-mode 'dired-mode) (setq filename (dired-file-name-at-point))) + ((git-link--using-magit-blob-mode) + (setq filename magit-buffer-file-name)) ((and (string-match-p "^magit-" (symbol-name major-mode)) (fboundp 'magit-file-at-point)) (setq filename (magit-file-at-point))))) @@ -324,6 +339,9 @@ return (FILENAME . REVISION) otherwise nil." (and (boundp 'git-timemachine-revision) git-timemachine-revision)) +(defun git-link--using-magit-blob-mode () + (bound-and-true-p magit-blob-mode)) + (defun git-link--read-remote () (let ((remotes (git-link--remotes)) (current (git-link--remote))) @@ -452,7 +470,8 @@ or active region. The URL will be added to the kill ring. If With a prefix argument prompt for the remote's name. Defaults to \"origin\"." (interactive (let* ((remote (git-link--select-remote)) - (region (when buffer-file-name (git-link--get-region)))) + (region (when (or buffer-file-name (git-link--using-magit-blob-mode)) + (git-link--get-region)))) (list remote (car region) (cadr region)))) (let (filename branch commit handler remote-info (remote-url (git-link--remote-url remote))) (if (null remote-url) @@ -482,7 +501,10 @@ Defaults to \"origin\"." (car remote-info) (cadr remote-info) filename - (if (or (git-link--using-git-timemachine) vc-revison git-link-use-commit) + (if (or (git-link--using-git-timemachine) + (git-link--using-magit-blob-mode) + vc-revison + git-link-use-commit) nil (url-hexify-string branch)) commit diff --git a/packages/git-timemachine-20181114.1342.el b/packages/git-timemachine-20190730.849.el similarity index 90% rename from packages/git-timemachine-20181114.1342.el rename to packages/git-timemachine-20190730.849.el index 2ee4129..196de28 100644 --- a/packages/git-timemachine-20181114.1342.el +++ b/packages/git-timemachine-20190730.849.el @@ -3,11 +3,11 @@ ;; Copyright (C) 2014 Peter Stiernström ;; Author: Peter Stiernström -;; Version: 4.8 -;; Package-Version: 20181114.1342 -;; URL: https://github.com/pidu/git-timemachine -;; Keywords: git -;; Package-Requires: ((emacs "24.3")) +;; Version: 4.11 +;; Package-Version: 20190730.849 +;; URL: https://gitlab.com/pidu/git-timemachine +;; Keywords: vc +;; Package-Requires: ((emacs "24.3") (transient "0.1.0")) ;; This file is not part of GNU Emacs @@ -33,6 +33,7 @@ (require 'vc-git) (require 'cl-lib) +(require 'transient) (defcustom git-timemachine-abbreviation-length 12 "Number of chars from the full sha1 hash to use for abbreviation." @@ -238,7 +239,13 @@ When passed a GIT-BRANCH, lists revisions from that branch." (setq git-timemachine-revision revision) (goto-char current-position) (when git-timemachine-show-minibuffer-details - (git-timemachine--show-minibuffer-details revision))))) + (git-timemachine--show-minibuffer-details revision)) + (git-timemachine--erm-workaround)))) + +(defun git-timemachine--erm-workaround () + "Workaround for enhanced ruby mode not detecting revision change." + (when (eq major-mode 'enh-ruby-mode) + (ignore-errors (erm-reset-buffer)))) (defun git-timemachine--show-minibuffer-details (revision) "Show details for REVISION in minibuffer." @@ -251,7 +258,9 @@ When passed a GIT-BRANCH, lists revisions from that branch." (propertize sha-or-subject 'face 'git-timemachine-minibuffer-detail-face) date-full date-relative))) (defun git-timemachine--find-new-current-line (curr-revision new-revision current-line) - "Return the new current line after a revision jump." + "Return the new current line after a revision jump. + +Given CURR-REVISION and NEW-REVISION determine if we need to updated CURRENT-LINE." (let* ((revisions (reverse (git-timemachine--revisions))) (current-commit (car curr-revision)) (curr-rev-number (+ (or (cl-position curr-revision revisions) 0) 1)) @@ -284,15 +293,13 @@ When passed a GIT-BRANCH, lists revisions from that branch." new-line)))) (defun git-timemachine--get-cursor-position () - "Return the cursor visual line number with respect to the -current window first line" + "Return the cursor visual line number with respect to the current window first line." (let* ((win-point-min (save-excursion (move-to-window-line 0) (point))) (cur-pos (count-screen-lines win-point-min (point)))) cur-pos)) (defun git-timemachine--set-cursor-position (POS) - "Set the cursor position to the POS visual line with -respect to the window first line" + "Set the cursor position to the POS visual line with respect to the window first line." (recenter POS)) (defun git-timemachine-abbreviate (revision) @@ -309,7 +316,7 @@ respect to the window first line" (switch-to-buffer parent-buffer nil t))))) (defun git-timemachine-blame () - "Call magit-blame on current revision." + "Call ‘magit-blame’ on current revision." (interactive) (if (fboundp 'magit-blame) (let ((magit-buffer-revision (car git-timemachine-revision))) @@ -334,12 +341,26 @@ respect to the window first line" "Show commit for current revision." (interactive) (let ((rev (car git-timemachine-revision))) - (if (fboundp 'magit-revision-mode) - (progn - (with-temp-buffer - (save-excursion (magit-mode-setup #'magit-revision-mode rev nil nil nil)))) + (if (fboundp 'magit-show-commit) + (magit-show-commit rev) (message "You need to install magit to show commit")))) +(define-transient-command git-timemachine-help () + "Show online help." + ["Navigate" + [("p" "show previous revision" git-timemachine-show-previous-revision) + ("n" "show next revision" git-timemachine-show-next-revision) + ("g" "show nth revision" git-timemachine-show-nth-revision) + ("t" "show fuzzy revision" git-timemachine-show-revision-fuzzy)]] + ["Kill current revision" + [("w" "kill abbreviated revision" git-timemachine-kill-abbreviated-revision) + ("W" "kill revision" git-timemachine-kill-revision)]] + ["Misc" + [("b" "blame current revision" git-timemachine-blame) + ("c" "show commit" git-timemachine-show-commit) + ("?" "show help" git-timemachine-help) + ("q" "quit" git-timemachine-quit)]]) + (define-minor-mode git-timemachine-mode "Git Timemachine, feel the wings of history." :init-value nil @@ -353,7 +374,8 @@ respect to the window first line" ("w" . git-timemachine-kill-abbreviated-revision) ("W" . git-timemachine-kill-revision) ("b" . git-timemachine-blame) - ("c" . git-timemachine-show-commit)) + ("c" . git-timemachine-show-commit) + ("?" . git-timemachine-help)) :group 'git-timemachine) (defun git-timemachine-validate (file) diff --git a/packages/github-search-20170824.323.el b/packages/github-search-20190624.436.el similarity index 95% rename from packages/github-search-20170824.323.el rename to packages/github-search-20190624.436.el index 02c9ea1..72f18ce 100644 --- a/packages/github-search-20170824.323.el +++ b/packages/github-search-20190624.436.el @@ -4,7 +4,7 @@ ;; Author: Ivan Malison ;; Keywords: github search clone api gh magit vc tools -;; Package-Version: 20170824.323 +;; Package-Version: 20190624.436 ;; URL: https://github.com/IvanMalison/github-search ;; Version: 0.0.1 ;; Package-Requires: ((magit "0.8.1") (gh "1.0.0")) @@ -37,9 +37,13 @@ (defvar github-search-get-clone-url-function 'github-search-get-clone-url) (defvar github-search-get-target-directory-for-repo-function 'github-search-prompt-for-target-directory) -(defvar github-search-clone-repository-function 'magit-clone) +(defvar github-search-clone-repository-function + 'github-search-default-clone-repository-function) (defvar github-search-page-limit 1) +(defun github-search-default-clone-repository-function (repo directory) + (magit-clone-regular repo directory nil)) + (defun github-search-format-repository (repo) (cons (funcall github-search-repo-format-function repo) repo)) diff --git a/packages/glsl-mode-20170927.1436.el b/packages/glsl-mode-20190514.145.el similarity index 73% rename from packages/glsl-mode-20170927.1436.el rename to packages/glsl-mode-20190514.145.el index 3056d6e..676d46f 100644 --- a/packages/glsl-mode-20170927.1436.el +++ b/packages/glsl-mode-20190514.145.el @@ -1,14 +1,16 @@ ;;; glsl-mode.el --- major mode for Open GLSL shader files ;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. -;; Copyright (C) 2011, 2014 Jim Hourihan +;; Copyright (C) 2011, 2014, 2019 Jim Hourihan ;; -;; Authors: Xavier.Decoret@imag.fr, -;; Jim Hourihan (updated for 4.5, etc) -;; Keywords: languages -;; Package-Version: 20170927.1436 -;; Version: 2.0 -;; X-URL: http://artis.inrialpes.fr/~Xavier.Decoret/resources/glsl-mode/ +;; Authors: Xavier.Decoret@imag.fr, +;; Jim Hourihan (updated for 4.6, etc) +;; Keywords: languages OpenGL GPU SPIR-V Vulkan +;; Package-Version: 20190514.145 +;; Version: 2.2 +;; X-URL: https://github.com/jimhourihan/glsl-mode +;; +;; Original X-URL http://artis.inrialpes.fr/~Xavier.Decoret/resources/glsl-mode/ ;; ;; This software is distributed in the hope that it will be useful, but ;; WITHOUT ANY WARRANTY; without even the implied warranty of @@ -30,19 +32,19 @@ ;; replaced with keyword lists for easier maintenance ;; * Added customization group and faces ;; * Preprocessor faces -;; * Updated to GLSL 4.5 +;; * Updated to GLSL 4.6 ;; * Separate deprecated symbols ;; * Made _ part of a word ;; * man page lookup at opengl.org ;; This package provides the following features: ;; * Syntax coloring (via font-lock) for grammar symbols and -;; builtin functions and variables for up to GLSL version 4.5 +;; builtin functions and variables for up to GLSL version 4.6 ;; * Indentation for the current line (TAB) and selected region (C-M-\). ;; * Switching between file.vert and file.frag ;; with S-lefttab (via ff-find-other-file) ;; * interactive function glsl-find-man-page prompts for glsl built -;; in function, formats opengl.org url and passes to w3m +;; in function, formats opengl.org url and passes to browse-url ;;; Installation: @@ -56,6 +58,9 @@ ;; (add-to-list 'auto-mode-alist '("\\.frag\\'" . glsl-mode)) ;; (add-to-list 'auto-mode-alist '("\\.geom\\'" . glsl-mode)) +;; Reference: +;; https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf + ;;; Code: (provide 'glsl-mode) @@ -70,12 +75,16 @@ "OpenGL Shading Language Major Mode" :group 'languages) -(defconst glsl-language-version "4.5" +(defconst glsl-language-version "4.6" "GLSL language version number.") -(defconst gl-version "4.5" +(defconst gl-version "4.6" "OpenGL major mode version number.") +(defvar glsl-mode-menu nil "Menu for GLSL mode") + +(defvar glsl-mode-hook nil "GLSL mode hook") + (defvar glsl-type-face 'glsl-type-face) (defface glsl-type-face '((t (:inherit font-lock-type-face))) "glsl: type face" @@ -120,12 +129,18 @@ (defvar glsl-mode-map (let ((glsl-mode-map (make-sparse-keymap))) - (define-key glsl-mode-map [S-iso-lefttab] 'ff-find-other-file) + (define-key glsl-mode-map [S-iso-lefttab] 'ff-find-other-file) glsl-mode-map) - "Keymap for GLSL major mode") + "Keymap for GLSL major mode.") +(defcustom glsl-browse-url-function 'browse-url + "Function used to display GLSL man pages. E.g. browse-url, eww, w3m, etc" + :type 'function + :group 'glsl) + (defcustom glsl-man-pages-base-url "http://www.opengl.org/sdk/docs/man/html/" - "Location of GL man pages" + "Location of GL man pages." + :type 'string :group 'glsl) ;;;###autoload @@ -136,12 +151,9 @@ (add-to-list 'auto-mode-alist '("\\.glsl\\'" . glsl-mode))) (eval-and-compile - ;; - ;; These vars are useful for completion so keep them around after - ;; compile as well. The goal here is to have the byte compiled code - ;; have optimized regexps so its not done at eval time. - ;; - + ;; These vars are useful for completion so keep them around after + ;; compile as well. The goal here is to have the byte compiled code + ;; have optimized regexps so its not done at eval time. (defvar glsl-type-list '("float" "double" "int" "void" "bool" "true" "false" "mat2" "mat3" "mat4" "dmat2" "dmat3" "dmat4" "mat2x2" "mat2x3" "mat2x4" "dmat2x2" @@ -185,24 +197,31 @@ '("varying" "attribute")) ; centroid is deprecated when used with varying (defvar glsl-builtin-list - '("abs" "acos" "acosh" "all" "any" "asin" "asinh" "atan" "atanh" + '("abs" "acos" "acosh" "all" "any" "anyInvocation" "allInvocations" + "allInvocationsEqual" "asin" "asinh" "atan" "atanh" + "atomicAdd" "atomicMin" "atomicMax" "atomicAnd" "atomicOr" + "atomicXor" "atomicExchange" "atomicCompSwap" "atomicCounter" "atomicCounterDecrement" "atomicCounterIncrement" + "atomicCounterAdd" "atomicCounterSubtract" "atomicCounterMin" + "atomicCounterMax" "atomicCounterAnd" "atomicCounterOr" + "atomicCounterXor" "atomicCounterExchange" "atomicCounterCompSwap" "barrier" "bitCount" "bitfieldExtract" "bitfieldInsert" "bitfieldReverse" "ceil" "clamp" "cos" "cosh" "cross" "degrees" "determinant" "dFdx" "dFdy" - "dFdyFine" "dFdxFine" "dFdyCoarse" "dFdxCourse" + "dFdyFine" "dFdxFine" "dFdyCoarse" "dFdxCourse" "distance" "dot" "fwidthFine" "fwidthCoarse" - "distance" "dot" "EmitStreamVertex" "EmitVertex" "EndPrimitive" + "EmitStreamVertex" "EmitStreamPrimitive" "EmitVertex" "EndPrimitive" "EndStreamPrimitive" "equal" "exp" "exp2" "faceforward" "findLSB" "findMSB" "floatBitsToInt" "floatBitsToUint" "floor" "fma" "fract" - "frexp" "fwidth" "greaterThan" "greaterThanEqual" "imageAtomicAdd" - "imageAtomicAnd" "imageAtomicCompSwap" "imageAtomicExchange" + "frexp" "fwidth" "greaterThan" "greaterThanEqual" "groupMemoryBarrier" + "imageAtomicAdd" "imageAtomicAnd" "imageAtomicCompSwap" "imageAtomicExchange" "imageAtomicMax" "imageAtomicMin" "imageAtomicOr" "imageAtomicXor" "imageLoad" "imageSize" "imageStore" "imulExtended" "intBitsToFloat" - "imageSamples" - "interpolateAtCentroid" "interpolateAtOffset" "interpolateAtSample" + "imageSamples" "interpolateAtCentroid" "interpolateAtOffset" "interpolateAtSample" "inverse" "inversesqrt" "isinf" "isnan" "ldexp" "length" "lessThan" - "lessThanEqual" "log" "log2" "matrixCompMult" "max" "memoryBarrier" "min" - "mix" "mod" "modf" "noise" "normalize" "not" "notEqual" "outerProduct" + "lessThanEqual" "log" "log2" "matrixCompMult" "max" "memoryBarrier" + "memoryBarrierAtomicCounter" "memoryBarrierBuffer" + "memoryBarrierShared" "memoryBarrierImage" "memoryBarrier" + "min" "mix" "mod" "modf" "normalize" "not" "notEqual" "outerProduct" "packDouble2x32" "packHalf2x16" "packSnorm2x16" "packSnorm4x8" "packUnorm2x16" "packUnorm4x8" "pow" "radians" "reflect" "refract" "round" "roundEven" "sign" "sin" "sinh" "smoothstep" "sqrt" "step" "tan" @@ -216,9 +235,10 @@ "unpackSnorm4x8" "unpackUnorm2x16" "unpackUnorm4x8" "usubBorrow")) (defvar glsl-deprecated-builtin-list - '("texture1D" "texture1DProj" "texture1DLod" "texture1DProjLod" + '("noise1" "noise2" "noise3" "noise4" + "texture1D" "texture1DProj" "texture1DLod" "texture1DProjLod" "texture2D" "texture2DProj" "texture2DLod" "texture2DProjLod" - "texture2DRect" "texture2DRectProj" + "texture2DRect" "texture2DRectProj" "texture3D" "texture3DProj" "texture3DLod" "texture3DProjLod" "shadow1D" "shadow1DProj" "shadow1DLod" "shadow1DProjLod" "shadow2D" "shadow2DProj" "shadow2DLod" "shadow2DProjLod" @@ -238,7 +258,6 @@ (defvar glsl-preprocessor-builtin-list '("__LINE__" "__FILE__" "__VERSION__")) - (autoload 'w3m-browse-url "w3m" "View URL using w3m") ) ; eval-and-compile (eval-when-compile @@ -247,13 +266,13 @@ (defvar glsl-font-lock-keywords-1 (list - (cons (eval-when-compile - (format "^[ \t]*#[ \t]*\\<\\(%s\\)\\>" + (cons (eval-when-compile + (format "^[ \t]*#[ \t]*\\<\\(%s\\)\\>" (regexp-opt glsl-preprocessor-directive-list))) - glsl-preprocessor-face) + glsl-preprocessor-face) (cons (eval-when-compile (glsl-ppre glsl-type-list)) - glsl-type-face) + glsl-type-face) (cons (eval-when-compile (glsl-ppre glsl-deprecated-modifier-list)) glsl-deprecated-keyword-face) @@ -274,11 +293,11 @@ glsl-deprecated-variable-name-face) (cons "gl_[A-Z][A-Za-z_]+" glsl-variable-name-face) ) - "Minimal highlighting expressions for GLSL mode") + "Highlighting expressions for GLSL mode.") (defvar glsl-font-lock-keywords glsl-font-lock-keywords-1 - "Default highlighting expressions for GLSL mode") + "Default highlighting expressions for GLSL mode.") (defvar glsl-mode-syntax-table (let ((glsl-mode-syntax-table (make-syntax-table))) @@ -287,42 +306,76 @@ (modify-syntax-entry ?\n "> b" glsl-mode-syntax-table) (modify-syntax-entry ?_ "w" glsl-mode-syntax-table) glsl-mode-syntax-table) - "Syntax table for glsl-mode") + "Syntax table for glsl-mode.") (defvar glsl-other-file-alist '(("\\.frag$" (".vert")) ("\\.vert$" (".frag")) ) - "Alist of extensions to find given the current file's extension") - + "Alist of extensions to find given the current file's extension.") (defun glsl-man-completion-list () + "Return list of all GLSL keywords." (append glsl-builtin-list glsl-deprecated-builtin-list)) (defun glsl-find-man-page (thing) + "Collects and displays manual entry for GLSL built-in function THING." (interactive (let ((word (current-word nil t))) - (list + (list (completing-read (concat "OpenGL.org GLSL man page: (" word "): ") (glsl-man-completion-list) nil nil nil nil word)))) (save-excursion - (browse-url - (concat glsl-man-pages-base-url thing ".xhtml")))) + (apply glsl-browse-url-function + (list (concat glsl-man-pages-base-url thing ".xhtml"))))) + +(easy-menu-define glsl-menu glsl-mode-map + "GLSL Menu" + `("GLSL" + ["Comment Out Region" comment-region + (c-fn-region-is-active-p)] + ["Uncomment Region" (comment-region (region-beginning) + (region-end) '(4)) + (c-fn-region-is-active-p)] + ["Indent Expression" c-indent-exp + (memq (char-after) '(?\( ?\[ ?\{))] + ["Indent Line or Region" c-indent-line-or-region t] + ["Fill Comment Paragraph" c-fill-paragraph t] + "----" + ["Backward Statement" c-beginning-of-statement t] + ["Forward Statement" c-end-of-statement t] + "----" + ["Up Conditional" c-up-conditional t] + ["Backward Conditional" c-backward-conditional t] + ["Forward Conditional" c-forward-conditional t] + "----" + ["Backslashify" c-backslash-region (c-fn-region-is-active-p)] + "----" + ["Find GLSL Man Page" glsl-find-man-page t] + )) ;;;###autoload -(define-derived-mode glsl-mode c-mode "GLSL" - "Major mode for editing OpenGLSL shader files." +(define-derived-mode glsl-mode prog-mode "GLSL" + "Major mode for editing GLSL shader files." + (c-initialize-cc-mode t) + (setq abbrev-mode t) + (c-init-language-vars-for 'c-mode) + (c-common-init 'c-mode) + (cc-imenu-init cc-imenu-c++-generic-expression) (set (make-local-variable 'font-lock-defaults) '(glsl-font-lock-keywords)) (set (make-local-variable 'ff-other-file-alist) 'glsl-other-file-alist) (set (make-local-variable 'comment-start) "// ") (set (make-local-variable 'comment-end) "") (set (make-local-variable 'comment-padding) "") + (easy-menu-add glsl-menu) (add-to-list 'align-c++-modes 'glsl-mode) + (c-run-mode-hooks 'c-mode-common-hook) + (run-mode-hooks 'glsl-mode-hook) + :after-hook (progn (c-make-noise-macro-regexps) + (c-make-macro-with-semi-re) + (c-update-modeline)) ) - ;(easy-menu-define c-glsl-menu glsl-mode-map "GLSL Mode Commands" - ; (cons "GLSL" (c-lang-const c-mode-menu glsl))) - ;;; glsl-mode.el ends here diff --git a/packages/gnuplot-20141231.2137.tar b/packages/gnuplot-20141231.2137.tar index e32ed93..d7e2ecf 100644 Binary files a/packages/gnuplot-20141231.2137.tar and b/packages/gnuplot-20141231.2137.tar differ diff --git a/packages/go-mode-20181012.329.el b/packages/go-mode-20190819.2109.el similarity index 78% rename from packages/go-mode-20181012.329.el rename to packages/go-mode-20190819.2109.el index c3976a9..e8c0744 100644 --- a/packages/go-mode-20181012.329.el +++ b/packages/go-mode-20190819.2109.el @@ -8,7 +8,7 @@ ;; Author: The go-mode Authors ;; Version: 1.5.0 -;; Package-Version: 20181012.329 +;; Package-Version: 20190819.2109 ;; Keywords: languages go ;; URL: https://github.com/dominikh/go-mode.el ;; @@ -59,23 +59,25 @@ function." (progn (forward-visible-line arg) (point)))))) (defun go-goto-opening-parenthesis (&optional _legacy-unused) - "Move up one level of parentheses." + "Move up one level of parentheses. + +Return non-nil if there was a paren to move up to." ;; The old implementation of go-goto-opening-parenthesis had an ;; optional argument to speed up the function. It didn't change the ;; function's outcome. ;; Silently fail if there's no matching opening parenthesis. - (condition-case nil - (backward-up-list) - (scan-error nil))) + (let ((open-char (nth 1 (syntax-ppss)))) + (when open-char + (goto-char open-char)))) (defconst go-dangling-operators-regexp "[^-]-\\|[^+]\\+\\|[/*&><.=|^]") (defconst go--max-dangling-operator-length 2 "The maximum length of dangling operators. This must be at least the length of the longest string matched by -‘go-dangling-operators-regexp.’, and must be updated whenever -that constant is changed.") +‘go-dangling-operators-regexp’ and must be updated whenever that +constant is changed.") (defconst go-identifier-regexp "[[:word:][:multibyte:]]+") (defconst go-type-name-no-prefix-regexp "\\(?:[[:word:][:multibyte:]]+\\.\\)?[[:word:][:multibyte:]]+") @@ -212,17 +214,23 @@ mis-identifying them as gb projects." :type '(repeat function) :group 'go) +(defcustom go-confirm-playground-uploads t + "Ask before uploading code to the public Go Playground. + +Set this to nil to upload without prompting. +" + :type 'boolean + :group 'go) + (defcustom godoc-command "go doc" "Which executable to use for `godoc'. -This can either be 'godoc' or 'go doc', both as an absolute path -or an executable in PATH." +This can be either an absolute path or an executable in PATH." :type 'string :group 'go) -(defcustom godoc-and-godef-command "godoc" - "Which executable to use for `godoc' in `godoc-and-godef-command'. -Must be 'godoc' and not 'go doc' and can be an absolute path or -an executable in PATH." +(defcustom godoc-and-godef-command "go doc" + "Which executable to use for `godoc-and-godef'. +This can be either an absolute path or an executable in PATH." :type 'string :group 'go) @@ -278,7 +286,7 @@ You can install gogetdoc with 'go get -u github.com/zmb3/gogetdoc'." ;; TODO: gogetdoc supports unsaved files, but not introducing ;; new artifical files, so this limitation will stay for now. (error "Cannot use gogetdoc on a buffer without a file name")) - (let ((posn (format "%s:#%d" (shell-quote-argument (file-truename buffer-file-name)) (1- (position-bytes point)))) + (let ((posn (format "%s:#%d" (file-truename buffer-file-name) (1- (position-bytes point)))) (out (godoc--get-buffer ""))) (with-current-buffer (get-buffer-create "*go-gogetdoc-input*") (setq buffer-read-only nil) @@ -530,89 +538,459 @@ STOP-AT-STRING is not true, over strings." (point-min)))) (defun go-previous-line-has-dangling-op-p () - "Return non-nil if the current line is a continuation line." - (let* ((cur-line (line-number-at-pos)) - (val (gethash cur-line go-dangling-cache 'nope))) - (if (or (go--buffer-narrowed-p) (equal val 'nope)) - (save-excursion - (beginning-of-line) - (go--backward-irrelevant t) - (setq val (looking-back go-dangling-operators-regexp - (- (point) go--max-dangling-operator-length))) - (if (not (go--buffer-narrowed-p)) - (puthash cur-line val go-dangling-cache)))) + "Return non-nil if the current line is a continuation line. +The return value is cached based on the current `line-beginning-position'." + (let* ((line-begin (line-beginning-position)) + (val (gethash line-begin go-dangling-cache 'nope))) + (when (or (go--buffer-narrowed-p) (equal val 'nope)) + (save-excursion + (go--forward-line -1) + (if (go--current-line-has-dangling-op-p) + (setq val (line-end-position)) + (setq val nil)) + + (if (not (go--buffer-narrowed-p)) + (puthash line-begin val go-dangling-cache)))) val)) -(defun go--at-function-definition () - "Return non-nil if point is on the opening curly brace of a -function definition. +(defun go--current-line-has-dangling-op-p () + "Return non-nil if current line ends in a dangling operator. +The return value is not cached." + (or + (go--line-suffix-p go-dangling-operators-regexp) + ;; treat comma as dangling operator in certain cases + (and + (go--line-suffix-p ",") + (save-excursion (end-of-line) (go--commas-indent-p))))) + + +(defun go--commas-indent-p () + "Return non-nil if in a context where dangling commas indent next line." + (not (or + (go--open-paren-position) + (go--in-composite-literal-p) + (go--in-case-clause-list-p) + (go--in-struct-definition-p)))) + +(defun go--in-case-clause-list-p () + "Return non-nil if inside a multi-line case cause list. + +This function is only concerned with list items on lines after the +case keyword. It returns nil for the case line itself." + (save-excursion + (beginning-of-line) + (when (not (looking-at go--case-or-default-regexp)) + (let (saw-colon) + ;; optionally skip line with the colon + (when (go--line-suffix-p ":") + (setq saw-colon t) + (forward-line -1)) + + ;; go backwards while at a comment or a line ending in comma + (while (and + (or + (go--boring-line-p) + (go--line-suffix-p ",")) + (not (looking-at go--case-regexp)) + (go--forward-line -1))) + + (and + (looking-at go--case-regexp) + ;; we weren't in case list if first line ended in colon + ;; and the "case" line ended in colon + (not (and saw-colon (looking-at ".*:[[:space:]]*$")))))))) + +(defun go--in-struct-definition-p () + "Return non-nil if point is inside a struct definition." + (save-excursion + (and + ;; inside curlies + (go-goto-opening-parenthesis) + (eq (char-after) ?{) -We do this by first calling (beginning-of-defun), which will take -us to the start of *some* function. We then look for the opening -curly brace of that function and compare its position against the -curly brace we are checking. If they match, we return non-nil." - (if (= (char-after) ?\{) - (save-excursion - (let ((old-point (point)) - start-nesting) - (beginning-of-defun) - (when (looking-at "func ") - (setq start-nesting (go-paren-level)) - (skip-chars-forward "^{") - (while (> (go-paren-level) start-nesting) - (forward-char) - (skip-chars-forward "^{") 0) - (if (and (= (go-paren-level) start-nesting) (= old-point (point))) - t)))))) - -(defun go--indentation-for-opening-parenthesis () - "Return the semantic indentation for the current opening parenthesis. - -If point is on an opening curly brace and said curly brace -belongs to a function declaration, the indentation of the func -keyword will be returned. Otherwise the indentation of the -current line will be returned." + ;; "struct" appears before opening curly + (backward-word) + (looking-at "struct[[:space:]]")))) + +(defun go--in-composite-literal-p () + "Return non-nil if point is in a composite literal." (save-excursion - (if (go--at-function-definition) - (progn - (beginning-of-defun) - (current-indentation)) - (current-indentation)))) + (and + (go-goto-opening-parenthesis) + + ;; Opening paren-like character is a curly. + (eq (char-after) ?{) + + (or + ;; Curly is preceded by non space (e.g. "Foo|{"). + (not (looking-back "[[:space:]]" (1- (point)))) + + (and + (progn (skip-syntax-backward " ") t) + + ;; Curly looks like a composite literal with implicit type + ;; name. In particular, the curly is the first character on the + ;; line or the previous character is a comma or colon. + (or (bolp) (looking-back "[,:]" (1- (point))))))))) + +(defun go--open-paren-position () + "Return non-nil if point is between '(' and ')'. + +The return value is the position of the opening paren." + (save-excursion + (let ((start-paren-level (go-paren-level))) + (and + (go-goto-opening-parenthesis) + + ;; opening paren-like character is actually a paren + (eq (char-after) ?\() + + ;; point is before the closing paren + (< (go-paren-level) start-paren-level) + + (point))))) (defun go-indentation-at-point () + "Return the appropriate indentation for the current line. + +This function works by walking a line's characters backwards. When it +encounters a closing paren or brace it bounces to the corresponding +opener. If it arrives at the beginning of the line you are indenting, +it moves to the end of the previous line if the current line is a +continuation line, else it moves to the containing opening paren or +brace. If it arrives at the beginning of a line other than the line +you are indenting, it will continue to the previous dangling line if +the line you are indenting was not a continuation line, otherwise it +is done." (save-excursion - (let (start-nesting) - (back-to-indentation) - (setq start-nesting (go-paren-level)) + (beginning-of-line) - (cond - ((go-in-string-p) - (current-indentation)) - ((looking-at "[])}]") - (go-goto-opening-parenthesis) - (if (go-previous-line-has-dangling-op-p) - (- (current-indentation) tab-width) - (go--indentation-for-opening-parenthesis))) - ((progn (go--backward-irrelevant t) - (looking-back go-dangling-operators-regexp - (- (point) go--max-dangling-operator-length))) - ;; only one nesting for all dangling operators in one operation - (if (go-previous-line-has-dangling-op-p) - (current-indentation) - (+ (current-indentation) tab-width))) - ((zerop (go-paren-level)) - 0) - ((progn (go-goto-opening-parenthesis) (< (go-paren-level) start-nesting)) - (if (go-previous-line-has-dangling-op-p) - (current-indentation) - (+ (go--indentation-for-opening-parenthesis) tab-width))) - (t - (current-indentation)))))) + (let ( + ;; Beginning of our starting line. + (start-line (point)) + + ;; Whether this is our first iteration of the outer while loop. + (first t) + + ;; Whether we start in a block (i.e. our first line is not a + ;; continuation line and is in an "if", "for", "func" etc. block). + (in-block) + + ;; Our desired indent relative to our ending line's indent. + (indent 0)) + + ;; Skip leading whitespace. + (skip-syntax-forward " ") + + ;; Decrement indent if the first character on the line is a closer. + (when (or (eq (char-after) ?\)) (eq (char-after) ?})) + (cl-decf indent tab-width)) + + (while (or + ;; Always run the first iteration so we process empty lines. + first + + ;; Otherwise stop if we are at the start of a line. + (not (bolp))) + (setq first nil) + + (cl-case (char-before) + + ;; We have found a closer (paren or brace). + ((?\) ?}) + (backward-char) + (let ((bol (line-beginning-position))) + + ;; Jump back to corresponding opener. + (go-goto-opening-parenthesis) + + ;; Here we decrement the indent if we are closing an indented + ;; expression. In other words, the closer's line was indented + ;; relative to the opener's line, and that indent should not + ;; be inherited by our starting line. + (when (and + ;; We care about dangling expressions, not child blocks. + (not in-block) + + ;; Opener and closer aren't on same line. + (< (point) bol) + + (go-previous-line-has-dangling-op-p) + + ;; Opener is at same paren level as start of line (ignore sub-expressions). + (eq (go-paren-level) (save-excursion (beginning-of-line) (go-paren-level))) + + ;; This dangling line opened indent relative to previous dangling line. + (go--continuation-line-indents-p)) + (cl-decf indent tab-width)))) + + ;; Brackets don't affect indentation, so just skip them. + ((?\]) + (backward-char))) + + ;; Skip non-closers since we are only interested in closing parens/braces. + (skip-syntax-backward "^)" (line-beginning-position)) + + (when (go-in-string-or-comment-p) + (go-goto-beginning-of-string-or-comment)) + + ;; At the beginning of the starting line. + (when (= start-line (point)) + + ;; We are a continuation line. + (if (go-previous-line-has-dangling-op-p) + (progn + ;; Presume a continuation line always gets an extra indent. + ;; We reduce the indent after the loop, if necessary. + (cl-incf indent tab-width) + + ;; Go to the end of the dangling line. + (goto-char (go-previous-line-has-dangling-op-p))) + + ;; If we aren't a continuation line and we have an enclosing paren + ;; or brace, jump to opener and increment our indent. + (when (go-goto-opening-parenthesis) + ;; We started in a child block if our opener is a curly brace. + (setq in-block (and + (eq (char-after) ?{) + (looking-back "[^[:space:]][[:space:]]" (- (point) 2)))) + (cl-incf indent tab-width)))) + + ;; If we stared in a child block we must follow dangling lines + ;; until they don't dangle anymore. This is to handle cases like: + ;; + ;; if foo || + ;; foo && + ;; foo { + ;; X + ;; + ;; There can be an arbitrary number of indents, so we must go back to + ;; the "if" to determine the indent of "X". + (when (and in-block (bolp) (go-previous-line-has-dangling-op-p)) + (goto-char (go-previous-line-has-dangling-op-p)))) + + ;; If our ending line is a continuation line but doesn't open + ;; an extra indent, reduce indent. We tentatively gave indents to all + ;; dangling lines and all lines inside open parens, so here we take that + ;; indent back. + ;; + ;; 1 + 1 + + ;; ending line 1 + foo( 1 + foo( + ;; starting line 1, becomes 1, + ;; ) ) + ;; + ;; + ;; 1 + 1 + + ;; ending line 1 + becomes 1 + + ;; starting line 1 1 + (when (and + (go-previous-line-has-dangling-op-p) + (not (go--continuation-line-indents-p))) + (cl-decf indent tab-width)) + + ;; Apply our computed indent relative to the indent of the ending line. + (+ indent (current-indentation))))) + +(defconst go--operator-chars "*/%<>&\\^+\\-|=!," + "Individual characters that appear in operators. +Comma is included because it is sometimes a dangling operator, so +needs to be considered by `go--continuation-line-indents-p'") + +(defun go--operator-precedence (op) + "Go operator precedence (higher binds tighter). + +Comma gets the default 0 precedence which is appropriate because commas +are loose binding expression separators." + (cl-case (intern op) + (! 6) + ((* / % << >> & &^) 5) + ((+ - | ^) 4) + ((== != < <= > >=) 3) + (&& 2) + (|| 1) + (t 0))) + +(defun go--continuation-line-indents-p () + "Return non-nil if the current continuation line opens an additional indent. + +This function works by looking at the Go operators used on the current +line. If all the operators bind tighter than the previous line's +dangling operator and the current line ends in a dangling operator or +open paren, the next line will have an additional indent. + +For example: +foo || + foo && // this continuation line opens another indent + foo +" + (save-excursion + (let (prev-op (all-tighter t)) + + ;; Record the dangling operator from previous line. + (save-excursion + (goto-char (go-previous-line-has-dangling-op-p)) + (go--end-of-line) + (skip-syntax-backward " ") + (let ((end (point))) + (skip-chars-backward go--operator-chars) + (setq prev-op (buffer-substring-no-properties (point) end)))) + + (beginning-of-line) + + (when (or + ;; We can only open indent if we have a dangling operator, or + (go--current-line-has-dangling-op-p) + ;; we end in an opening paren/brace or comma. + (go--line-suffix-p "[(,]\\|[^[:space:]]{")) + + (let ((prev-precedence (go--operator-precedence prev-op)) + (start-depth (go-paren-level)) + (line-start (line-beginning-position))) + + (end-of-line) + + ;; While we haven't found a looser operator and are on the starting line... + (while (and all-tighter (> (point) line-start)) + + ;; Skip over non-operator characters. + (skip-chars-backward (concat "^" go--operator-chars) line-start) + + (let ((end (point))) + (cond + ;; Ignore sub-expressions at different paren levels. + ((/= (go-paren-level) start-depth) + (skip-syntax-backward "^()")) + + ((go-in-string-or-comment-p) + (go-goto-beginning-of-string-or-comment)) + + ;; We found an operator. Check if it has lower precedence. + ((/= (skip-chars-backward go--operator-chars) 0) + (when (>= + prev-precedence + (go--operator-precedence (buffer-substring (point) end))) + (setq all-tighter nil))))))) + all-tighter)))) + +(defun go--end-of-line () + "Move to the end of the code on the current line. +Point will be left before any trailing comments. Point will be left +after the opening backtick of multiline strings." + (end-of-line) + (let ((keep-going t)) + (while keep-going + (skip-syntax-backward " ") + (when (looking-back "\\*/" (- (point) 2)) + ;; back up so we are in the /* comment */ + (backward-char)) + (if (go-in-comment-p) + (go-goto-beginning-of-string-or-comment) + (setq keep-going nil)))) + (when (go-in-string-p) + (go-goto-beginning-of-string-or-comment) + ;; forward one so point is after the opening "`" + (forward-char))) + +(defun go--line-suffix-p (re) + "Return non-nil if RE matches the end of the line starting from `point'. + +Trailing whitespace, trailing comments and trailing multiline strings are +ignored." + (let ((start (point)) + (end (save-excursion (go--end-of-line) (point)))) + (when (< start end) + (string-match-p + (concat "\\(?:" re "\\)$") + (buffer-substring-no-properties start end))))) + +(defun go--boring-line-p () + "Return non-nil if the current line probably doesn't impact indentation. + +A boring line is one that starts with a comment, is empty, is part of a +multiline comment, or starts and ends in a multiline string." + (or + (looking-at (concat go--comment-start-regexp "\\|[[:space:]]*$")) + (go-in-comment-p) + (and (go-in-string-p) (save-excursion (end-of-line) (go-in-string-p))))) + +(defun go--forward-line (&optional count) + "Like `forward-line' but skip comments and empty lines. + +Return non-nil if point changed lines." + (let (moved) + (while (and + (zerop (forward-line count)) + (setq moved t) + (go--boring-line-p)) + (setq count (if (and count (< count 0 )) -1 1))) + moved)) + +(defconst go--comment-start-regexp "[[:space:]]*\\(/\\*\\|//\\)") + +(defun go--case-comment-p (indent) + "Return non-nil if looking at a comment attached to a case statement. + +INDENT is the normal indent of this line, i.e. that of the case body." + (when (and + (> (current-indentation) 0) + (looking-at go--comment-start-regexp)) + + (let (switch-before + case-after + has-case-aligned-preceding-comment) + + (save-excursion + ;; Search for previous case-aligned comment. + (while (and + (zerop (forward-line -1)) + (cond + ((looking-at "^[[:space:]]*$")) + + ((looking-at go--comment-start-regexp) + (when (= (current-indentation) (- indent tab-width)) + (setq has-case-aligned-preceding-comment t)) + t) + + ((go-in-comment-p))))) + + ;; Record if a switch (or select) precedes us. + (setq switch-before (looking-at "^[[:space:]]*\\(switch\\|select\\)[[:space:]]"))) + + ;; Record if first proceeding non-comment line is a case statement. + (save-excursion + (while (and + (zerop (forward-line 1)) + (or + (looking-at go--comment-start-regexp) + (looking-at "^[[:space:]]*$") + (go-in-comment-p)))) + + (setq case-after (looking-at go--case-or-default-regexp))) + + (and + ;; a "case" statement comes after our comment + case-after + + (or + ;; "switch" statement precedes us, always align with "case" + switch-before + + ;; a preceding comment is aligned with "case", we should too + has-case-aligned-preceding-comment + + ;; other cases are ambiguous, so if comment is currently + ;; aligned with "case", leave it that way + (= (current-indentation) (- indent tab-width))))))) + +(defconst go--case-regexp "\\([[:space:]]*case\\([[:space:]]\\|$\\)\\)") +(defconst go--case-or-default-regexp (concat "\\(" go--case-regexp "\\|" "[[:space:]]*default:\\)")) (defun go-mode-indent-line () (interactive) (let (indent shift-amt + ;; case sensitively match "case", "default", etc. + (case-fold-search nil) (pos (- (point-max) (point))) (point (point)) (beg (line-beginning-position))) @@ -620,8 +998,17 @@ current line will be returned." (if (go-in-string-or-comment-p) (goto-char point) (setq indent (go-indentation-at-point)) - (if (looking-at (concat go-label-regexp ":\\([[:space:]]*/.+\\)?$\\|case .+:\\|default:")) - (cl-decf indent tab-width)) + (when (or + (and + (looking-at (concat go-label-regexp ":\\([[:space:]]*/.+\\)?$\\|" go--case-or-default-regexp)) + ;; don't think last part of multiline case statement is a label + (not (go-previous-line-has-dangling-op-p)) + (not (go--in-case-clause-list-p)) + (not (go--in-composite-literal-p))) + + ;; comment attached above a "case" statement + (go--case-comment-p indent)) + (cl-decf indent tab-width)) (setq shift-amt (- indent (current-column))) (if (zerop shift-amt) nil @@ -894,6 +1281,21 @@ Function result is a unparenthesized type or a parameter list." This is intended to be called from `before-change-functions'." (setq go-dangling-cache (make-hash-table :test 'eql))) +(defun go--electric-indent-function (inserted-char) + (cond + ;; Indent after starting a "//" or "/*" comment. + ;; This is handy for comments above "case" statements. + ((or (eq inserted-char ?/) (eq inserted-char ?*)) + (when (eq (char-before (1- (point))) ?/) + 'do-indent)) + + ((eq inserted-char ? ) + (and + (eq (char-before (- (point) 1)) ?e) + (eq (char-before (- (point) 2)) ?s) + (eq (char-before (- (point) 3)) ?a) + (eq (char-before (- (point) 4)) ?c))))) + ;;;###autoload (define-derived-mode go-mode prog-mode "Go" "Major mode for editing Go source text. @@ -977,8 +1379,9 @@ with goflymake \(see URL `https://github.com/dougm/goflymake'), gocode (set (make-local-variable 'parse-sexp-lookup-properties) t) (set (make-local-variable 'syntax-propertize-function) #'go-propertize-syntax) - (if (boundp 'electric-indent-chars) - (set (make-local-variable 'electric-indent-chars) '(?\n ?} ?\)))) + (when (boundp 'electric-indent-chars) + (set (make-local-variable 'electric-indent-chars) '(?\n ?} ?\) ?:)) + (add-hook 'electric-indent-functions #'go--electric-indent-function nil t)) (set (make-local-variable 'compilation-error-screen-columns) nil) @@ -1067,8 +1470,8 @@ with goflymake \(see URL `https://github.com/dougm/goflymake'), gocode (defun gofmt () "Format the current buffer according to the formatting tool. -The tool used can be set via ‘gofmt-command` (default: gofmt) and additional -arguments can be set as a list via ‘gofmt-args`." +The tool used can be set via ‘gofmt-command’ (default: gofmt) and additional +arguments can be set as a list via ‘gofmt-args’." (interactive) (let ((tmpfile (go--make-nearby-temp-file "gofmt" nil ".go")) (patchbuf (get-buffer-create "*Gofmt patch*")) @@ -1274,27 +1677,36 @@ declaration." (defun go-play-region (start end) "Send the region between START and END to the Playground. If non-nil `go-play-browse-function' is called with the -Playground URL." +Playground URL. + +By default this function will prompt to confirm you want to upload +code to the Playground. You can disable the confirmation by setting +`go-confirm-playground-uploads' to nil. +" (interactive "r") - (let* ((url-request-method "POST") - (url-request-extra-headers - '(("Content-Type" . "application/x-www-form-urlencoded"))) - (url-request-data - (encode-coding-string - (buffer-substring-no-properties start end) - 'utf-8)) - (content-buf (url-retrieve - "https://play.golang.org/share" - (lambda (arg) - (cond - ((equal :error (car arg)) - (signal 'go-play-error (cdr arg))) - (t - (re-search-forward "\n\n") - (let ((url (format "https://play.golang.org/p/%s" - (buffer-substring (point) (point-max))))) - (when go-play-browse-function - (funcall go-play-browse-function url))))))))))) + (if (and go-confirm-playground-uploads + (not (yes-or-no-p "Upload to public Go Playground?"))) + (message "Upload aborted") + (let* ((url-request-method "POST") + (url-request-extra-headers + '(("Content-Type" . "application/x-www-form-urlencoded"))) + (url-request-data + (encode-coding-string + (buffer-substring-no-properties start end) + 'utf-8)) + + (content-buf (url-retrieve + "https://play.golang.org/share" + (lambda (arg) + (cond + ((equal :error (car arg)) + (signal 'go-play-error (cdr arg))) + (t + (re-search-forward "\n\n") + (let ((url (format "https://play.golang.org/p/%s" + (buffer-substring (point) (point-max))))) + (when go-play-browse-function + (funcall go-play-browse-function url)))))))))))) ;;;###autoload (defun go-download-play (url) @@ -1383,7 +1795,8 @@ If IGNORE-CASE is non-nil, the comparison is case-insensitive." (dolist (file files) (unless (member file '("." "..")) (let ((file (concat dir "/" file))) - (if (file-directory-p file) + (if (and (file-directory-p file) + (not (file-symlink-p file))) (setq dirs (append (cons file (go--directory-dirs file)) dirs)))))) @@ -1422,7 +1835,7 @@ It looks for archive files in /pkg/." (reverse (remove nil (mapcar (lambda (line) - (when (string-match "^\\(.+\\):\\([[:digit:]]+\\): imported and not used: \".+\".*$" line) + (when (string-match "^\\(.+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\): imported and not used: \".+\".*$" line) (let ((error-file-name (match-string 1 line)) (error-line-num (match-string 2 line))) (if (string= (file-truename error-file-name) (file-truename buffer-file-name)) @@ -1445,7 +1858,7 @@ they will be removed completely." (let ((cur-buffer (current-buffer)) flymake-state lines) (when (boundp 'flymake-mode) (setq flymake-state flymake-mode) - (flymake-mode-off)) + (flymake-mode -1)) (save-some-buffers nil (lambda () (equal cur-buffer (current-buffer)))) (if (buffer-modified-p) (message "Cannot operate on unsaved buffer") @@ -1457,7 +1870,7 @@ they will be removed completely." (comment-region (line-beginning-position) (line-end-position)) (go--delete-whole-line))) (message "Removed %d imports" (length lines))) - (if flymake-state (flymake-mode-on))))) + (if flymake-state (flymake-mode 1))))) (defun godef--find-file-line-column (specifier other-window) "Given a file name in the format of `filename:line:column', diff --git a/packages/go-rename-20180627.648.el b/packages/go-rename-20190805.2101.el similarity index 97% rename from packages/go-rename-20180627.648.el rename to packages/go-rename-20190805.2101.el index fb29df9..04fccab 100644 --- a/packages/go-rename-20180627.648.el +++ b/packages/go-rename-20190805.2101.el @@ -5,7 +5,7 @@ ;; license that can be found in the LICENSE file. ;; Version: 0.1 -;; Package-Version: 20180627.648 +;; Package-Version: 20190805.2101 ;; Package-Requires: ((go-mode "1.3.1")) ;; Keywords: tools @@ -42,7 +42,7 @@ the `gorename' tool. With FORCE, call `gorename' with the `-force' flag." (interactive (list - (unless (buffer-modified-p (or (not buffer-file-name))) + (if (and buffer-file-name (not (buffer-modified-p))) (read-string "New name: " (thing-at-point 'symbol))) current-prefix-arg)) (if (not buffer-file-name) diff --git a/packages/google-translate-20180926.1925.tar b/packages/google-translate-20190620.1416.tar similarity index 86% rename from packages/google-translate-20180926.1925.tar rename to packages/google-translate-20190620.1416.tar index be398eb..471950d 100644 Binary files a/packages/google-translate-20180926.1925.tar and b/packages/google-translate-20190620.1416.tar differ diff --git a/packages/goto-chg-20180105.1833.el b/packages/goto-chg-20190110.2114.el similarity index 96% rename from packages/goto-chg-20180105.1833.el rename to packages/goto-chg-20190110.2114.el index 6788b9f..1e426c1 100644 --- a/packages/goto-chg-20180105.1833.el +++ b/packages/goto-chg-20190110.2114.el @@ -15,16 +15,17 @@ ;; ;; You should have received a copy of the GNU General Public ;; License along with this program; if not, write to the Free -;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -;; MA 02111-1307 USA +;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301 USA ;; ;;------------------------------------------------------------------- ;; ;; Author: David Andersson -;; Maintainer: Vasilij Schneidermann +;; Maintainer: Vasilij Schneidermann ;; Created: 16 May 2002 -;; Version: 1.7.2 -;; Package-Version: 20180105.1833 +;; Version: 1.7.3 +;; Package-Version: 20190110.2114 +;; Package-Requires: ((undo-tree "0.1.3")) ;; Keywords: convenience, matching ;; URL: https://github.com/emacs-evil/goto-chg ;; @@ -51,6 +52,8 @@ ;;-------------------------------------------------------------------- ;; History ;; +;; Ver 1.7.3 2019-01-07 Vasilij Schneidermann +;; Fix errors when used with persistent undo ;; Ver 1.7.2 2018-01-05 Vasilij Schneidermann ;; Fix byte-compiler warnings again ;; Ver 1.7.1 2017-12-31 Vasilij Schneidermann @@ -96,6 +99,8 @@ ;;; Code: +(require 'undo-tree) + (defvar glc-default-span 8 "*goto-last-change don't visit the same point twice. glc-default-span tells how far around a visited point not to visit again.") (defvar glc-current-span 8 "Internal for goto-last-change.\nA copy of glc-default-span or the ARG passed to goto-last-change.") (defvar glc-probe-depth 0 "Internal for goto-last-change.\nIt is non-zero between successive goto-last-change.") @@ -212,11 +217,6 @@ Return nil if E represents no real change. that is, it was previously saved or unchanged. Nil otherwise." (and (listp e) (eq (car e) t))) -(defvar buffer-undo-tree) -(declare-function undo-tree-current "undo-tree.el") -(declare-function undo-tree-node-undo "undo-tree.el") -(declare-function undo-tree-node-previous "undo-tree.el") - ;;;###autoload (defun goto-last-change (arg) "Go to the point where the last edit was made in the current buffer. @@ -249,7 +249,7 @@ discarded. See variable `undo-limit'." glc-current-span glc-default-span) (if (< (prefix-numeric-value arg) 0) (error "Negative arg: Cannot reverse as the first operation")))) - (cond ((null buffer-undo-list) + (cond ((and (null buffer-undo-list) (null buffer-undo-tree)) (error "Buffer has not been changed")) ((eq buffer-undo-list t) (error "No change info (undo is disabled)"))) @@ -297,6 +297,7 @@ discarded. See variable `undo-limit'." ((or passed-save-entry (glc-is-filetime (car l))) (setq passed-save-entry t))) (setq l (cdr l))) + (undo-list-transfer-to-tree) (when (not glc-seen-canary) (while (and (not (null l)) (not glc-seen-canary) (< n new-probe-depth)) (cond ((eq 'undo-tree-canary (car l)) ; used by buffer-undo-tree @@ -311,7 +312,7 @@ discarded. See variable `undo-limit'." (when (not glc-seen-canary) (setq l (cdr l))))) (when glc-seen-canary - (while (< n new-probe-depth) + (while (and (< n new-probe-depth) (undo-tree-node-p l)) (cond ((null l) ;(setq this-command t) ; Disrupt repeat sequence (error "No further change info")) diff --git a/packages/grandshell-theme-20180606.517.tar b/packages/grandshell-theme-20180606.517.tar index 70a8d70..9ca0617 100644 Binary files a/packages/grandshell-theme-20180606.517.tar and b/packages/grandshell-theme-20180606.517.tar differ diff --git a/packages/graphql-20180912.31.el b/packages/graphql-20180912.31.el deleted file mode 100644 index 75873f5..0000000 --- a/packages/graphql-20180912.31.el +++ /dev/null @@ -1,220 +0,0 @@ -;;; graphql.el --- GraphQL utilities -*- lexical-binding: t; -*- - -;; Copyright (C) 2017 Sean Allred - -;; Author: Sean Allred -;; Keywords: hypermedia, tools, lisp -;; Homepage: https://github.com/vermiculus/graphql.el -;; Package-Version: 20180912.31 -;; Package-X-Original-Version: 0.1.1 -;; Package-Requires: ((emacs "25")) - -;; 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 . - -;;; Commentary: - -;; GraphQL.el provides a generally-applicable domain-specific language -;; for creating and executing GraphQL queries against your favorite -;; web services. - -;;; Code: - -(require 'pcase) - -(defun graphql--encode-object (obj) - "Encode OBJ as a GraphQL string." - (cond - ((stringp obj) - obj) - ((symbolp obj) - (symbol-name obj)) - ((numberp obj) - (number-to-string obj)) - ((and (consp obj) - (not (consp (cdr obj)))) - (symbol-name (car obj))))) - -(defun graphql--encode-argument-spec (spec) - "Encode an argument spec SPEC. -SPEC is of the form..." - (graphql--encode-argument (car spec) (cdr spec))) - -(defun graphql--encode-argument (key value) - "Encode an argument KEY with value VALUE." - (format "%s:%s" key (graphql--encode-argument-value value))) - -(defun graphql--encode-argument-value (value) - "Encode an argument value VALUE. -VALUE is expected to be one of the following: - -* a symbol -* a 'variable', i.e. \\='($ variableName) -* an object (as a list) -* a string -* a vector of values (e.g., symbols) -* a number -* something encode-able by `graphql-encode'." - (cond - ((symbolp value) - (symbol-name value)) - ((eq '$ (car-safe value)) - (format "$%s" (cadr value))) - ((listp value) - (format "{%s}" (mapconcat #'graphql--encode-argument-spec value ","))) - ((stringp value) - (format "\"%s\"" value)) - ((vectorp value) - (format "[%s]" (mapconcat #'graphql-encode value ","))) - ((numberp value) - (number-to-string value)) - (t - (graphql-encode value)))) - -(defun graphql--encode-parameter-spec (spec) - "Encode a parameter SPEC. -SPEC is expected to be of the following form: - - (NAME TYPE [REQUIRED] . [DEFAULT]) - -NAME is the name of the parameter. - -TYPE is the parameter's type. - -A non-nil value for REQUIRED will indicate the parameter is -required. A value of `!' is recommended. - -A non-nil value for DEFAULT will provide a default value for the -parameter." - ;; Unfortunately can't use `pcase' here because the first DEFAULT - ;; value (in the case of a complex value) might be misunderstood as - ;; the value for REQUIRED. We need to know if the third cons is the - ;; very last one; not just that the list has at least three - ;; elements. - (if (eq (last spec) (nthcdr 2 spec)) - (graphql--encode-parameter (nth 0 spec) - (nth 1 spec) - (car (last spec)) - (cdr (last spec))) - (graphql--encode-parameter (nth 0 spec) - (nth 1 spec) - nil - (nthcdr 2 spec)))) - -(defun graphql--encode-parameter (name type &optional required default) - "Encode a GraphQL parameter with a NAME and TYPE. -If REQUIRED is non-nil, mark the parameter as required. -If DEFAULT is non-nil, is the default value of the parameter." - (format "$%s:%s%s%s" - (symbol-name name) - (symbol-name type) - (if required "!" "") - (if default - (concat "=" (graphql--encode-argument-value default)) - ""))) - -(defun graphql--get-keys (g) - "Get the keyword arguments from a graph G. -Returns a list where the first element is a plist of arguments -and the second is a 'clean' copy of G." - (or (and (not (consp g)) - (list nil g)) - (let (graph keys) - (while g - (if (keywordp (car g)) - (let* ((param (pop g)) - (value (pop g))) - (push (cons param value) keys)) - (push (pop g) graph))) - (list keys (nreverse graph))))) - -(defun graphql-encode (g) - "Encode graph G as a GraphQL string." - (pcase (graphql--get-keys g) - (`(,keys ,graph) - (let ((object (or (car-safe graph) graph)) - (name (alist-get :op-name keys)) - (params (alist-get :op-params keys)) - (arguments (alist-get :arguments keys)) - (fields (cdr-safe graph))) - (concat - (graphql--encode-object object) - (when name - (format " %S" name)) - (when arguments - ;; Format arguments "key:value,key:value,..." - (format "(%s)" - (mapconcat #'graphql--encode-argument-spec arguments ","))) - (when params - (format "(%s)" - (mapconcat #'graphql--encode-parameter-spec params ","))) - (when fields - (format "{%s}" - (mapconcat #'graphql-encode fields " ")))))))) - -(defun graphql-simplify-response-edges (data) - "Simplify DATA to collapse edges into their nodes." - (pcase data - ;; When we encounter a collection of edges, simplify those edges - ;; into their nodes - (`(,object (edges . ,edges)) - (cons object (mapcar #'graphql-simplify-response-edges - (mapcar (lambda (edge) (alist-get 'node edge)) - edges)))) - ;; When we encounter a plain cons cell (not a list), let it pass - (`(,(and key (guard (not (consp key)))) . ,(and value (guard (not (consp value))))) - (cons key value)) - ;; symbols should pass unaltered - (`,(and symbol (guard (symbolp symbol))) - symbol) - ;; everything else should be mapped - (_ (mapcar #'graphql-simplify-response-edges data)))) - -(defun graphql--genform-operation (args kind) - "Generate the Lisp form for an operation. -ARGS is is a list ([NAME [PARAMETERS]] GRAPH) where NAME is the -name of the operation, PARAMETERS are its parameters, and GRAPH -is the form of the actual operation. - -KIND can be `query' or `mutation'." - (pcase args - (`(,name ,parameters ,graph) - `(graphql-encode '(,kind :op-name ,name - :op-params ,parameters - ,@graph))) - - (`(,name ,graph) - `(graphql-encode '(,kind :op-name ,name - ,@graph))) - - (`(,graph) - `(graphql-encode '(,kind ,@graph))) - - (_ (error "Bad form")))) - -(defmacro graphql-query (&rest args) - "Construct a Query object. -ARGS is a listof the form described by `graphql--genform-operation'. - -\(fn [NAME] [(PARAMETER-SPEC...)] GRAPH)" - (graphql--genform-operation args 'query)) - -(defmacro graphql-mutation (&rest args) - "Construct a Mutation object. -ARGS is a listof the form described by `graphql--genform-operation'. - -\(fn [NAME] [(PARAMETER-SPEC...)] GRAPH)" - (graphql--genform-operation args 'mutation)) - -(provide 'graphql) -;;; graphql.el ends here diff --git a/packages/grizzl-20160818.737.el b/packages/grizzl-20160818.737.el new file mode 100644 index 0000000..5157126 --- /dev/null +++ b/packages/grizzl-20160818.737.el @@ -0,0 +1,404 @@ +;;; grizzl.el --- Fast fuzzy search index for Emacs. -*- lexical-binding: t -*- + +;; Copyright © 2013-2014 Chris Corbyn +;; Copyright © 2015 Bozhidar Batsov +;; +;; Author: Chris Corbyn +;; Maintainer: Bozhidar Batsov +;; URL: https://github.com/grizzl/grizzl +;; Package-Version: 20160818.737 +;; Version: 0.1.2 +;; Keywords: convenience, usability +;; Package-Requires: ((cl-lib "0.5") (emacs "24.3")) + +;; 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 . + +;; This file is not part of GNU Emacs. + +;;; Commentary: + +;; Grizzl provides a fuzzy completion framework for general purpose +;; use in Emacs Lisp projects. +;; +;; grizzl provides the underlying data structures and sesrch +;; algorithm without any UI attachment. At the core, a fuzzy search +;; index is created from a list of strings, using `grizzl-make-index'. +;; A fuzzy search term is then used to get a result from this index +;; with `grizzl-search'. Because grizzl considers the usage of a +;; fuzzy search index to operate in real-time as a user enters a +;; search term in the minibuffer, the framework optimizes for this use +;; case. Any result can be passed back into `grizzl-search' as a hint +;; to continue searching. The search algorithm is able to understand +;; insertions and deletions and therefore minimizes the work it needs +;; to do in this case. The intended use here is to collect a result +;; on each key press and feed that result into the search for the next +;; key press. Once a search is complete, the matched strings are then +;; read, using `grizzl-result-strings'. The results are ordered on the +;; a combination of the Levenshtein Distance and a character-proximity +;; scoring calculation. This means shorter strings are favoured, but +;; adjacent letters are more heavily favoured. +;; +;; It is assumed that the index will be re-used across multiple +;; searches on larger sets of data. +;; +;; Call `grizzl-completing-read' with an index returned by +;; `grizzl-make-index': +;; +;; (defvar *index* (grizzl-make-index '("one" "two" "three"))) +;; (grizzl-completing-read "Number: " *index*) +;; +;; When the user hits ENTER, either one of the strings is returned on +;; success, or nil of nothing matched. +;; +;; The arrow keys can be used to navigate within the results. + + +;;; Code: + +(eval-when-compile + (require 'cl-lib)) + +;;; --- Public Functions + +;;;###autoload +(defun grizzl-make-index (strings &rest options) + "Makes an index from the list STRINGS for use with `grizzl-search'. + +If :PROGRESS-FN is given as a keyword argument, it is called repeatedly +with integers N and TOTAL. + +If :CASE-SENSITIVE is specified as a non-nil keyword argument, the index +will be created case-sensitive, otherwise it will be case-insensitive." + (let ((lookup-table (make-hash-table)) + (total-strs (length strings)) + (case-sensitive (plist-get options :case-sensitive)) + (progress-fn (plist-get options :progress-fn)) + (string-data (vconcat (mapcar (lambda (s) + (cons s (length s))) + strings)))) + (cl-reduce (lambda (list-offset str) + (grizzl-index-insert str list-offset lookup-table + :case-sensitive case-sensitive) + (when progress-fn + (funcall progress-fn (1+ list-offset) total-strs)) + (1+ list-offset)) + strings + :initial-value 0) + (maphash (lambda (_char str-map) + (maphash (lambda (list-offset locations) + (puthash list-offset (reverse locations) str-map)) + str-map)) lookup-table) + `((case-sensitive . ,case-sensitive) + (lookup-table . ,lookup-table) + (string-data . ,string-data)))) + +;;;###autoload +(defun grizzl-search (term index &optional old-result) + "Fuzzy searches for TERM in INDEX prepared with `grizzl-make-index'. + +OLD-RESULT may be specified as an existing search result to increment from. +The result can be read with `grizzl-result-strings'." + (let* ((cased-term (if (grizzl-index-case-sensitive-p index) + term + (downcase term))) + (result (grizzl-rewind-result cased-term index old-result)) + (matches (copy-hash-table (grizzl-result-matches result))) + (from-pos (length (grizzl-result-term result))) + (remainder (substring cased-term from-pos)) + (lookup-table (grizzl-lookup-table index))) + (cl-reduce (lambda (acc-res ch) + (let ((sub-table (gethash ch lookup-table))) + (if (not sub-table) + (clrhash matches) + (grizzl-search-increment sub-table matches)) + (grizzl-cons-result cased-term matches acc-res))) + remainder + :initial-value result))) + +;;;###autoload +(defun grizzl-result-count (result) + "Returns the number of matches present in RESULT." + (hash-table-count (grizzl-result-matches result))) + +;;;###autoload +(defun grizzl-result-strings (result index &rest options) + "Returns the ordered list of matched strings in RESULT, using INDEX. + +If the :START option is specified, results are read from the given offset. +If the :END option is specified, up to :END results are returned." + (let* ((matches (grizzl-result-matches result)) + (strings (grizzl-index-strings index)) + (loaded '())) + (maphash (lambda (string-offset _char-offset) + (push string-offset loaded)) + matches) + (let* ((ordered (sort loaded + (lambda (a b) + (< (cadr (gethash a matches)) + (cadr (gethash b matches)))))) + (start (or (plist-get options :start) 0)) + (end (min (plist-get options :end) (length ordered))) + (best (if (or start end) + (cl-delete-if-not 'identity + (cl-subseq ordered start end)) + ordered))) + (mapcar (lambda (n) + (car (elt strings n))) + best)))) + +;;; --- Private Functions + +(defun grizzl-cons-result (term matches results) + "Build a new result for TERM and hash-table MATCHES consed with RESULTS." + (cons (cons term matches) results)) + +(defun grizzl-rewind-result (term index result) + "Adjusts RESULT according to TERM, ready for a new search." + (if result + (let* ((old-term (grizzl-result-term result)) + (new-len (length term)) + (old-len (length old-term))) + (if (and (>= new-len old-len) + (string-equal old-term (substring term 0 old-len))) + result + (grizzl-rewind-result term index (cdr result)))) + (grizzl-cons-result "" (grizzl-base-matches index) nil))) + +(defun grizzl-base-matches (index) + "Returns the full set of matches in INDEX, with an out-of-bound offset." + (let ((matches (make-hash-table))) + (cl-reduce (lambda (n s-len) + (puthash n (list -1 0 (cdr s-len)) matches) + (1+ n)) + (grizzl-index-strings index) + :initial-value 0) + matches)) + +(defun grizzl-result-term (result) + "Returns the search term used to find the matches in RESULT." + (car (car result))) + +(defun grizzl-result-matches (result) + "Returns the internal hash used to track the matches in RESULT." + (cdar result)) + +(defun grizzl-index-insert (string list-offset index &rest options) + "Inserts STRING at LIST-OFFSET into INDEX." + (let ((case-sensitive (plist-get options :case-sensitive))) + (cl-reduce (lambda (char-offset cs-char) + (let* ((char (if case-sensitive + cs-char + (downcase cs-char))) + (str-map (or (gethash char index) + (puthash char (make-hash-table) index))) + (offsets (gethash list-offset str-map))) + (puthash list-offset + (cons char-offset offsets) + str-map) + (1+ char-offset))) + string + :initial-value 0))) + +(defun grizzl-lookup-table (index) + "Returns the lookup table portion of INDEX." + (cdr (assoc 'lookup-table index))) + +(defun grizzl-index-strings (index) + "Returns the vector of strings stored in INDEX." + (cdr (assoc 'string-data index))) + +(defun grizzl-index-case-sensitive-p (index) + "Predicate to test of INDEX is case-sensitive." + (cdr (assoc 'case-sensitive index))) + +(defun grizzl-search-increment (sub-table result) + "Use the search lookup table to filter already-accumulated results." + (cl-flet ((next-offset (key current sub-table) + (cl-find-if (lambda (v) + (> v current)) + (gethash key sub-table)))) + (maphash (lambda (k v) + (let* ((oldpos (car v)) + (oldrank (cadr v)) + (len (cl-caddr v)) + (newpos (next-offset k oldpos sub-table))) + (if newpos + (puthash k (list newpos + (grizzl-inc-rank oldrank oldpos newpos len) + len) + result) + (remhash k result)))) + result))) + +(defun grizzl-inc-rank (oldrank oldpos newpos len) + "Increment the current match distance as a new char is matched." + (let ((distance (if (< oldpos 0) 1 (- newpos oldpos)))) + (+ oldrank (* len (* distance distance))))) + +;;; --- Configuration Variables + +(defvar *grizzl-read-max-results* 10 + "The maximum number of results to show in `grizzl-completing-read'.") + +;;; --- Runtime Processing Variables + +(defvar *grizzl-current-result* nil + "The search result in `grizzl-completing-read'.") + +(defvar *grizzl-current-selection* 0 + "The selected offset in `grizzl-completing-read'.") + +(defface grizzl-selection-face + `((((class color) (background light)) + (:foreground "red")) + (((class color) (background dark)) + (:foreground "red")) + (t (:foreground "red"))) + "Face for selected result." + :group 'grizzl-mode) + +(defface grizzl-prompt-face + `((t :inherit 'mode-line-inactive)) + "Face used for grizzl prompt." + :group 'grizzl-mode) + +;;; --- Minor Mode Definition + +(defvar *grizzl-keymap* (make-sparse-keymap) + "Internal keymap used by the minor-mode in `grizzl-completing-read'.") + +(define-key *grizzl-keymap* (kbd "") 'grizzl-set-selection+1) +(define-key *grizzl-keymap* (kbd "C-p") 'grizzl-set-selection+1) +(define-key *grizzl-keymap* (kbd "") 'grizzl-set-selection-1) +(define-key *grizzl-keymap* (kbd "C-n") 'grizzl-set-selection-1) + +(define-minor-mode grizzl-mode + "Toggle the internal mode used by `grizzl-completing-read'." + nil + " Grizzl" + *grizzl-keymap*) + +;;; --- Public Functions + +;;;###autoload +(defun grizzl-completing-read (prompt index) + "Performs a completing-read in the minibuffer using INDEX to fuzzy search. +Each key pressed in the minibuffer filters down the list of matches." + (minibuffer-with-setup-hook + (lambda () + (setq *grizzl-current-result* nil) + (setq *grizzl-current-selection* 0) + (grizzl-mode 1) + (let* ((hookfun (lambda () + (setq *grizzl-current-result* + (grizzl-search (minibuffer-contents) + index + *grizzl-current-result*)) + (grizzl-display-result index prompt))) + (exitfun (lambda () + (grizzl-mode -1) + (remove-hook 'post-command-hook hookfun t)))) + (add-hook 'minibuffer-exit-hook exitfun nil t) + (add-hook 'post-command-hook hookfun nil t))) + (let ((read-value (read-from-minibuffer ">>> "))) + (or (grizzl-selected-result index) read-value)))) + +;;;###autoload +(defun grizzl-selected-result (index) + "Get the selected string from INDEX in a `grizzl-completing-read'." + (elt (grizzl-result-strings *grizzl-current-result* index + :start 0 + :end *grizzl-read-max-results*) + (grizzl-current-selection))) + +;;;###autoload +(defun grizzl-set-selection+1 () + "Move the selection up one row in `grizzl-completing-read'." + (interactive) + (grizzl-move-selection 1)) + +;;;###autoload +(defun grizzl-set-selection-1 () + "Move the selection down one row in `grizzl-completing-read'." + (interactive) + (grizzl-move-selection -1)) + +;;; --- Private Functions + +(defun grizzl-move-selection (delta) + "Move the selection by DELTA rows in `grizzl-completing-read'." + (setq *grizzl-current-selection* (+ (grizzl-current-selection) delta)) + (when (not (= (grizzl-current-selection) *grizzl-current-selection*)) + (beep))) + +(defun grizzl-display-result (index prompt) + "Renders a series of overlays to list the matches in the result." + (let* ((matches (grizzl-result-strings *grizzl-current-result* index + :start 0 + :end *grizzl-read-max-results*))) + (delete-all-overlays) + (overlay-put (make-overlay (point-min) (point-min)) + 'before-string + (format "%s\n%s\n" + (mapconcat 'identity + (grizzl-map-format-matches matches) + "\n") + (grizzl-format-prompt-line prompt))) + (set-window-text-height nil (max 3 (+ 2 (length matches)))))) + +(defun grizzl-map-format-matches (matches) + "Convert the set of string MATCHES into propertized text objects." + (if (= 0 (length matches)) + (list (propertize "-- NO MATCH --" 'face 'outline-3)) + (cdr (cl-reduce (lambda (acc str) + (let* ((idx (car acc)) + (lst (cdr acc)) + (sel (= idx (grizzl-current-selection)))) + (cons (1+ idx) + (cons (grizzl-format-match str sel) lst)))) + matches + :initial-value '(0))))) + +(defun grizzl-format-match (match-str selected) + "Default match string formatter in `grizzl-completing-read'. + +MATCH-STR is the string in the selection list and SELECTED is non-nil +if this is the current selection." + (let ((margin (if selected "> " " ")) + (face (if selected 'grizzl-selection-face 'default))) + (propertize (format "%s%s" margin match-str) 'face face))) + +(defun grizzl-format-prompt-line (prompt) + "Returns a string to render a full-width prompt in `grizzl-completing-read'." + (let* ((count (grizzl-result-count *grizzl-current-result*)) + (match-info (format " (%d candidate%s) ---- *-" + count (if (= count 1) "" "s")))) + (concat (propertize (format "-*%s *-" prompt) 'face 'grizzl-prompt-face) + + (propertize " " + 'face 'grizzl-prompt-face + 'display `(space :align-to (- right + ,(1+ (length match-info))))) + (propertize match-info 'face 'grizzl-prompt-face)))) + +(defun grizzl-current-selection () + "Get the currently selected index in `grizzl-completing-read'." + (let ((max-selection + (min (1- *grizzl-read-max-results*) + (1- (grizzl-result-count *grizzl-current-result*))))) + (max 0 (min max-selection *grizzl-current-selection*)))) + +(provide 'grizzl) + +;;; grizzl.el ends here diff --git a/packages/groovy-mode-20181111.1057.tar b/packages/groovy-mode-20190407.2314.tar similarity index 97% rename from packages/groovy-mode-20181111.1057.tar rename to packages/groovy-mode-20190407.2314.tar index 36d208a..1983081 100644 Binary files a/packages/groovy-mode-20181111.1057.tar and b/packages/groovy-mode-20190407.2314.tar differ diff --git a/packages/gruvbox-theme-20181013.1144.tar b/packages/gruvbox-theme-20190720.337.tar similarity index 90% rename from packages/gruvbox-theme-20181013.1144.tar rename to packages/gruvbox-theme-20190720.337.tar index bed8237..2685fae 100644 Binary files a/packages/gruvbox-theme-20181013.1144.tar and b/packages/gruvbox-theme-20190720.337.tar differ diff --git a/packages/haml-mode-20170924.453.el b/packages/haml-mode-20190219.2102.el similarity index 99% rename from packages/haml-mode-20170924.453.el rename to packages/haml-mode-20190219.2102.el index 865372b..6bf0e7b 100644 --- a/packages/haml-mode-20170924.453.el +++ b/packages/haml-mode-20190219.2102.el @@ -5,7 +5,7 @@ ;; Author: Natalie Weizenbaum ;; URL: https://github.com/nex3/haml-mode ;; Package-Requires: ((emacs "24") (cl-lib "0.5")) -;; Package-Version: 20170924.453 +;; Package-Version: 20190219.2102 ;; Package-X-Original-Version: 0 ;; Created: 2007-03-08 ;; By: Natalie Weizenbaum @@ -143,7 +143,9 @@ respectively." (defun haml-fontify-region-as-ruby (beg end) "Use Ruby's font-lock variables to fontify the region between BEG and END." (haml-fontify-region beg end ruby-font-lock-keywords - ruby-font-lock-syntax-table + (if (boundp 'ruby-mode-syntax-table) + ruby-mode-syntax-table + ruby-font-lock-syntax-table) (if (fboundp 'ruby-syntax-propertize) 'ruby-syntax-propertize 'ruby-syntax-propertize-function))) diff --git a/packages/haskell-mode-20180917.923.tar b/packages/haskell-mode-20190801.50.tar similarity index 96% rename from packages/haskell-mode-20180917.923.tar rename to packages/haskell-mode-20190801.50.tar index 1d58cfd..ea34110 100644 Binary files a/packages/haskell-mode-20180917.923.tar and b/packages/haskell-mode-20190801.50.tar differ diff --git a/packages/haskell-snippets-20160919.22.tar b/packages/haskell-snippets-20160919.22.tar index 34e24b9..cdf8425 100644 Binary files a/packages/haskell-snippets-20160919.22.tar and b/packages/haskell-snippets-20160919.22.tar differ diff --git a/packages/helm-20181117.731.tar b/packages/helm-20190821.735.tar similarity index 89% rename from packages/helm-20181117.731.tar rename to packages/helm-20190821.735.tar index 4203348..c8c8047 100644 Binary files a/packages/helm-20181117.731.tar and b/packages/helm-20190821.735.tar differ diff --git a/packages/helm-bibtex-20181030.2142.tar b/packages/helm-bibtex-20190814.1056.tar similarity index 94% rename from packages/helm-bibtex-20181030.2142.tar rename to packages/helm-bibtex-20190814.1056.tar index 5c4a188..2f8157b 100644 Binary files a/packages/helm-bibtex-20181030.2142.tar and b/packages/helm-bibtex-20190814.1056.tar differ diff --git a/packages/helm-company-20180828.1612.el b/packages/helm-company-20190812.1429.el similarity index 85% rename from packages/helm-company-20180828.1612.el rename to packages/helm-company-20190812.1429.el index 0bed582..3d1eb14 100644 --- a/packages/helm-company-20180828.1612.el +++ b/packages/helm-company-20190812.1429.el @@ -4,8 +4,8 @@ ;; Author: Yasuyuki Oka ;; Maintainer: Daniel Ralston -;; Version: 0.2.3 -;; Package-Version: 20180828.1612 +;; Version: 0.2.5 +;; Package-Version: 20190812.1429 ;; URL: https://github.com/Sodel-the-Vociferous/helm-company ;; Package-Requires: ((helm "1.5.9") (company "0.6.13")) @@ -134,11 +134,8 @@ annotations.") ;; `company-manual-begin' keeps company from throwing an error in ;; `company-post-command', its post-command hook. (when (company-manual-begin) - (company--insert-candidate candidate) - (funcall company-backend 'post-completion candidate) - (run-hooks 'helm-company-after-completion-hooks) - ;; for GC - (helm-company-cleanup-post-action)))) + (company-finish candidate) + (run-hooks 'helm-company-after-completion-hooks)))) (defun helm-company-action-show-document (candidate) "Show the documentation of the CANDIDATE." @@ -194,7 +191,10 @@ annotations.") (if (fboundp 'with-helm-display-same-window) (with-helm-display-same-window ,@body) - ,@body)))) + ,@body) + + ;; For GC + (setq helm-company--display-candidates-hash nil)))) (defun helm-company-run-show-doc-buffer () "Run showing documentation action from `helm-company'." @@ -221,21 +221,12 @@ annotations.") (concat candidate " " (helm-company--propertize-annotation annotation))))) (defun helm-company--get-annotations (candidate) - "Return a list of the annotations (if any) supplied for a -candidate by company-backend. - -When getting annotations from `company-backend', first it tries -with the `candidate' arg. If that doesn't work, it gets the -original candidate string(s) from -`helm-company-display-candidates-hash', and tries with those." - (company-call-backend 'annotation candidate)) - -(defun helm-company--make-display-candidate-pairs (candidates) - (cl-loop for cand in candidates - append - (cl-loop for annot in (helm-company--get-annotations cand) - collect (cons (helm-company--make-display-string cand annot) - cand)))) + "Return the annotation (if any) supplied for a candidate by +company-backend." + (let ((annot (company-call-backend 'annotation candidate))) + (if (null annot) + nil + (helm-company--clean-string annot)))) (defun helm-company--make-display-candidate-hash (candidates) (let ((hash (make-hash-table :test 'equal :size 1000))) @@ -246,24 +237,6 @@ original candidate string(s) from do (puthash key (cons display-str candidate) hash)) hash)) -(defun helm-company-add-annotations-transformer-1 (candidates &optional sort) - (with-helm-current-buffer - (let ((results (helm-company--make-display-candidate-pairs candidates))) - (if sort - (sort results #'helm-generic-sort-fn) - results)))) - -(defun helm-company-add-annotations-transformer (candidates _source) - "Transform a flat list of completion candidate strings -into (DISPLAY . REAL) pairs. - -The display strings have the company-provided annotation -appended, and formatted in the `company-tooltip-annotation' -face." - (if (or (not helm-company-show-annotations) (consp (car candidates))) - candidates - (helm-company-add-annotations-transformer-1 candidates (null helm--in-fuzzy)))) - (defun helm-company-get-display-strings () (let ((sort (null helm--in-fuzzy)) (display-strs (hash-table-keys helm-company-display-candidates-hash))) @@ -280,6 +253,29 @@ face." (mapcar (lambda (display-str) (car (gethash display-str helm-company-display-candidates-hash))) display-strs))) +;; Taken verbatim from `company--clean-string'. I don't use that function +;; directly because it's a private function inside `company', so I can't rely on +;; it. I have copied it here. +(defun helm-company--clean-string (str) + (replace-regexp-in-string + "\\([^[:graph:] ]\\)\\|\\(\ufeff\\)\\|[[:multibyte:]]" + (lambda (match) + (cond + ((match-beginning 1) + ;; FIXME: Better char for 'non-printable'? + ;; We shouldn't get any of these, but sometimes we might. + "\u2017") + ((match-beginning 2) + ;; Zero-width non-breakable space. + "") + ((> (string-width match) 1) + (concat + (make-string (1- (string-width match)) ?\ufeff) + match)) + (t match))) + str)) + + (defvar helm-company-map (let ((keymap (make-sparse-keymap))) (set-keymap-parent keymap helm-map) @@ -322,13 +318,18 @@ It is useful to narrow candidates." (interactive) (unless company-candidates (company-complete) - ;; (company-call-frontends 'hide) Work around a quirk with company. - ;; `company-complete' inserts the common part of all candidates into the - ;; buffer. But, it doesn't update `company-prefix' -- and `company-prefix' - ;; is all `company-finish' replaces in the buffer. (issue #9) + ;; Work around a quirk with company. `company-complete' inserts the common + ;; part of all candidates into the buffer. But, it doesn't update + ;; `company-prefix' -- and `company-prefix' is all `company-finish' replaces + ;; in the buffer. (issue #9) (when company-common (setq company-prefix company-common))) - (let ((initial-pattern (and helm-company-initialize-pattern-with-prefix company-prefix))) + (let ((initial-pattern (and helm-company-initialize-pattern-with-prefix + company-prefix)) + + ;; Abort company completion & hide company frontend if we keyboard-quit + ;; (C-g) out of `helm-company'. + (helm-quit-hook (cons 'company-abort helm-quit-hook))) (when company-point (helm :sources 'helm-source-company :buffer "*helm company*" diff --git a/packages/helm-core-20181117.1055.tar b/packages/helm-core-20190820.1142.tar similarity index 92% rename from packages/helm-core-20181117.1055.tar rename to packages/helm-core-20190820.1142.tar index 9867d61..eace56e 100644 Binary files a/packages/helm-core-20181117.1055.tar and b/packages/helm-core-20190820.1142.tar differ diff --git a/packages/helm-cscope-20170326.722.el b/packages/helm-cscope-20190615.41.el similarity index 76% rename from packages/helm-cscope-20170326.722.el rename to packages/helm-cscope-20190615.41.el index 3095604..cbeef8b 100644 --- a/packages/helm-cscope-20170326.722.el +++ b/packages/helm-cscope-20190615.41.el @@ -4,7 +4,7 @@ ;; Author: alpha22jp ;; URL: https://github.com/alpha22jp/helm-cscope.el -;; Package-Version: 20170326.722 +;; Package-Version: 20190615.41 ;; Keywords: cscope, helm ;; Version: 0.1.1 ;; Package-Requires: ((xcscope "1.0") (helm "1.6.7") (cl-lib "0.5") (emacs "24.1")) @@ -22,6 +22,9 @@ ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . +;;; Contributors: +;; Sanjeev Sivasankaran in 2019 added no-prompt versions. + ;;; Commentary: ;; `helm-cscope.el' is a `helm' interface for xcscope.el. @@ -51,6 +54,12 @@ "Face used to highlight line number in the *helm-cscope* buffer." :group 'helm-cscope) +(defvar helm-cscope-execute-action-if-one nil + "Automatically perform action if result consists of only one row.") + +(defvar helm-cscope-after-display-hook nil + "Call hook after the select action has been processed.") + (defconst helm-cscope--parse-regexp "\\`\\([^ ]+\\) \\([^ ]+\\) \\([0-9]+\\) \\(.*\\)") @@ -75,7 +84,8 @@ (save-restriction (widen) (goto-char (point-min)) - (forward-line (1- line-number))) + (forward-line (1- line-number)) + (run-hooks 'helm-cscope-after-display-hook)) (when cscope-fuzzy-search-range (let ((fuzzy-search-text-regexp @@ -185,6 +195,14 @@ "Find this symbol " nil nil t))) (helm-cscope--find-common "-0" symbol)) +;;;###autoload +(defun helm-cscope-find-this-symbol-no-prompt() + "Locate a symbol in source code [no user prompting]." + (interactive) + (let ((symbol (cscope-extract-symbol-at-cursor nil nil)) + (helm-execute-action-at-once-if-one helm-cscope-execute-action-if-one)) + (helm-cscope--find-common "-0" symbol))) + ;;;###autoload (defun helm-cscope-find-global-definition (symbol) "Find a symbol's global definition." @@ -193,6 +211,14 @@ "Find this global definition " nil nil t))) (helm-cscope--find-common "-1" symbol)) +;;;###autoload +(defun helm-cscope-find-global-definition-no-prompt() + "Find a symbol's global definition [no user prompting]." + (interactive) + (let ((symbol (cscope-extract-symbol-at-cursor nil nil)) + (helm-execute-action-at-once-if-one helm-cscope-execute-action-if-one)) + (helm-cscope--find-common "-1" symbol))) + ;;;###autoload (defun helm-cscope-find-called-function (symbol) "Display functions called by a function." @@ -201,6 +227,14 @@ "Find functions called by this function " nil nil t))) (helm-cscope--find-common "-2" symbol)) +;;;###autoload +(defun helm-cscope-find-called-function-no-prompt () + "Display functions called by a function [no user prompting]." + (interactive) + (let ((symbol (cscope-extract-symbol-at-cursor nil nil)) + (helm-execute-action-at-once-if-one helm-cscope-execute-action-if-one)) + (helm-cscope--find-common "-2" symbol))) + ;;;###autoload (defun helm-cscope-find-calling-this-function (symbol) "Display functions calling a function." @@ -209,6 +243,14 @@ "Find functions calling this function " nil nil t))) (helm-cscope--find-common "-3" symbol)) +;;;###autoload +(defun helm-cscope-find-calling-this-function-no-prompt() + "Display functions calling a function [no user prompting]." + (interactive) + (let ((symbol (cscope-extract-symbol-at-cursor nil nil)) + (helm-execute-action-at-once-if-one helm-cscope-execute-action-if-one)) + (helm-cscope--find-common "-3" symbol))) + ;;;###autoload (defun helm-cscope-find-this-text-string (symbol) "Locate where a text string occurs." @@ -217,6 +259,14 @@ "Find this text string " nil t nil))) (helm-cscope--find-common "-4" symbol)) +;;;###autoload +(defun helm-cscope-find-this-text-string-no-prompt() + "Locate where a text string occurs [no user prompting]." + (interactive) + (let ((symbol (cscope-extract-symbol-at-cursor nil nil)) + (helm-execute-action-at-once-if-one helm-cscope-execute-action-if-one)) + (helm-cscope--find-common "-4" symbol))) + ;;;###autoload (defun helm-cscope-find-egrep-pattern (symbol) "Run egrep over the cscope database." @@ -235,6 +285,14 @@ "Find this file " t nil t)))) (helm-cscope--find-common "-7" symbol)) +;;;###autoload +(defun helm-cscope-find-this-file-no-prompt () + "Locate a file [no user prompting]." + (interactive) + (let ((symbol (cscope-extract-symbol-at-cursor nil nil)) + (helm-execute-action-at-once-if-one helm-cscope-execute-action-if-one)) + (helm-cscope--find-common "-7" symbol))) + ;;;###autoload (defun helm-cscope-find-files-including-file (symbol) "Locate all files #including a file." @@ -244,6 +302,13 @@ "Find files #including this file " t nil nil)))) (helm-cscope--find-common "-8" symbol)) +(defun helm-cscope-find-files-including-file-no-prompt () + "Locate all files #including a file [no user prompting]." + (interactive) + (let ((symbol (cscope-extract-symbol-at-cursor nil nil)) + (helm-execute-action-at-once-if-one helm-cscope-execute-action-if-one)) + (helm-cscope--find-common "-8" symbol))) + ;;;###autoload (defun helm-cscope-find-assignments-to-this-symbol (symbol) "Locate assignments to a symbol in the source code." @@ -252,6 +317,14 @@ "Find assignments to this symbol " nil nil t))) (helm-cscope--find-common "-9" symbol)) +;;;###autoload +(defun helm-cscope-find-assignments-to-this-symbol-no-prompt () + "Locate assignments to a symbol in the source code[no user prompting]." + (interactive) + (let ((symbol (cscope-extract-symbol-at-cursor nil nil)) + (helm-execute-action-at-once-if-one helm-cscope-execute-action-if-one)) + (helm-cscope--find-common "-9" symbol))) + (defvar helm-cscope-mode-name " Helm cscope") (defvar helm-cscope-mode-map (make-sparse-keymap)) diff --git a/packages/helm-dash-20190527.1118.el b/packages/helm-dash-20190527.1118.el new file mode 100644 index 0000000..ff0bc3b --- /dev/null +++ b/packages/helm-dash-20190527.1118.el @@ -0,0 +1,135 @@ +;;; helm-dash.el --- Offline documentation browser for +150 APIs using Dash docsets. -*- lexical-binding: t; -*- +;; Copyright (C) 2013-2014 Raimon Grau +;; Copyright (C) 2013-2014 Toni Reina + +;; Author: Raimon Grau +;; Toni Reina +;; Bryan Gilbert +;; +;; URL: https://github.com/dash-docs-el/helm-dash +;; Package-Version: 20190527.1118 +;; Version: 1.3.0 +;; Package-Requires: ((emacs "24.4") (dash-docs "1.4.0") (helm "1.9.2") (cl-lib "0.5")) +;; Keywords: docs + +;; 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 . +;; +;;; Commentary: +;; +;; Clone the functionality of dash using helm foundation. Browse +;; documentation via dash docsets. +;; +;; M-x helm-dash +;; M-x helm-dash-at-point +;; +;; More info in the project site https://github.com/areina/helm-dash +;; +;;; Code: + +(eval-when-compile (require 'cl)) +(require 'dash-docs) +(require 'helm) +(require 'helm-multi-match) + +;;; Customize + +(defgroup helm-dash nil + "Search Dash docsets using helm." + :prefix "helm-dash-" + :group 'applications) + + +(defvaralias 'helm-dash-docsets-path 'dash-docs-docsets-path) +(defvaralias 'helm-dash-docsets-url 'dash-docs-docsets-url) +(defvaralias 'helm-dash-min-length 'dash-docs-min-length) +(defvaralias 'helm-dash-candidate-format 'dash-docs-candidate-format) +(defvaralias 'helm-dash-enable-debugging 'dash-docs-enable-debugging) +(defvaralias 'helm-dash-browser-func 'dash-docs-browser-func) +(defvaralias 'helm-dash-common-docsets 'dash-docs-common-docsets) +(defvaralias 'helm-dash-ignored-docsets 'dash-docs-ignored-docsets) + +(defalias 'helm-dash--candidate 'dash-docs--candidate) +(defalias 'helm-dash--run-query 'dash-docs--run-query) +(defalias 'helm-dash-actions 'dash-docs-actions) +(defalias 'helm-dash-activate-docset 'dash-docs-activate-docset) +(defalias 'helm-dash-create-buffer-connections 'dash-docs-create-buffer-connections) +(defalias 'helm-dash-create-common-connections 'dash-docs-create-common-connections) +(defalias 'helm-dash-deactivate-docset 'dash-docs-deactivate-docset) +(defalias 'helm-dash-initialize-debugging-buffer 'dash-docs-initialize-debugging-buffer) +(defalias 'helm-dash-install-docset 'dash-docs-install-docset) +(defalias 'helm-dash-install-docset-from-file 'dash-docs-install-docset-from-file) +(defalias 'helm-dash-installed-docsets 'dash-docs-installed-docsets) +(defalias 'helm-dash-install-user-docset 'dash-docs-install-user-docset) +(defalias 'helm-dash-maybe-narrow-docsets 'dash-docs-maybe-narrow-docsets) +(defalias 'helm-dash-reset-connections 'dash-docs-reset-connections) + +(defvar helm-dash-history-input nil) + +(defun helm-dash-search () + "Iterates every `helm-dash-connections' looking for the `helm-pattern'." + (let ((connections (helm-dash-maybe-narrow-docsets helm-pattern))) + (cl-loop for docset in connections + append (cl-loop for row in (helm-dash--run-query docset helm-pattern) + collect (helm-dash--candidate docset row))))) + +(make-obsolete #'helm-dash-search nil "1.3.0") + +(defun helm-dash--build-source (docset) + "Build a Helm source for DOCSET." + (lexical-let ((docset docset)) + (helm-build-sync-source (car docset) + :action-transformer #'helm-dash-actions + :candidates (lambda () + (cl-loop for row in (helm-dash--run-query docset helm-pattern) + collect (helm-dash--candidate docset row))) + :volatile t + :persistent-help "View doc" + :requires-pattern helm-dash-min-length))) + +(defun helm-dash--sources-narrowed-docsets () + "Return a list of Helm sources for narrowed docsets. + +Narrowed docsets are those returned by +`helm-dash-maybe-narrow-docsets'." + (let ((connections (helm-dash-maybe-narrow-docsets helm-pattern))) + (cl-loop for docset in connections + append (list (helm-dash--build-source docset))))) + +;;; Autoloads + +;;;###autoload +(defun helm-dash (&optional input-pattern) + "Bring up a `helm-dash' search interface. +If INPUT-PATTERN is non-nil, use it as an initial input in helm search." + (interactive) + (helm-dash-initialize-debugging-buffer) + (helm-dash-create-common-connections) + (helm-dash-create-buffer-connections) + (helm :sources (helm-dash--sources-narrowed-docsets) + :buffer "*helm-dash*" + :prompt "Doc for: " + :history 'helm-dash-history-input + :input input-pattern + :helm-candidate-number-limit 1000)) + +;;;###autoload +(defun helm-dash-at-point () + "Bring up a `helm-dash' search interface with symbol at point." + (interactive) + (helm-dash + (substring-no-properties (or (thing-at-point 'symbol) "")))) + +(provide 'helm-dash) + +;;; helm-dash.el ends here diff --git a/packages/helm-descbinds-20180429.1456.el b/packages/helm-descbinds-20190501.935.el similarity index 87% rename from packages/helm-descbinds-20180429.1456.el rename to packages/helm-descbinds-20190501.935.el index bbc524b..25f6395 100644 --- a/packages/helm-descbinds-20180429.1456.el +++ b/packages/helm-descbinds-20190501.935.el @@ -7,7 +7,7 @@ ;; Author: Taiki SUGAWARA ;; URL: https://github.com/emacs-helm/helm-descbinds -;; Package-Version: 20180429.1456 +;; Package-Version: 20190501.935 ;; Keywords: helm, help ;; Version: 1.12 ;; Package-Requires: ((helm "1.5")) @@ -107,6 +107,19 @@ This function will be called with two arguments KEY and BINDING." "A list of section order by name regexp." :type '(repeat (regexp :tag "Regexp"))) +(defvar helm-descbinds-prefix-help + "This is a prefix key, hit RET to see all bindings using this prefix. + +A “prefix key†is a key sequence whose binding is a keymap. The keymap +defines what to do with key sequences that extend the prefix key. For +example, ‘C-x’ is a prefix key, and it uses a keymap that is also stored +in the variable ‘ctl-x-map’. This keymap defines bindings for key +sequences starting with ‘C-x’. +See (info \"(elisp) Prefix Keys\") for more infos." + "A brief documentation of what is a prefix key. +This string is extracted from Elisp manual, +see (info \"(elisp) Prefix Keys\").") + (defvar helm-descbinds-Orig-describe-bindings (symbol-function 'describe-bindings)) (defvar helm-descbind--initial-full-frame helm-full-frame) @@ -192,12 +205,27 @@ This function will be called with two arguments KEY and BINDING." ;; directly `call-interactively'. (call-interactively x))))) +(defun helm-descbinds-display-string-in-help (str) + (with-current-buffer (help-buffer) + (let ((inhibit-read-only t)) + (erase-buffer) + (insert str)) + (help-mode) + (display-buffer (current-buffer)))) + (defun helm-descbinds-action:describe (candidate) "An action that describe selected CANDIDATE function." (let ((name (cdr candidate))) - (if (equal name "Keyboard Macro") - (describe-key (kbd (car candidate))) - (describe-function name)))) + (when (member name '("ignore" "ignore-event")) + (setq name 'ignore)) + (pcase name + ((pred (string= "Keyboard Macro")) + (describe-key (kbd (car candidate)))) + ((pred (string= "Prefix Command")) + (helm-descbinds-display-string-in-help + helm-descbinds-prefix-help)) + ((guard (and (symbolp name) (fboundp name))) + (describe-function name))))) (defun helm-descbinds-action:find-func (candidate) "An action that find selected CANDIDATE function." @@ -229,7 +257,10 @@ Provide a useful behavior for prefix commands." (helm-make-actions "helm-descbinds this prefix" (lambda (cand) - (describe-bindings (kbd (car cand))))) + (let ((binding (car cand))) + (if (member binding '("" "")) + (message "Key is bound to `ignore' because there is nothing to do") + (describe-bindings (kbd binding)))))) actions)) (defun helm-descbinds-sources (buffer &optional prefix menus) diff --git a/packages/helm-lsp-20190423.548.el b/packages/helm-lsp-20190423.548.el new file mode 100644 index 0000000..ba85364 --- /dev/null +++ b/packages/helm-lsp-20190423.548.el @@ -0,0 +1,118 @@ +;;; helm-lsp.el --- LSP helm integration -*- lexical-binding: t; -*- + +;; Copyright (C) 2018 Ivan Yonchovski + +;; 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 . + +;; Author: Ivan Yonchovski +;; Keywords: languages, debug +;; Package-Version: 20190423.548 +;; URL: https://github.com/yyoncho/helm-lsp +;; Package-Requires: ((emacs "25.1") (dash "2.14.1") (lsp-mode "5.0") (helm "2.0")) +;; Version: 0.1 + +;;; Commentary: + +;; `helm' for lsp function. + +;;; Code: + +(require 'helm) +(require 'helm-imenu) +(require 'dash) +(require 'lsp-mode) + +(defvar helm-lsp-symbols-request-id nil) +(defvar helm-lsp-symbols-result-p nil) +(defvar helm-lsp-symbols-result nil) + +(defun helm-lsp-workspace-symbol-action (candidate) + "Action for helm workspace symbol. +CANDIDATE is the selected item in the helm menu." + (-let* (((&hash "uri" "range" (&hash "start" (&hash "line" "character"))) (gethash "location" candidate))) + (find-file (lsp--uri-to-path uri)) + (goto-char (point-min)) + (forward-line line) + (forward-char character))) + +(defun helm-lsp--workspace-symbol (workspaces name input) + "Search against WORKSPACES NAME with default INPUT." + (if workspaces + (helm + :sources (helm-build-sync-source name + :candidates (lambda () + (if helm-lsp-symbols-result-p + helm-lsp-symbols-result + (with-lsp-workspaces workspaces + (-let (((request &as &plist :id request-id) (lsp-make-request + "workspace/symbol" + (list :query helm-pattern)))) + ;; cancel if there is pending request + (when helm-lsp-symbols-request-id + (lsp--cancel-request helm-lsp-symbols-request-id) + (setq helm-lsp-symbols-request-id nil)) + + (setq helm-lsp-symbols-request-id request-id) + (lsp-send-request-async + request + (lambda (candidates) + (setq helm-lsp-symbols-request-id nil) + (and helm-alive-p + (let ((helm-lsp-symbols-result candidates) + (helm-lsp-symbols-result-p t)) + (helm-update)))) + 'detached) + nil)))) + :action 'helm-lsp-workspace-symbol-action + :volatile t + :fuzzy-match t + :match (-const t) + :keymap helm-map + :candidate-transformer (lambda (candidates) + (-map + (-lambda ((candidate &as &hash "containerName" container-name "name" "kind")) + (let ((type (or (alist-get kind lsp--symbol-kind) "Unknown"))) + (cons + (concat (if (s-blank? container-name) + name + (concat container-name "." name)) + " " + (propertize (concat "(" type ")") 'face 'font-lock-keyword-face)) + candidate))) + candidates)) + :candidate-number-limit nil + :requires-pattern 0) + :input input) + (user-error "No LSP workspace active"))) + +;;;###autoload +(defun helm-lsp-workspace-symbol (arg) + "`helm' for lsp workspace/symbol. +When called with prefix ARG the default selection will be symbol at point." + (interactive "P") + (helm-lsp--workspace-symbol (lsp-workspaces) + "Workspace symbol" + (when arg (thing-at-point 'symbol)))) + +;;;###autoload +(defun helm-lsp-global-workspace-symbol (arg) + "`helm' for lsp workspace/symbol for all of the current workspaces. +When called with prefix ARG the default selection will be symbol at point." + (interactive "P") + (helm-lsp--workspace-symbol (-uniq (-flatten (ht-values (lsp-session-folder->servers (lsp-session))))) + "Global workspace symbols" + (when arg (thing-at-point 'symbol)))) + +(provide 'helm-lsp) +;;; helm-lsp.el ends here diff --git a/packages/helm-make-20181107.2126.el b/packages/helm-make-20190729.1221.el similarity index 82% rename from packages/helm-make-20181107.2126.el rename to packages/helm-make-20190729.1221.el index 0cb7e62..d87e4ba 100644 --- a/packages/helm-make-20181107.2126.el +++ b/packages/helm-make-20190729.1221.el @@ -1,12 +1,11 @@ ;;; helm-make.el --- Select a Makefile target with helm -;; Copyright (C) 2014 Oleh Krehel +;; Copyright (C) 2014-2019 Oleh Krehel ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/helm-make -;; Package-Version: 20181107.2126 +;; Package-Version: 20190729.1221 ;; Version: 0.2.0 -;; Package-Requires: ((helm "1.5.3") (projectile "0.11.0")) ;; Keywords: makefile ;; This file is not part of GNU Emacs @@ -31,8 +30,14 @@ ;;; Code: -(require 'helm) +(require 'subr-x) +(require 'cl-lib) +(eval-when-compile + (require 'helm-source nil t)) +(declare-function helm "ext:helm") +(declare-function helm-marked-candidates "ext:helm") +(declare-function helm-build-sync-source "ext:helm") (declare-function ivy-read "ext:ivy") (declare-function projectile-project-root "ext:projectile") @@ -122,6 +127,16 @@ You can reset the cache by calling `helm-make-reset-db'." (const :tag "Ido" ido) (const :tag "Ivy" ivy))) +(defcustom helm-make-nproc 1 + "Use that many processing units to compile the project. + +If `0', automatically retrieve available number of processing units +using `helm--make-get-nproc'. + +Regardless of the value of this variable, it can be bypassed by +passing an universal prefix to `helm-make' or `helm-make-projectile'." + :type 'integer) + (defvar helm-make-command nil "Store the make command.") @@ -135,8 +150,27 @@ An exception is \"GNUmakefile\", only GNU make understands it.") (defvar helm-make-ninja-filename "build.ninja" "Ninja build filename which ninja recognizes.") +(defun helm--make-get-nproc () + "Retrieve available number of processing units on this machine. + +If it fails to do so, `1' will be returned. +" + (cond + ((member system-type '(gnu gnu/linux gnu/kfreebsd cygwin)) + (if (executable-find "nproc") + (string-to-number (string-trim (shell-command-to-string "nproc"))) + (warn "Can not retrieve available number of processing units, \"nproc\" not found") + 1)) + ;; What about the other systems '(darwin windows-nt aix berkeley-unix hpux usg-unix-v)? + (t + (warn "Retrieving available number of processing units not implemented for system-type %s" system-type) + 1))) + +(defvar helm-make--last-item nil) + (defun helm--make-action (target) "Make TARGET." + (setq helm-make--last-item target) (let* ((targets (and (eq helm-make-completion-method 'helm) (or (> (length (helm-marked-candidates)) 1) ;; Give single marked candidate precedence over current selection. @@ -180,13 +214,29 @@ ninja.build file." (replace-regexp-in-string "^/\\(scp\\|ssh\\).+?:" "" (shell-quote-argument (file-name-directory file))) - arg)) + (let ((jobs (abs (if arg (prefix-numeric-value arg) + (if (= helm-make-nproc 0) (helm--make-get-nproc) + helm-make-nproc))))) + (if (> jobs 0) jobs 1)))) + +(defcustom helm-make-directory-functions-list + '(helm-make-current-directory helm-make-project-directory) + "Functions that return Makefile's directory, sorted by priority." + :type + '(repeat + (choice + (const :tag "Default directory" helm-make-current-directory) + (const :tag "Project directory" helm-make-project-directory) + (function :tag "Custom function")))) ;;;###autoload (defun helm-make (&optional arg) "Call \"make -j ARG target\". Target is selected with completion." - (interactive "p") - (let ((makefile (helm--make-makefile-exists default-directory))) + (interactive "P") + (let ((makefile nil)) + (cl-find-if + (lambda (fn) (setq makefile (helm--make-makefile-exists (funcall fn)))) + helm-make-directory-functions-list) (if (not makefile) (error "No build file in %s" default-directory) (setq helm-make-command (helm--make-construct-command arg makefile)) @@ -236,7 +286,7 @@ ninja.build file." (with-temp-buffer (insert-file-contents makefile) (goto-char (point-min)) - (while (re-search-forward "^\\([^: \n]+\\):" nil t) + (while (re-search-forward "^\\([^: \n]+\\) *:\\(?: \\|$\\)" nil t) (let ((str (match-string 1))) (unless (string-match "^\\." str) (push str targets))))) @@ -352,20 +402,21 @@ and cache targets of MAKEFILE, if `helm-make-cache-targets' is t." (delete-dups helm-make-target-history) (cl-case helm-make-completion-method (helm + (require 'helm) (helm :sources (helm-build-sync-source "Targets" :candidates 'targets :fuzzy-match helm-make-fuzzy-matching :action 'helm--make-action) :history 'helm-make-target-history - :preselect (when helm-make-target-history - (car helm-make-target-history)))) + :preselect helm-make--last-item)) (ivy - (ivy-read "Target: " - targets - :history 'helm-make-target-history - :preselect (car helm-make-target-history) - :action 'helm--make-action - :require-match helm-make-require-match)) + (unless (window-minibuffer-p) + (ivy-read "Target: " + targets + :history 'helm-make-target-history + :preselect (car helm-make-target-history) + :action 'helm--make-action + :require-match helm-make-require-match))) (ido (let ((target (ido-completing-read "Target: " targets @@ -384,7 +435,7 @@ followed by `projectile-project-root'/build, for a makefile. You can specify an additional directory to search for a makefile by setting the buffer local variable `helm-make-build-dir'." - (interactive "p") + (interactive "P") (require 'projectile) (let ((makefile (helm--make-makefile-exists (projectile-project-root) @@ -397,6 +448,16 @@ setting the buffer local variable `helm-make-build-dir'." (setq helm-make-command (helm--make-construct-command arg makefile)) (helm--make makefile)))) +(defun helm-make-project-directory () + "Return the current project root directory if found." + (if (and (fboundp 'project-current) (project-current)) + (car (project-roots (project-current))) + nil)) + +(defun helm-make-current-directory() + "Return the current directory." + default-directory) + (provide 'helm-make) ;;; helm-make.el ends here diff --git a/packages/helm-mu-20180513.921.el b/packages/helm-mu-20190819.1311.el similarity index 96% rename from packages/helm-mu-20180513.921.el rename to packages/helm-mu-20190819.1311.el index de62769..cb03188 100644 --- a/packages/helm-mu-20180513.921.el +++ b/packages/helm-mu-20190819.1311.el @@ -5,7 +5,7 @@ ;; Author: Titus von der Malsburg ;; Maintainer: Titus von der Malsburg ;; URL: https://github.com/emacs-helm/helm-mu -;; Package-Version: 20180513.921 +;; Package-Version: 20190819.1311 ;; Version: 1.0.0 ;; Package-Requires: ((helm "1.5.5")) @@ -111,7 +111,6 @@ (require 'cl-lib) (require 'helm) (require 'mu4e) -(require 'helm-easymenu) (defgroup helm-mu nil "Helm completion for mu." @@ -127,6 +126,11 @@ used: maildir:/INBOX" :group 'helm-mu :type 'string) +(defcustom helm-mu-always-use-default-search-string nil + "By default, starting a search from mu4e-headers-mode will not use the default search string, and will instead prefill the search with the current query. With this option set to non-nil, use default-search-string even when starting a search from mu4e-headers-mode." + :group 'helm-mu + :type 'boolean) + (defcustom helm-mu-skip-duplicates mu4e-headers-skip-duplicates "With this option set to non-nil, show only one of duplicate messages. This is useful when you have multiple copies of the same @@ -182,8 +186,11 @@ than '~/.mu' to store your data" :group 'helm-mu :type 'string) -(easy-menu-add-item nil '("Tools" "Helm" "Tools") ["Mu" helm-mu t]) -(easy-menu-add-item nil '("Tools" "Helm" "Tools") ["Mu contacts" helm-mu-contacts t]) +;;;###autoload +(progn + (require 'helm-easymenu) + (easy-menu-add-item nil '("Tools" "Helm" "Tools") ["Mu" helm-mu t]) + (easy-menu-add-item nil '("Tools" "Helm" "Tools") ["Mu contacts" helm-mu-contacts t])) (defface helm-mu-contacts-name-face @@ -311,7 +318,7 @@ by appending a `*' to the pattern input by the user" (width (cdr f-w)) (val (mu4e-message-field candidate (car f-w))) (str)) (setq str - (case field + (cl-case field (:subject (concat (mu4e~headers-thread-prefix (mu4e-message-field candidate :thread)) @@ -419,7 +426,7 @@ address. The name column has a predefined width." (defun helm-mu-action-get-contact-emails (_candidate) "Get the emails from/to (marked) contact" ;; Extract email from marked candidates - (let* ((emails (mapcar #'first + (let* ((emails (mapcar #'cl-first (mapcar #'split-string (helm-marked-candidates)))) ;; Compose the search query for helm-mu and let bind it to @@ -487,7 +494,8 @@ email." current query will be used to initialize the search. Otherwise `helm-mu-default-search-string' will be used." (interactive) - (let* ((query (if (eq major-mode 'mu4e-headers-mode) + (let* ((query (if (and (eq major-mode 'mu4e-headers-mode) + (not helm-mu-always-use-default-search-string)) (mu4e-last-query) helm-mu-default-search-string)) ;; Do not append space it there is already trailing space or query is diff --git a/packages/helm-notmuch-20180730.1722.el b/packages/helm-notmuch-20190320.1048.el similarity index 54% rename from packages/helm-notmuch-20180730.1722.el rename to packages/helm-notmuch-20190320.1048.el index bef7ece..a1f95da 100644 --- a/packages/helm-notmuch-20180730.1722.el +++ b/packages/helm-notmuch-20190320.1048.el @@ -1,12 +1,13 @@ ;;; helm-notmuch.el --- Search emails with Notmuch and Helm -*- lexical-binding: t; -*- ;; Copyright (C) 2016-2017 Chunyang Xu +;; Copyright (C) 2019 Pierre Neidhardt ;; Author: Chunyang Xu -;; URL: https://github.com/xuchunyang/helm-notmuch -;; Package-Version: 20180730.1722 +;; URL: https://github.com/emacs-helm/helm-notmuch +;; Package-Version: 20190320.1048 ;; Keywords: mail -;; Version: 1.1 +;; Version: 1.2 ;; Package-Requires: ((helm "1.9.3") (notmuch "0.21")) ;; This program is free software; you can redistribute it and/or modify @@ -24,22 +25,26 @@ ;;; Commentary: -;; To use, type M-x helm-notmuch. helm-notmuch will gets start to search when +;; To use, type `M-x helm-notmuch'. `helm-notmuch' only starts to search when ;; length of your input is no less than 2. ;; News: -;; - 2017-09-04 v1.1 Fix a regexp bug and use `notmuch-command' instead of hardcode "notmuch" -;; - 2016-11-28 v1.0 Add two user options: `helm-notmuch-max-matches' and `helm-notmuch-match-incomplete-words' +;; - 2019-03-20 v1.2 Improve incomplete word matching and turn on by default. +;; Fix bugs with -show-search and incomplete special queries. +;; Allow displaying multiple buffers and add action to display in other window. +;; - 2017-09-04 v1.1 Fix a regexp bug and use `notmuch-command' instead of hardcoding "notmuch". +;; - 2016-11-28 v1.0 Add two user options: `helm-notmuch-max-matches' and `helm-notmuch-match-incomplete-words'. ;;; Code: (require 'helm) +(require 'helm-utils) (require 'notmuch) (defgroup helm-notmuch nil "Helm interface for notmuch." :group 'notmuch - :link '(url-link :tag "Homepage" "https://github.com/xuchunyang/helm-notmuch")) + :link '(url-link :tag "Homepage" "https://github.com/emacs-helm/helm-notmuch")) (defcustom helm-notmuch-max-matches 0 "Maximum number of matches shown. @@ -48,7 +53,7 @@ Notice that a setting of 0 means \"Show all matches\"." :type '(choice (const :tag "Show all matches" 0) (integer :tag "Maximum number of matches shown" 50))) -(defcustom helm-notmuch-match-incomplete-words nil +(defcustom helm-notmuch-match-incomplete-words t "If non-nil, treat last word in query as incomplete. If this variable is non-nil, include results with words for which @@ -99,70 +104,89 @@ slows down searches." (defun helm-notmuch-candidate-formatter (cand) "Format the single entry CAND." - (let ((text (substring cand (+ 2 helm-notmuch-thread-id-length))) - (id (substring cand 0 helm-notmuch-thread-id-length)) - cstart astart alen tstart tags) - (with-temp-buffer - (insert text) - (goto-char (point-min)) - - ; Align message counts - (search-forward "[") - (setq cstart (point)) - (search-forward "]") - (save-excursion - (save-restriction - (narrow-to-region cstart (point)) - (goto-char (point-min)) - (when (re-search-forward "\([0-9]\+\)" nil t) - (replace-match "")))) - (forward-char) - (just-one-space (- helm-notmuch-thread-count-width - (- (point) cstart))) - (forward-char) - - ; Align (and truncate) authors - (setq astart (point)) - (search-forward ";") - (delete-char -1) - (setq alen (- (point) astart)) - (if (> alen helm-notmuch-author-width) - (progn - (delete-region (- (point) (- alen - (- helm-notmuch-author-width 3))) - (point)) - (insert "...")) - (just-one-space (- (+ helm-notmuch-author-width 1) alen))) - - ; Colour tags - (goto-char (- (point-max) 1)) - (save-excursion - (search-backward "(") - (setq tstart (+ (point) 1))) - (setq tags (split-string (buffer-substring tstart (point)))) - (delete-region tstart (point)) - (insert (notmuch-tag-format-tags tags tags)) - - ; Colour the whole line according to tags - (notmuch-search-color-line (point-min) (point-max) tags) - (setq text (buffer-string))) - (cons text id))) + (if (not (string-match-p "\\[" cand)) + ;; This protects against notmuch errors sent to standard output. + "" + (let ((text (substring cand (+ 2 helm-notmuch-thread-id-length))) + (id (substring cand 0 helm-notmuch-thread-id-length)) + cstart astart alen tstart tags) + (with-temp-buffer + (insert text) + (goto-char (point-min)) + + ;; Align message counts + (search-forward "[") + (setq cstart (point)) + (search-forward "]") + (save-excursion + (save-restriction + (narrow-to-region cstart (point)) + (goto-char (point-min)) + (when (re-search-forward "\([0-9]\+\)" nil t) + (replace-match "")))) + (forward-char) + (just-one-space (- helm-notmuch-thread-count-width + (- (point) cstart))) + (forward-char) + + ;; Align (and truncate) authors + (setq astart (point)) + (search-forward ";") + (delete-char -1) + (setq alen (- (point) astart)) + (if (> alen helm-notmuch-author-width) + (progn + (delete-region (- (point) (- alen + (- helm-notmuch-author-width 3))) + (point)) + (insert "...")) + (just-one-space (- (+ helm-notmuch-author-width 1) alen))) + + ;; Colour tags + (goto-char (- (point-max) 1)) + (save-excursion + (search-backward "(") + (setq tstart (+ (point) 1))) + (setq tags (split-string (buffer-substring tstart (point)))) + (delete-region tstart (point)) + (insert (notmuch-tag-format-tags tags tags)) + + ;; Colour the whole line according to tags + (notmuch-search-color-line (point-min) (point-max) tags) + (setq text (buffer-string))) + (cons text id)))) (defun helm-notmuch-maybe-match-incomplete (pattern) (if helm-notmuch-match-incomplete-words - (if (string-match-p "[[:alnum:]]$" pattern) - (concat pattern "*") - pattern) + (mapconcat #'identity + (mapcar (lambda (term) + (if (string-match-p "^[[:alnum:]]+$" term) + (concat term "*") + term)) + (split-string pattern)) + " ") pattern)) -(defun helm-notmuch-show (candidate) - "Display CANDIDATE using notmuch-show, retaining the query context." - (notmuch-show candidate nil nil - (helm-notmuch-maybe-match-incomplete helm-pattern))) +(defun helm-notmuch-show (_candidate &optional other-window) + "Display marked candidates using `notmuch-show', retaining the query context." + (helm-window-show-buffers + (save-window-excursion + (cl-loop for candidate in (helm-marked-candidates) + collect (progn (notmuch-show candidate nil nil + (helm-notmuch-maybe-match-incomplete + helm-pattern)) + (current-buffer)))) + other-window)) + +(defun helm-notmuch-show-other-window (_candidate) + "Display marked candidates using `notmuch-show' in other window. +See `helm-notmuch-show'." + (helm-notmuch-show nil 'other-window)) (defun helm-notmuch-search (candidate) "Display notmuch query in notmuch-search buffer, highlighting CANDIDATE." - (notmuch-search (helm-notmuch-maybe-match-incomplete helm-pattern) + (notmuch-search (helm-notmuch-maybe-match-incomplete + (with-helm-buffer helm-input-local)) nil (replace-regexp-in-string "^thread:" "" candidate))) @@ -174,6 +198,7 @@ slows down searches." :pattern-transformer #'helm-notmuch-maybe-match-incomplete :nohighlight t :action '(("Show message in notmuch" . helm-notmuch-show) + ("Show message in notmuch in other window" . helm-notmuch-show-other-window) ("Open notmuch-search query buffer" . helm-notmuch-search)))) ;;;###autoload diff --git a/packages/helm-org-20190819.617.el b/packages/helm-org-20190819.617.el new file mode 100644 index 0000000..5b16ea9 --- /dev/null +++ b/packages/helm-org-20190819.617.el @@ -0,0 +1,517 @@ +;;; helm-org.el --- Helm for org headlines and keywords completion -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2019 Thierry Volpiatto +;; Author: Thierry Volpiatto + +;; URL: https://github.com/emacs-helm/helm-org +;; Package-Version: 20190819.617 +;; Package-Requires: ((helm "3.3") (emacs "24.4")) +;; Version: 1.0 + +;; 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 . + + +;;; Commentary: +;; +;; Helm for org headlines and keywords completion + +;;; Code: +(require 'cl-lib) +(require 'helm) +(require 'helm-utils) +(require 'org) + +(defvar helm-completing-read-handlers-alist) + +;; Menu +;;;###autoload +(progn + (require 'helm-easymenu) + (easy-menu-add-item + nil '("Tools" "Helm") + '("Org" + ["Org headlines in org agenda files" helm-org-agenda-files-headings t] + ["Org headlines in buffer" helm-org-in-buffer-headings t]) + "Elpa")) + + +;; Load org-with-point-at macro when compiling +(eval-when-compile + (require 'org-macs)) + +(declare-function org-agenda-switch-to "org-agenda.el") + +(defgroup helm-org nil + "Org related functions for helm." + :group 'helm) + +(defcustom helm-org-headings-fontify nil + "Fontify org buffers before parsing them. +This reflect fontification in `helm-buffer' when non--nil. +NOTE: This will be slow on large org buffers." + :group 'helm-org + :type 'boolean) + +(defcustom helm-org-format-outline-path nil + "Show all org level as path." + :group 'helm-org + :type 'boolean) + +(defcustom helm-org-show-filename nil + "Show org filenames in `helm-org-agenda-files-headings' when non--nil. +Note this have no effect in `helm-org-in-buffer-headings'." + :group 'helm-org + :type 'boolean) + +(defcustom helm-org-headings-min-depth 1 + "Minimum depth of org headings to start with." + :group 'helm-org + :type 'integer) + +(defcustom helm-org-headings-max-depth 8 + "Go down to this maximum depth of org headings." + :group 'helm-org + :type 'integer) + +(defcustom helm-org-headings-actions + '(("Go to heading" . helm-org-goto-marker) + ("Open in indirect buffer `C-c i'" . helm-org--open-heading-in-indirect-buffer) + ("Refile heading(s) (marked-to-selected|current-to-selected) `C-c w`" . helm-org--refile-heading-to) + ("Insert link to this heading `C-c l`" . helm-org-insert-link-to-heading-at-marker)) + "Default actions alist for `helm-source-org-headings-for-files'." + :group 'helm-org + :type '(alist :key-type string :value-type function)) + +(defcustom helm-org-truncate-lines t + "Truncate org-header-lines when non-nil." + :type 'boolean + :group 'helm-org) + +(defcustom helm-org-ignore-autosaves nil + "Ignore autosave files when starting `helm-org-agenda-files-headings'." + :type 'boolean + :group 'helm-org) + + +;;; Help +;; +(defvar helm-org-headings-help-message + "* Helm Org headings + +** Tips + +*** Refiling + +You can refile one or more headings at a time. + +To refile one heading, move the point to the entry you want to refile and run +\\[helm-org-in-buffer-headings]. Then select the heading you want to refile to +and press \\\\[helm-org-run-refile-heading-to] or select the refile action from the actions menu. + +To refile multiple headings, run \\[helm-org-in-buffer-headings] and mark the +headings you want to refile. Then select the heading you want to refile to +\(without marking it) and press \\\\[helm-org-run-refile-heading-to] or select the refile action from the +actions menu. + +*** Tags completion + +Tags completion use `completing-read-multiple', perhaps have a +look at its docstring. + +**** Single tag + +From an org heading hit C-c C-c which provide a +\"Tags\" prompt, then hit TAB and RET if you want to enter an +existing tag or write a new tag in prompt. At this point you end +up with an entry in your prompt, if you enter RET, the entry is +added as tag in your org header. + +**** Multiple tags + +If you want to add more tag to your org header, add a separator[1] after +your tag and write a new tag or hit TAB to find another existing +tag, and so on until you have all the tags you want +e.g \"foo,bar,baz\" then press RET to finally add the tags to your +org header. +Note: [1] A separator can be a comma, a colon i.e. [,:] or a space. + +** Commands +\\ +\\[helm-org-run-open-heading-in-indirect-buffer]\t\tOpen heading in indirect buffer. +\\[helm-org-run-refile-heading-to]\t\tRefile current or marked headings to selection. +\\[helm-org-run-insert-link-to-heading-at-marker]\t\tInsert link at point to selection." + ) + +;;; Org capture templates +;; +;; +(defvar org-capture-templates) +(defun helm-source-org-capture-templates () + "Build source for org capture templates." + (helm-build-sync-source "Org Capture Templates:" + :candidates (cl-loop for template in org-capture-templates + collect (cons (nth 1 template) (nth 0 template))) + :action '(("Do capture" . (lambda (template-shortcut) + (org-capture nil template-shortcut)))))) + +;;; Org headings +;; +;; +(defun helm-org-goto-marker (marker) + "Go to MARKER in org buffer." + (switch-to-buffer (marker-buffer marker)) + (goto-char (marker-position marker)) + (org-show-context) + (re-search-backward "^\\*+ " nil t) + (org-show-entry) + (org-show-children)) + +(defun helm-org--open-heading-in-indirect-buffer (marker) + "Open org heading at MARKER in indirect buffer." + (helm-org-goto-marker marker) + (org-tree-to-indirect-buffer) + + ;; Put the non-indirect buffer at the bottom of the prev-buffers + ;; list so it won't be selected when the indirect buffer is killed + (set-window-prev-buffers nil (append (cdr (window-prev-buffers)) + (car (window-prev-buffers))))) + +(defun helm-org-run-open-heading-in-indirect-buffer () + "Open selected Org heading in an indirect buffer." + (interactive) + (with-helm-alive-p + (helm-exit-and-execute-action #'helm-org--open-heading-in-indirect-buffer))) +(put 'helm-org-run-open-heading-in-indirect-buffer 'helm-only t) + +(defvar helm-org-headings-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c i") 'helm-org-run-open-heading-in-indirect-buffer) + (define-key map (kbd "C-c w") 'helm-org-run-refile-heading-to) + (define-key map (kbd "C-c l") 'helm-org-run-insert-link-to-heading-at-marker) + map) + "Keymap for `helm-source-org-headings-for-files'.") + +(defclass helm-org-headings-class (helm-source-sync) + ((parents + :initarg :parents + :initform nil + :custom boolean) + (match :initform + (lambda (candidate) + (string-match + helm-pattern + (helm-aif (get-text-property 0 'helm-real-display candidate) + it + candidate)))) + (help-message :initform 'helm-org-headings-help-message) + (action :initform 'helm-org-headings-actions) + (keymap :initform 'helm-org-headings-map) + (group :initform 'helm-org))) + +(defmethod helm--setup-source :after ((source helm-org-headings-class)) + (let ((parents (slot-value source 'parents))) + (setf (slot-value source 'candidate-transformer) + (lambda (candidates) + (let ((cands (helm-org-get-candidates candidates parents))) + (if parents (nreverse cands) cands)))))) + +(defun helm-source-org-headings-for-files (filenames &optional parents) + "Build source for org headings in files FILENAMES. +When PARENTS is specified, bild source for heading that are parents of +current heading." + (helm-make-source "Org Headings" 'helm-org-headings-class + :filtered-candidate-transformer 'helm-org-startup-visibility + :parents parents + :candidates filenames)) + +(defun helm-org-startup-visibility (candidates _source) + "Indent headings and hide leading stars displayed in the helm buffer. +If `org-startup-indented' and `org-hide-leading-stars' are nil, do +nothing to CANDIDATES." + (cl-loop for i in candidates + collect + ;; Transformation is not needed if these variables are t. + (if (or helm-org-show-filename helm-org-format-outline-path) + (cons + (car i) (cdr i)) + (cons + (if helm-org-headings-fontify + (when (string-match "^\\(\\**\\)\\(\\* \\)\\(.*\n?\\)" (car i)) + (replace-match "\\1\\2\\3" t nil (car i))) + (when (string-match "^\\(\\**\\)\\(\\* \\)\\(.*\n?\\)" (car i)) + (let ((foreground (org-find-invisible-foreground))) + (with-helm-current-buffer + (cond + ;; org-startup-indented is t, and org-hide-leading-stars is t + ;; Or: #+STARTUP: indent hidestars + ((and org-startup-indented org-hide-leading-stars) + (with-helm-buffer + (require 'org-indent) + (org-indent-mode 1) + (replace-match + (format "%s\\2\\3" + (propertize (replace-match "\\1" t nil (car i)) + 'face `(:foreground ,foreground))) + t nil (car i)))) + ;; org-startup-indented is nil, org-hide-leading-stars is t + ;; Or: #+STARTUP: noindent hidestars + ((and (not org-startup-indented) org-hide-leading-stars) + (with-helm-buffer + (replace-match + (format "%s\\2\\3" + (propertize (replace-match "\\1" t nil (car i)) + 'face `(:foreground ,foreground))) + t nil (car i)))) + ;; org-startup-indented is nil, and org-hide-leading-stars is nil + ;; Or: #+STARTUP: noindent showstars + (t + (with-helm-buffer + (replace-match "\\1\\2\\3" t nil (car i))))))))) + (cdr i))))) + +(defun helm-org-get-candidates (filenames &optional parents) + "Get org headings for file FILENAMES. +Get PARENTS of heading when specified." + (apply #'append + (mapcar (lambda (filename) + (helm-org--get-candidates-in-file + filename + helm-org-headings-fontify + (or parents (null helm-org-show-filename)) + parents)) + filenames))) + +(defun helm-org--get-candidates-in-file (filename &optional fontify nofname parents) + "Get candidates for org FILENAME. +Fontify each heading when FONTIFY is specified. +Don't show filename when NOFNAME. +Get PARENTS as well when specified." + (with-current-buffer (pcase filename + ((pred bufferp) filename) + ((pred stringp) (find-file-noselect filename t))) + (let ((match-fn (if fontify + #'match-string + #'match-string-no-properties)) + (search-fn (lambda () + (re-search-forward + org-complex-heading-regexp nil t))) + (file (unless (or (bufferp filename) nofname) + (concat (helm-basename filename) ":")))) + (when parents + (add-function :around (var search-fn) + (lambda (old-fn &rest args) + (when (org-up-heading-safe) + (apply old-fn args))))) + (save-excursion + (save-restriction + (unless (and (bufferp filename) + (buffer-base-buffer filename)) + ;; Only widen direct buffers, not indirect ones. + (widen)) + (unless parents (goto-char (point-min))) + ;; clear cache for new version of org-get-outline-path + (and (boundp 'org-outline-path-cache) + (setq org-outline-path-cache nil)) + (cl-loop with width = (window-width (helm-window)) + while (funcall search-fn) + for beg = (point-at-bol) + for end = (point-at-eol) + when (and fontify + (null (text-property-any + beg end 'fontified t))) + do (jit-lock-fontify-now beg end) + for level = (length (match-string-no-properties 1)) + for heading = (funcall match-fn 4) + if (and (>= level helm-org-headings-min-depth) + (<= level helm-org-headings-max-depth)) + collect `(,(propertize + (if helm-org-format-outline-path + (org-format-outline-path + ;; org-get-outline-path changed in signature and behaviour since org's + ;; commit 105a4466971. Let's fall-back to the new version in case + ;; of wrong-number-of-arguments error. + (condition-case nil + (append (apply #'org-get-outline-path + (unless parents + (list t level heading))) + (list heading)) + (wrong-number-of-arguments + (org-get-outline-path t t))) + width file) + (if file + (concat file (funcall match-fn 0)) + (funcall match-fn 0))) + 'helm-real-display heading) + . ,(point-marker)))))))) + +(defun helm-org-insert-link-to-heading-at-marker (marker) + "Insert link to heading at MARKER position." + (with-current-buffer (marker-buffer marker) + (let ((heading-name (save-excursion (goto-char (marker-position marker)) + (nth 4 (org-heading-components)))) + (file-name (buffer-file-name))) + (with-helm-current-buffer + (org-insert-link + file-name (concat "file:" file-name "::*" heading-name)))))) + +(defun helm-org-run-insert-link-to-heading-at-marker () + "Run interactively `helm-org-insert-link-to-heading-at-marker'." + (interactive) + (with-helm-alive-p + (helm-exit-and-execute-action + 'helm-org-insert-link-to-heading-at-marker))) + +(defun helm-org--refile-heading-to (marker) + "Refile headings to heading at MARKER. +If multiple candidates are marked in the Helm session, they will +all be refiled. If no headings are marked, the selected heading +will be refiled." + (let* ((victims (with-helm-buffer (helm-marked-candidates))) + (buffer (marker-buffer marker)) + (filename (buffer-file-name buffer)) + (rfloc (list nil filename nil marker))) + (when (and (= 1 (length victims)) + (equal (helm-get-selection) (car victims))) + ;; No candidates are marked; we are refiling the entry at point + ;; to the selected heading + (setq victims (list (point)))) + ;; Probably best to check that everything returned a value + (when (and victims buffer filename rfloc) + (cl-loop for victim in victims + do (org-with-point-at victim + (org-refile nil nil rfloc)))))) + +(defun helm-org-in-buffer-preselect () + "Return the current or closest visible heading as a regexp string." + (save-excursion + (cond ((org-at-heading-p) (forward-line 0)) + ((org-before-first-heading-p) + (outline-next-visible-heading 1)) + (t (outline-previous-visible-heading 1))) + (regexp-quote (buffer-substring-no-properties (point) + (point-at-eol))))) + +(defun helm-org-run-refile-heading-to () + "Helm org refile heading action." + (interactive) + (with-helm-alive-p + (helm-exit-and-execute-action 'helm-org--refile-heading-to))) +(put 'helm-org-run-refile-heading-to 'helm-only t) + +;;;###autoload +(defun helm-org-agenda-files-headings () + "Preconfigured helm for org files headings." + (interactive) + (let ((autosaves (cl-loop for f in (org-agenda-files) + when (file-exists-p + (expand-file-name + (concat "#" (helm-basename f) "#") + (helm-basedir f))) + collect (helm-basename f)))) + (when (or (null autosaves) + helm-org-ignore-autosaves + (y-or-n-p (format "%s have auto save data, continue? " + (mapconcat #'identity autosaves ", ")))) + (helm :sources (helm-source-org-headings-for-files (org-agenda-files)) + :candidate-number-limit 99999 + :truncate-lines helm-org-truncate-lines + :buffer "*helm org headings*")))) + +;;;###autoload +(defun helm-org-in-buffer-headings () + "Preconfigured helm for org buffer headings." + (interactive) + (let (helm-org-show-filename) + (helm :sources (helm-source-org-headings-for-files + (list (current-buffer))) + :candidate-number-limit 99999 + :preselect (helm-org-in-buffer-preselect) + :truncate-lines helm-org-truncate-lines + :buffer "*helm org inbuffer*"))) + +;;;###autoload +(defun helm-org-parent-headings () + "Preconfigured helm for org headings that are parents of the current heading." + (interactive) + ;; Use a large max-depth to ensure all parents are displayed. + (let ((helm-org-headings-min-depth 1) + (helm-org-headings-max-depth 50)) + (helm :sources (helm-source-org-headings-for-files + (list (current-buffer)) t) + :candidate-number-limit 99999 + :truncate-lines helm-org-truncate-lines + :buffer "*helm org parent headings*"))) + +;;;###autoload +(defun helm-org-capture-templates () + "Preconfigured helm for org templates." + (interactive) + (helm :sources (helm-source-org-capture-templates) + :candidate-number-limit 99999 + :truncate-lines helm-org-truncate-lines + :buffer "*helm org capture templates*")) + +;;; Org tag completion + +;; Based on code from Anders Johansson posted on 3 Mar 2016 at +;; + +(defvar crm-separator) + +;;;###autoload +(defun helm-org-completing-read-tags (prompt collection pred req initial + hist def inherit-input-method _name _buffer) + "Completing read function for Org tags. + +This function is used as a `completing-read' function in +`helm-completing-read-handlers-alist' by `org-set-tags' and +`org-capture'. + +NOTE: Org tag completion will work only if you disable org fast tag +selection, see (info \"(org) setting tags\")." + (if (not (string= "Tags: " prompt)) + ;; Not a tags prompt. Use normal completion by calling + ;; `org-icompleting-read' again without this function in + ;; `helm-completing-read-handlers-alist' + (let ((helm-completing-read-handlers-alist + (rassq-delete-all + 'helm-org-completing-read-tags + (copy-alist helm-completing-read-handlers-alist)))) + (org-icompleting-read + prompt collection pred req initial hist def inherit-input-method)) + ;; Tags prompt + (let* ((curr (and (stringp initial) + (not (string= initial "")) + (org-split-string initial ":"))) + (table (delete curr + (org-uniquify + (mapcar #'car org-last-tags-completion-table)))) + (crm-separator ":\\|,\\|\\s-")) + (cl-letf (((symbol-function 'crm-complete-word) + 'self-insert-command)) + (mapconcat #'identity + (completing-read-multiple + prompt table pred nil initial hist def) + ":"))))) + +(provide 'helm-org) + +;; Local Variables: +;; byte-compile-warnings: (not obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-org.el ends here diff --git a/packages/helm-org-rifle-20180923.2209.el b/packages/helm-org-rifle-20190809.1831.el similarity index 99% rename from packages/helm-org-rifle-20180923.2209.el rename to packages/helm-org-rifle-20190809.1831.el index d7b8e3b..9e25e2d 100644 --- a/packages/helm-org-rifle-20180923.2209.el +++ b/packages/helm-org-rifle-20190809.1831.el @@ -2,8 +2,8 @@ ;; Author: Adam Porter ;; Url: http://github.com/alphapapa/helm-org-rifle -;; Package-Version: 20180923.2209 -;; Version: 1.7.0-pre +;; Package-Version: 20190809.1831 +;; Version: 1.7.0 ;; Package-Requires: ((emacs "24.4") (dash "2.12") (f "0.18.1") (helm "1.9.4") (s "1.10.0")) ;; Keywords: hypermedia, outlines @@ -952,6 +952,7 @@ because it uses variables in its outer scope." ;; FIXME: Partial excludes seem to put the partially ;; negated entry at the end of results. Not sure why. ;; Could it actually be a good feature, though? + ;; TODO: Collect outline paths recursively in stages to avoid calling `org-get-outline-path' on every node. (or (cl-loop for elem in (when (or helm-org-rifle-test-against-path helm-org-rifle-always-test-excludes-against-path) (setq path (org-get-outline-path))) @@ -1464,7 +1465,6 @@ NODES is a list of plists as returned by `helm-org-rifle-transform-candidates-to (defun helm-org-rifle--listify (item) "If ITEM is an atom, return (list ITEM). If ITEM is a list, return ITEM." - ;; TODO: This could simply be e.g. (defun listify (&rest args) args) (cl-typecase item (list item) (atom (list item)) diff --git a/packages/helm-pass-20180607.2348.el b/packages/helm-pass-20180607.2348.el deleted file mode 100644 index b678cef..0000000 --- a/packages/helm-pass-20180607.2348.el +++ /dev/null @@ -1,86 +0,0 @@ -;;; helm-pass.el --- helm interface of pass, the standard Unix password manager -*- lexical-binding: t; -*- - -;; Copyright (C) 2016--2018 J. Alexander Branham - -;; Author: J. Alexander Branham -;; Maintainer: J. Alexander Branham -;; URL: https://github.com/jabranham/helm-pass -;; Package-Version: 20180607.2348 -;; Version: 0.2 -;; Package-Requires: ((emacs "25") (helm "0") (password-store "0") (auth-source-pass "4.0.0")) - -;; This file is not part of GNU Emacs. - -;;; License: -;; -;; 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 -;; - -;;; Commentary: - -;; Emacs helm interface for pass, the standard Unix password manager - -;; Users of helm-pass may also be interested in functionality provided by other Emacs packages dealing with pass: -;; password-store.el (which helm-pass relies on): https://git.zx2c4.com/password-store/tree/contrib/emacs/password-store.el -;; pass.el (a major mode for pass): https://github.com/NicolasPetton/pass -;; auth-source-pass.el (integration of Emacs' auth-source with pass, included in Emacs 26+): https://github.com/DamienCassou/auth-password-store - -;; Usage: - -;; (require 'helm-pass) -;; - -;;; Code: - -(require 'helm) -(require 'password-store) -(require 'auth-source-pass) - -(defgroup helm-pass nil - "Emacs helm interface for helm-pass" - :group 'helm) - -(defun helm-pass-get-username (entry) - "Get username for ENTRY. - -Does not clear it from clipboard." - (let ((username (auth-source-pass-get "user" entry))) - (if username - (progn (password-store-clear) - (kill-new username)) - (message "Username not found!")))) - -(defcustom helm-pass-actions - '(("Copy password to clipboard" . password-store-copy) - ("Copy username to clipboard" . helm-pass-get-username) - ("Edit entry" . password-store-edit) - ("Browse url of entry" . password-store-url)) - "List of actions for `helm-pass'." - :group 'helm-pass - :type '(alist :key-type string :value-type function)) - -(defvar helm-pass-source-pass - (helm-build-sync-source "Password File" - :candidates #'password-store-list - :action helm-pass-actions)) - -;;;###autoload -(defun helm-pass () - "Helm interface for pass." - (interactive) - (helm :sources 'helm-pass-source-pass - :buffer "*helm-pass*")) - -(provide 'helm-pass) -;;; helm-pass.el ends here diff --git a/packages/helm-pass-20190315.1335.el b/packages/helm-pass-20190315.1335.el new file mode 100644 index 0000000..c50cebc --- /dev/null +++ b/packages/helm-pass-20190315.1335.el @@ -0,0 +1,152 @@ +;;; helm-pass.el --- helm interface of pass, the standard Unix password manager -*- lexical-binding: t; -*- + +;; Copyright (C) 2016--2018 J. Alexander Branham +;; Copyright (C) 2019 Pierre Neidhardt + +;; Author: J. Alexander Branham +;; Maintainer: Pierre Neidhardt +;; URL: https://github.com/emacs-helm/helm-pass +;; Package-Version: 20190315.1335 +;; Version: 0.3 +;; Package-Requires: ((emacs "25") (helm "0") (password-store "0") (auth-source-pass "4.0.0")) + +;; This file is not part of GNU Emacs. + +;;; License: +;; +;; 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 +;; + +;;; Commentary: +;; +;; Emacs Helm interface for pass, the standard Unix password manager +;; +;; Users of helm-pass may also be interested in functionality provided by other +;; Emacs packages dealing with pass: +;; +;; - password-store.el (which helm-pass relies on): +;; https://git.zx2c4.com/password-store/tree/contrib/emacs/password-store.el +;; +;; - pass.el (a major mode for pass): https://github.com/NicolasPetton/pass +;; +;; - auth-source-pass.el (integration of Emacs' auth-source with pass, included +;; in Emacs 26+): https://github.com/DamienCassou/auth-password-store + +;; Usage: +;; +;; (require 'helm-pass) +;; M-x helm-pass + +;;; Code: + +(require 'helm) +(require 'password-store) +(require 'auth-source-pass) +(require 'thingatpt) +(require 'seq) + +(defvar exwm-title) +(declare-function eww-current-url "eww") + +(defgroup helm-pass nil + "Emacs helm interface for helm-pass" + :group 'helm) + +(defun helm-pass-get-username (entry) + "Get username for ENTRY. + +Does not clear it from clipboard." + (let ((username (auth-source-pass-get "user" entry))) + (if username + (progn (password-store-clear) + (kill-new username)) + (message "Username not found!")))) + +(defcustom helm-pass-actions + '(("Copy password to clipboard" . password-store-copy) + ("Copy username to clipboard" . helm-pass-get-username) + ("Edit entry" . password-store-edit) + ("Browse url of entry" . password-store-url)) + "List of actions for `helm-pass'." + :group 'helm-pass + :type '(alist :key-type string :value-type function)) + +(defvar helm-pass-source-pass + (helm-build-sync-source "Password File" + :candidates #'password-store-list + :action helm-pass-actions)) + +(defun helm-pass-find-url-in-string (string) + "Return URL from STRING." + (with-temp-buffer + (insert string) + (goto-char (point-min)) + (while (and (not (eobp)) + (not (thing-at-point-url-at-point))) + (forward-word)) + (thing-at-point-url-at-point))) + +(defvar helm-pass-domain-regexp + (rx "//" + (group + (* (not (any "/"))) + "." + (* (not (any "." "/")))) + "/")) + +(defun helm-pass-get-domain (url) + "Return the various domain elements or URL as a list of strings." + (when url + (string-match helm-pass-domain-regexp url) + (split-string (match-string 1 url) "\\."))) + +(defun helm-pass-get-subdomain (domain &optional count) + "Return the last COUNT elements of DOMAIN as a dot-separated string. +COUNT defaults to 2. +For instance, (\"foo\" \"example\" \"org\") results in \"example.org\". +If domain does not have enough elements, return nil." + (setq count (or count 2)) + (when (>= (length domain) count) + (mapconcat #'identity (seq-drop domain (- (length domain) count)) "."))) + +(defun helm-pass-get-input-from-eww () + "Get default prompt from EWW." + (let* ((domain (helm-pass-get-domain (eww-current-url)))) + (helm-pass-get-subdomain domain))) + +(defun helm-pass-get-input-from-exwm () + "Get default prompt from the current EXWM window." + (when exwm-title + (let* ((url (helm-pass-find-url-in-string exwm-title)) + (domain (helm-pass-get-domain url))) + (helm-pass-get-subdomain domain)))) + +(defun helm-pass-get-input () + "Get default prompt from the current mode." + (cond + ((derived-mode-p 'eww-mode) + (helm-pass-get-input-from-eww)) + ((derived-mode-p 'exwm-mode) + (helm-pass-get-input-from-exwm)))) + +;;;###autoload +(defun helm-pass () + "Helm interface for pass." + (interactive) + (helm :sources 'helm-pass-source-pass + :input (helm-pass-get-input) + :buffer "*helm-pass*")) + +(provide 'helm-pass) +;;; helm-pass.el ends here diff --git a/packages/helm-projectile-20180815.1514.el b/packages/helm-projectile-20190731.1538.el similarity index 99% rename from packages/helm-projectile-20180815.1514.el rename to packages/helm-projectile-20190731.1538.el index 723d0a7..c97c363 100644 --- a/packages/helm-projectile-20180815.1514.el +++ b/packages/helm-projectile-20190731.1538.el @@ -4,7 +4,7 @@ ;; Author: Bozhidar Batsov ;; URL: https://github.com/bbatsov/helm-projectile -;; Package-Version: 20180815.1514 +;; Package-Version: 20190731.1538 ;; Created: 2011-31-07 ;; Keywords: project, convenience ;; Version: 0.14.0 @@ -792,7 +792,6 @@ Other file extensions can be customized with the variable `projectile-other-file (interactive "P") (let* ((project-root (projectile-project-root)) (other-files (projectile-get-other-files (buffer-file-name) - (projectile-current-project-files) flex-matching))) (if other-files (if (= (length other-files) 1) @@ -964,8 +963,10 @@ DIR is the project root, if not set then current directory is used" (declare-function helm-rg "helm-rg") (defun helm-projectile-rg--region-selection () - (when (use-region-p) - (buffer-substring-no-properties (region-beginning) (region-end)))) + (when helm-projectile-set-input-automatically + (if (region-active-p) + (buffer-substring-no-properties (region-beginning) (region-end)) + (helm-rg--get-thing-at-pt)))) ;;;###autoload (defun helm-projectile-rg () @@ -975,7 +976,9 @@ DIR is the project root, if not set then current directory is used" (if (projectile-project-p) (let ((helm-rg-prepend-file-name-line-at-top-of-matches nil) (helm-rg-include-file-on-every-match-line t)) - (helm-rg (or (helm-projectile-rg--region-selection) "") nil (list (projectile-project-root)))) + (helm-rg (helm-projectile-rg--region-selection) + nil + (list (projectile-project-root)))) (error "You're not in a project")) (when (yes-or-no-p "`helm-rg' is not installed. Install? ") (condition-case nil diff --git a/packages/helm-pydoc-20160918.542.tar b/packages/helm-pydoc-20160918.542.tar index 9760b6d..9ed7632 100644 Binary files a/packages/helm-pydoc-20160918.542.tar and b/packages/helm-pydoc-20160918.542.tar differ diff --git a/packages/helm-spotify-plus-20180107.1138.el b/packages/helm-spotify-plus-20190807.2115.el similarity index 57% rename from packages/helm-spotify-plus-20180107.1138.el rename to packages/helm-spotify-plus-20190807.2115.el index 46ff6ca..f31570a 100644 --- a/packages/helm-spotify-plus-20180107.1138.el +++ b/packages/helm-spotify-plus-20190807.2115.el @@ -2,9 +2,10 @@ ;; Copyright (C) ;; Author: Wanderson Ferreira and Luis Moneda +;; Homepage: https://github.com/wandersoncferreira/helm-spotify-plus ;; Package: helm-spotify-plus ;; Package-Requires: ((emacs "24.4") (helm "2.0.0") (multi "2.0.1")) -;; Package-Version: 20180107.1138 +;; Package-Version: 20190807.2115 ;; Version: 0.1 ;; This file is not part of GNU Emacs. @@ -44,14 +45,16 @@ :type 'string :group 'helm-spotify-plus) (defcustom helm-spotify-plus-market-region "US" - "Variable to define what is the default market region. Nil values to disable this filter." + "Variable to define what is the default market region. +Nil values to disable this filter." :type 'string :group 'helm-spotify-plus) (defcustom helm-spotify-plus-page-number 5 - "Variable to control the number of pages of the requests. 5 pages with 50 candidates each, therefore there will be 250 candidates in your buffer." + "Variable to control the number of pages of the requests. +5 pages with 50 candidates each, results in 250 candidates in your buffer." :type 'integer :group 'helm-spotify-plus) - + (defun helm-spotify-plus-alist-get (symbols alist) "Look up the value for the chain of SYMBOLS in ALIST." (if symbols @@ -88,7 +91,21 @@ ;; Spotify controllers ;; ;;;;;;;;;;;;;;;;;;;;;;;;; -(defun helm-spotify-plus-action (action) +(defvar helm-spotify-plus-action-hashtable #s(hash-table + size 20 + test equal + data ( + "play-unix" "Play" + "play-darwin" "play" + "next-unix" "Next" + "next-darwin" "next track" + "pause-unix" "Pause" + "pause-darwin" "pause" + "previous-unix" "Previous" + "previous-darwin" "previous track" + "playpause-unix" "PlayPause" + "playpause-darwin" "playpause"))) +(defun helm-spotify-plus-action-unix (action) "Send a given ACTION to dbus." (if helm-spotify-plus-dbus-prefer-local (call-process "/bin/bash" nil nil nil "-c" (format (concat helm-spotify-plus-dbus-call "org.mpris.MediaPlayer2.Player.%s") action)) @@ -96,80 +113,123 @@ (format (concat helm-spotify-plus-dbus-call "org.mpris.MediaPlayer2.Player.%s") action)))) (defun helm-spotify-plus-action-darwin (action) - "Send a given ACTION to osascript such as PLAY, PAUSE, NEXT" + "Send a given ACTION to osascript such as PLAY, PAUSE, NEXT." (let ((action-string (format "osascript -e 'tell application \"Spotify\" to %s'" action))) (shell-command action-string))) -(defun helm-spotify-plus-next () - "Play the next song." +(defun helm-spotify-plus-action (action) + "Execute the proper ACTION in the correct environment." (interactive) (cond ((eq system-type 'gnu/linux) - (helm-spotify-plus-action "Next")) + (helm-spotify-plus-action-unix + (gethash (format "%s-unix" action) helm-spotify-plus-action-hashtable))) ((eq system-type 'darwin) - (helm-spotify-plus-action-darwin "next track")) - ((eq system-type 'windows-nt) - (message "Sorry, there is no support for Windows yet")) + (helm-spotify-plus-action-darwin + (gethash (format "%s-darwin" action) helm-spotify-plus-action-hashtable))) (t (message "Sorry, there is no support for your OS yet.")))) +(defun helm-spotify-plus-next () + "Play the next song." + (interactive) + (if (>= (length helm-spotify-plus-queue) 2) + (helm-spotify-plus-queue-track-finished) + (helm-spotify-plus-action "next"))) + (defun helm-spotify-plus-pause () "Pause the current song." (interactive) - (cond - ((eq system-type 'gnu/linux) - (helm-spotify-plus-action "Pause")) - ((eq system-type 'darwin) - (helm-spotify-plus-action-darwin "pause")) - ((eq system-type 'windows-nt) - (message "Sorry, there is no support for Windows yet")) - (t - (message "Sorry, there is no support for your OS yet.")))) + (helm-spotify-plus-queue-stop) + (helm-spotify-plus-action "pause")) (defun helm-spotify-plus-play () "Play a song." (interactive) - (cond - ((eq system-type 'gnu/linux) - (helm-spotify-plus-action "Play")) - ((eq system-type 'darwin) - (helm-spotify-plus-action-darwin "play track")) - ((eq system-type 'windows-nt) - (message "Sorry, there is no support for Windows yet")) - (t - (message "Sorry, there is no support for your OS yet.")))) + (helm-spotify-plus-queue-stop) + (helm-spotify-plus-action "play")) (defun helm-spotify-plus-previous () "Plays previous song." (interactive) - (cond - ((eq system-type 'gnu/linux) - (helm-spotify-plus-action "Previous")) - ((eq system-type 'darwin) - (helm-spotify-plus-action-darwin "previous track")) - ((eq system-type 'windows-nt) - (message "Sorry, there is no support for Windows yet")) - (t - (message "Sorry, there is no support for your OS yet.")))) - + (helm-spotify-plus-queue-stop) + (helm-spotify-plus-action "previous")) (defun helm-spotify-plus-toggle-play-pause () "Toggle between play and pause song." (interactive) - (cond - ((eq system-type 'gnu/linux) - (helm-spotify-plus-action "PlayPause")) - ((eq system-type 'darwin) - (helm-spotify-plus-action-darwin "playpause")) - ((eq system-type 'windows-nt) - (message "Sorry, there is no support for Windows yet")) - (t - (message "Sorry, there is no support for your OS yet.")))) + (helm-spotify-plus-action "playpause")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; End of spotify controllers definition. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;; +;; Queue functionality ;; +;;;;;;;;;;;;;;;;;;;;;;;;; + +(defcustom helm-spotify-queue-song-end-soft-limit 300 + "Time in milliseconds for preemptive skip to next queued track. +This is so spotify doesn't start a new song due to mismatch in time." + :type 'integer :group 'helm-spotify-plus) + +(defvar helm-spotify-plus-queue nil) +(defvar helm-spotify-plus-queue-timer nil) + +(defun helm-spotify-plus-queue-track-finished () + "Called when track finished according to queue timer. +Can be called to skip to next song in queue." + (setq helm-spotify-plus-queue (cdr helm-spotify-plus-queue)) + (helm-spotify-plus-queue-play-queue)) + +(defun helm-spotify-plus-queue-play-queue () + "Play next TRACK in the queue." + (when helm-spotify-plus-queue-timer + (cancel-timer helm-spotify-plus-queue-timer) + (setq helm-spotify-plus-queue-timer nil)) + + (when helm-spotify-plus-queue + (let ((current-track (car helm-spotify-plus-queue))) + (helm-spotify-plus-play-track current-track) + (setq helm-spotify-plus-queue-timer (run-at-time + (format "%d millisec" (- (alist-get 'duration_ms current-track) helm-spotify-queue-song-end-soft-limit)) + nil + 'helm-spotify-plus-queue-track-finished))))) + +(defun helm-spotify-plus-queue-stop () + "Stops the `helm-spotify-plus-queue-timer' and empties the `helm-spotify-plus-queue'" + (when helm-spotify-plus-queue-timer + (cancel-timer helm-spotify-plus-queue-timer) + (setq helm-spotify-plus-queue-timer nil)) + (setq helm-spotify-plus-queue nil)) + +(defun helm-spotify-plus-queue-add-track (track) + "Add the TRACK to the queue." + (if helm-spotify-plus-queue + (add-to-list 'helm-spotify-plus-queue track t) + (progn + (setq helm-spotify-plus-queue (list track)) + (helm-spotify-plus-queue-play-queue)))) + +(defun helm-spotify-plus-queue-play-track-wrapper (track) + "Wrapper for `helm-spotify-plus-play-track' to correctly go ahead of the queue and play the TRACK." + (if helm-spotify-plus-queue + (progn + (setq helm-spotify-plus-queue (cdr helm-spotify-plus-queue)) ; remove the interrupted track from the queue + (add-to-list 'helm-spotify-plus-queue track)) ; add the "play now" track to the front of the queue + (setq helm-spotify-plus-queue (list track))) + + (helm-spotify-plus-queue-play-queue)) + +(defun helm-spotify-plus-queue-play-album-wrapper (track) + "Wrapper for `helm-spotify-plus-play-album' to stop queue-playing and play a TRACK." + (helm-spotify-plus-queue-stop) + (helm-spotify-plus-play-album track)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; End of queue functionality. ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (defvar helm-spotify-plus-spotify-api-authentication-url "https://accounts.spotify.com/api/token") (defvar helm-spotify-plus-client-key "515f0ff545a349bcadf98efab945972f") (defvar helm-spotify-plus-client-secret "7618bf445df14b568782b13e37cf63e6") @@ -177,17 +237,17 @@ (defun helm-spotify-plus-get-token () "Get the token for the `helm-spotify-plus' Web App." (let ((url-request-method "POST") - (url-request-data "&grant_type=client_credentials") - (url-request-extra-headers - `(("Content-Type" . "application/x-www-form-urlencoded") - ("Authorization" . ,(concat "Basic " (base64-encode-string (concat helm-spotify-plus-client-key ":" helm-spotify-plus-client-secret) t)))))) + (url-request-data "&grant_type=client_credentials") + (url-request-extra-headers + `(("Content-Type" . "application/x-www-form-urlencoded") + ("Authorization" . ,(concat "Basic " (base64-encode-string (concat helm-spotify-plus-client-key ":" helm-spotify-plus-client-secret) t)))))) (with-current-buffer - (url-retrieve-synchronously helm-spotify-plus-spotify-api-authentication-url) + (url-retrieve-synchronously helm-spotify-plus-spotify-api-authentication-url) (goto-char url-http-end-of-headers) (let* ((response (json-read)) - (token-type (alist-get 'token_type response)) - (token (alist-get 'access_token response))) - (cons token-type token))))) + (token-type (alist-get 'token_type response)) + (token (alist-get 'access_token response))) + (cons token-type token))))) (defmulti-method helm-spotify-plus-play-href 'windows-nt (href) @@ -222,8 +282,8 @@ (defun helm-spotify-plus-search-formatted-helper (search-term counter) "Helper function to format the output due to SEARCH-TERM and COUNTER." (mapcar (lambda (track) - (cons (helm-spotify-plus-format-track track) track)) - (helm-spotify-plus-alist-get '(tracks items) (helm-spotify-plus-artist-track-search search-term counter)))) + (cons (helm-spotify-plus-format-track track) track)) + (helm-spotify-plus-alist-get '(tracks items) (helm-spotify-plus-artist-track-search search-term counter)))) (defun helm-spotify-plus-insert-market-region-url (new-url market-region) "Function to insert in the NEW-URL a value passed as MARKET-REGION." @@ -236,64 +296,64 @@ (defun helm-spotify-plus-artist-track-search (search-term counter) "Function to get the current match between the SEARCH-TERM and amount of requests defined by COUNTER." (let ((offset (* helm-spotify-plus-limit counter)) - (market-region (helm-spotify-plus-split-string "m" search-term)) - (url-default "https://api.spotify.com/v1/search?q=%s&type=track&limit=%s&offset=%d")) + (market-region (helm-spotify-plus-split-string "m" search-term)) + (url-default "https://api.spotify.com/v1/search?q=%s&type=track&limit=%s&offset=%d")) (cond - + ((and (string-match "a:" search-term) (string-match "t:" search-term)) ;both the artist and track name are available (let* ((artist-name (helm-spotify-plus-split-string "a" search-term)) - (track-name (helm-spotify-plus-split-string "t" search-term)) - (new-url (format "https://api.spotify.com/v1/search?q=%s artist:%s&type=track&limit=%s&offset=%d" - track-name artist-name helm-spotify-plus-limit offset))) - (if helm-spotify-plus-market-region - (helm-spotify-plus-request (helm-spotify-plus-insert-market-region-url new-url market-region)) - (helm-spotify-plus-request new-url)))) - + (track-name (helm-spotify-plus-split-string "t" search-term)) + (new-url (format "https://api.spotify.com/v1/search?q=%s artist:%s&type=track&limit=%s&offset=%d" + track-name artist-name helm-spotify-plus-limit offset))) + (if helm-spotify-plus-market-region + (helm-spotify-plus-request (helm-spotify-plus-insert-market-region-url new-url market-region)) + (helm-spotify-plus-request new-url)))) + ((string-match "a:" search-term) ;only the artist name was given (let* ((artist-name (helm-spotify-plus-split-string "a" search-term)) - (new-url (format "https://api.spotify.com/v1/search?q=artist:%s&type=track&limit=%s&offset=%d" artist-name - helm-spotify-plus-limit offset))) - (if helm-spotify-plus-market-region - (helm-spotify-plus-request (helm-spotify-plus-insert-market-region-url new-url market-region)) - (helm-spotify-plus-request new-url)))) - + (new-url (format "https://api.spotify.com/v1/search?q=artist:%s&type=track&limit=%s&offset=%d" artist-name + helm-spotify-plus-limit offset))) + (if helm-spotify-plus-market-region + (helm-spotify-plus-request (helm-spotify-plus-insert-market-region-url new-url market-region)) + (helm-spotify-plus-request new-url)))) + ((string-match "t:" search-term) ; only the track name was given (let* ((track-name (helm-spotify-plus-split-string "t" search-term)) - (new-url (format "https://api.spotify.com/v1/search?q=%s&type=track&limit=%s&offset=%d" track-name - helm-spotify-plus-limit offset))) - (if helm-spotify-plus-market-region - (helm-spotify-plus-request (helm-spotify-plus-insert-market-region-url new-url market-region)) - (helm-spotify-plus-request new-url)))) - + (new-url (format "https://api.spotify.com/v1/search?q=%s&type=track&limit=%s&offset=%d" track-name + helm-spotify-plus-limit offset))) + (if helm-spotify-plus-market-region + (helm-spotify-plus-request (helm-spotify-plus-insert-market-region-url new-url market-region)) + (helm-spotify-plus-request new-url)))) + (t ;Else case... do a regular search for the track name (if helm-spotify-plus-market-region - (if (string-match "m:" search-term) - (let* ((search-term-filtered (string-trim (car (split-string search-term "m:")))) - (new-url (format url-default search-term-filtered helm-spotify-plus-limit offset)) - (new-url-market (helm-spotify-plus-insert-market-region-url new-url market-region))) - (helm-spotify-plus-request new-url-market)) - (helm-spotify-plus-request (helm-spotify-plus-insert-market-region-url (format url-default search-term - helm-spotify-plus-limit offset) market-region))) - (helm-spotify-plus-request (format url-default search-term helm-spotify-plus-limit offset))))))) - + (if (string-match "m:" search-term) + (let* ((search-term-filtered (string-trim (car (split-string search-term "m:")))) + (new-url (format url-default search-term-filtered helm-spotify-plus-limit offset)) + (new-url-market (helm-spotify-plus-insert-market-region-url new-url market-region))) + (helm-spotify-plus-request new-url-market)) + (helm-spotify-plus-request (helm-spotify-plus-insert-market-region-url (format url-default search-term + helm-spotify-plus-limit offset) market-region))) + (helm-spotify-plus-request (format url-default search-term helm-spotify-plus-limit offset))))))) + (defun helm-spotify-plus-split-string (letter search-term) "Function to split based in the LETTER using the SEARCH-TERM." (if (string-match (format "%s:" letter) search-term) (let* ((delimiter (format ".*%s:" letter)) - (name-tmp (car (cdr (split-string search-term delimiter)))) - (name (car (split-string name-tmp " [a-z]:")))) - (string-trim name)) + (name-tmp (car (cdr (split-string search-term delimiter)))) + (name (car (split-string name-tmp " [a-z]:")))) + (string-trim name)) nil)) (defun helm-spotify-plus-request (a-url) "Function to request an json given a correct A-URL." (let* ((token (helm-spotify-plus-get-token)) - (access-token (cdr token)) - (url-request-extra-headers - `(("Authorization" . ,(concat "Bearer " access-token))))) + (access-token (cdr token)) + (url-request-extra-headers + `(("Authorization" . ,(concat "Bearer " access-token))))) (with-current-buffer - (url-retrieve-synchronously a-url) + (url-retrieve-synchronously a-url) (goto-char url-http-end-of-headers) (json-read)))) @@ -324,14 +384,15 @@ (defun helm-spotify-plus-actions-for-track (actions track) "Return a list of helm ACTIONS available for this TRACK." - `((,(format "Play Track - %s" (helm-spotify-plus-decode-utf8 (helm-spotify-plus-alist-get '(name) track))) . helm-spotify-plus-play-track) - (,(format "Play Album - %s" (helm-spotify-plus-decode-utf8 (helm-spotify-plus-alist-get '(album name) track))) . helm-spotify-plus-play-album) + `((,(format "Play Track - %s" (helm-spotify-plus-decode-utf8 (helm-spotify-plus-alist-get '(name) track))) . helm-spotify-plus-queue-play-track-wrapper) + (,(format "Play Album - %s" (helm-spotify-plus-decode-utf8 (helm-spotify-plus-alist-get '(album name) track))) . helm-spotify-plus-queue-play-album-wrapper) + (,(format (if helm-spotify-plus-queue "Queue Track - %s" "Start Queue Playing - %s") (helm-spotify-plus-decode-utf8 (helm-spotify-plus-alist-get '(name) track))) . helm-spotify-plus-queue-add-track) ("Show Track Metadata" . pp))) (defun helm-spotify-plus-get-search-string () "Function to require an input string for the user." - (read-string "Enter the (partial/full) name of an Track: ")) + (read-string "Enter the (partial/full) name of a track: ")) ;;;###autoload (defun helm-spotify-plus () @@ -344,7 +405,7 @@ :action-transformer (lambda (actions track) (helm-spotify-plus-actions-for-track actions track))) - :buffer "*helm-spotify*")) + :buffer "*helm-spotify*")) (provide 'helm-spotify-plus) diff --git a/packages/helm-swoop-20180215.1154.el b/packages/helm-swoop-20190814.1234.el similarity index 87% rename from packages/helm-swoop-20180215.1154.el rename to packages/helm-swoop-20190814.1234.el index d0ce214..ad9a78d 100644 --- a/packages/helm-swoop-20180215.1154.el +++ b/packages/helm-swoop-20190814.1234.el @@ -1,24 +1,27 @@ -;;; helm-swoop.el --- Efficiently hopping squeezed lines powered by helm interface -*- coding: utf-8; lexical-binding: t -*- +;;; helm-swoop.el --- Efficiently hopping squeezed lines powered by helm interface -*- lexical-binding: t -*- ;; Copyright (C) 2013 - 2018 by Shingo Fukuyama -;; Version: 1.7.4 -;; Package-Version: 20180215.1154 +;; Version: 2.0.0 +;; Package-Version: 20190814.1234 ;; Author: Shingo Fukuyama - http://fukuyama.co ;; URL: https://github.com/ShingoFukuyama/helm-swoop ;; Created: Oct 24 2013 ;; Keywords: helm swoop inner buffer search -;; Package-Requires: ((helm "1.0") (emacs "24.3")) +;; Package-Requires: ((helm "3.2") (emacs "24.4")) -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2 of -;; the License, or (at your option) any later version. +;; This program is 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. +;; 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 . ;;; Commentary: @@ -93,6 +96,7 @@ (require 'helm-grep) (declare-function migemo-search-pattern-get "migemo") +(declare-function migemo-forward "migemo") (declare-function projectile-buffers-with-file-or-process "projectile") (declare-function projectile-project-buffers "projectile") (defvar projectile-buffers-filter-function) @@ -121,31 +125,34 @@ :group 'helm-swoop) (defcustom helm-swoop-speed-or-color nil - "If nil, you can slightly boost invoke speed in exchange for text color" - :group 'helm-swoop :type 'boolean) + "If nil, you can slightly boost invoke speed in exchange for text color" + :group 'helm-swoop :type 'boolean) (defcustom helm-swoop-use-line-number-face nil "Use face to line numbers on helm-swoop buffer" :group 'helm-swoop :type 'boolean) (defcustom helm-swoop-split-with-multiple-windows nil - "Split window when having multiple windows open" - :group 'helm-swoop :type 'boolean) + "Split window when having multiple windows open" + :group 'helm-swoop :type 'boolean) (defcustom helm-swoop-move-to-line-cycle t - "Return to the opposite side of line" - :group 'helm-swoop :type 'boolean) + "Return to the opposite side of line" + :group 'helm-swoop :type 'boolean) (defcustom helm-swoop-split-direction 'split-window-vertically - "Split direction" - :type '(choice (const :tag "vertically" split-window-vertically) - (const :tag "horizontally" split-window-horizontally)) - :group 'helm-swoop) + "Split direction" + :type '(choice (const :tag "vertically" split-window-vertically) + (const :tag "horizontally" split-window-horizontally)) + :group 'helm-swoop) (defcustom helm-swoop-use-fuzzy-match nil "If t, use fuzzy matching functions as well as exact matches." :group 'helm-swoop :type 'boolean) +(defcustom helm-swoop-min-overlay-length 2 + "Minimum pattern length before applying the overlay on the matched word." + :group 'helm-swoop :type 'integer) (defvar helm-swoop-split-window-function (lambda ($buf &rest _$args) - (if helm-swoop-split-with-multiple-windows - (funcall helm-swoop-split-direction) - (when (one-window-p) + (if helm-swoop-split-with-multiple-windows + (funcall helm-swoop-split-direction) + (when (one-window-p) (funcall helm-swoop-split-direction))) (other-window 1) (switch-to-buffer $buf)) @@ -160,6 +167,14 @@ :group 'helm-swoop :type 'hook) +(defcustom helm-swoop-flash-region-function 'helm-swoop-flash-word + "The function used to flash the result when a search done." + :group 'helm-swoop + :type '(choice + (const :tag "Default highlight function" helm-swoop-flash-word) + (const :tag "Pulse highlight function" pulse-momentary-highlight-region) + function)) + (defvar helm-swoop-candidate-number-limit 19999) (defvar helm-swoop-buffer "*Helm Swoop*") (defvar helm-swoop-prompt "Swoop: ") @@ -169,8 +184,8 @@ ;; Buffer local variables (defvar helm-swoop-list-cache) -(defvar helm-swoop-pattern) ; Keep helm-pattern value -(defvar helm-swoop-last-query) ; Last search query for resume +(defvar helm-swoop-pattern nil) ; Keep helm-pattern value +(defvar helm-swoop-last-query nil) ; Last search query for resume (defvar-local helm-swoop-last-prefix-number 1) ; For multiline highlight ;; Global variables @@ -181,21 +196,55 @@ (defvar helm-swoop-line-overlay nil "Overlay object to indicate other window's line") +(defvar helm-swoop--basic-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (dolist (action '(next-line previous-line next-page previous-page + beginning-of-buffer end-of-buffer toggle-visible-mark)) + (let ((orig-fn (intern (format "helm-%s" action))) + (new-fn (intern (format "helm-swoop-%s" action)))) + (defalias new-fn `(lambda (&optional arg) + (interactive "p") + (call-interactively ',orig-fn) + (helm-swoop--move-line-action)) + (format "Replacement of `%s' action for `helm-swoop'. + +\(fn ARG)" orig-fn)) + (define-key map `[remap ,orig-fn] new-fn))) + map)) + (defvar helm-swoop-map (let (($map (make-sparse-keymap))) - (set-keymap-parent $map helm-map) + (set-keymap-parent $map helm-swoop--basic-map) (define-key $map (kbd "C-c C-e") 'helm-swoop-edit) (define-key $map (kbd "M-i") 'helm-multi-swoop-all-from-helm-swoop) (define-key $map (kbd "C-w") 'helm-swoop-yank-thing-at-point) (define-key $map (kbd "^") 'helm-swoop-caret-match) - (delq nil $map)) + $map) "Keymap for helm-swoop") +(defvar helm-multi-swoop--basic-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (dolist (action '(next-line previous-line next-page previous-page + beginning-of-buffer end-of-buffer toggle-visible-mark)) + (let ((orig-fn (intern (format "helm-%s" action))) + (new-fn (intern (format "helm-multi-swoop-%s" action)))) + (defalias new-fn `(lambda (&optional arg) + (interactive "p") + (call-interactively ',orig-fn) + (helm-multi-swoop--move-line-action)) + (format "Replacement of `%s' action for `helm-multi-swoop'. + +\(fn ARG)" orig-fn)) + (define-key map `[remap ,orig-fn] new-fn))) + map)) + (defvar helm-multi-swoop-map (let (($map (make-sparse-keymap))) - (set-keymap-parent $map helm-map) + (set-keymap-parent $map helm-multi-swoop--basic-map) (define-key $map (kbd "C-c C-e") 'helm-multi-swoop-edit) - (delq nil $map))) + $map)) (defvar helm-c-source-swoop-match-functions '(helm-mm-exact-match @@ -203,10 +252,10 @@ helm-mm-3-migemo-match)) (defvar helm-c-source-swoop-search-functions - '(helm-mm-exact-search - helm-mm-search - helm-candidates-in-buffer-search-default-fn - helm-mm-3-migemo-search)) + '(helm-mm-exact-search + helm-mm-search + helm-candidates-in-buffer-search-default-fn + helm-mm-3-migemo-search)) (defun helm-swoop-match-functions () (if helm-swoop-use-fuzzy-match @@ -224,14 +273,7 @@ :group 'helm-swoop :type 'function) (defun helm-swoop-pre-input-optimize ($query) - (when $query - (let (($regexp (list '("\+" . "\\\\+") - '("\*" . "\\\\*") - '("\#" . "\\\\#")))) - (mapc (lambda ($r) - (setq $query (replace-regexp-in-string (car $r) (cdr $r) $query))) - $regexp) - $query))) + (when $query (regexp-quote $query))) (defsubst helm-swoop--goto-line ($line) (goto-char (point-min)) @@ -241,13 +283,11 @@ (recenter (/ (window-height) 2))) (defsubst helm-swoop--delete-overlay ($identity &optional $beg $end) - (or $beg (setq $beg (point-min))) - (or $end (setq $end (point-max))) - (overlay-recenter $end) + (overlay-recenter (or $end (point-max))) (mapc (lambda ($o) (if (overlay-get $o $identity) (delete-overlay $o))) - (overlays-in $beg $end))) + (overlays-in (or $beg (point-min)) (or $end (point-max))))) (defsubst helm-swoop--get-string-at-line () (buffer-substring-no-properties (point-at-bol) (point-at-eol))) @@ -312,7 +352,7 @@ (helm-swoop--unveil-invisible-overlay)) (defun helm-swoop--validate-regexp (regexp) - (condition-case nil + (condition-case _err (progn (string-match-p regexp "") t) @@ -320,9 +360,9 @@ (defun helm-swoop--target-word-overlay ($identity &optional $threshold) (interactive) - (or $threshold (setq $threshold 2)) (save-excursion (let (($pat (split-string helm-pattern " ")) + ($threshold (or $threshold 2)) $o) (mapc (lambda ($wd) (when (and (helm-swoop--validate-regexp $wd) (< $threshold (length $wd))) @@ -334,15 +374,12 @@ (if (string-match "^\\^\\[0\\-9\\]\\+\\.\\(.+\\)" $wd) (setq $wd (concat "^" (match-string 1 $wd)))) (overlay-recenter (point-max)) - (let (finish) - (while (and (not finish) (re-search-forward $wd nil t)) - (if (= (match-beginning 0) (match-end 0)) - (forward-char 1) - (setq $o (make-overlay (match-beginning 0) (match-end 0))) - (overlay-put $o 'face 'helm-swoop-target-word-face) - (overlay-put $o $identity t)) - (when (eobp) - (setq finish t)))))) + (while (and (not (eobp)) (re-search-forward $wd nil t)) + (if (= (match-beginning 0) (match-end 0)) + (forward-char 1) + (setq $o (make-overlay (match-beginning 0) (match-end 0))) + (overlay-put $o 'face 'helm-swoop-target-word-face) + (overlay-put $o $identity t))))) $pat)))) (defun helm-swoop--restore-unveiled-overlay () @@ -366,24 +403,6 @@ This function needs to call after latest helm-swoop-line-overlay set." ;; helm action ------------------------------------------------ -(defadvice helm-next-line (around helm-swoop-next-line disable) - (let ((helm-move-to-line-cycle-in-source t)) - ad-do-it - (when (called-interactively-p 'any) - (helm-swoop--move-line-action)))) - -(defadvice helm-previous-line (around helm-swoop-previous-line disable) - (let ((helm-move-to-line-cycle-in-source t)) - ad-do-it - (when (called-interactively-p 'any) - (helm-swoop--move-line-action)))) - -(defadvice helm-toggle-visible-mark (around helm-swoop-toggle-visible-mark disable) - (let ((helm-move-to-line-cycle-in-source t)) - ad-do-it - (when (called-interactively-p 'any) - (helm-swoop--move-line-action)))) - (defun helm-swoop--move-line-action () (with-helm-window (let* (($key (helm-swoop--get-string-at-line)) @@ -392,12 +411,11 @@ This function needs to call after latest helm-swoop-line-overlay set." ;; Synchronizing line position (when (and $key $num) (with-selected-window helm-swoop-synchronizing-window - (progn - (helm-swoop--goto-line $num) - (with-current-buffer helm-swoop-target-buffer - (delete-overlay helm-swoop-line-overlay) - (helm-swoop--target-line-overlay-move)) - (helm-swoop--recenter))) + (helm-swoop--goto-line $num) + (with-current-buffer helm-swoop-target-buffer + (delete-overlay helm-swoop-line-overlay) + (helm-swoop--target-line-overlay-move)) + (helm-swoop--recenter)) (setq helm-swoop-last-line-info (cons helm-swoop-target-buffer $num)))))) @@ -446,8 +464,8 @@ This function needs to call after latest helm-swoop-line-overlay set." (string-to-number (match-string 0)) $list))) (setq $nearest-line (helm-swoop--nearest-line - (cdr helm-swoop-last-line-info) - $list)) + (cdr helm-swoop-last-line-info) + $list)) (goto-char $p) (re-search-forward (concat "^" (number-to-string $nearest-line) @@ -465,12 +483,12 @@ This function needs to call after latest helm-swoop-line-overlay set." "Overlay target words" (with-helm-window (setq helm-swoop-pattern helm-pattern) - (when (< 2 (length helm-pattern)) + (when (< helm-swoop-min-overlay-length (length helm-pattern)) (helm-swoop--delete-overlay 'target-buffer) - (helm-swoop--target-word-overlay 'target-buffer) + (helm-swoop--target-word-overlay 'target-buffer helm-swoop-min-overlay-length) (with-selected-window helm-swoop-synchronizing-window (helm-swoop--delete-overlay 'target-buffer) - (helm-swoop--target-word-overlay 'target-buffer))))) + (helm-swoop--target-word-overlay 'target-buffer helm-swoop-min-overlay-length))))) (defun helm-swoop-flash-word ($match-beg $match-end) (interactive) @@ -490,15 +508,14 @@ If $linum is number, lines are separated by $linum" (let (($buf (get-buffer $buffer))) (when $buf (with-current-buffer $buf - (let (($bufstr (helm-swoop--buffer-substring (point-min) (point-max))) - $return) + (let (($bufstr (helm-swoop--buffer-substring (point-min) (point-max)))) (with-temp-buffer (insert $bufstr) (goto-char (point-min)) (let (($i 1)) (insert (format "%s " $i)) (while (re-search-forward "\n" nil t) - (cl-incf $i) + (setq $i (1+ $i)) (if helm-swoop-use-line-number-face (insert (propertize (format "%s" $i) 'font-lock-face 'helm-swoop-line-number-face) " ") (insert (format "%s " $i)))) @@ -507,8 +524,7 @@ If $linum is number, lines are separated by $linum" (goto-char (point-min)) (while (re-search-forward "^[0-9]+\\s-*$" nil t) (replace-match "")))) - (setq $return (helm-swoop--buffer-substring (point-min) (point-max)))) - $return))))) + (helm-swoop--buffer-substring (point-min) (point-max)))))))) (defun helm-swoop--goto-line-action ($line) (run-hooks 'helm-swoop-before-goto-line-action-hook) @@ -519,10 +535,10 @@ If $linum is number, lines are separated by $linum" (mapconcat 'identity (split-string helm-pattern " ") "\\|"))) - (when (or (and (and (featurep 'migemo) helm-migemo-mode) - (migemo-forward $regex nil t)) + (when (or (and (featurep 'migemo) helm-migemo-mode (migemo-forward $regex nil t)) (re-search-forward $regex nil t)) - (helm-swoop-flash-word (match-beginning 0) (match-end 0)) + (funcall helm-swoop-flash-region-function + (match-beginning 0) (match-end 0)) (goto-char (match-beginning 0)) (run-hooks 'helm-swoop-after-goto-line-action-hook))) (helm-swoop--recenter)) @@ -544,7 +560,8 @@ If $linum is number, lines are separated by $linum" (header-line . ,(substitute-command-keys "[\\\\[helm-swoop-edit]] Edit mode, \ [\\\\[helm-multi-swoop-all-from-helm-swoop]] apply all buffers")) - (action . (("Go to Line" . helm-swoop--goto-line-action))) + (action . (("Go to Line" . helm-swoop--goto-line-action) + ("Edit" . helm-swoop--edit))) ,(if (and helm-swoop-last-prefix-number (> helm-swoop-last-prefix-number 1)) '(multiline)) @@ -571,10 +588,11 @@ If $linum is number, lines are separated by $linum" (setq helm-swoop-last-prefix-number (or $multiline 1))) ;; $multiline is for resume -;; Delete cache when modified file is saved +;; Delete cache when buffer is saved or file changes on disk (defun helm-swoop--clear-cache () (if (boundp 'helm-swoop-list-cache) (setq helm-swoop-list-cache nil))) (add-hook 'after-save-hook 'helm-swoop--clear-cache) +(add-hook 'after-revert-hook 'helm-swoop--clear-cache) (defadvice narrow-to-region (around helm-swoop-advice-narrow-to-region activate) (helm-swoop--clear-cache) @@ -594,19 +612,7 @@ If $linum is number, lines are separated by $linum" (helm-swoop-back-to-last-point t) (helm-swoop--restore-unveiled-overlay)) (setq helm-swoop-invisible-targets nil) - (ad-disable-advice 'helm-next-line 'around 'helm-swoop-next-line) - (ad-activate 'helm-next-line) - (ad-disable-advice 'helm-previous-line 'around 'helm-swoop-previous-line) - (ad-activate 'helm-previous-line) - (ad-disable-advice 'helm-toggle-visible-mark 'around 'helm-swoop-toggle-visible-mark) - (ad-activate 'helm-toggle-visible-mark) - (ad-disable-advice 'helm-move--next-line-fn 'around - 'helm-multi-swoop-next-line-cycle) - (ad-activate 'helm-move--next-line-fn) - (ad-disable-advice 'helm-move--previous-line-fn 'around - 'helm-multi-swoop-previous-line-cycle) - (ad-activate 'helm-move--previous-line-fn) - (remove-hook 'helm-update-hook 'helm-swoop--pattern-match) + (remove-hook 'helm-after-update-hook 'helm-swoop--pattern-match) (remove-hook 'helm-after-update-hook 'helm-swoop--keep-nearest-position) (setq helm-swoop-last-query helm-swoop-pattern) (mapc (lambda ($ov) @@ -646,19 +652,7 @@ If $linum is number, lines are separated by $linum" (unwind-protect (progn ;; For synchronizing line position - (ad-enable-advice 'helm-next-line 'around 'helm-swoop-next-line) - (ad-activate 'helm-next-line) - (ad-enable-advice 'helm-previous-line 'around 'helm-swoop-previous-line) - (ad-activate 'helm-previous-line) - (ad-enable-advice 'helm-toggle-visible-mark 'around 'helm-swoop-toggle-visible-mark) - (ad-activate 'helm-toggle-visible-mark) - (ad-enable-advice 'helm-move--next-line-fn 'around - 'helm-multi-swoop-next-line-cycle) - (ad-activate 'helm-move--next-line-fn) - (ad-enable-advice 'helm-move--previous-line-fn 'around - 'helm-multi-swoop-previous-line-cycle) - (ad-activate 'helm-move--previous-line-fn) - (add-hook 'helm-update-hook 'helm-swoop--pattern-match) + (add-hook 'helm-after-update-hook 'helm-swoop--pattern-match) (add-hook 'helm-after-update-hook 'helm-swoop--keep-nearest-position t) (cond ($query (if (string-match @@ -745,7 +739,7 @@ If $linum is number, lines are separated by $linum" ;; For helm-resume ------------------------ (defadvice helm-resume-select-buffer - (around helm-swoop-if-selected-as-resume activate) + (around helm-swoop-if-selected-as-resume activate) "Resume if *Helm Swoop* buffer selected as a resume when helm-resume with prefix" (if (boundp 'helm-swoop-last-query) @@ -890,7 +884,7 @@ If $linum is number, lines are separated by $linum" " [\\\\[helm-swoop--edit-complete]] Complete" ", [\\\\[helm-swoop--edit-cancel]] Cancel" ", [\\\\[helm-swoop--edit-delete-all-lines]] Delete All" - )) + )) 'face 'helm-bookmark-addressbook))) ;; Line number and editable area (while (re-search-forward "^\\([0-9]+\s\\)\\(.*\\)$" nil t) @@ -901,7 +895,7 @@ If $linum is number, lines are separated by $linum" ;; Line number (add-text-properties $bol1 $eol1 '(face font-lock-function-name-face - intangible t)) + intangible t)) ;; Editable area (remove-text-properties $bol2 $eol2 '(read-only t)) ;; For line tail @@ -1122,9 +1116,11 @@ If $linum is number, lines are separated by $linum" (split-string helm-pattern " ") "\\|") nil t) - (helm-swoop-flash-word (match-beginning 0) (match-end 0)) + (funcall helm-swoop-flash-region-function + (match-beginning 0) (match-end 0)) (goto-char (match-beginning 0))) - (helm-swoop--recenter))))))) + (helm-swoop--recenter))) + ("Edit" . helm-multi-swoop--edit))))) (setq $preserve-position (cons (cons $buf (point)) $preserve-position)) (setq @@ -1135,22 +1131,7 @@ If $linum is number, lines are separated by $linum" $buffs) (unwind-protect (progn - (ad-enable-advice 'helm-next-line 'around - 'helm-multi-swoop-next-line) - (ad-activate 'helm-next-line) - (ad-enable-advice 'helm-previous-line 'around - 'helm-multi-swoop-previous-line) - (ad-activate 'helm-previous-line) - (ad-enable-advice 'helm-toggle-visible-mark 'around - 'helm-multi-swoop-toggle-visible-mark) - (ad-activate 'helm-toggle-visible-mark) - (ad-enable-advice 'helm-move--next-line-fn 'around - 'helm-multi-swoop-next-line-cycle) - (ad-activate 'helm-move--next-line-fn) - (ad-enable-advice 'helm-move--previous-line-fn 'around - 'helm-multi-swoop-previous-line-cycle) - (ad-activate 'helm-move--previous-line-fn) - (add-hook 'helm-update-hook 'helm-swoop--pattern-match) + (add-hook 'helm-after-update-hook 'helm-swoop--pattern-match) (add-hook 'helm-after-update-hook 'helm-swoop--keep-nearest-position t) (setq helm-swoop-line-overlay (make-overlay (point) (point))) @@ -1177,22 +1158,7 @@ If $linum is number, lines are separated by $linum" (helm-swoop-back-to-last-point t) (helm-swoop--restore-unveiled-overlay)) (setq helm-swoop-invisible-targets nil) - (ad-disable-advice 'helm-next-line 'around - 'helm-multi-swoop-next-line) - (ad-activate 'helm-next-line) - (ad-disable-advice 'helm-previous-line 'around - 'helm-multi-swoop-previous-line) - (ad-activate 'helm-previous-line) - (ad-disable-advice 'helm-toggle-visible-mark 'around - 'helm-multi-swoop-toggle-visible-mark) - (ad-activate 'helm-toggle-visible-mark) - (ad-disable-advice 'helm-move--next-line-fn 'around - 'helm-multi-swoop-next-line-cycle) - (ad-activate 'helm-move--next-line-fn) - (ad-disable-advice 'helm-move--previous-line-fn 'around - 'helm-multi-swoop-previous-line-cycle) - (ad-activate 'helm-move--previous-line-fn) - (remove-hook 'helm-update-hook 'helm-swoop--pattern-match) + (remove-hook 'helm-after-update-hook 'helm-swoop--pattern-match) (remove-hook 'helm-after-update-hook 'helm-swoop--keep-nearest-position) (setq helm-multi-swoop-last-query helm-swoop-pattern) (helm-swoop--restore-unveiled-overlay) @@ -1335,12 +1301,8 @@ Last selected buffers will be applied to helm-multi-swoop. (defun helm-swoop--wrap-function-with-pre-input-function ($target-func $pre-input-func) - (let (($restore helm-swoop-pre-input-function)) - (unwind-protect - (progn - (setq helm-swoop-pre-input-function $pre-input-func) - (funcall $target-func)) - (setq helm-swoop-pre-input-function $restore)))) + (let ((helm-swoop-pre-input-function $pre-input-func)) + (funcall $target-func))) ;;;###autoload (defun helm-swoop-without-pre-input () @@ -1490,7 +1452,7 @@ Last selected buffers will be applied to helm-multi-swoop. ;; Line number (add-text-properties $bol1 $eol1 '(face font-lock-function-name-face - intangible t)) + intangible t)) ;; Editable area (remove-text-properties $bol2 $eol2 '(read-only t)) ;; (add-text-properties $bol2 $eol2 '(font-lock-face helm-match)) @@ -1538,20 +1500,20 @@ Last selected buffers will be applied to helm-multi-swoop. (let ($contents) ;; Make ((number . line) (number . line) (number . line) ...) (with-temp-buffer - (insert (format "%s" (nth (1+ $i) $list))) - (goto-char (point-min)) - (while (re-search-forward "^\\([0-9]+\\)\s" nil t) - (setq $contents - (cons (cons (string-to-number (match-string 1)) - (buffer-substring-no-properties - (point) - (save-excursion - (if (re-search-forward - "^\\([0-9]+\\)\s\\|^\\(\\-+\\)" nil t) - (1- (match-beginning 0)) - (goto-char (point-max)) - (re-search-backward "\n" nil t))))) - $contents)))) + (insert (format "%s" (nth (1+ $i) $list))) + (goto-char (point-min)) + (while (re-search-forward "^\\([0-9]+\\)\s" nil t) + (setq $contents + (cons (cons (string-to-number (match-string 1)) + (buffer-substring-no-properties + (point) + (save-excursion + (if (re-search-forward + "^\\([0-9]+\\)\s\\|^\\(\\-+\\)" nil t) + (1- (match-beginning 0)) + (goto-char (point-max)) + (re-search-backward "\n" nil t))))) + $contents)))) ;; Make ((buffer-name (number . line) (number . line) ...) ;; (buffer-name (number . line) (number . line) ...) ...) (setq $pairs (cons (cons (nth $i $list) $contents) $pairs))) @@ -1632,7 +1594,7 @@ Last selected buffers will be applied to helm-multi-swoop. (or $point (setq $point (point))) (let (($face (or (get-char-property $point 'read-face-name) (get-char-property $point 'face)))) - $face)) + $face)) (defun helm-swoop--cull-face-include-line ($face) (let (($list) ($po (point-min))) @@ -1648,7 +1610,7 @@ Last selected buffers will be applied to helm-multi-swoop. (point-max))))) (overlay-put $ov 'face 'helm-swoop-target-word-face) (overlay-put $ov 'target-buffer 'helm-swoop-target-word-face))))) - (nreverse (delete-dups $list)))) + (nreverse (delete-dups $list)))) (defun helm-swoop-same-face-at-point (&optional $face) (interactive) @@ -1669,7 +1631,8 @@ Last selected buffers will be applied to helm-multi-swoop. (while (<= (setq $po (next-single-property-change $po 'face)) $poe) (when (eq 'helm-swoop-target-word-face (helm-swoop--get-at-face $po)) (goto-char $po)))) - (helm-swoop--recenter)))))))) + (helm-swoop--recenter))) + ("Edit" . helm-swoop--edit)))))) (defun helm-multi-swoop-same-face-at-point (&optional $face) (interactive) @@ -1692,4 +1655,9 @@ Last selected buffers will be applied to helm-multi-swoop. :$buflist (helm-multi-swoop--get-buffer-list))) (provide 'helm-swoop) + +;; Local Variables: +;; indent-tabs-mode: nil +;; End: + ;;; helm-swoop.el ends here diff --git a/packages/helm-xref-20180528.1516.el b/packages/helm-xref-20190821.1252.el similarity index 54% rename from packages/helm-xref-20180528.1516.el rename to packages/helm-xref-20190821.1252.el index 436f561..73b404d 100644 --- a/packages/helm-xref-20180528.1516.el +++ b/packages/helm-xref-20190821.1252.el @@ -3,9 +3,9 @@ ;; Copyright (C) 2017 Fritz Stelzer ;; Author: Fritz Stelzer -;; URL: https://github.com/brotzeitmacher/helm-xref -;; Package-Version: 20180528.1516 -;; Version: 0.2 +;; URL: https://github.com/brotzeit/helm-xref +;; Package-Version: 20190821.1252 +;; Version: 0.4 ;; Package-Requires: ((emacs "25.1") (helm "1.9.4")) ;;; License: @@ -20,9 +20,13 @@ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. +;;; Contributors: +;; Sanjeev Sivasankaran in 2019 changed font-face. + ;;; Code: (require 'helm) +(require 'helm-utils) (require 'xref) (require 'cl-seq) @@ -34,23 +38,25 @@ :prefix "helm-xref-" :group 'helm) (defface helm-xref-file-name - '((t (:foreground "cyan"))) + '((t (:inherit 'font-lock-builtin-face))) "Face for xref file name" :group 'helm-xref) (defface helm-xref-line-number - '((t (:inherit 'compilation-line-number))) + '((t (:inherit 'helm-grep-lineno))) "Face for xref line number" :group 'helm-xref) -(defcustom helm-xref-candidate-formatting-function 'helm-xref-format-candidate-short +(defcustom helm-xref-candidate-formatting-function 'helm-xref-format-candidate-short "Select the function for candidate formatting." - :type '(radio (function-item helm-xref-format-candidate-short) - (function-item helm-xref-format-candidate-long) - function) + :type '(radio + (function-item helm-xref-format-candidate-short) + (function-item helm-xref-format-candidate-full-path) + (function-item helm-xref-format-candidate-long) + function) :group 'helm-xref) -(defun helm-xref-candidates (xrefs) +(defun helm-xref-candidates-26 (xrefs) "Convert XREF-ALIST items to helm candidates and add them to `helm-xref-alist'." (dolist (xref xrefs) (with-slots (summary location) xref @@ -62,6 +68,23 @@ (push (cons candidate xref) helm-xref-alist)))) (setq helm-xref-alist (reverse helm-xref-alist))) +(defun helm-xref-candidates-27 (fetcher alist) + "Convert XREF-ALIST items to helm candidates and add them to `helm-xref-alist'." + (cl-assert (functionp fetcher)) + (let* ((xrefs + (or + (assoc-default 'fetched-xrefs alist) + (funcall fetcher)))) + (dolist (xref xrefs) + (with-slots (summary location) xref + (let* ((line (xref-location-line location)) + (file (xref-location-group location)) + candidate) + (setq candidate + (funcall helm-xref-candidate-formatting-function file line summary)) + (push (cons candidate xref) helm-xref-alist))))) + (setq helm-xref-alist (reverse helm-xref-alist))) + (defun helm-xref-format-candidate-short (file line summary) "Build short form of candidate format with FILE, LINE, and SUMMARY." (concat @@ -75,8 +98,20 @@ ":" summary)) +(defun helm-xref-format-candidate-full-path (file line summary) + "Same as `helm-xref-format-candidate-short', but display entire path." + (concat + (propertize file 'font-lock-face 'helm-xref-file-name) + (when (string= "integer" (type-of line)) + (concat + ":" + (propertize (int-to-string line) + 'font-lock-face 'helm-xref-line-number))) + ":" + summary)) + (defun helm-xref-format-candidate-long (file line summary) - "Build long form of candidate format with FILE, LINE, and SUMMARY." + "Use two lines for each candidate. One contains the path and the other the actual candidate." (concat (propertize file 'font-lock-face 'helm-xref-file-name) (when (string= "integer" (type-of line)) @@ -95,9 +130,9 @@ Use FUNC to display buffer." (let* ((marker (xref-location-marker location)) (buf (marker-buffer marker)) (offset (marker-position marker))) - (with-current-buffer buf - (goto-char offset) - (funcall func buf))))) + (switch-to-buffer buf) + (goto-char offset) + (funcall func buf)))) (defun helm-xref-source () "Return a `helm' source for xref results." @@ -105,9 +140,10 @@ Use FUNC to display buffer." :candidates (lambda () helm-xref-alist) :persistent-action (lambda (xref-item) - (helm-xref-goto-xref-item xref-item 'display-buffer)) - :action (lambda (xref-item) - (helm-xref-goto-xref-item xref-item 'switch-to-buffer)) + (helm-xref-goto-xref-item + xref-item '(lambda (buf) (helm-highlight-current-line)))) + :action '(("Switch to buffer" . (lambda (xref-item) (helm-xref-goto-xref-item xref-item 'switch-to-buffer))) + ("Other window" . (lambda (xref-item) (helm-xref-goto-xref-item xref-item 'switch-to-buffer-other-window)))) :candidate-number-limit 9999)) (defun helm-xref-show-xrefs (xrefs _alist) @@ -115,10 +151,24 @@ Use FUNC to display buffer." Needs to be set the value of `xref-show-xrefs-function'." (setq helm-xref-alist nil) - (helm-xref-candidates xrefs) + (helm-xref-candidates-26 xrefs) (helm :sources (helm-xref-source) :truncate-lines t :buffer "*helm-xref*")) +(defun helm-xref-show-xrefs-27 (fetcher alist) + "Function to display XREFS. + +Needs to be set the value of `xref-show-xrefs-function'." + (setq helm-xref-alist nil) + (helm-xref-candidates-27 fetcher alist) + (helm :sources (helm-xref-source) + :truncate-lines t + :buffer "*helm-xref*")) + +(if (< emacs-major-version 27) + (setq xref-show-xrefs-function 'helm-xref-show-xrefs) + (setq xref-show-xrefs-function 'helm-xref-show-xrefs-27)) + (provide 'helm-xref) ;;; helm-xref.el ends here diff --git a/packages/hemisu-theme-20130508.1844.tar b/packages/hemisu-theme-20130508.1844.tar index 09db34f..3d2ae90 100644 Binary files a/packages/hemisu-theme-20130508.1844.tar and b/packages/hemisu-theme-20130508.1844.tar differ diff --git a/packages/hierarchy-20171221.1151.el b/packages/hierarchy-20190425.842.el similarity index 99% rename from packages/hierarchy-20171221.1151.el rename to packages/hierarchy-20190425.842.el index de74820..755fec5 100644 --- a/packages/hierarchy-20171221.1151.el +++ b/packages/hierarchy-20190425.842.el @@ -5,7 +5,7 @@ ;; Author: Damien Cassou ;; Maintainer: Damien Cassou ;; Version: 0.7.0 -;; Package-Version: 20171221.1151 +;; Package-Version: 20190425.842 ;; Package-Requires: ((emacs "25.1")) ;; GIT: https://github.com/DamienCassou/hierarchy ;; URL: https://github.com/DamienCassou/hierarchy @@ -102,7 +102,8 @@ should be an item of the hierarchy." (error "An item (%s) can only have one parent: '%s' vs '%s'" item existing-parent parent)) ((not has-parent-p) - (push item (map-elt (hierarchy--children hierarchy) parent (list))) + (let ((existing-children (map-elt (hierarchy--children hierarchy) parent (list)))) + (map-put (hierarchy--children hierarchy) parent (append existing-children (list item)))) (map-put (hierarchy--parents hierarchy) item parent))))) (defun hierarchy--set-equal (list1 list2 &rest cl-keys) diff --git a/packages/highlight-indentation-20171218.937.el b/packages/highlight-indentation-20181204.839.el similarity index 75% rename from packages/highlight-indentation-20171218.937.el rename to packages/highlight-indentation-20181204.839.el index eb35e82..b9446b9 100644 --- a/packages/highlight-indentation-20171218.937.el +++ b/packages/highlight-indentation-20181204.839.el @@ -2,7 +2,7 @@ ;; Author: Anton Johansson - http://antonj.se ;; Created: Dec 15 23:42:04 2010 ;; Version: 0.7.0 -;; Package-Version: 20171218.937 +;; Package-Version: 20181204.839 ;; URL: https://github.com/antonj/Highlight-Indentation-for-Emacs ;; ;; This program is free software; you can redistribute it and/or @@ -38,6 +38,19 @@ major mode. This value is always used by `highlight-indentation-mode' if set buffer local. Set buffer local with `highlight-indentation-set-offset'" + :type 'integer + :group 'highlight-indentation) + +(defcustom highlight-indentation-blank-lines nil + "Show indentation guides on blank lines. Experimental. + +Known issues: +- Doesn't work well with completion popups that use overlays +- Overlays on blank lines sometimes aren't cleaned up or updated perfectly + Can be refershed by scrolling +- Not yet implemented for highlight-indentation-current-column-mode +- May not work perfectly near the bottom of the screen +- Point appears after indent guides on blank lines" :group 'highlight-indentation) (defvar highlight-indentation-overlay-priority 1) @@ -83,6 +96,8 @@ (save-match-data (save-excursion (let ((inhibit-point-motion-hooks t) + (start (save-excursion (goto-char start) (beginning-of-line) (point))) + (end (save-excursion (goto-char end) (line-beginning-position 2)))) (highlight-indentation-delete-overlays-region start end overlay) (funcall func start end overlay))))) @@ -94,24 +109,71 @@ (defun highlight-indentation-put-overlays-region (start end overlay) "Place overlays between START and END." - (goto-char start) + (goto-char end) (let (o ;; overlay (last-indent 0) - (pos start)) - (while (< pos end) - (beginning-of-line) - (while (and (integerp (char-after)) - (not (= 10 (char-after))) ;; newline - (= 32 (char-after))) ;; space - (when (= 0 (% (current-column) highlight-indentation-offset)) - (setq pos (point) - last-indent pos - o (make-overlay pos (+ pos 1))) - (overlay-put o overlay t) - (overlay-put o 'priority highlight-indentation-overlay-priority) - (overlay-put o 'face 'highlight-indentation-face)) - (forward-char)) - (forward-line) ;; Next line + (last-char 0) + (pos (point)) + (loop t)) + (while (and loop + (>= pos start)) + (save-excursion + (beginning-of-line) + (let ((c 0) + (cur-column (current-column))) + (while (and (setq c (char-after)) + (integerp c) + (not (= 10 c)) ;; newline + (= 32 c)) ;; space + (when (= 0 (% cur-column highlight-indentation-offset)) + (let ((p (point))) + (setq o (make-overlay p (+ p 1)))) + (overlay-put o overlay t) + (overlay-put o 'priority highlight-indentation-overlay-priority) + (overlay-put o 'face 'highlight-indentation-face)) + (forward-char) + (setq cur-column (current-column))) + (when (and highlight-indentation-blank-lines + (integerp c) + (or (= 10 c) + (= 13 c))) + (when (< cur-column last-indent) + (let ((column cur-column) + (s nil) + (show t) + num-spaces) + (while (< column last-indent) + (if (>= 0 + (setq num-spaces + (% + (- last-indent column) + highlight-indentation-offset))) + (progn + (setq num-spaces (1- highlight-indentation-offset)) + (setq show t)) + (setq show nil)) + (setq s (cons (concat + (if show + (propertize " " + 'face + 'highlight-indentation-face) + "") + (make-string num-spaces 32)) + s)) + (setq column (+ column num-spaces (if show 1 0)))) + (setq s (apply 'concat (reverse s))) + (let ((p (point))) + (setq o (make-overlay p p))) + (overlay-put o overlay t) + (overlay-put o 'priority highlight-indentation-overlay-priority) + (overlay-put o 'after-string s)) + (setq cur-column last-indent))) + (setq last-indent (* highlight-indentation-offset + (ceiling (/ (float cur-column) + highlight-indentation-offset)))))) + (when (= pos start) + (setq loop nil)) + (forward-line -1) ;; previous line (setq pos (point))))) (defun highlight-indentation-guess-offset () diff --git a/packages/hl-anything-20160422.1708.tar b/packages/hl-anything-20160422.1708.tar index 65962c5..3791e2e 100644 Binary files a/packages/hl-anything-20160422.1708.tar and b/packages/hl-anything-20160422.1708.tar differ diff --git a/packages/hl-todo-20181031.1909.el b/packages/hl-todo-20190807.1831.el similarity index 50% rename from packages/hl-todo-20181031.1909.el rename to packages/hl-todo-20190807.1831.el index 2a93604..93b5150 100644 --- a/packages/hl-todo-20181031.1909.el +++ b/packages/hl-todo-20190807.1831.el @@ -1,11 +1,13 @@ ;;; hl-todo.el --- highlight TODO and similar keywords -*- lexical-binding: t -*- -;; Copyright (C) 2013-2018 Jonas Bernoulli +;; Copyright (C) 2013-2019 Jonas Bernoulli ;; Author: Jonas Bernoulli ;; Homepage: https://github.com/tarsius/hl-todo ;; Keywords: convenience -;; Package-Version: 20181031.1909 +;; Package-Version: 20190807.1831 + +;; Package-Requires: ((emacs "25")) ;; This file is not part of GNU Emacs. @@ -26,20 +28,22 @@ ;; Highlight TODO and similar keywords in comments and strings. -;; You can either turn on `hl-todo-mode' in individual buffers or use -;; the the global variant `global-hl-todo-mode'. Note that the option -;; `hl-todo-activate-in-modes' controls in what buffers the local mode -;; will be activated if you do the latter. By default it will only be -;; activated in buffers whose major-mode derives from `prog-mode'. +;; You can either explicitly turn on `hl-todo-mode' in certain buffers +;; or use the the global variant `global-hl-todo-mode', which enables +;; the local mode based on each buffer's major-mode and the options +;; `hl-todo-include-modes' and `hl-todo-exclude-modes'. By default +;; `hl-todo-mode' is enabled for all buffers whose major-mode derive +;; from either `prog-mode' or `text-mode', except `org-mode'. ;; This package also provides commands for moving to the next or -;; previous keyword and to invoke `occur' with a regexp that matches -;; all known keywords. If you want to use these commands, then you -;; should bind them in `hl-todo-mode-map', e.g.: +;; previous keyword, to invoke `occur' with a regexp that matches all +;; known keywords, and to insert a keyword. If you want to use these +;; commands, then you should bind them in `hl-todo-mode-map', e.g.: ;; ;; (define-key hl-todo-mode-map (kbd "C-c p") 'hl-todo-previous) ;; (define-key hl-todo-mode-map (kbd "C-c n") 'hl-todo-next) ;; (define-key hl-todo-mode-map (kbd "C-c o") 'hl-todo-occur) +;; (define-key hl-todo-mode-map (kbd "C-c i") 'hl-todo-insert) ;; See [[https://www.emacswiki.org/emacs/FixmeMode][this list]] on the Emacswiki for other packages that implement ;; the same basic features, but which might also provide additional @@ -47,6 +51,11 @@ ;;; Code: +(require' cl-lib) + +(eval-when-compile + (require 'subr-x)) + (defgroup hl-todo nil "Highlight TODO and similar keywords in comments and strings." :group 'font-lock-extra-types) @@ -60,20 +69,31 @@ color specified using the option `hl-todo-keyword-faces' as foreground color." :group 'hl-todo) -(defcustom hl-todo-activate-in-modes '(prog-mode text-mode) - "Major-modes in which `hl-todo-mode' should be activated. +(define-obsolete-variable-alias 'hl-todo-activate-in-modes + 'hl-todo-include-modes "hl-todo 3.1.0") -This is used by `global-hl-todo-mode', which activates -`hl-todo-mode' in all buffers whose major-mode derived from one -of the modes listed here. +(defcustom hl-todo-include-modes '(prog-mode text-mode) + "Major-modes in which `hl-todo-mode' is activated. -Even though `org-mode' indirectly derives from `text-mode' this -mode is never activated in `org-mode' buffers because that mode -provides its own TODO keyword handling." +This is used by `global-hl-todo-mode', which activates the local +`hl-todo-mode' in all buffers whose major-mode derive from one +of the modes listed here, but not from one of the modes listed +in `hl-todo-exclude-modes'." :package-version '(hl-todo . "2.1.0") :group 'hl-todo :type '(repeat function)) +(defcustom hl-todo-exclude-modes '(org-mode) + "Major-modes in which `hl-todo-mode' is not activated. + +This is used by `global-hl-todo-mode', which activates the local +`hl-todo-mode' in all buffers whose major-mode derived from one +of the modes listed in `hl-todo-include-modes', but not from one +of the modes listed here." + :package-version '(hl-todo . "3.1.0") + :group 'hl-todo + :type '(repeat function)) + (defcustom hl-todo-text-modes '(text-mode) "Major-modes that are considered text-modes. @@ -99,11 +119,25 @@ located inside a string." ("HACK" . "#d0bf8f") ("TEMP" . "#d0bf8f") ("FIXME" . "#cc9393") - ("XXX" . "#cc9393") - ("XXXX" . "#cc9393") - ("???" . "#cc9393")) - "Faces used to highlight specific TODO keywords." - :package-version '(hl-todo . "2.0.0") + ("XXX+" . "#cc9393") + ("\\?\\?\\?+" . "#cc9393")) + "Faces used to highlight specific TODO keywords. + +Each entry has the form (KEYWORD . COLOR). KEYWORD is used as +part of a regular expression. If (regexp-quote KEYWORD) is not +equal to KEYWORD, then it is ignored by `hl-todo-insert-keyword'. + +The syntax class of the characters at either end has to be `w' +\(which means word) in `hl-todo--syntax-table'. That syntax +table derives from `text-mode-syntax-table' but uses `w' as the +class of \"?\". + +This package, like most of Emacs, does not use POSIX regexp +backtracking. See info node `(elisp)POSIX Regexp' for why that +matters. If you have two keywords \"TODO-NOW\" and \"TODO\", then +they must be specified in that order. Alternatively you could +use \"TODO\\(-NOW\\)?\"." + :package-version '(hl-todo . "3.0.0") :group 'hl-todo :type '(repeat (cons (string :tag "Keyword") (choice :tag "Face " @@ -126,36 +160,59 @@ including alphanumeric characters, cannot be used here." (defvar-local hl-todo--regexp nil) (defvar-local hl-todo--keywords nil) -(defun hl-todo--setup () +(defun hl-todo--regexp () + (or hl-todo--regexp (hl-todo--setup-regexp))) + +(defun hl-todo--setup-regexp () + (when-let ((bomb (assoc "???" hl-todo-keyword-faces))) + ;; If the user customized this variable before we started to + ;; treat the strings as regexps, then the string "???" might + ;; still be present. We have to remove it because it results + ;; in the regexp search taking forever. + (setq hl-todo-keyword-faces (delete bomb hl-todo-keyword-faces))) (setq hl-todo--regexp (concat "\\(\\<" - (regexp-opt (mapcar #'car hl-todo-keyword-faces) t) - "\\>" + "\\(" (mapconcat #'car hl-todo-keyword-faces "\\|") "\\)" + "\\(?:\\>\\|\\>\\?\\)" (and (not (equal hl-todo-highlight-punctuation "")) (concat "[" hl-todo-highlight-punctuation "]*")) - "\\)")) + "\\)"))) + +(defun hl-todo--setup () + (hl-todo--setup-regexp) (setq hl-todo--keywords `(((lambda (bound) (hl-todo--search nil bound)) (1 (hl-todo--get-face) t t)))) (font-lock-add-keywords nil hl-todo--keywords t)) -(defvar hl-todo--syntax-table (copy-syntax-table text-mode-syntax-table)) +(defvar hl-todo--syntax-table + (let ((table (copy-syntax-table text-mode-syntax-table))) + (modify-syntax-entry ?? "w" table) + table)) (defun hl-todo--search (&optional regexp bound backward) (unless regexp (setq regexp hl-todo--regexp)) - (and (let ((case-fold-search nil)) - (with-syntax-table hl-todo--syntax-table - (funcall (if backward #'re-search-backward #'re-search-forward) - regexp bound t))) - (or (apply #'derived-mode-p hl-todo-text-modes) - (nth 8 (syntax-ppss)) ; inside comment or string - (and (or (not bound) - (funcall (if backward #'< #'>) bound (point))) - (hl-todo--search regexp bound backward))))) + (cl-block nil + (while (let ((case-fold-search nil)) + (with-syntax-table hl-todo--syntax-table + (funcall (if backward #'re-search-backward #'re-search-forward) + regexp bound t))) + (cond ((or (apply #'derived-mode-p hl-todo-text-modes) + (hl-todo--inside-comment-or-string-p)) + (cl-return t)) + ((and bound (funcall (if backward #'<= #'>=) (point) bound)) + (cl-return nil)))))) + +(defun hl-todo--inside-comment-or-string-p () + (nth 8 (syntax-ppss))) (defun hl-todo--get-face () - (let ((face (cdr (assoc (match-string 2) hl-todo-keyword-faces)))) + (let* ((keyword (match-string 2)) + (face (cdr (cl-find-if (lambda (elt) + (string-match-p (format "\\`%s\\'" (car elt)) + keyword)) + hl-todo-keyword-faces)))) (if (stringp face) (list :inherit 'hl-todo :foreground face) face))) @@ -184,8 +241,8 @@ including alphanumeric characters, cannot be used here." hl-todo-mode hl-todo--turn-on-mode-if-desired) (defun hl-todo--turn-on-mode-if-desired () - (when (and (apply #'derived-mode-p hl-todo-activate-in-modes) - (not (derived-mode-p 'org-mode))) + (when (and (apply #'derived-mode-p hl-todo-include-modes) + (not (apply #'derived-mode-p hl-todo-exclude-modes))) (hl-todo-mode 1))) ;;;###autoload @@ -200,7 +257,7 @@ A negative argument means move backward that many keywords." (not (eobp)) (progn (when (let ((case-fold-search nil)) - (looking-at hl-todo--regexp)) + (looking-at (hl-todo--regexp))) (goto-char (match-end 0))) (or (hl-todo--search) (user-error "No more matches")))) @@ -217,7 +274,7 @@ A negative argument means move forward that many keywords." (while (and (> arg 0) (not (bobp)) (let ((start (point))) - (hl-todo--search (concat hl-todo--regexp "\\=") nil t) + (hl-todo--search (concat (hl-todo--regexp) "\\=") nil t) (or (hl-todo--search nil nil t) (progn (goto-char start) (user-error "No more matches"))))) @@ -229,9 +286,50 @@ A negative argument means move forward that many keywords." "Use `occur' to find all TODO or similar keywords. This actually finds a superset of the highlighted keywords, because it uses a regexp instead of a more sophisticated -matcher." +matcher. It also finds occurrences that are not within a +string or comment." (interactive) - (occur hl-todo--regexp)) + (with-syntax-table hl-todo--syntax-table + (occur (hl-todo--regexp)))) + +;;;###autoload +(defun hl-todo-insert (keyword) + "Insert TODO or similar keyword. +If point is not inside a string or comment, then insert a new +comment. If point is at the end of the line, then insert the +comment there, otherwise insert it as a new line before the +current line." + (interactive + (list (completing-read + "Insert keyword: " + (cl-mapcan (pcase-lambda (`(,keyword . ,face)) + (and (equal (regexp-quote keyword) keyword) + (list (propertize + keyword 'face + (if (stringp face) + (list :inherit 'hl-todo :foreground face) + face))))) + hl-todo-keyword-faces)))) + (cond + ((hl-todo--inside-comment-or-string-p) + (insert (concat (and (not (memq (char-before) '(?\s ?\t))) " ") + keyword + (and (not (memq (char-after) '(?\s ?\t ?\n))) " ")))) + ((eolp) + (insert (concat (and (not (memq (char-before) '(?\s ?\t))) " ") + (format "%s %s " comment-start keyword)))) + (t + (goto-char (line-beginning-position)) + (insert (format "%s %s \n" + (if (derived-mode-p 'lisp-mode 'emacs-lisp-mode) + (format "%s%s" comment-start comment-start) + comment-start) + keyword)) + (backward-char) + (indent-region (line-beginning-position) (line-end-position))))) + +(define-obsolete-function-alias 'hl-todo-insert-keyword + 'hl-todo-insert "hl-todo 3.0.0") ;;; _ (provide 'hl-todo) diff --git a/packages/hlint-refactor-20170818.448.el b/packages/hlint-refactor-20190115.900.el similarity index 95% rename from packages/hlint-refactor-20170818.448.el rename to packages/hlint-refactor-20190115.900.el index 6c6be24..a8f4212 100644 --- a/packages/hlint-refactor-20170818.448.el +++ b/packages/hlint-refactor-20190115.900.el @@ -4,7 +4,7 @@ ;; Author Matthew Pickering ;; Keywords: haskell, refactor -;; Package-Version: 20170818.448 +;; Package-Version: 20190115.900 ;; Version: 0.0.1 ;; URL: https://github.com/mpickering/hlint-refactor-mode @@ -57,10 +57,12 @@ exit code." "Send text from START to END to PROGRAM with ARGS preserving the point. This uses `call-process-region-checked' internally." (let ((line (line-number-at-pos)) - (column (current-column))) + (column (current-column)) + (ws (window-start))) (hlint-refactor-call-process-region-checked start end program args) (goto-line line) - (move-to-column column))) + (move-to-column column) + (set-window-start (selected-window) ws))) ;;;###autoload (defun hlint-refactor-refactor-buffer (&optional args) diff --git a/packages/ht-20180129.2234.el b/packages/ht-20190611.2131.el similarity index 92% rename from packages/ht-20180129.2234.el rename to packages/ht-20190611.2131.el index 3907e1e..9503c30 100644 --- a/packages/ht-20180129.2234.el +++ b/packages/ht-20190611.2131.el @@ -4,7 +4,7 @@ ;; Author: Wilfred Hughes ;; Version: 2.3 -;; Package-Version: 20180129.2234 +;; Package-Version: 20190611.2131 ;; Keywords: hash table, hash map, hash ;; Package-Requires: ((dash "2.12.0")) @@ -30,6 +30,7 @@ ;;; Code: (require 'dash) +(require 'gv) (defmacro ht (&rest pairs) "Create a hash table with the key-value pairs given. @@ -95,13 +96,26 @@ user-supplied test created via `define-hash-table-test'." If KEY isn't present, return DEFAULT (nil if not specified)." (gethash key table default)) +(gv-define-setter ht-get (value table key) `(ht-set! ,table ,key ,value)) + (defun ht-get* (table &rest keys) "Look up KEYS in nested hash tables, starting with TABLE. The lookup for each key should return another hash table, except for the final key, which may return any value." (if (cdr keys) (apply #'ht-get* (ht-get table (car keys)) (cdr keys)) - (ht-get table (car keys)))) + (if keys + (ht-get table (car keys)) + table))) + +(gv-define-setter ht-get* (value table &rest keys) + `(if (cdr ',keys) + (let* ((first-key (car ',keys)) + (last-key (-last-item ',keys)) + (butlast-key (butlast (cdr ',keys))) + (h (apply #'ht-get* (ht-get ,table first-key) butlast-key))) + (ht-set! h last-key ,value)) + (ht-set! ,table (car ',keys) ,value))) (defun ht-update! (table from-table) "Update TABLE according to every key-value pair in FROM-TABLE." @@ -215,7 +229,8 @@ inverse of `ht<-alist'. The following is not guaranteed: (defun ht-contains? (table key) "Return 't if TABLE contains KEY." - (not (eq (ht-get table key 'ht--not-found) 'ht--not-found))) + (let ((not-found-symbol (make-symbol "ht--not-found"))) + (not (eq (ht-get table key not-found-symbol) not-found-symbol)))) (defalias 'ht-contains-p 'ht-contains?) @@ -227,6 +242,8 @@ inverse of `ht<-alist'. The following is not guaranteed: "Return true if the actual number of entries in TABLE is zero." (zerop (ht-size table))) +(defalias 'ht-empty-p 'ht-empty?) + (defun ht-select (function table) "Return a hash table containing all entries in TABLE for which FUNCTION returns a truthy value. diff --git a/packages/hy-mode-20180702.1940.el b/packages/hy-mode-20180702.1940.el deleted file mode 100644 index 3a4ad2a..0000000 --- a/packages/hy-mode-20180702.1940.el +++ /dev/null @@ -1,1617 +0,0 @@ -;;; hy-mode.el --- Major mode for Hylang -*- lexical-binding: t -*- - -;; Copyright © 2013 Julien Danjou -;; © 2017 Eric Kaschalk -;; -;; Authors: Julien Danjou -;; Eric Kaschalk -;; URL: http://github.com/hylang/hy-mode -;; Package-Version: 20180702.1940 -;; Version: 1.0 -;; Keywords: languages, lisp, python -;; Package-Requires: ((dash "2.13.0") (dash-functional "1.2.0") (s "1.11.0") (emacs "24")) - -;; hy-mode 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. -;; -;; hy-mode 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 hy-mode. If not, see . - -;; This file is not part of GNU Emacs. - -;;; Commentary: - -;; Provides font-lock, indentation, and navigation for the Hy -;; language. (http://hylang.org) - -;;; Code: - -(require 'cl) -(require 'dash) -(require 'dash-functional) -(require 's) - -(defgroup hy-mode nil - "A mode for Hy" - :prefix "hy-mode-" - :group 'applications) - -;;; Configuration -;;;; Inferior shell - -(defconst hy-shell-interpreter "hy" - "Default Hy interpreter name.") - -(defvar hy-shell-interpreter-args "--spy" - "Default arguments for Hy interpreter.") - -(defvar hy-shell-use-control-codes? nil - "Append `--control-codes' flag to `hy-shell-interpreter-args'? - -Requires recent version of Hy and `hy-shell-interpreter-args' to contain `--spy'. -Keep nil unless using specific Hy branch.") - -(defvar hy-shell-spy-delim "" - "If using `--spy' interpreter arg then delimit spy ouput by this string.") - -;;;; Highlighting - -(defvar hy-font-lock-highlight-percent-args? t - "Whether to highlight '%i' symbols in Hy's clojure-like syntax for lambdas.") - -;;;; Indentation - -(defvar hy-indent-special-forms - '(:exact - ("when" "unless" - "for" "for*" "for/a" "for/a*" - "while" - "except" "catch") - - :fuzzy - ("def" - "with" - "with/a" - "fn" - "fn/a" - "lambda")) - "Special forms to always indent following line by +1. - -Fuzzy forms require match at start of symbol (eg. with-something) -will indent special. Exact forms require the symbol and def exactly match.") - -;;; Syntax Table - -(defconst hy-mode-syntax-table - (-let [table - (copy-syntax-table lisp-mode-syntax-table)] - (modify-syntax-entry ?\{ "(}" table) - (modify-syntax-entry ?\} "){" table) - (modify-syntax-entry ?\[ "(]" table) - (modify-syntax-entry ?\] ")[" table) - - ;; Quote characters are prefixes - (modify-syntax-entry ?\~ "'" table) - (modify-syntax-entry ?\@ "'" table) - - ;; "," is a symbol in Hy, namely the tuple constructor - (modify-syntax-entry ?\, "_ p" table) - - ;; "|" is a symbol in hy, naming the or operator - (modify-syntax-entry ?\| "_ p" table) - - ;; "#" is a tag macro, we include # in the symbol - (modify-syntax-entry ?\# "_ p" table) - - table) - "Hy mode's syntax table.") - -(defconst inferior-hy-mode-syntax-table - (copy-syntax-table hy-mode-syntax-table) - "Inferior Hy mode's syntax tables inherits Hy mode's table.") - -;;; Keywords - -(defconst hy--kwds-anaphorics - '("ap-if" "ap-each" "ap-each-while" "ap-map" "ap-map-when" "ap-filter" - "ap-reject" "ap-dotimes" "ap-first" "ap-last" "ap-reduce" "ap-pipe" - "ap-compose" "xi") - - "Hy anaphoric contrib keywords.") - -(defconst hy--kwds-builtins - '("*map" "accumulate" "and" "assoc" "butlast" "calling-module-name" "car" - "cdr" "chain" "coll?" "combinations" "comp" "complement" "compress" "cons" - "cons?" "constantly" "count" "cut" "cycle" "dec" "defmain" "del" - "dict-comp" "disassemble" "distinct" "doto" "drop" "drop-last" "drop-while" - "empty?" "even?" "every?" "filter" "first" "flatten" "float?" "fraction" - "genexpr" "gensym" "get" "group-by" "identity" "inc" "input" - "instance?" "integer" "integer-char?" "integer?" "interleave" "interpose" - "is" "is-not" "is_not" "islice" "iterable?" "iterate" "iterator?" "juxt" - "keyword" "keyword?" "last" "list*" "list-comp" "macroexpand" - "macroexpand-1" "map" "merge-with" "multicombinations" "name" "neg?" "none?" - "nth" "numeric?" "odd?" "or" "partition" "permutations" - "pos?" "product" "quasiquote" "quote" "range" "read" "read-str" - "reduce" "remove" "repeat" "repeatedly" "rest" "second" "setv" "set-comp" - "slice" "some" "string" "string?" "symbol?" "take" "take-nth" "take-while" - "tee" "unquote" "unquote-splice" "xor" "zero?" "zip" "zip-longest" - - ;; Pure python builtins - "abs" "all" "any" "bin" "bool" "callable" "chr" - "compile" "complex" "delattr" "dict" "dir" "divmod" "enumerate" - "eval" "float" "format" "frozenset" "getattr" "globals" "hasattr" - "hash" "help" "hex" "id" "isinstance" "issubclass" "iter" "len" - "list" "locals" "max" "memoryview" "min" "next" "object" "oct" "open" - "ord" "pow" "repr" "reversed" "round" "set" "setattr" - "sorted" "str" "sum" "super" "tuple" "type" "vars" - "ascii" "bytearray" "bytes" "exec" - "--package--" "__package__" "--import--" "__import__" - "--all--" "__all__" "--doc--" "__doc__" "--name--" "__name__") - - "Hy builtin keywords.") - -(defconst hy--kwds-constants - '("True" "False" "None" - "Ellipsis" - "NotImplemented" - "nil" ; For those that alias None as nil - ) - - "Hy constant keywords.") - -(defconst hy--kwds-exceptions - '("ArithmeticError" "AssertionError" "AttributeError" "BaseException" - "DeprecationWarning" "EOFError" "EnvironmentError" "Exception" - "FloatingPointError" "FutureWarning" "GeneratorExit" "IOError" - "ImportError" "ImportWarning" "IndexError" "KeyError" - "KeyboardInterrupt" "LookupError" "MemoryError" "NameError" - "NotImplementedError" "OSError" "OverflowError" - "PendingDeprecationWarning" "ReferenceError" "RuntimeError" - "RuntimeWarning" "StopIteration" "SyntaxError" "SyntaxWarning" - "SystemError" "SystemExit" "TypeError" "UnboundLocalError" - "UnicodeDecodeError" "UnicodeEncodeError" "UnicodeError" - "UnicodeTranslateError" "UnicodeWarning" "UserWarning" "VMSError" - "ValueError" "Warning" "WindowsError" "ZeroDivisionError" - "BufferError" "BytesWarning" "IndentationError" "ResourceWarning" "TabError") - - "Hy exception keywords.") - -(defconst hy--kwds-defs - '("defn" "defn/a" "defun" - "defmacro" "defmacro/g!" "defmacro!" - "defreader" "defsharp" "deftag" - "defmain" "defmulti" - "defmethod") - - "Hy definition keywords.") - -(defconst hy--kwds-operators - '("!=" "%" "%=" "&" "&=" "*" "**" "**=" "*=" "+" "+=" "," "-" - "-=" "/" "//" "//=" "/=" "<" "<<" "<<=" "<=" "=" ">" ">=" ">>" ">>=" - "^" "^=" "|" "|=" "~") - - "Hy operator keywords.") - -(defconst hy--kwds-special-forms - '(;; Looping - "loop" "recur" - "for" "for*" "for/a" "for/a*" - - ;; Threading - "->" "->>" "as->" - - ;; Flow control - "return" - "if" "if*" "if-not" "lif" "lif-not" - "else" "unless" "when" - "break" "continue" - "while" "cond" - "do" "progn" - - ;; Functional - "fn" "fn/a" - "yield" "yield-from" - "with" "with*" "with/a" "with/a*" - "with-gensyms" - - ;; Error Handling - "except" "try" "throw" "raise" "catch" "finally" "assert" - - ;; Special - "print" - "not" - "in" "not-in" - - ;; Misc - "global" "nonlocal" - "eval" "eval-and-compile" "eval-when-compile" - - ;; Discontinued in Master - "apply" "kwapply") - - "Hy special forms keywords.") - -;;; Font Locks -;;;; Definitions - -(defconst hy--font-lock-kwds-builtins - (list - (rx-to-string - `(: symbol-start - (or ,@hy--kwds-operators - ,@hy--kwds-builtins - ,@hy--kwds-anaphorics) - symbol-end)) - - '(0 font-lock-builtin-face)) - - "Hy builtin keywords.") - -(defconst hy--font-lock-kwds-constants - (list - (rx-to-string - `(: symbol-start - (or ,@hy--kwds-constants) - symbol-end)) - - '(0 font-lock-constant-face)) - - "Hy constant keywords.") - -(defconst hy--font-lock-kwds-defs - (list - (rx-to-string - `(: "(" - symbol-start - (group-n 1 (or ,@hy--kwds-defs)) - (1+ space) - (group-n 2 (1+ word)))) - - '(1 font-lock-keyword-face) - '(2 font-lock-function-name-face nil t)) - - "Hy definition keywords.") - -(defconst hy--font-lock-kwds-exceptions - (list - (rx-to-string - `(: symbol-start - (or ,@hy--kwds-exceptions) - symbol-end)) - - '(0 font-lock-type-face)) - - "Hy exception keywords.") - -(defconst hy--font-lock-kwds-special-forms - (list - (rx-to-string - `(: symbol-start - (or ,@hy--kwds-special-forms) - symbol-end)) - - '(0 font-lock-keyword-face)) - - "Hy special forms keywords.") - -;;;; Static - -(defconst hy--font-lock-kwds-aliases - (list - (rx (group-n 1 (or "defmacro-alias" "defn-alias" "defun-alias")) - (1+ space) - "[" - (group-n 2 (1+ anything)) - "]") - - '(1 font-lock-keyword-face) - '(2 font-lock-function-name-face nil t)) - - "Hy aliasing keywords.") - -(defconst hy--font-lock-kwds-class - (list - (rx (group-n 1 "defclass") - (1+ space) - (group-n 2 (1+ word))) - - '(1 font-lock-keyword-face) - '(2 font-lock-type-face)) - - "Hy class keywords.") - -(defconst hy--font-lock-kwds-decorators - (list - (rx - (or (: "#@" - (syntax open-parenthesis)) - (: symbol-start - "with-decorator" - symbol-end - (1+ space))) - (1+ word)) - - '(0 font-lock-type-face)) - - "Hylight the symbol after `#@' or `with-decorator' macros.") - -(defconst hy--font-lock-kwds-imports - (list - (rx symbol-start - (or "import" "require" ":as") - symbol-end) - - '(0 font-lock-keyword-face)) - - "Hy import keywords.") - -(defconst hy--font-lock-kwds-self - (list - (rx symbol-start - (group "self") - (or "." symbol-end)) - - '(1 font-lock-keyword-face)) - - "Hy self keyword.") - -(defconst hy--font-lock-kwds-tag-macros - (list - (rx "#" - (not (any "*" "@" "[")) ; #* is unpacking, #@ decorator, #[ bracket str - (0+ word)) - - '(0 font-lock-function-name-face)) - - "Hylight tag macros, ie. `#tag-macro', so they stand out.") - -;;;; Misc - -(defconst hy--font-lock-kwds-anonymous-funcs - (list - (rx symbol-start - (group "%" (1+ digit)) - (or "." symbol-end)) - - '(1 font-lock-variable-name-face)) - - "Hy '#%(print %1 %2)' styling anonymous variables.") - -(defconst hy--font-lock-kwds-func-modifiers - (list - (rx symbol-start "&" (1+ word)) - - '(0 font-lock-type-face)) - - "Hy '&rest/&kwonly/...' styling.") - -(defconst hy--font-lock-kwds-kwargs - (list - (rx symbol-start ":" (1+ word)) - - '(0 font-lock-constant-face)) - - "Hy ':kwarg' styling.") - -(defconst hy--font-lock-kwds-shebang - (list - (rx buffer-start "#!" (0+ not-newline) eol) - - '(0 font-lock-comment-face)) - - "Hy shebang line.") - -(defconst hy--font-lock-kwds-unpacking - (list - (rx (or "#*" "#**") - symbol-end) - - '(0 font-lock-keyword-face)) - - "Hy #* arg and #** kwarg unpacking keywords.") - -(defconst hy--font-lock-kwds-variables - (list - (rx symbol-start - "setv" - symbol-end - (1+ space) - (group (1+ word))) - - '(1 font-lock-variable-name-face)) - - "Hylight variable names in setv/def, only first name.") - -;;;; Advanced Keywords - -(defconst hy--tag-comment-prefix-rgx - (rx "#_" (* " ") (group-n 1 (not (any " ")))) - "The regex to match #_ tag comment prefixes.") - -(defun hy--search-comment-macro (limit) - "Search for a comment forward stopping at LIMIT." - (-when-let* ((_ (re-search-forward hy--tag-comment-prefix-rgx limit t)) - (md (match-data)) - (start (match-beginning 1)) - (state (syntax-ppss start))) - (if (hy--in-string-or-comment? state) - (hy--search-comment-macro limit) - (goto-char start) - (forward-sexp) - (setf (elt md 3) (point)) - (set-match-data md) - t))) - -(defconst hy--font-lock-kwds-tag-comment-prefix - (list 'hy--search-comment-macro - - '(1 font-lock-comment-face t)) - "Support for higlighting #_(form) the form as a comment.") - -;;;; Grouped - -(defconst hy-font-lock-kwds - (list hy--font-lock-kwds-aliases - hy--font-lock-kwds-builtins - hy--font-lock-kwds-class - hy--font-lock-kwds-constants - hy--font-lock-kwds-defs - hy--font-lock-kwds-decorators - hy--font-lock-kwds-exceptions - hy--font-lock-kwds-func-modifiers - hy--font-lock-kwds-imports - hy--font-lock-kwds-kwargs - hy--font-lock-kwds-self - hy--font-lock-kwds-shebang - hy--font-lock-kwds-special-forms - hy--font-lock-kwds-tag-macros - hy--font-lock-kwds-unpacking - hy--font-lock-kwds-variables - - ;; Advanced kwds - hy--font-lock-kwds-tag-comment-prefix - - ;; Optional kwds - (when hy-font-lock-highlight-percent-args? - hy--font-lock-kwds-anonymous-funcs)) - - "All Hy font lock keywords.") - -;;; Utilities -;;;; Sexp Navigation - -;; Aliases for `parse-partial-sexp' value -(defun hy--sexp-inermost-char (state) - (nth 1 state)) -(defun hy--start-of-last-sexp (state) - (nth 2 state)) -(defun hy--in-string? (state) - (nth 3 state)) -(defun hy--in-string-or-comment? (state) - (or (nth 3 state) (nth 4 state))) -(defun hy--start-of-string (state) - (nth 8 state)) -(defun hy--prior-sexp? (state) - (number-or-marker-p (hy--start-of-last-sexp state))) - -;;;; General purpose - -(defun hy--str-or-nil (text) - "If TEXT is non-blank, return TEXT else nil." - (and (not (s-blank? text)) text)) - -(defun hy--str-or-empty (text) - "Return TEXT or the empty string it TEXT is nil." - (if text text "")) - -(defun hy--current-form-string () - "Get form containing current point as string plus a trailing newline." - (save-excursion - (-when-let* ((state (syntax-ppss)) - (start-pos (hy--sexp-inermost-char state))) - (goto-char start-pos) - (while (ignore-errors (forward-sexp))) - - (concat (buffer-substring-no-properties start-pos (point)) "\n")))) - -(defun hy--last-sexp-string () - "Get form containing last s-exp point as string plus a trailing newline." - (save-excursion - (-when-let* ((state (syntax-ppss)) - (start-pos (hy--start-of-last-sexp state))) - (goto-char start-pos) - (while (ignore-errors (forward-sexp))) - - (concat (buffer-substring-no-properties start-pos (point)) "\n")))) - -;;; Indentation -;;;; Utilities - -(defun hy--anything-before? (pos) - "Determine if chars before POS in current line." - (s-matches? (rx (not blank)) - (buffer-substring (line-beginning-position) pos))) - -(defun hy--anything-after? (pos) - "Determine if POS is before line-end-position." - (when pos - (< pos (line-end-position)))) - -(defun hy--check-non-symbol-sexp (pos) - "Check for a non-symbol yet symbol-like (tuple constructor comma) at POS." - (and (member (char-after pos) '(?\, ?\|)) - (char-equal (char-after (1+ pos)) ?\s))) - -;;;; Normal Indent - -(defun hy--normal-indent (last-sexp) - "Determine normal indentation column of LAST-SEXP. - -Example: - (a (b c d - e - f)) - -1. Indent e => start at d -> c -> b. -Then backwards-sexp will throw error trying to jump to a. -Observe 'a' need not be on the same line as the ( will cause a match. -Then we determine indentation based on whether there is an arg or not. - -2. Indenting f will go to e. -Now since there is a prior sexp d but we have no sexps-before on same line, -the loop will terminate without error and the prior lines indentation is it." - (goto-char last-sexp) - (-let [last-sexp-start nil] - (if (ignore-errors - (while (hy--anything-before? (point)) - (setq last-sexp-start (prog1 - ;; Indentation should ignore quote chars - (cond - ((-contains? '(?\' ?\` ?\~ ?\#) - (char-before)) - (1- (point))) - - ((and (eq ?\@ (char-before)) - (save-excursion - (forward-char -1) - (eq ?\~ (char-before)))) - (- (point) 2)) - - (t (point))) - - (backward-sexp)))) - t) - (current-column) - (if (not (hy--anything-after? last-sexp-start)) - (1+ (current-column)) - (goto-char last-sexp-start) ; Align with function argument - (current-column))))) - -;;;; Function or form - -(defun hy--not-function-form-p () - "Non-nil if form at point doesn't represent a function call." - (or (-contains? '(?\[ ?\{) (char-after)) - (not (looking-at (rx anything ; Skips form opener - (or (syntax symbol) (syntax word))))))) - -;;;; Hy find indent spec - -(defun hy--find-indent-spec (state) - "Return integer for special indentation of form or nil to use normal indent. - -Note that `hy--not-function-form-p' filters out forms that are lists and dicts. -Point is always at the start of a function." - (-when-let - (function (and (hy--prior-sexp? state) - (thing-at-point 'symbol))) - - (or (-contains? (plist-get hy-indent-special-forms :exact) - function) - (-some (-cut s-matches? <> function) - (plist-get hy-indent-special-forms :fuzzy))))) - -;;;; Hy indent function - -(defun hy-indent-function (indent-point state) - "Indent at INDENT-POINT where STATE is `parse-partial-sexp' for INDENT-POINT." - (goto-char (hy--sexp-inermost-char state)) - - (if (hy--not-function-form-p) - (1+ (current-column)) ; Indent after [, {, ... is always 1 - (forward-char 1) ; Move to start of sexp - - (cond ((hy--check-non-symbol-sexp (point)) ; Comma tuple constructor - (+ 2 (current-column))) - - ((hy--find-indent-spec state) ; Special form uses fixed indendation - (1+ (current-column))) - - (t - (hy--normal-indent calculate-lisp-indent-last-sexp))))) - -;;; Bracket String Literals - -(defun hy--match-bracket-string (limit) - "Search forward for a bracket string literal." - (re-search-forward - (rx "#[" - (0+ not-newline) - "[" - (group (1+ (not (any "]")))) - "]" - (0+ not-newline) - "]") - limit - t)) - -(defun hy-syntax-propertize-function (start end) - "Implements context sensitive syntax highlighting beyond `font-lock-keywords'. - -In particular this implements bracket string literals. -START and END are the limits with which to search for bracket strings passed -and determined by `font-lock-mode' internals when making an edit to a buffer." - (save-excursion - (goto-char start) - - ;; Start goes to current line, need to go to start of #[[ block - (when (nth 1 (syntax-ppss)) ; when inermost-char go to [ => [ => # - (goto-char (- (hy--sexp-inermost-char (syntax-ppss)) 2))) - - (while (hy--match-bracket-string end) - (put-text-property (1- (match-beginning 1)) (match-beginning 1) - 'syntax-table (string-to-syntax "|")) - - (put-text-property (match-end 1) (1+ (match-end 1)) - 'syntax-table (string-to-syntax "|"))))) - -;;; Font Lock Syntactics - -(defun hy--string-in-doc-position? (state) - "Is STATE within a docstring?" - (if (= 1 (hy--start-of-string state)) ; Identify module docstring - t - (-when-let* ((first-sexp (hy--sexp-inermost-char state)) - (function (save-excursion - (goto-char (1+ first-sexp)) - (thing-at-point 'symbol)))) - (and (s-matches? (rx "def" (not blank)) function) - (not (s-matches? (rx "defmethod") function)))))) - -(defun hy-font-lock-syntactic-face-function (state) - "Return syntactic face function for the position represented by STATE. -STATE is a `parse-partial-sexp' state, and the returned function is the -Lisp font lock syntactic face function. String is shorthand for either -a string or comment." - (if (hy--in-string? state) - (if (hy--string-in-doc-position? state) - font-lock-doc-face - font-lock-string-face) - font-lock-comment-face)) - -;;; Shell Integration -;;;; Configuration - -(defconst hy-shell-buffer-name "Hy" - "Default buffer name for Hy interpreter.") - -(defconst hy-shell-internal-buffer-name "Hy Internal" - "Default buffer name for the internal Hy process.") - -(defvar hy-shell-buffer nil - "The current shell buffer for Hy.") - -(defvar hy-shell-internal-buffer nil - "The current internal shell buffer for Hy.") - -(defvar hy--shell-output-filter-in-progress nil - "Whether we are waiting for output in `hy-shell-send-string-no-output'.") - -(defvar hy--shell-font-lock-enable t - "Whether the shell should font-lock the current line.") - -(defconst hy--shell-spy-delim-uuid "#cbb4fcbe-b6ba-4812-afa3-4a5ac7b20501" - "UUID denoting end of python block in `--spy --control-categories' output") - -;;;; Shell buffer utilities - -(defun hy-installed? () - "Is the `hy-shell-interpreter' command available?" - (when (executable-find hy-shell-interpreter) t)) - -(defun hy--shell-format-process-name (proc-name) - "Format a PROC-NAME with closing astericks." - (->> proc-name (s-prepend "*") (s-append "*"))) - -(defun hy-shell-get-process (&optional internal) - "Get process corr. to `hy-shell-buffer-name'/`hy-shell-internal-buffer-name'." - (-> (if internal hy-shell-internal-buffer-name hy-shell-buffer-name) - hy--shell-format-process-name - get-buffer-process)) - -(defun hy--shell-current-buffer-process () - "Get process associated with current buffer." - (get-buffer-process (current-buffer))) - -(defun hy--shell-current-buffer-a-process? () - "Is `current-buffer' a live process?" - (process-live-p (hy--shell-current-buffer-process))) - -(defun hy--shell-get-or-create-buffer () - "Get or create `hy-shell-buffer' buffer for current hy shell process." - (if hy-shell-buffer - hy-shell-buffer - (hy--shell-with-shell-buffer - (-let [proc-name - (process-name (hy--shell-current-buffer-process))] - (generate-new-buffer proc-name))))) - -(defun hy--shell-buffer? (&optional internal) - "Is `hy-shell-buffer'/`hy-shell-internal-buffer' set and does it exist?" - (-let [buffer - (if internal hy-shell-internal-buffer hy-shell-buffer)] - (and buffer - (buffer-live-p buffer)))) - -(defun hy--shell-kill-buffer (&optional internal) - "Kill `hy-shell-buffer'/`hy-shell-internal-buffer'." - (-let [buffer - (if internal hy-shell-internal-buffer hy-shell-buffer)] - (when (hy--shell-buffer? internal) - (kill-buffer buffer) - (when (derived-mode-p 'inferior-hy-mode) - (setf buffer nil))))) - -(defun hy-shell-kill () - "Kill all hy processes." - (hy--shell-kill-buffer) - (hy--shell-kill-buffer 'internal)) - -;;;; Shell macros - -(defmacro hy--shell-with-shell-buffer (&rest forms) - "Execute FORMS in the shell buffer." - (-let [shell-process - (gensym)] - `(-let [,shell-process - (hy-shell-get-process)] - (with-current-buffer (process-buffer ,shell-process) - ,@forms)))) - -(defmacro hy--shell-with-font-locked-shell-buffer (&rest forms) - "Execute FORMS in the shell buffer with font-lock turned on." - `(hy--shell-with-shell-buffer - (save-current-buffer - (unless (hy--shell-buffer?) - (setq hy-shell-buffer (hy--shell-get-or-create-buffer))) - (set-buffer hy-shell-buffer) - - (unless (font-lock-mode) (font-lock-mode 1)) - (unless (derived-mode-p 'hy-mode) (hy-mode)) - - ,@forms))) - -;;;; Font locking - -(defun hy--shell-faces-to-font-lock-faces (text &optional start-pos) - "Set all 'face in TEXT to 'font-lock-face optionally starting at START-POS." - (let ((pos 0) - (start-pos (or start-pos 0))) - (while (and (/= pos (length text)) - (setq next (next-single-property-change pos 'face text))) - (-let* ((plist (text-properties-at pos text)) - ((&plist 'face face) plist)) - (set-text-properties (+ start-pos pos) (+ start-pos next) - (-doto plist - (plist-put 'face nil) - (plist-put 'font-lock-face face))) - (setq pos next))))) - -(defun hy--shell-fontify-prompt-post-command-hook () - "Fontify just the current line in `hy-shell-buffer' for `post-command-hook'. - -Constantly extracts current prompt text and executes and manages applying -`hy--shell-faces-to-font-lock-faces' to the text." - (-when-let* (((_ . prompt-end) comint-last-prompt) - (_ (and prompt-end - (> (point) prompt-end) ; new command is being entered - (hy--shell-current-buffer-a-process?)))) ; process alive? - (let* ((input (buffer-substring-no-properties prompt-end (point-max))) - (deactivate-mark nil) - (buffer-undo-list t) - (font-lock-buffer-pos nil) - (text (hy--shell-with-font-locked-shell-buffer - (delete-region (line-beginning-position) (point-max)) - (setq font-lock-buffer-pos (point)) - (insert input) - (font-lock-ensure) - (buffer-substring font-lock-buffer-pos (point-max))))) - (hy--shell-faces-to-font-lock-faces text prompt-end)))) - -(defun hy--shell-font-lock-turn-on () - "Turn on fontification of current line for hy shell." - (hy--shell-with-shell-buffer - (hy--shell-kill-buffer) - - ;; Required - I don't understand why killing doesn't capture the end nil setq - (setq-local hy-shell-buffer nil) - - (add-hook 'post-command-hook - 'hy--shell-fontify-prompt-post-command-hook nil 'local) - (add-hook 'kill-buffer-hook - 'hy--shell-kill-buffer nil 'local))) - -(defun hy--shell-font-lock-spy-output (string) - "Applies font-locking to hy outputted python blocks when `--spy' is enabled." - (with-temp-buffer - (if (s-contains? hy--shell-spy-delim-uuid string) - (-let ((python-indent-guess-indent-offset - nil) - ((python-block hy-output) - (s-split hy--shell-spy-delim-uuid string))) - (python-mode) - (insert python-block) - (font-lock-default-fontify-buffer) - (-> (buffer-string) - hy--shell-faces-to-font-lock-faces - s-chomp - (s-concat hy-shell-spy-delim hy-output))) - string))) - -;;;; Send strings - -(defun hy--shell-end-of-output? (string) - "Return non-nil if STRING ends with the prompt." - (s-matches? comint-prompt-regexp string)) - -(defun hy--shell-output-filter (string) - "If STRING ends with input prompt then set filter in progress done." - (when (hy--shell-end-of-output? string) - (setq hy--shell-output-filter-in-progress nil)) - "\n=> ") - -(defun hy--shell-send-string (string &optional process internal) - "Internal implementation of shell send string functionality." - (let ((process (or process - (hy-shell-get-process internal))) - (hy--shell-output-filter-in-progress t)) - - (->> string (s-append "\n") (comint-send-string process)) - - (while hy--shell-output-filter-in-progress - (accept-process-output process)))) - -(defun hy-shell-send-string-no-output (string &optional process internal) - "Send STRING to hy PROCESS and inhibit printing output." - (-let [comint-preoutput-filter-functions - '(hy--shell-output-filter)] - (hy--shell-send-string string process internal))) - -(defun hy-shell-send-string-internal (string) - "Send STRING to internal hy shell process." - (hy-shell-send-string-no-output string nil 'internal)) - -(defun hy--shell-send-internal-setup-code () - "Send setup code for autocompletion and eldoc to hy internal process." - (hy-shell-send-string-internal (concat hy-eldoc-setup-code - hy-company-setup-code))) - -(defun hy-shell-send-string (string &optional process) - "Send STRING to hy PROCESS." - (-let [comint-output-filter-functions - '(hy--shell-output-filter)] - (hy--shell-send-string string process))) - -(defun hy--shell-send-async (string) - "Send STRING to internal hy process asynchronously." - (let ((output-buffer " *Comint Hy Redirect Work Buffer*") - (proc (hy-shell-get-process 'internal))) - (with-current-buffer (get-buffer-create output-buffer) - (erase-buffer) - (comint-redirect-send-command-to-process string output-buffer proc nil t) - - (set-buffer (process-buffer proc)) - (while (and (null comint-redirect-completed) - (accept-process-output proc nil 100 t))) - (set-buffer output-buffer) - (buffer-string)))) - -;;;; Update internal process - -(defun hy--shell-update-imports () - "Send imports/requires to the current internal process. - -This is currently done manually as I'm not sure of the consequences of doing -so automatically through eg. regular intervals. Sending the imports allows -Eldoc to function (and will allow autocompletion once modules are completed). - -Right now the keybinding is not publically exposed." - (interactive) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward (rx "(" (0+ space) - (or "import" "require" "sys.path.extend")) - nil t) - (hy-shell-send-string-internal (hy--current-form-string))))) - -;;;; Shell creation - -(defun hy--shell-calculate-interpreter-args () - "Calculate `hy-shell-interpreter-args' based on `--spy' flag." - (if (and hy-shell-use-control-codes? - (s-contains? "--spy" hy-shell-interpreter-args)) - (s-concat hy-shell-interpreter-args " --control-codes") - hy-shell-interpreter-args)) - -(defun hy--shell-calculate-command (&optional internal) - "Calculate the string used to execute the inferior Hy process." - (format "%s %s" - (shell-quote-argument hy-shell-interpreter) - (if internal - "" - (hy--shell-calculate-interpreter-args)))) - -(defun hy--shell-make-comint (cmd proc-name &optional show internal) - "Create and return comint process PROC-NAME with CMD, opt. INTERNAL and SHOW." - (-when-let* ((proc-buffer-name - (hy--shell-format-process-name proc-name)) - (_ - (not (comint-check-proc proc-buffer-name))) - (cmdlist - (split-string-and-unquote cmd)) - (buffer - (apply 'make-comint-in-buffer proc-name proc-buffer-name - (car cmdlist) nil (cdr cmdlist))) - (process - (get-buffer-process buffer))) - (with-current-buffer buffer - (unless (derived-mode-p 'inferior-hy-mode) - (inferior-hy-mode))) - (when show - (display-buffer buffer)) - (if internal - (progn - (set-process-query-on-exit-flag process nil) - (setq hy-shell-internal-buffer buffer)) - (setq hy-shell-buffer buffer)) - proc-buffer-name)) - -;;;; Run Shell - -(defun run-hy-internal () - "Start an inferior hy process in the background for autocompletion." - (interactive) - (unless (hy-installed?) - (message "Hy not found, activate a virtual environment containing Hy to use -Eldoc, Anaconda, and other hy-mode features.")) - - (when (and (not (hy-shell-get-process 'internal)) - (hy-installed?)) - (-let [hy--shell-font-lock-enable - nil] - (prog1 - (-> (hy--shell-calculate-command 'internal) - (hy--shell-make-comint hy-shell-internal-buffer-name nil 'internal) - get-buffer-process) - (hy--shell-send-internal-setup-code) - (message "Hy internal process successfully started"))))) - -(defun run-hy (&optional cmd) - "Run an inferior Hy process. - -CMD defaults to the result of `hy--shell-calculate-command'." - (interactive) - (unless (hy-installed?) - (message "Hy not found, activate a virtual environment with Hy.")) - - (-> (or cmd (hy--shell-calculate-command)) - (hy--shell-make-comint hy-shell-buffer-name 'show) - get-buffer-process)) - -;;; Eldoc -;;;; Setup Code - -(defconst hy-eldoc-setup-code - "(import builtins) -(import inspect) -(import [hy.macros [-hy-macros]]) - -(defn --HYDOC-format-argspec [argspec] - \"Lispy version of format argspec covering all defun kwords.\" - (setv docs \"\") - - (defmacro add-docs [&rest forms] - `(do (when docs (setv docs (+ docs \" \"))) - (setv docs (+ docs ~@forms)))) - - (defn format-args [&rest args] - (->> args - (map (fn [x] (-> x str (.replace \"_\" \"-\")))) - (.join \" \"))) - - (setv args argspec.args) - (setv defaults argspec.defaults) - (setv varargs argspec.varargs) - (setv varkw argspec.varkw) - (setv kwonlyargs argspec.kwonlyargs) - (setv kwonlydefaults argspec.kwonlydefaults) - - (when (and args defaults) - (setv args (-> argspec.defaults - len - (drop-last argspec.args) - list)) - (setv defaults (-> args - len - (drop argspec.args) - list))) - - (when (and kwonlyargs kwonlydefaults) - (setv kwonlyargs (->> kwonlyargs - (remove (fn [x] (in x (.keys kwonlydefaults)))) - list)) - (setv kwonlydefaults (->> kwonlydefaults - (.items) - (*map (fn [k v] (.format \"[{} {}]\" k v))) - list))) - - (when args - (add-docs (format-args #* args))) - (when defaults - (add-docs \"&optional \" - (format-args #* defaults))) - (when varargs - (add-docs \"&rest \" - (format-args varargs))) - (when varkw - (add-docs \"&kwargs \" - (format-args varkw))) - (when kwonlyargs - (add-docs \"&kwonly \" - (format-args #* kwonlyargs))) - (when kwonlydefaults - (add-docs (if-not kwonlyargs \"&kwonly \" \"\") - (format-args #* kwonlydefaults))) - - docs) - -(defn --HYDOC-format-eldoc-string [obj-name f &optional full] - \"Format an obj name for callable f.\" - (if f.--doc-- - (.format \"{obj}: ({args}){docs}\" - :obj (.replace obj-name \"_\" \"-\") - :args (--HYDOC-format-argspec (inspect.getfullargspec f)) - :docs (if full - (->> f.--doc-- (.splitlines) (.join \"\n\") (+ \"\n\")) - (+ \" - \" (->> f.--doc-- (.splitlines) first)))) - (.format \"{obj}: ({args})\" - :obj (.replace obj-name \"_\" \"-\") - :args (--HYDOC-format-argspec (inspect.getfullargspec f))))) - -(defn --HYDOC-python-eldoc [obj &optional full] - \"Build eldoc string for python obj or string. - -Not all defuns can be argspeced - eg. C defuns.\" - (try - (do (when (isinstance obj str) - (setv obj (.eval builtins obj (globals)))) - (setv full-doc (.getdoc inspect obj)) - (setv doc full-doc) - (try - (setv doc (--HYDOC-format-eldoc-string obj.--name-- obj - :full full)) - (except [e TypeError] - (setv doc (->> doc (.splitlines) first (+ \"builtin: \"))) - (when full - (setv doc (+ doc \"\n\" - (->> full-doc (.splitlines) rest (.join \"\")))))))) - (except [e Exception] - (setv doc \"\"))) - doc) - -(defn --HYDOC-macro-eldoc [obj &optional full] - \"Get eldoc string for a macro.\" - (try - (do (setv obj (.replace obj \"-\" \"_\")) - (setv macros (get -hy-macros None)) - - (when (in obj macros) - (--HYDOC-format-eldoc-string obj (get macros obj) :full full))) - (except [e Exception] \"\"))) - -(defn --HYDOC [obj &optional full] - \"Get eldoc string for any obj.\" - (setv doc (--HYDOC-python-eldoc obj :full full)) - (unless doc (setv doc (--HYDOC-macro-eldoc obj :full full))) - doc)" - "Symbol introspection code to send to the internal process for eldoc.") - -;;;; Utilities - -(defun hy--eldoc-chomp-output (text) - "Chomp prefixes and suffixes from eldoc process output." - (->> text - (s-chop-suffixes '("\n=> " "=> " "\n")) - (s-chop-prefixes '("\"" "'" "\"'" "'\"")) - (s-chop-suffixes '("\"" "'" "\"'" "'\"")))) - -(defun hy--eldoc-remove-syntax-errors (text) - "Quick fix to address parsing an incomplete dot-dsl." - (if (< 1 (-> text s-lines length)) - "" - text)) - -(defun hy--eldoc-send (string) - "Send STRING for eldoc to internal process returning output." - (-> string - hy--shell-send-async - hy--eldoc-chomp-output - hy--eldoc-remove-syntax-errors - hy--str-or-nil)) - -(defun hy--eldoc-format-command (symbol &optional full raw) - "Inspect SYMBOL with hydoc, optionally include FULL docs for a buffer." - (format "(try (--HYDOC %s :full %s) (except [e Exception] (str)))" - (if raw symbol (s-concat "\"" symbol "\"")) - (if full "True" "False"))) - -(defun hy--eldoc-get-inner-symbol () - "Traverse and inspect innermost sexp and return formatted string for eldoc." - (save-excursion - (-when-let (function - (and (hy-shell-get-process 'internal) - (-some-> (syntax-ppss) hy--sexp-inermost-char goto-char) - (not (hy--not-function-form-p)) - (progn (forward-char) (thing-at-point 'symbol)))) - - ;; Attribute method call (eg. ".format str") needs following sexp - (if (and (s-starts-with? "." function) - (ignore-errors (forward-sexp) (forward-char) t)) - (pcase (char-after) - ;; Can't send just .method to eldoc - ((or ?\) ?\s ?\C-j) nil) - - ;; Dot dsl doesn't work on literals - (?\[ (concat "list" function)) - (?\{ (concat "dict" function)) - (?\" (concat "str" function)) - - ;; Otherwise complete the dot dsl - (_ (progn - (forward-char) - (concat (thing-at-point 'symbol) function)))) - function)))) - -(defun hy--fontify-text (text regexp &rest faces) - "Fontify portions of TEXT matching REGEXP with FACES." - (when text - (-each - (s-matched-positions-all regexp text) - (-lambda ((beg . end)) - (--each faces - (add-face-text-property beg end it nil text)))))) - -(defun hy--eldoc-fontify-text (text) - "Fontify eldoc TEXT." - (let ((kwd-rx - (rx string-start (1+ (not (any space ":"))) ":")) - (kwargs-rx - (rx symbol-start "&" (1+ word))) - (quoted-args-rx - (rx "`" (1+ (not space)) "`"))) - (hy--fontify-text - text kwd-rx 'font-lock-keyword-face) - (hy--fontify-text - text kwargs-rx 'font-lock-type-face) - (hy--fontify-text - text quoted-args-rx 'font-lock-constant-face 'bold-italic)) - text) - -;;;; Documentation Functions - -(defun hy--eldoc-get-docs (obj &optional full) - "Get eldoc or optionally buffer-formatted docs for `obj'." - (when obj - (hy--eldoc-fontify-text - (or (-> obj (hy--eldoc-format-command full) hy--eldoc-send) - (-> obj (hy--eldoc-format-command full t) hy--eldoc-send))))) - -(defun hy-eldoc-documentation-function () - "Drives `eldoc-mode', retrieves eldoc msg string for inner-most symbol." - (-> (hy--eldoc-get-inner-symbol) - hy--eldoc-get-docs)) - -;;; Describe thing at point - -(defun hy--docs-for-thing-at-point () - "Mirrors `hy-eldoc-documentation-function' formatted for a buffer, not a msg." - (-> (thing-at-point 'symbol) - (hy--eldoc-get-docs t) - hy--format-docs-for-buffer)) - -(defun hy--format-docs-for-buffer (text) - "Format raw hydoc TEXT for inserting into hyconda buffer." - (-let [kwarg-newline-regexp - (rx "," - (1+ (not (any "," ")"))) - (group-n 1 "\\\n") - (1+ (not (any "," ")"))))] - (-some--> text - (s-replace "\\n" "\n" it) - (replace-regexp-in-string kwarg-newline-regexp - "newline" it nil t 1)))) - -(defun hy-describe-thing-at-point () - "Implement shift-k docs lookup for `spacemacs/evil-smart-doc-lookup'." - (interactive) - (-when-let* ((text (hy--docs-for-thing-at-point)) - (doc-buffer "*Hyconda*")) - (with-current-buffer (get-buffer-create doc-buffer) - (erase-buffer) - (switch-to-buffer-other-window doc-buffer) - - (insert text) - (goto-char (point-min)) - (forward-line) - - (insert "------\n") - (fill-region (point) (point-max)) - - ;; Eventually make hyconda-view-minor-mode, atm this is sufficient - (local-set-key "q" 'quit-window) - (when (fboundp 'evil-local-set-key) - (evil-local-set-key 'normal "q" 'quit-window))))) - -;;; Autocompletion - -(defconst hy-company-setup-code - "(import builtins) -(import hy) -(try - (import [hy.lex.parser [hy-symbol-unmangle hy-symbol-mangle]]) - (except [e ImportError] - (import [hy.lex.parser [unmangle :as hy-symbol-unmangle - mangle :as hy-symbol-mangle]]))) -(try - (import [hy.compiler [-compile-table]]) - (except [e ImportError] - (import [hy.compiler [-special-form-compilers :as -compile-table]]))) - -(import [hy.macros [-hy-macros]]) -(import [hy.core.shadow [*]]) -(import [hy.core.language [*]]) - -(defn --HYCOMPANY-get-obj [text] - (when (in \".\" text) - (.join \".\" (-> text (.split \".\") butlast)))) - -(defn --HYCOMPANY-get-attr [text] - (if (in \".\" text) - (-> text (.split \".\") last) - text)) - -(defn --HYCOMPANY-get-obj-candidates [obj] - (try - (->> obj builtins.eval dir (map hy-symbol-unmangle) list) - (except [e Exception] - []))) - -(defn --HYCOMPANY-get-macros [] - \"Extract macro names from all namespaces and compile-table symbols.\" - (->> -hy-macros - (.values) - (map dict.keys) - (chain -compile-table) - flatten - (map --HYCOMPANY-get-name) - (map hy-symbol-unmangle) - distinct - list)) - -(defn --HYCOMPANY-get-global-candidates [] - (->> (globals) - (.keys) - (map hy-symbol-unmangle) - (chain (--HYCOMPANY-get-macros)) - flatten - distinct - list)) - -(defn --HYCOMPANY-get-name [x] - \"Return the candidate name for x.\" - (if (isinstance x str) - x - x.--name--)) - -(defn --HYCOMPANY-trim-candidates [candidates attr] - \"Limit list of candidates to those starting with attr.\" - (list (filter (fn [cand] (.startswith cand attr)) candidates))) - -(defn --HYCOMPANY [text] - (setv obj (--HYCOMPANY-get-obj text)) - (setv attr (--HYCOMPANY-get-attr text)) - - (if obj - (setv candidates (--HYCOMPANY-get-obj-candidates obj)) - (setv candidates (--HYCOMPANY-get-global-candidates))) - - (setv choices (--HYCOMPANY-trim-candidates candidates attr)) - - (if obj - (list (map (fn [x] (+ obj \".\" x)) - choices)) - choices)) - -(defn --HYANNOTATE-search-builtins [text] - (setv text (hy-symbol-mangle text)) - (try - (do (setv obj (builtins.eval text)) - (setv obj-name obj.--class--.--name--) - (cond [(in obj-name [\"function\" \"builtin_function_or_method\"]) - \"def\"] - [(= obj-name \"type\") - \"class\"] - [(= obj-name \"module\") - \"module\"] - [True \"instance\"])) - (except [e Exception] - None))) - -(defn --HYANNOTATE-search-compiler [text] - (in text -compile-table)) - -(defn --HYANNOTATE-search-shadows [text] - (->> hy.core.shadow - dir - (map hy-symbol-unmangle) - (in text))) - -(defn --HYANNOTATE-search-macros [text] - (setv text (hy-symbol-mangle text)) - (for [macro-dict (.values -hy-macros)] - (when (in text macro-dict) - (return (get macro-dict text)))) - None) - -(defn --HYANNOTATE [x] - ;; only builtins format on case basis - (setv annotation (--HYANNOTATE-search-builtins x)) - (when (and (not annotation) (--HYANNOTATE-search-shadows x)) - (setv annotation \"shadowed\")) - (when (and (not annotation) (--HYANNOTATE-search-compiler x)) - (setv annotation \"compiler\")) - (when (and (not annotation) (--HYANNOTATE-search-macros x)) - (setv annotation \"macro\")) - - (if annotation - (.format \"<{} {}>\" annotation x) - \"\"))" - "Autocompletion setup code to send to the internal process.") - -(defconst hy--company-regexp - (rx "'" - (group (1+ (not (any ",]")))) - "'" - (any "," "]")) - "Regex to extra candidates from --HYCOMPANY.") - -(defun hy--company-format-str (string) - "Format STRING to send to hy for completion candidates." - (-some->> string (format "(--HYCOMPANY \"%s\")" ))) - -(defun hy--company-format-annotate-str (string) - "Format STRING to send to hy for its annotation." - (-some->> string (format "(--HYANNOTATE \"%s\")"))) - -(defun hy--company-annotate (candidate) - "Get company annotation for CANDIDATE string." - (-some->> candidate - hy--company-format-annotate-str - hy--shell-send-async - s-chomp - (s-chop-prefix "'") - (s-chop-suffix "'"))) - -(defun hy--company-candidates (string) - "Get candidates for completion of STRING." - (unless (s-starts-with? "." string) - (-some->> string - hy--company-format-str - hy--shell-send-async - (s-match-strings-all hy--company-regexp) - (-select-column 1)))) - -(defun company-hy (command &optional arg &rest ignored) - (interactive (list 'interactive)) - (cl-case command - (prefix (company-grab-symbol)) - (candidates (hy--company-candidates arg)) - (annotation (hy--company-annotate arg)) - (meta (-> arg hy--eldoc-get-docs hy--str-or-empty)))) - -;;; Keybindings - -;;;###autoload -(defun hy-insert-pdb () - "Import and set pdb trace at point." - (interactive) - (insert "(do (import pdb) (pdb.set-trace))")) - -;;;###autoload -(defun hy-insert-pdb-threaded () - "Import and set pdb trace at point for a threading macro." - (interactive) - (insert "((fn [x] (import pdb) (pdb.set-trace) x))")) - -;;;###autoload -(defun hy-shell-start-or-switch-to-shell () - (interactive) - (if (and (hy--shell-buffer?) (get-buffer-process hy-shell-buffer)) - (switch-to-buffer-other-window - (hy--shell-get-or-create-buffer)) - (run-hy))) - -;;;###autoload -(defun hy-shell-eval-buffer () - "Send the buffer to the shell, inhibiting output." - (interactive) - (-let [text - (buffer-string)] - (unless (hy--shell-buffer?) - (hy-shell-start-or-switch-to-shell)) - (hy--shell-with-shell-buffer - (hy-shell-send-string-no-output text)))) - -;;;###autoload -(defun hy-shell-eval-region () - "Send highlighted region to shell, inhibiting output." - (interactive) - (when (and (region-active-p) - (not (region-noncontiguous-p))) - (-let [text - (buffer-substring (region-beginning) (region-end))] - (unless (hy--shell-buffer?) - (hy-shell-start-or-switch-to-shell)) - (hy--shell-with-shell-buffer - (hy-shell-send-string-no-output text))))) - -;;;###autoload -(defun hy-shell-eval-current-form () - "Send form containing current point to shell." - (interactive) - (-when-let (text (hy--current-form-string)) - (unless (hy--shell-buffer?) - (hy-shell-start-or-switch-to-shell)) - (hy--shell-with-shell-buffer - (hy-shell-send-string text)))) - -;;;###autoload -(defun hy-shell-eval-last-sexp () - "Send form containing the last s-expression to shell." - (interactive) - (-when-let (text (hy--last-sexp-string)) - (unless (hy--shell-buffer?) - (hy-shell-start-or-switch-to-shell)) - (hy--shell-with-shell-buffer - (hy-shell-send-string text)))) - -;;; hy-mode and inferior-hy-mode -;;;; Hy-mode setup - -(defun hy--mode-setup-eldoc () - (make-local-variable 'eldoc-documentation-function) - (setq-local eldoc-documentation-function 'hy-eldoc-documentation-function) - (eldoc-mode +1)) - -(defun hy--mode-setup-font-lock () - (setq-local font-lock-multiline t) - (setq font-lock-defaults - '(hy-font-lock-kwds - nil nil - (("+-*/.<>=!?$%_&~^:@" . "w")) ; syntax alist - nil - (font-lock-mark-block-function . mark-defun) - (font-lock-syntactic-face-function ; Differentiates (doc)strings - . hy-font-lock-syntactic-face-function)))) - -(defun hy--mode-setup-inferior () - ;; (add-to-list 'company-backends 'company-hy) - (setenv "PYTHONIOENCODING" "UTF-8") - - (run-hy-internal) - (add-hook 'pyvenv-post-activate-hooks 'run-hy-internal nil t)) - -(defun hy--mode-setup-syntax () - ;; Bracket string literals require context sensitive highlighting - (setq-local syntax-propertize-function 'hy-syntax-propertize-function) - - ;; AutoHighlightSymbol needs adjustment for symbol recognition - (setq-local ahs-include "^[0-9A-Za-z/_.,:;*+=&%|$#@!^?-~\-]+$") - - ;; Lispy comment syntax - (setq-local comment-start ";") - (setq-local comment-start-skip - "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") - (setq-local comment-add 1) - - ;; Lispy indent with hy-specialized indentation - (setq-local indent-tabs-mode nil) - (setq-local indent-line-function 'lisp-indent-line) - (setq-local lisp-indent-function 'hy-indent-function)) - -(defun hy--mode-setup-smartparens () - "Setup smartparens, if active, pairs for Hy." - (when (fboundp 'sp-local-pair) - (sp-local-pair '(hy-mode) "`" "`" :actions nil) - (sp-local-pair '(hy-mode) "'" "'" :actions nil) - (sp-local-pair '(inferior-hy-mode) "`" "" :actions nil) - (sp-local-pair '(inferior-hy-mode) "'" "" :actions nil))) - -;;;; Inferior-hy-mode setup - -(defun hy--inferior-mode-setup () - ;; Comint config - (setq mode-line-process '(":%s")) - (setq-local indent-tabs-mode nil) - (setq-local comint-prompt-read-only t) - (setq-local comint-prompt-regexp (rx bol "=>" space)) - - ;; Highlight errors according to colorama python package - (ansi-color-for-comint-mode-on) - (setq-local comint-output-filter-functions '(ansi-color-process-output)) - - ;; Don't startup font lock for internal processes - (when hy--shell-font-lock-enable - (if (fboundp 'xterm-color-filter) - (setq-local comint-preoutput-filter-functions - `(xterm-color-filter hy--shell-font-lock-spy-output)) - (setq-local comint-preoutput-filter-functions - `(hy--shell-font-lock-spy-output))) - (hy--shell-font-lock-turn-on)) - - ;; Fixes issue with "=>", no side effects from this advice - (advice-add 'comint-previous-input :before - (lambda (&rest args) (setq-local comint-stored-incomplete-input "")))) - -;;; Core - -(add-to-list 'auto-mode-alist '("\\.hy\\'" . hy-mode)) -(add-to-list 'interpreter-mode-alist '("hy" . hy-mode)) - -;;;###autoload -(define-derived-mode inferior-hy-mode comint-mode "Inferior Hy" - "Major mode for Hy inferior process." - (hy--inferior-mode-setup)) - -;;;###autoload -(define-derived-mode hy-mode prog-mode "Hy" - "Major mode for editing Hy files." - (hy--mode-setup-eldoc) - (hy--mode-setup-font-lock) - (hy--mode-setup-inferior) - (hy--mode-setup-smartparens) - (hy--mode-setup-syntax)) - -;; Spacemacs users please see spacemacs-hy, all bindings defined there -(set-keymap-parent hy-mode-map lisp-mode-shared-map) -(define-key hy-mode-map (kbd "C-c C-z") 'hy-shell-start-or-switch-to-shell) -(define-key hy-mode-map (kbd "C-c C-b") 'hy-shell-eval-buffer) -(define-key hy-mode-map (kbd "C-c C-t") 'hy-insert-pdb) -(define-key hy-mode-map (kbd "C-c C-S-t") 'hy-insert-pdb-threaded) -(define-key hy-mode-map (kbd "C-c C-r") 'hy-shell-eval-region) -(define-key hy-mode-map (kbd "C-M-x") 'hy-shell-eval-current-form) -(define-key hy-mode-map (kbd "C-c C-e") 'hy-shell-eval-last-sexp) -(define-key inferior-hy-mode-map (kbd "C-c C-z") (lambda () - (interactive) - (other-window -1))) - -(provide 'hy-mode) - -;;; hy-mode.el ends here diff --git a/packages/hy-mode-20190620.1804.tar b/packages/hy-mode-20190620.1804.tar new file mode 100644 index 0000000..22568ac Binary files /dev/null and b/packages/hy-mode-20190620.1804.tar differ diff --git a/packages/hydra-20181110.1740.tar b/packages/hydra-20190821.939.tar similarity index 89% rename from packages/hydra-20181110.1740.tar rename to packages/hydra-20190821.939.tar index 81e848e..7f1538d 100644 Binary files a/packages/hydra-20181110.1740.tar and b/packages/hydra-20190821.939.tar differ diff --git a/packages/ibuffer-projectile-20180325.325.el b/packages/ibuffer-projectile-20181202.352.el similarity index 83% rename from packages/ibuffer-projectile-20180325.325.el rename to packages/ibuffer-projectile-20181202.352.el index 47ba274..2dd9329 100644 --- a/packages/ibuffer-projectile-20180325.325.el +++ b/packages/ibuffer-projectile-20181202.352.el @@ -3,10 +3,10 @@ ;; Copyright (C) 2011-2014 Steve Purcell ;; ;; Author: Steve Purcell -;; Keywords: themes -;; Package-Requires: ((projectile "0.11.0")) +;; Keywords: convenience +;; Package-Requires: ((projectile "0.11.0") (emacs "24")) ;; URL: http://github.com/purcell/ibuffer-projectile -;; Package-Version: 20180325.325 +;; Package-Version: 20181202.352 ;; Package-X-Original-Version: 0 ;; ;; This program is free software; you can redistribute it and/or modify @@ -45,6 +45,19 @@ ;; to programmatically obtain a list of filter groups that you can ;; combine with your own custom groups. ;; +;; To display filenames relative to the project root, use project-relative-file +;; in `ibuffer-formats', e.g.: +;; +;; (setq ibuffer-formats +;; '((mark modified read-only " " +;; (name 18 18 :left :elide) +;; " " +;; (size 9 -1 :right) +;; " " +;; (mode 16 16 :left :elide) +;; " " +;; project-relative-file))) + ;;; Code: (require 'ibuffer) @@ -111,7 +124,10 @@ If the file is not in a project, then nil is returned instead." (:description "projectile root dir" :reader (read-regexp "Filter by projectile root dir (regexp): ")) (ibuffer-awhen (ibuffer-projectile-root buf) - (equal qualifier it))) + (if (stringp qualifier) + (or (string-match-p qualifier (car it)) + (string-match-p qualifier (cdr-safe it))) + (equal qualifier it)))) ;;;###autoload (autoload 'ibuffer-make-column-project-name "ibuffer-projectile") (define-ibuffer-column project-name @@ -130,6 +146,15 @@ If the file is not in a project, then nil is returned instead." (string-lessp project1 project2) (not (null project1))))) +;;;###autoload (autoload 'ibuffer-make-column-project-relative-file "ibuffer-projectile") +(define-ibuffer-column project-relative-file + (:name "Filename") + (when buffer-file-name + (let ((root (cdr (ibuffer-projectile-root buffer)))) + (if root + (file-relative-name buffer-file-name root) + (abbreviate-file-name buffer-file-name))))) + ;;;###autoload (defun ibuffer-projectile-generate-filter-groups () "Create a set of ibuffer filter groups based on the projectile root dirs of buffers." @@ -142,7 +167,7 @@ If the file is not in a project, then nil is returned instead." ;;;###autoload (defun ibuffer-projectile-set-filter-groups () - "Set the current filter groups to filter by vc root dir." + "Set the current filter groups to filter by projectile root dir." (interactive) (setq ibuffer-filter-groups (ibuffer-projectile-generate-filter-groups)) (message "ibuffer-projectile: groups set") diff --git a/packages/idris-mode-20180922.2051.tar b/packages/idris-mode-20190427.1539.tar similarity index 96% rename from packages/idris-mode-20180922.2051.tar rename to packages/idris-mode-20190427.1539.tar index a807fbd..ea88c3a 100644 Binary files a/packages/idris-mode-20180922.2051.tar and b/packages/idris-mode-20190427.1539.tar differ diff --git a/packages/iedit-20181114.950.tar b/packages/iedit-20190419.803.tar similarity index 95% rename from packages/iedit-20181114.950.tar rename to packages/iedit-20190419.803.tar index 1386ab2..7b7257b 100644 Binary files a/packages/iedit-20181114.950.tar and b/packages/iedit-20190419.803.tar differ diff --git a/packages/ietf-docs-20190420.851.el b/packages/ietf-docs-20190420.851.el new file mode 100644 index 0000000..d218388 --- /dev/null +++ b/packages/ietf-docs-20190420.851.el @@ -0,0 +1,148 @@ +;;; ietf-docs.el --- Fetch, Cache and Load IETF documents + +;; Copyright (c) 2015 by Christian E. Hopps +;; All rights reserved. + +;; Author: Christian E. Hopps +;; Package-Version: 20190420.851 +;; Package-X-Original-Version: 1.0.0 +;; Keywords: ietf, rfc +;; URL: https://github.com/choppsv1/ietf-docs + +;; This file is NOT part of GNU Emacs. + +;;; License: + +;; Licensed under the Apache License, Version 2.0 (the "License"); +;; you may not use this file except in compliance with the License. +;; You may obtain a copy of the License at +;; +;; http://www.apache.org/licenses/LICENSE-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, +;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;; See the License for the specific language governing permissions and +;; limitations under the License. + +;;; Commentary: +;; +;; Functions supporting fetching, caching and opening the IETF +;; document referenced by the text at the point. +;; +;;; Code: + +;; Suggested binding: C-c i o +;; (global-set-key (kbd "C-c i o") 'ietf-docs-open-at-point) + +(require 'thingatpt) + +(defgroup ietf-docs nil + "Customizable variables for ietf-docs functions" + :group 'communications) + +(defcustom ietf-docs-cache-directory (expand-file-name "~/ietf-docs-cache/") + "Local directory to store downloaded IETF documents. Created if necessary." + :type 'directory + :group 'ietf-docs) + +(defcustom ietf-docs-draft-url-directory "http://tools.ietf.org/id/" + "The base URL to fetch IETF drafts from." + :type 'string + :group 'ietf-docs) + +(defcustom ietf-docs-rfc-url-directory "http://tools.ietf.org/rfc/" + "The base URL to fetch IETF RFCs from." + :type 'string + :group 'ietf-docs) + +;-------------------------------------------------- +; Define a thing-at-point for draft and RFC names. +;-------------------------------------------------- + +(defvar ietf-draft-or-rfc-regexp "\\(\\(RFC\\|rfc\\)\\(-\\| \\)?[0-9]+\\)\\|\\(draft-[-[:alnum:]]+\\(.txt\\|.html\\|.xml\\)?\\)") + +(put 'ietf-docs-name 'bounds-of-thing-at-point 'thing-at-point-bounds-of-ietf-name-at-point) +(defun thing-at-point-bounds-of-ietf-name-at-point () + (if (thing-at-point-looking-at ietf-draft-or-rfc-regexp) + (let ((beginning (match-beginning 0)) + (end (match-end 0))) + (cons beginning end)))) + +(put 'ietf-docs-name 'thing-at-point 'thing-at-point-ietf-name-at-point) +(defun thing-at-point-ietf-name-at-point () + "Return the ietf document name around or before point." + (let ((name "")) + (if (thing-at-point-looking-at ietf-draft-or-rfc-regexp) + (progn + (setq name (buffer-substring-no-properties (match-beginning 0) + (match-end 0))) + (if (string-match "\\(?:RFC\\|rfc\\)\\(?:[ ]+\\|-\\)?\\([0-9]+\\)" name) + (setq name (concat "rfc" (match-string 1 name)))) + (if (string-match "draft-\\([-[:alnum:]]+\\)\\(?:.txt\\|.html\\|.xml\\)" name) + (setq name (concat "draft-" (match-string 1 name)))) + name)))) + +(put 'ietf-docs-name 'end-op + (function (lambda () + (let ((bounds (thing-at-point-bounds-of-ietf-name-at-point))) + (if bounds + (goto-char (cdr bounds)) + (error "No IETF document name here")))))) + +(put 'ietf-docs-name 'beginning-op + (function (lambda () + (let ((bounds (thing-at-point-bounds-of-ietf-name-at-point))) + (if bounds + (goto-char (car bounds)) + (error "No IETF document name here")))))) + +(defun ietf-docs-starts-with (string prefix) + "Return t if STRING starts with PREFIX." + (let* ((l (length prefix))) + (string= (substring string 0 l) prefix))) + +(defun ietf-docs-at-point () + "Return the ietf document name at the point with .txt extension." + (let ((docname (thing-at-point 'ietf-docs-name))) + (if docname + (concat (file-name-sans-extension docname) ".txt")))) + +(defun ietf-docs-fetch-to-cache (filename &optional reload) + (let* ((pathname (concat (file-name-as-directory ietf-docs-cache-directory) (downcase filename))) + url) + (if (and (file-exists-p pathname) (not reload)) + (message "Cached path %s" pathname) + (setq filename (downcase filename)) + (make-directory ietf-docs-cache-directory t) + (if (ietf-docs-starts-with filename "rfc") + (setq url (concat ietf-docs-rfc-url-directory filename)) + (setq url (concat ietf-docs-draft-url-directory filename))) + (message url) + (url-copy-file url pathname t) + (message "Downloading %s to %s" url pathname) + pathname) + pathname)) + +;;;###autoload +(defun ietf-docs-at-point-fetch-to-cache (&optional reload) + "Load the document around the point into the cache if not + present. If prefix argument is given force cache RELOAD." + (interactive "P") + (let ((docname (ietf-docs-at-point))) + (if docname + (ietf-docs-fetch-to-cache docname reload)))) + +;;;###autoload +(defun ietf-docs-open-at-point (&optional reload) + "Open the IETF internet-draft or RFC indicated by the point in a new + buffer. RELOAD the cache if PREFIX argument is specified" + (interactive "P") + (let ((pathname (ietf-docs-at-point-fetch-to-cache reload))) + (if pathname + (find-file-read-only pathname) + (error "No IETF document name around point")))) + +(provide 'ietf-docs) + +;;; ietf-docs.el ends here diff --git a/packages/imenu-list-20180601.1402.el b/packages/imenu-list-20190115.2130.el similarity index 98% rename from packages/imenu-list-20180601.1402.el rename to packages/imenu-list-20190115.2130.el index d34c194..04a4c4d 100644 --- a/packages/imenu-list-20180601.1402.el +++ b/packages/imenu-list-20190115.2130.el @@ -4,7 +4,7 @@ ;; Author: Bar Magal (2015) ;; Version: 0.8 -;; Package-Version: 20180601.1402 +;; Package-Version: 20190115.2130 ;; Homepage: https://github.com/bmag/imenu-list ;; Package-Requires: ((cl-lib "0.5")) @@ -418,7 +418,11 @@ See `display-buffer-alist' for a description of BUFFER and ALIST." (or (get-buffer-window buffer) (let ((window (ignore-errors (split-window (frame-root-window) (imenu-list-split-size) imenu-list-position)))) (when window - (window--display-buffer buffer window 'window alist t) + ;; since Emacs 27.0.50, `window--display-buffer' doesn't take a + ;; `dedicated' argument, so instead call `set-window-dedicated-p' + ;; directly (works both on new and old Emacs versions) + (window--display-buffer buffer window 'window alist) + (set-window-dedicated-p window t) window)))) (defun imenu-list-install-display-buffer () diff --git a/packages/impatient-mode-20181002.1231.tar b/packages/impatient-mode-20181002.1231.tar index 056bb4c..376044e 100644 Binary files a/packages/impatient-mode-20181002.1231.tar and b/packages/impatient-mode-20181002.1231.tar differ diff --git a/packages/import-js-20180709.1833.el b/packages/import-js-20180709.1833.el new file mode 100644 index 0000000..3b578ef --- /dev/null +++ b/packages/import-js-20180709.1833.el @@ -0,0 +1,179 @@ +;;; import-js.el --- Import Javascript dependencies -*- lexical-binding: t; -*- +;; Copyright (C) 2015 Henric Trotzig and Kevin Kehl +;; +;; Author: Kevin Kehl +;; URL: http://github.com/Galooshi/emacs-import-js/ +;; Package-Version: 20180709.1833 +;; Package-Requires: ((grizzl "0.1.0") (emacs "24")) +;; Version: 1.0.0 +;; Keywords: javascript + +;; This file is not part of GNU Emacs. + +;;; License: + +;; Licensed under the MIT license, see: +;; http://github.com/Galooshi/emacs-import-js/blob/master/LICENSE + +;;; Commentary: + +;; Quick start: +;; run-import-js +;; +;; Bind the following commands: +;; import-js-import +;; import-js-goto +;; +;; For a detailed introduction see: +;; http://github.com/Galooshi/emacs-import-js/blob/master/README.md + +;;; Code: + +(require 'json) + +(eval-when-compile + (require 'grizzl)) + +(defvar import-js-handler nil "Current import-js output handler") +(defvar import-js-output "" "Partial import-js output") +(defvar import-js-process nil "Current import-js process") +(defvar import-js-current-project-root nil "Current project root") + +(defun import-js-check-daemon () + (unless import-js-process + (throw 'import-js-daemon "import-js-daemon not running"))) + +(defun import-js-json-encode-alist (alist) + (let ((json-encoding-pretty-print nil)) + (json-encode-alist alist))) + +(defun import-js-send-input (input-alist) + "Append the current buffer content and path to file to a data alist, and send to import-js" + (let ((input-json (import-js-json-encode-alist (append input-alist + `(("fileContent" . ,(buffer-string)) + ("pathToFile" . ,(buffer-file-name))))))) + (process-send-string import-js-process input-json) + (process-send-string import-js-process "\n"))) + +(defun import-js-locate-project-root (path) + "Find the dir containing package.json by walking up the dir tree from path" + (let ((parent-dir (file-name-directory path)) + (project-found nil)) + (while (and parent-dir (not (setf project-found (file-exists-p (concat parent-dir "package.json"))))) + (let* ((pd (file-name-directory (directory-file-name parent-dir))) + (pd-exists (not (equal pd parent-dir)))) + (setf parent-dir (if pd-exists pd nil)))) + (if project-found parent-dir "."))) + +(defun import-js-word-at-point () + "Get the module of interest" + (save-excursion + (skip-chars-backward "A-Za-z0-9:_") + (let ((beg (point)) module) + (skip-chars-forward "A-Za-z0-9:_") + (setq module (buffer-substring-no-properties beg (point))) + module))) + +(defun import-js-write-content (import-data) + "Write output data from import-js to the buffer" + (let ((file-content (cdr (assoc 'fileContent import-data)))) + (write-region file-content nil buffer-file-name)) + (revert-buffer t t t)) + +(defun import-js-add (add-alist) + "Resolves an import with multiple matches" + (import-js-send-input `(("command" . "add") + ("commandArg" . ,add-alist)))) + +(defun import-js-handle-unresolved (unresolved word) + "Map unresolved imports to a path" + (let ((paths (mapcar + (lambda (car) + (cdr (assoc 'importPath car))) + (cdr (assoc-string word unresolved))))) + (minibuffer-with-setup-hook + (lambda () (make-sparse-keymap)) + (grizzl-completing-read (format "Unresolved import (%s)" word) + (grizzl-make-index + paths + 'files + import-js-current-project-root + nil))))) + +(defun import-js-handle-data (process data) + "Handles STDOUT from node, which arrives in chunks" + (setq import-js-output (concat import-js-output data)) + (if (string-match "DAEMON active" data) + ;; Ignore the startup message + (setq import-js-output "") + (when (string-match "\n$" data) + (let ((import-data import-js-output)) + (setq import-js-output "") + (funcall import-js-handler import-data))))) + +(defun import-js-handle-imports (import-data) + "Check to see if import is unresolved. If resolved, write file. Else, prompt the user to select" + (let* ((import-alist (json-read-from-string import-data)) + (unresolved (cdr (assoc 'unresolvedImports import-alist)))) + (if unresolved + (import-js-add (mapcar + (lambda (word) + (let ((key (car word))) + (cons key (import-js-handle-unresolved unresolved key)))) + unresolved)) + (import-js-write-content import-alist)))) + +(defun import-js-handle-goto (import-data) + "Navigate to the indicated file" + (let ((goto-list (json-read-from-string import-data))) + (find-file (cdr (assoc 'goto goto-list))))) + +;;;###autoload +(defun import-js-import () + "Run import-js on a particular module" + (interactive) + (save-some-buffers) + (import-js-check-daemon) + (setq import-js-output "") + (setq import-js-handler 'import-js-handle-imports) + (import-js-send-input `(("command" . "word") + ("commandArg" . ,(import-js-word-at-point))))) + +;;;###autoload +(defun import-js-fix () + "Run import-js on an entire file, importing or fixing as necessary" + (interactive) + (save-some-buffers) + (import-js-check-daemon) + (setq import-js-output "") + (setq import-js-handler 'import-js-handle-imports) + (import-js-send-input `(("command" . "fix")))) + +;;;###autoload +(defun import-js-goto () + "Run import-js goto function, which returns a path to the specified module" + (interactive) + (import-js-check-daemon) + (setq import-js-output "") + (setq import-js-handler 'import-js-handle-goto) + (import-js-send-input `(("command" . "goto") + ("commandArg" . ,(import-js-word-at-point))))) + +;;;###autoload +(defun run-import-js () + "Start the import-js daemon" + (interactive) + (kill-import-js) + (let ((process-connection-type nil)) + (setq import-js-process (start-process "import-js" nil "importjsd" "start" (format "--parent-pid=%s" (emacs-pid)))) + (set-process-filter import-js-process 'import-js-handle-data))) + +;;;###autoload +(defun kill-import-js () + "Kill the currently running import-js daemon process" + (interactive) + (if import-js-process + (delete-process import-js-process))) + +(provide 'import-js) +;;; import-js.el ends here diff --git a/packages/importmagic-20180520.303.tar b/packages/importmagic-20180520.303.tar index 0f0b177..4f90431 100644 Binary files a/packages/importmagic-20180520.303.tar and b/packages/importmagic-20180520.303.tar differ diff --git a/packages/inf-ruby-20180521.1348.el b/packages/inf-ruby-20190609.1126.el similarity index 99% rename from packages/inf-ruby-20180521.1348.el rename to packages/inf-ruby-20190609.1126.el index 7921d99..f93ec5d 100644 --- a/packages/inf-ruby-20180521.1348.el +++ b/packages/inf-ruby-20190609.1126.el @@ -8,10 +8,10 @@ ;; Dmitry Gutov ;; Kyle Hargraves ;; URL: http://github.com/nonsequitur/inf-ruby -;; Package-Version: 20180521.1348 +;; Package-Version: 20190609.1126 ;; Created: 8 April 1998 ;; Keywords: languages ruby -;; Version: 2.5.1 +;; Version: 2.5.2 ;; 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 @@ -830,7 +830,7 @@ automatically." (with-bundler (file-exists-p "Gemfile"))) (inf-ruby-console-run (concat (when with-bundler "bundle exec ") - "rails console " + "rails console -e " env) "rails"))) diff --git a/packages/inkpot-theme-20181026.509.el b/packages/inkpot-theme-20190816.715.el similarity index 95% rename from packages/inkpot-theme-20181026.509.el rename to packages/inkpot-theme-20190816.715.el index 51a5bce..c0b158a 100644 --- a/packages/inkpot-theme-20181026.509.el +++ b/packages/inkpot-theme-20190816.715.el @@ -3,7 +3,7 @@ ;; Author: Sarah Iovan ;; Campbell Barton ;; URL: https://github.com/ideasman42/emacs-inkpot-theme -;; Package-Version: 20181026.509 +;; Package-Version: 20190816.715 ;; Version: 0.1 ;; Keywords: color, theme @@ -61,6 +61,7 @@ '(cursor ((t (:background "#8b8bff" :foreground "#cfdfef")))) '(show-paren-match ((t (:background "#4e4e8f")))) '(show-paren-match-face ((t (:background "#4e4e8f")))) + '(show-paren-match-expression ((t (:background "#2e2e3f")))) '(link ((t (:foreground "#ff8bff")))) '(link-visited ((t (:foreground "#cb6ecbv")))) ; not a vim color, just a little darker @@ -80,9 +81,10 @@ '(isearch ((t (:bold t :foreground "#303030" :background "#ad7b57")))) '(lazy-highlight ((t (:foreground "#303030" :background "#ad7b57")))) '(isearch-fail ((t (:foreground "#ffffff" :background "#ce4e4e")))) - - '(mode-line ((t (:bold t :foreground "#b9b9b9" :background "#3e3e5e")))) - '(mode-line-inactive ((t (:bold t :foreground "#708090" :background "#3e3e5e")))) + '(mode-line ((t (:bold t :foreground "#b9b9b9" :background "#3e3e5e" + :box (:line-width -1 :color "#7070a0"))))) + '(mode-line-inactive ((t (:bold t :foreground "#708090" :background "#3e3e5e" + :box (:line-width -1 :color "#7070a0"))))) '(mode-line-buffer-id ((t (:bold t :foreground "#b9b9b9" :background "#3e3e5e")))) '(minibuffer-prompt ((t (:bold t :foreground "#708090")))) '(default-italic ((t (:italic t)))) @@ -100,6 +102,16 @@ '(font-lock-type-face ((t (:foreground "#ff8bff")))) '(font-lock-variable-name-face ((t nil))) '(font-lock-warning-face ((t (:foreground "#ffffff" :background "#6e2e2e")))) + + ;; diff-mode + ;; + ;; Not from the inkpot palette, dark colors so we can see the refined colors properly. + '(diff-added ((t (:background "#163616")))) + '(diff-removed ((t (:background "#361616")))) + ;; Refine colors for emacs 27+. + '(diff-refine-added ((t (:background "#306d30")))) + '(diff-refine-removed ((t (:background "#6d3030")))) + '(w3m-anchor ((t (:foreground "#c080d0")))) '(info-xref ((t (:foreground "#409090")))) '(info-menu-star ((t (:foreground "#409090")))) diff --git a/packages/intero-20181109.1547.el b/packages/intero-20190530.1308.el similarity index 98% rename from packages/intero-20181109.1547.el rename to packages/intero-20190530.1308.el index 88fb48d..3aa0bb6 100644 --- a/packages/intero-20181109.1547.el +++ b/packages/intero-20190530.1308.el @@ -11,7 +11,7 @@ ;; Author: Chris Done ;; Maintainer: Chris Done ;; URL: https://github.com/commercialhaskell/intero -;; Package-Version: 20181109.1547 +;; Package-Version: 20190530.1308 ;; Created: 3rd June 2016 ;; Version: 0.1.13 ;; Keywords: haskell, tools @@ -73,9 +73,9 @@ (defcustom intero-package-version (cl-case system-type ;; Until is fixed: - (windows-nt "0.1.34") - (cygwin "0.1.34") - (t "0.1.34")) + (windows-nt "0.1.40") + (cygwin "0.1.40") + (t "0.1.40")) "Package version to auto-install. This version does not necessarily have to be the latest version @@ -237,15 +237,23 @@ The buffer's filename (or working directory) is checked against `intero-whitelist' and `intero-blacklist'. If both the whitelist and blacklist match, then the whitelist entry wins, and `intero-mode' is enabled." - (when (and (derived-mode-p 'haskell-mode) - (let* ((file (or (buffer-file-name) default-directory)) - (blacklisted (intero-directories-contain-file - file intero-blacklist)) - (whitelisted (intero-directories-contain-file - file intero-whitelist))) - (or whitelisted (not blacklisted)))) + (when (intero-mode-should-start-p) (intero-mode 1))) +(defun intero-mode-should-start-p () + "Predicate whether intero should start given user config. +The buffer's filename (or working directory) is checked against +`intero-whitelist' and `intero-blacklist'. If both the whitelist +and blacklist match, then the whitelist entry wins, and +`intero-mode' is enabled." + (and (derived-mode-p 'haskell-mode) + (let* ((file (or (buffer-file-name) default-directory)) + (blacklisted (intero-directories-contain-file + file intero-blacklist)) + (whitelisted (intero-directories-contain-file + file intero-whitelist))) + (or whitelisted (not blacklisted))))) + ;;;###autoload (define-globalized-minor-mode intero-global-mode intero-mode intero-mode-maybe @@ -1417,9 +1425,12 @@ stack's default)." 'face 'font-lock-comment-face)) (let* ((script-buffer (with-current-buffer (find-file-noselect (intero-make-temp-file "intero-script")) + ;; Commented out this line due to this bug: + ;; https://github.com/chrisdone/intero/issues/569 + ;; GHC 8.4.3 has some bug causing a panic on GHCi. + ;; :set -fdefer-type-errors (insert ":set prompt \"\" :set -fbyte-code -:set -fdefer-type-errors :set -fdiagnostics-color=never :set prompt \"\\4 \" ") @@ -2231,6 +2242,7 @@ Installing intero-%s for GHC %s ... (concat "intero-" intero-package-version) "--flag" "haskeline:-terminfo" "--resolver" (concat "ghc-" ghc-version) + "haskeline-0.7.5.0" "ghc-paths-0.1.0.9" "mtl-2.2.2" "network-2.7.0.0" "random-1.1" "syb-0.7")) (0 (message "Installed successfully! Starting Intero in a moment ...") @@ -2245,6 +2257,8 @@ We don't know why it failed. Please read the above output and try installing manually. If that doesn't work, report this as a problem. +Guess: You might need the \"tinfo\" package, e.g. libtinfo-dev. + WHAT TO DO NEXT If you don't want to Intero to try installing itself again for @@ -3166,10 +3180,11 @@ suggestions are available." ;; Add a note if we found a suggestion to make (when note (setf (flycheck-error-message msg) - (concat text - "\n\n" - (propertize "(Hit `C-c C-r' in the Haskell buffer to apply suggestions)" - 'face 'font-lock-warning-face))))))) + (concat text "\n\n" + (propertize + (substitute-command-keys + "(Hit `\\[intero-apply-suggestions]' in the Haskell buffer to apply suggestions)") + 'face 'font-lock-warning-face))))))) (setq intero-lighter (if (null intero-suggestions) " Intero" @@ -3486,6 +3501,7 @@ Equivalent to 'warn', but label the warning as coming from intero." (intero-help-refresh))) 'keymap (let ((map (make-sparse-keymap))) (define-key map [mouse-1] 'push-button) + (define-key map (kbd "RET") 'push-button) map)) (insert " ") (insert-text-button @@ -3493,6 +3509,7 @@ Equivalent to 'warn', but label the warning as coming from intero." 'buffer (current-buffer) 'keymap (let ((map (make-sparse-keymap))) (define-key map [mouse-1] 'push-button) + (define-key map (kbd "RET") 'push-button) map) 'action (lambda (&rest ignore) (setq intero-help-entries @@ -3504,6 +3521,7 @@ Equivalent to 'warn', but label the warning as coming from intero." 'buffer (current-buffer) 'keymap (let ((map (make-sparse-keymap))) (define-key map [mouse-1] 'push-button) + (define-key map (kbd "RET") 'push-button) map) 'action (lambda (&rest ignore) (pop intero-help-entries) diff --git a/packages/ivy-20181111.1757.tar b/packages/ivy-20190821.1017.tar similarity index 75% rename from packages/ivy-20181111.1757.tar rename to packages/ivy-20190821.1017.tar index dc12724..b78620f 100644 Binary files a/packages/ivy-20181111.1757.tar and b/packages/ivy-20190821.1017.tar differ diff --git a/packages/ivy-hydra-20180614.2200.el b/packages/ivy-hydra-20190731.1602.el similarity index 69% rename from packages/ivy-hydra-20180614.2200.el rename to packages/ivy-hydra-20190731.1602.el index 96c43f0..6ecb7b4 100644 --- a/packages/ivy-hydra-20180614.2200.el +++ b/packages/ivy-hydra-20190731.1602.el @@ -1,12 +1,12 @@ ;;; ivy-hydra.el --- Additional key bindings for Ivy -*- lexical-binding: t -*- -;; Copyright (C) 2015-2018 Free Software Foundation, Inc. +;; Copyright (C) 2015-2019 Free Software Foundation, Inc. ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/swiper -;; Package-Version: 20180614.2200 -;; Version: 0.10.0 -;; Package-Requires: ((emacs "24.1") (ivy "0.9.0") (hydra "0.13.4")) +;; Package-Version: 20190731.1602 +;; Version: 0.12.0 +;; Package-Requires: ((emacs "24.1") (ivy "0.12.0") (hydra "0.13.4")) ;; Keywords: convenience ;; This file is part of GNU Emacs. @@ -22,7 +22,7 @@ ;; GNU General Public License for more details. ;; For a full copy of the GNU General Public License -;; see . +;; see . ;;; Commentary: @@ -47,8 +47,8 @@ " ^ ^ ^ ^ ^ ^ | ^Call^ ^ ^ | ^Cancel^ | ^Options^ | Action _w_/_s_/_a_: %-14s(ivy-action-name) ^-^-^-^-^-^-+-^-^---------^-^--+-^-^------+-^-^-------+-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------- -^ ^ _k_ ^ ^ | _f_ollow occ_u_r | _i_nsert | _c_: calling %-5s(if ivy-calling \"on\" \"off\") _C_ase-fold: %-10`ivy-case-fold-search -_h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _m_: matcher %-5s(ivy--matcher-desc)^^^^^^^^^^^^ _t_runcate: %-11`truncate-lines +^ ^ _k_ ^ ^ | _f_ollow occ_U_r | _i_nsert | _c_: calling %-5s(if ivy-calling \"on\" \"off\") _C_ase-fold: %-10`ivy-case-fold-search +_h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _M_: matcher %-5s(ivy--matcher-desc)^^^^^^^^^^^^ _T_runcate: %-11`truncate-lines ^ ^ _j_ ^ ^ | _g_o ^ ^ | ^ ^ | _<_/_>_: shrink/grow^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _D_efinition of this menu " ;; arrows @@ -56,8 +56,14 @@ _h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _m_: matcher %-5s(ivy--matcher-desc) ("j" ivy-next-line) ("k" ivy-previous-line) ("l" ivy-end-of-buffer) + ;; mark + ("m" ivy-mark) + ("u" ivy-unmark) + ("DEL" ivy-unmark-backward) + ("t" ivy-toggle-marks) ;; actions ("o" keyboard-escape-quit :exit t) + ("r" ivy-dispatching-done-hydra :exit t) ("C-g" keyboard-escape-quit :exit t) ("i" nil) ("C-o" nil) @@ -67,15 +73,15 @@ _h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _m_: matcher %-5s(ivy--matcher-desc) ("g" ivy-call) ("C-m" ivy-done :exit t) ("c" ivy-toggle-calling) - ("m" ivy-rotate-preferred-builders) + ("M" ivy-rotate-preferred-builders) (">" ivy-minibuffer-grow) ("<" ivy-minibuffer-shrink) ("w" ivy-prev-action) ("s" ivy-next-action) ("a" ivy-read-action) - ("t" (setq truncate-lines (not truncate-lines))) + ("T" (setq truncate-lines (not truncate-lines))) ("C" ivy-toggle-case-fold) - ("u" ivy-occur :exit t) + ("U" ivy-occur :exit t) ("D" (ivy-exit-with-action (lambda (_) (find-function 'hydra-ivy/body))) :exit t)) @@ -83,14 +89,24 @@ _h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _m_: matcher %-5s(ivy--matcher-desc) (defvar ivy-dispatching-done-columns 2 "Number of columns to use if the hint does not fit on one line.") +(defvar ivy-dispatching-done-idle nil + "When non-nil, the hint will be delayed by this many seconds.") + +(defvar ivy-dispatching-done-hydra-exit-keys '(("M-o" nil "back") + ("C-g" nil)) + "Keys that can be used to exit `ivy-dispatching-done-hydra'.") + (defun ivy-dispatching-done-hydra () "Select one of the available actions and call `ivy-done'." (interactive) (let* ((actions (ivy-state-action ivy-last)) - (estimated-len (+ 25 (length - (mapconcat - (lambda (x) (format "[%s] %s" (nth 0 x) (nth 2 x))) - (cdr actions) ", ")))) + (extra-actions ivy-dispatching-done-hydra-exit-keys) + (doc (concat "action: " + (mapconcat + (lambda (x) (format "[%s] %s" (nth 0 x) (nth 2 x))) + (append (cdr actions) + extra-actions) ", "))) + (estimated-len (length doc)) (n-columns (if (> estimated-len (window-width)) ivy-dispatching-done-columns nil))) @@ -98,7 +114,7 @@ _h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _m_: matcher %-5s(ivy--matcher-desc) (ivy-done) (funcall (eval - `(defhydra ivy-read-action (:color teal :columns ,n-columns) + `(defhydra ivy-read-action (:color teal :columns ,n-columns :idle ,ivy-dispatching-done-idle) "action" ,@(mapcar (lambda (x) (list (nth 0 x) @@ -107,10 +123,9 @@ _h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _m_: matcher %-5s(ivy--matcher-desc) (ivy-done)) (nth 2 x))) (cdr actions)) - ("M-o" nil "back") - ("C-g" nil))))))) + ,@extra-actions)))))) -(define-key ivy-minibuffer-map (kbd "M-o") 'ivy-dispatching-done-hydra) +(setq ivy-read-action-function (lambda (_) (ivy-dispatching-done-hydra))) (provide 'ivy-hydra) diff --git a/packages/ivy-rich-20181001.1147.el b/packages/ivy-rich-20190707.107.el similarity index 66% rename from packages/ivy-rich-20181001.1147.el rename to packages/ivy-rich-20190707.107.el index 4e9cb86..37523a9 100644 --- a/packages/ivy-rich-20181001.1147.el +++ b/packages/ivy-rich-20190707.107.el @@ -4,8 +4,8 @@ ;; Author: Yevgnen Koh ;; Package-Requires: ((emacs "24.4") (ivy "0.8.0")) -;; Package-Version: 20181001.1147 -;; Version: 0.1.1 +;; Package-Version: 20190707.107 +;; Version: 0.1.3 ;; Keywords: ivy ;; This program is free software; you can redistribute it and/or modify @@ -87,7 +87,7 @@ to hold the project name." :type 'boolean) (make-obsolete-variable 'ivy-rich-switch-buffer-align-virtual-buffer obsolete-message "0.1.0") -(defcustom ivy-rich--display-transformers-list +(defcustom ivy-rich-display-transformers-list '(ivy-switch-buffer (:columns ((ivy-rich-candidate (:width 30)) @@ -98,6 +98,10 @@ to hold the project name." (ivy-rich-switch-buffer-path (:width (lambda (x) (ivy-rich-switch-buffer-shorten-path x (ivy-rich-minibuffer-width 0.3)))))) :predicate (lambda (cand) (get-buffer cand))) + counsel-find-file + (:columns + ((ivy-read-file-transformer) + (ivy-rich-counsel-find-file-truename (:face font-lock-doc-face)))) counsel-M-x (:columns ((counsel-M-x-transformer (:width 40)) @@ -113,7 +117,13 @@ to hold the project name." counsel-recentf (:columns ((ivy-rich-candidate (:width 0.8)) - (ivy-rich-file-last-modified-time (:face font-lock-comment-face))))) + (ivy-rich-file-last-modified-time (:face font-lock-comment-face)))) + package-install + (:columns + ((ivy-rich-candidate (:width 30)) + (ivy-rich-package-version (:width 16 :face font-lock-comment-face)) + (ivy-rich-package-archive-summary (:width 7 :face font-lock-builtin-face)) + (ivy-rich-package-install-summary (:face font-lock-doc-face))))) "Definitions for ivy-rich transformers. The definitions should be in the following plist format @@ -157,6 +167,11 @@ predication will not be transformed. Note that you may need to disable and enable the `ivy-rich-mode' again to make this variable take effect.") +(define-obsolete-variable-alias + 'ivy-rich--display-transformers-list + 'ivy-rich-display-transformers-list + "0.1.2" + "Used `ivy-rich-display-transformers-list' instead.") ;; Common Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defalias 'ivy-rich-candidate 'identity) @@ -258,28 +273,36 @@ or /a/…/f.el." (ivy-rich-switch-buffer-shorten-path new-file len))) file)) +(defun ivy-rich--local-values (buffer args) + (let ((buffer (get-buffer buffer))) + (if (listp args) + (mapcar #'(lambda (x) (buffer-local-value x buffer)) args) + (buffer-local-value args buffer)))) + (defun ivy-rich-switch-buffer-buffer-name (candidate) candidate) (defun ivy-rich-switch-buffer-indicators (candidate) - (with-current-buffer - (get-buffer candidate) - (let ((modified (if (and (buffer-modified-p) - (not (derived-mode-p 'dired-mode 'comint-mode 'eshell-mode)) - (ivy-rich-switch-buffer-user-buffer-p candidate)) - "*" - "")) - (readonly (if (and buffer-read-only - (ivy-rich-switch-buffer-user-buffer-p candidate)) - "!" - "")) - (process (if (get-buffer-process (current-buffer)) - "&" - "")) - (remote (if (file-remote-p (or (buffer-file-name) default-directory)) - "@" - ""))) - (format "%s%s%s%s" remote readonly modified process)))) + (let* ((buffer (get-buffer candidate)) + (process-p (get-buffer-process buffer))) + (cl-destructuring-bind + (mode filename directory read-only) + (ivy-rich--local-values candidate '(major-mode buffer-file-name default-directory buffer-read-only)) + (let ((modified (if (and (buffer-modified-p buffer) + (null process-p) + (ivy-rich-switch-buffer-user-buffer-p candidate)) + "*" + "")) + (readonly (if (and read-only (ivy-rich-switch-buffer-user-buffer-p candidate)) + "!" + "")) + (process (if process-p + "&" + "")) + (remote (if (file-remote-p (or filename directory)) + "@" + ""))) + (format "%s%s%s%s" remote readonly modified process))))) (defun ivy-rich-switch-buffer-size (candidate) (with-current-buffer @@ -291,76 +314,110 @@ or /a/…/f.el." (t (format "%d " size)))))) (defun ivy-rich-switch-buffer-major-mode (candidate) + (capitalize + (replace-regexp-in-string + "-" + " " + (replace-regexp-in-string + "-mode" + "" + (symbol-name (ivy-rich--local-values candidate 'major-mode)))))) + +(defun ivy-rich-switch-buffer-in-project-p (candidate) (with-current-buffer (get-buffer candidate) - (capitalize - (replace-regexp-in-string "-" " " (replace-regexp-in-string "-mode" "" (symbol-name major-mode)))))) - -(defun ivy-rich-switch-buffer-in-propject-p (candidate) - (with-current-buffer - (get-buffer candidate) - (and (and (bound-and-true-p projectile-mode) - (projectile-project-p)) - (not (and (file-remote-p (or (buffer-file-name) default-directory)) - (not ivy-rich-parse-remote-buffer)))))) + (unless (or (and (file-remote-p (or (buffer-file-name) default-directory)) + (not ivy-rich-parse-remote-buffer)) + ;; Workaround for `browse-url-emacs' buffers , it changes + ;; `default-directory' to "http://" (#25) + (string-match "https?:\\/\\/" default-directory)) + (cond ((bound-and-true-p projectile-mode) + (let ((project (projectile-project-name))) + (unless (string= project "-") + project))) + ((require 'project nil t) + (let ((project (project-current))) + (when project + (file-name-nondirectory + (directory-file-name + (car (project-roots project))))))))))) (defun ivy-rich-switch-buffer-project (candidate) - (with-current-buffer - (get-buffer candidate) - (if (ivy-rich-switch-buffer-in-propject-p candidate) - (if (string= (projectile-project-name) "-") - "" - (projectile-project-name)) - ""))) + (or (ivy-rich-switch-buffer-in-project-p candidate) "")) + +(defun ivy-rich--switch-buffer-root-and-filename (candidate) + (let* ((buffer (get-buffer candidate)) + (truenamep t)) + (cl-destructuring-bind + (filename directory mode) + (ivy-rich--local-values buffer '(buffer-file-name default-directory major-mode)) + ;; Only make sense when `filename' and `root' are both not `nil' + (when (and filename + directory + (if (file-remote-p filename) ivy-rich-parse-remote-buffer t) + (not (eq mode 'dired-mode)) + (ivy-rich-switch-buffer-in-project-p candidate)) + ;; Find the project root directory or `default-directory' + (setq directory (cond ((bound-and-true-p projectile-mode) + (or (ivy-rich--local-values buffer 'projectile-project-root) + (with-current-buffer buffer + (projectile-project-root)))) + ((require 'project nil t) + (with-current-buffer buffer + (setq truenamep nil) + (car (project-roots (project-current))))))) + (if truenamep + (setq filename (or (ivy-rich--local-values buffer 'buffer-file-truename) + (file-truename filename)))) + (cons (expand-file-name directory) + (expand-file-name filename)))))) (defun ivy-rich-switch-buffer-path (candidate) - (with-current-buffer - (get-buffer candidate) - (if (or (and (file-remote-p (or (buffer-file-name) default-directory)) - (not ivy-rich-parse-remote-buffer)) - ;; Workaround for `browse-url-emacs' buffers , it changes - ;; `default-directory' to "http://" (#25) - (string-match "https?:\\/\\/" default-directory)) - "" - (let* (;; Find the project root directory or `default-directory' - (root (file-truename - (if (ivy-rich-switch-buffer-in-propject-p candidate) - (projectile-project-root) - default-directory))) - ;; Find the file name or `nil' - (filename - (if (buffer-file-name) - (if (and (buffer-file-name) - (string-match "^https?:\\/\\/" (buffer-file-name)) - (not (file-exists-p (buffer-file-name)))) - nil - (file-truename (buffer-file-name))) - (if (eq major-mode 'dired-mode) - (file-truename (dired-current-directory)) - nil))) - (path (cond ((or (memq ivy-rich-path-style '(full absolute)) - (and (null ivy-rich-parse-remote-file-path) - (or (file-remote-p root)))) - (expand-file-name (or filename root))) - ((memq ivy-rich-path-style '(abbreviate abbrev)) - (abbreviate-file-name (or filename root))) - ((or (eq ivy-rich-path-style 'relative) - t) ; make 'relative default - (if (and filename root) - (substring-no-properties (string-remove-prefix root filename)) - ""))))) - path)))) + (if-let ((result (ivy-rich--switch-buffer-root-and-filename candidate))) + (cl-destructuring-bind (root . filename) result + (cond + ;; Case: absolute + ((or (memq ivy-rich-path-style '(full absolute)) + (and (null ivy-rich-parse-remote-file-path) + (or (file-remote-p root)))) + (or filename root)) + ;; Case: abbreviate + ((memq ivy-rich-path-style '(abbreviate abbrev)) + (abbreviate-file-name (or filename root))) + ;; Case: relative + ((or (eq ivy-rich-path-style 'relative) + t) ; make 'relative default + (if (and filename root) + (let ((relative-path (string-remove-prefix root filename))) + (if (string= relative-path candidate) + (file-name-as-directory + (file-name-nondirectory + (directory-file-name (file-name-directory filename)))) + relative-path)) + "")))) + "")) + + +;; Supports for `counsel-find-file' +(defun ivy-rich-counsel-find-file-truename (candidate) + (let ((type (car (file-attributes (directory-file-name (expand-file-name candidate ivy--directory)))))) + (if (stringp type) + (concat "-> " (expand-file-name type ivy--directory)) + ""))) ;; Supports for `counsel-M-x', `counsel-describe-function', `counsel-describe-variable' (defun ivy-rich-counsel-function-docstring (candidate) - (let ((doc (documentation (intern candidate)))) - (if (and doc (string-match "^\\(.+\\)\\([\r\n]\\)?" doc)) + (let ((doc (replace-regexp-in-string + ":\\(\\(before\\|after\\)\\(-\\(whilte\\|until\\)\\)?\\|around\\|override\\|\\(filter-\\(args\\|return\\)\\)\\) advice:[ ]*‘.+?’[\r\n]+" + "" + (or (ignore-errors (documentation (intern-soft candidate))) "")))) + (if (string-match "^\\(.+\\)\\([\r\n]\\)?" doc) (setq doc (match-string 1 doc)) ""))) (defun ivy-rich-counsel-variable-docstring (candidate) (let ((doc (documentation-property - (intern candidate) 'variable-documentation))) + (intern-soft candidate) 'variable-documentation))) (if (and doc (string-match "^\\(.+\\)\\([\r\n]\\)?" doc)) (setq doc (match-string 1 doc)) ""))) @@ -399,6 +456,28 @@ or /a/…/f.el." candidate) (t (file-truename filename))))))) +;; Supports for `counsel-projectile' +;; Possible setup: +;; counsel-projectile-switch-project +;; (:columns +;; ((ivy-rich-counsel-projectile-switch-project-project-name (:width 20 :face success)) +;; (ivy-rich-candidate))) +(defun ivy-rich-counsel-projectile-switch-project-project-name (candidate) + (or (projectile-project-name candidate) "")) + +;; Supports for `package-install' +(defun ivy-rich-package-install-summary (candidate) + (let ((package-desc (cadr (assoc-string candidate package-archive-contents)))) + (if package-desc (package-desc-summary package-desc) ""))) + +(defun ivy-rich-package-archive-summary (candidate) + (let ((package-arch (cadr (assoc-string candidate package-archive-contents)))) + (if package-arch (package-desc-archive package-arch) ""))) + +(defun ivy-rich-package-version (candidate) + (let ((package-vers (cadr (assoc-string candidate package-archive-contents)))) + (if package-vers (package-version-join (package-desc-version package-vers)) ""))) + ;; Definition of `ivy-rich-mode' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar ivy-rich--original-display-transformers-list nil) ; Backup list @@ -450,7 +529,7 @@ or /a/…/f.el." (ivy-rich-format candidate columns delimiter)))))) (defun ivy-rich-set-display-transformer () - (cl-loop for (cmd transformer-props) on ivy-rich--display-transformers-list by 'cddr do + (cl-loop for (cmd transformer-props) on ivy-rich-display-transformers-list by 'cddr do (let* ((cmd-string (symbol-name cmd)) (package (if (string-match "^\\(swiper\\|counsel\\)" cmd-string) (match-string 1 cmd-string)))) @@ -473,6 +552,12 @@ or /a/…/f.el." (ivy-rich-set-display-transformer)) (ivy-rich-unset-display-transformer))) +;;;###autoload +(defun ivy-rich-reload () + (when ivy-rich-mode + (ivy-rich-mode -1) + (ivy-rich-mode 1))) + (provide 'ivy-rich) ;;; ivy-rich.el ends here diff --git a/packages/ivy-xref-20180821.1211.el b/packages/ivy-xref-20190611.1305.el similarity index 84% rename from packages/ivy-xref-20180821.1211.el rename to packages/ivy-xref-20190611.1305.el index 6a0176e..ea73672 100644 --- a/packages/ivy-xref-20180821.1211.el +++ b/packages/ivy-xref-20190611.1305.el @@ -4,7 +4,7 @@ ;; Author: Alex Murray ;; URL: https://github.com/alexmurray/ivy-xref -;; Package-Version: 20180821.1211 +;; Package-Version: 20190611.1305 ;; Version: 0.1 ;; Package-Requires: ((emacs "25.1") (ivy "0.10.0")) @@ -78,14 +78,19 @@ (nreverse collection))) ;;;###autoload -(defun ivy-xref-show-xrefs (xrefs alist) - "Show the list of XREFS and ALIST via ivy." +(defun ivy-xref-show-xrefs (fetcher alist) + "Show the list of xrefs returned by FETCHER and ALIST via ivy." ;; call the original xref--show-xref-buffer so we can be used with ;; dired-do-find-regexp-and-replace etc which expects to use the normal xref ;; results buffer but then bury it and delete the window containing it ;; immediately since we don't want to see it - see ;; https://github.com/alexmurray/ivy-xref/issues/2 - (let ((buffer (xref--show-xref-buffer xrefs alist))) + (let* ((xrefs (if (functionp fetcher) + ;; Emacs 27 + (or (assoc-default 'fetched-xrefs alist) + (funcall fetcher)) + fetcher)) + (buffer (xref--show-xref-buffer fetcher alist))) (quit-window) (let ((orig-buf (current-buffer)) (orig-pos (point)) @@ -114,5 +119,17 @@ ;; return value buffer)) +;;;###autoload +(defun ivy-xref-show-defs (fetcher alist) + (let ((xrefs (funcall fetcher))) + (cond + ((not (cdr xrefs)) + (xref-pop-to-location (car xrefs) + (assoc-default 'display-action alist))) + (t + (ivy-xref-show-xrefs fetcher + (cons (cons 'fetched-xrefs xrefs) + alist)))))) + (provide 'ivy-xref) ;;; ivy-xref.el ends here diff --git a/packages/jabber-20180927.2325.tar b/packages/jabber-20180927.2325.tar index 9e3cc1c..5e6d670 100644 Binary files a/packages/jabber-20180927.2325.tar and b/packages/jabber-20180927.2325.tar differ diff --git a/packages/japanese-holidays-20160928.618.el b/packages/japanese-holidays-20190317.1220.el similarity index 89% rename from packages/japanese-holidays-20160928.618.el rename to packages/japanese-holidays-20190317.1220.el index 42f091e..3aefb27 100644 --- a/packages/japanese-holidays-20160928.618.el +++ b/packages/japanese-holidays-20190317.1220.el @@ -5,8 +5,8 @@ ;; Author: Takashi Hattori ;; Hiroya Murata ;; Created: 1999-04-20 -;; Version: 1.160928 -;; Package-Version: 20160928.618 +;; Version: 1.190317 +;; Package-Version: 20190317.1220 ;; Keywords: calendar ;; Prefix: japanese-holiday- ;; URL: https://github.com/emacs-jp/japanese-holidays @@ -174,7 +174,7 @@ (japanese-holiday-range (holiday-fixed 4 29 "ã¿ã©ã‚Šã®æ—¥") '(2 17 1989) '(1 1 2007)) (japanese-holiday-range - (holiday-fixed 12 23 "天皇誕生日") '(2 17 1989)) + (holiday-fixed 12 23 "天皇誕生日") '(2 17 1989) '(5 1 2019)) ;; 国民ã®ç¥æ—¥ã«é–¢ã™ã‚‹æ³•å¾‹ã®ä¸€éƒ¨ã‚’改正ã™ã‚‹æ³•å¾‹ (å¹³æˆ7年法律第22å·) (japanese-holiday-range (holiday-fixed 7 20 "æµ·ã®æ—¥") '(1 1 1996) '(1 1 2003)) @@ -182,10 +182,12 @@ (japanese-holiday-range (holiday-float 1 1 2 "æˆäººã®æ—¥") '(1 1 2000)) (japanese-holiday-range - (holiday-float 10 1 2 "体育ã®æ—¥") '(1 1 2000)) + (holiday-float 10 1 2 "体育ã®æ—¥") '(1 1 2000) '(1 1 2020)) ;; 国民ã®ç¥æ—¥ã«é–¢ã™ã‚‹æ³•å¾‹åŠã³è€äººç¦ç¥‰æ³•ã®ä¸€éƒ¨ã‚’改正ã™ã‚‹æ³•å¾‹ (å¹³æˆ13年法律第59å·) (japanese-holiday-range - (holiday-float 7 1 3 "æµ·ã®æ—¥") '(1 1 2003)) + (holiday-float 7 1 3 "æµ·ã®æ—¥") '(1 1 2003) '(1 1 2020)) + (japanese-holiday-range + (holiday-float 7 1 3 "æµ·ã®æ—¥") '(1 1 2021)) (japanese-holiday-range (holiday-float 9 1 3 "敬è€ã®æ—¥") '(1 1 2003)) ;; 国民ã®ç¥æ—¥ã«é–¢ã™ã‚‹æ³•å¾‹ã®ä¸€éƒ¨ã‚’改正ã™ã‚‹æ³•å¾‹ (å¹³æˆ17年法律第43å·) @@ -195,7 +197,28 @@ (holiday-fixed 5 4 "ã¿ã©ã‚Šã®æ—¥") '(1 1 2007)) ;; 国民ã®ç¥æ—¥ã«é–¢ã™ã‚‹æ³•å¾‹ã®ä¸€éƒ¨ã‚’改正ã™ã‚‹æ³•å¾‹ (å¹³æˆ26年法律第43å·) (japanese-holiday-range - (holiday-fixed 8 11 "å±±ã®æ—¥") '(1 1 2016))))) + (holiday-fixed 8 11 "å±±ã®æ—¥") '(1 1 2016) '(1 1 2020)) + (japanese-holiday-range + (holiday-fixed 8 11 "å±±ã®æ—¥") '(1 1 2021)) + ;; 天皇ã®é€€ä½ç­‰ã«é–¢ã™ã‚‹çš‡å®¤å…¸ç¯„特例法 (å¹³æˆ29年法律第63å·) + (japanese-holiday-range + (holiday-fixed 2 23 "天皇誕生日") '(5 1 2019)) + ;; 天皇ã®å³ä½ã®æ—¥åŠã³å³ä½ç¤¼æ­£æ®¿ã®å„€ã®è¡Œã‚れる日を休日ã¨ã™ã‚‹æ³•å¾‹ (å¹³æˆ30年法律第99å·) + (japanese-holiday-range + (holiday-fixed 5 1 "å³ä½ã®æ—¥") '(12 14 2018) '(1 1 2020)) + (japanese-holiday-range + (holiday-fixed 10 22 "å³ä½ç¤¼æ­£æ®¿ã®å„€") '(12 14 2018) '(1 1 2020)) + ;; å¹³æˆä¸‰å二年æ±äº¬ã‚ªãƒªãƒ³ãƒ”ック競技大会・æ±äº¬ãƒ‘ラリンピック競技大会特別措置法åŠã³ å¹³æˆä¸‰å一年ラグビーワールドカップ大会特別措置法ã®ä¸€éƒ¨ã‚’改正ã™ã‚‹æ³•å¾‹ï¼ˆå¹³æˆ30年法律第55å·ï¼‰ + (japanese-holiday-range + (holiday-fixed 7 23 "æµ·ã®æ—¥") '(1 1 2020) '(1 1 2021)) + (japanese-holiday-range + (holiday-fixed 7 24 "スãƒãƒ¼ãƒ„ã®æ—¥") '(1 1 2020) '(1 1 2021)) + (japanese-holiday-range + (holiday-fixed 8 10 "å±±ã®æ—¥") '(1 1 2020) '(1 1 2021)) + ;; 国民ã®ç¥æ—¥ã«é–¢ã™ã‚‹æ³•å¾‹ã®ä¸€éƒ¨ã‚’改正ã™ã‚‹æ³•å¾‹ï¼ˆå¹³æˆ30年法律第57å·ï¼‰ + (japanese-holiday-range + (holiday-float 10 1 2 "スãƒãƒ¼ãƒ„ã®æ—¥") '(1 1 2021)) + ))) (holiday-filter-visible-calendar '(;; 皇太å­æ˜Žä»è¦ªçŽ‹ã®çµå©šã®å„€ã®è¡Œã‚れる日を休日ã¨ã™ã‚‹æ³•å¾‹ (昭和34年法律第16å·) ((4 10 1959) "明ä»è¦ªçŽ‹ã®çµå©šã®å„€") @@ -204,7 +227,8 @@ ;; å³ä½ç¤¼æ­£æ®¿ã®å„€ã®è¡Œã‚れる日を休日ã¨ã™ã‚‹æ³•å¾‹ (å¹³æˆ2年法律第24å·) ((11 12 1990) "å³ä½ç¤¼æ­£æ®¿ã®å„€") ;; 皇太å­å¾³ä»è¦ªçŽ‹ã®çµå©šã®å„€ã®è¡Œã‚れる日を休日ã¨ã™ã‚‹æ³•å¾‹ (å¹³æˆ5年法律第32å·) - ((6 9 1993) "å¾³ä»è¦ªçŽ‹ã®çµå©šã®å„€")))) + ((6 9 1993) "å¾³ä»è¦ªçŽ‹ã®çµå©šã®å„€") + ))) "*Japanese holidays. See the documentation for `calendar-holidays' for details." :type 'sexp @@ -327,9 +351,9 @@ It can be face face, or list of faces for corresponding weekdays." curr (pop rest)) (when (= (japanese-holiday-subtract-date (car curr) (car prev)) 2) (let* ((date (japanese-holiday-add-days (car prev) 1)) - (sotable-date (japanese-holiday-make-sortable date))) + (sortable-date (japanese-holiday-make-sortable date))) (when (cond - ((>= sotable-date + ((>= sortable-date (eval-when-compile (japanese-holiday-make-sortable '(1 1 2007)))) (catch 'found @@ -339,7 +363,7 @@ It can be face face, or list of faces for corresponding weekdays." (cadr holiday)) (throw 'found nil))) t)) - ((>= sotable-date + ((>= sortable-date (eval-when-compile (japanese-holiday-make-sortable '(12 27 1985)))) (not (or (= (calendar-day-of-week date) 0) diff --git a/packages/js2-mode-20180724.801.tar b/packages/js2-mode-20190815.1327.tar similarity index 98% rename from packages/js2-mode-20180724.801.tar rename to packages/js2-mode-20190815.1327.tar index ae66014..38b5d40 100644 Binary files a/packages/js2-mode-20180724.801.tar and b/packages/js2-mode-20190815.1327.tar differ diff --git a/packages/js2-refactor-20180502.1042.tar b/packages/js2-refactor-20190630.2108.tar similarity index 96% rename from packages/js2-refactor-20180502.1042.tar rename to packages/js2-refactor-20190630.2108.tar index 60ad4b1..a7fffd0 100644 Binary files a/packages/js2-refactor-20180502.1042.tar and b/packages/js2-refactor-20190630.2108.tar differ diff --git a/packages/json-mode-20180718.809.el b/packages/json-mode-20190123.422.el similarity index 98% rename from packages/json-mode-20180718.809.el rename to packages/json-mode-20190123.422.el index 0c600a3..cbc2d51 100644 --- a/packages/json-mode-20180718.809.el +++ b/packages/json-mode-20190123.422.el @@ -4,7 +4,7 @@ ;; Author: Josh Johnston ;; URL: https://github.com/joshwnj/json-mode -;; Package-Version: 20180718.809 +;; Package-Version: 20190123.422 ;; Version: 1.6.0 ;; Package-Requires: ((json-reformat "0.0.5") (json-snatcher "1.0.0")) @@ -122,7 +122,8 @@ This function calls `json-mode--update-auto-mode' to change the (set (make-local-variable 'font-lock-defaults) '(json-font-lock-keywords-1 t))) ;; Well formatted JSON files almost always begin with “{†or “[â€. -(add-to-list 'magic-mode-alist '("^[{[]$" . json-mode)) +;;;###autoload +(add-to-list 'magic-fallback-mode-alist '("^[{[]$" . json-mode)) ;;;###autoload (defun json-mode-show-path () diff --git a/packages/json-navigator-20171220.819.el b/packages/json-navigator-20190131.1031.el similarity index 95% rename from packages/json-navigator-20171220.819.el rename to packages/json-navigator-20190131.1031.el index cb86365..a55a1ef 100644 --- a/packages/json-navigator-20171220.819.el +++ b/packages/json-navigator-20190131.1031.el @@ -1,11 +1,11 @@ ;;; json-navigator.el --- View and navigate JSON structures -;; Copyright (C) 2017 Damien Cassou +;; Copyright (C) 2017-2019 Damien Cassou ;; Author: Damien Cassou ;; URL: https://github.com/DamienCassou/json-navigator -;; Package-Version: 20171220.819 -;; Version: 0.1.0 +;; Package-Version: 20190131.1031 +;; Version: 0.1.1 ;; Package-Requires: ((emacs "24.3") (hierarchy "0.6.0")) ;; This file is not part of GNU Emacs. @@ -183,8 +183,13 @@ instead of a full one." ;;;###autoload (defun json-navigator-navigate-region (&optional start end) "Navigate JSON inside region between START and END. -If START (respectively END) is nil, use `point-min' (respectively `point-max') instead." - (interactive "r") +If START (respectively END) is nil, use `point-min' (respectively +`point-max') instead. + +Interactively, if no region is active, use the whole buffer instead." + (interactive (if (use-region-p) + (list (region-beginning) (region-end)) + (list))) (let ((start (or start (point-min))) (end (or end (point-max)))) (json-navigator-display-tree (json-navigator--read-region start end)))) diff --git a/packages/jsonnet-mode-20180822.1619.el b/packages/jsonnet-mode-20181211.1853.el similarity index 99% rename from packages/jsonnet-mode-20180822.1619.el rename to packages/jsonnet-mode-20181211.1853.el index 1b7029b..043dbf4 100644 --- a/packages/jsonnet-mode-20180822.1619.el +++ b/packages/jsonnet-mode-20181211.1853.el @@ -4,7 +4,7 @@ ;; Author: Nick Lanham ;; URL: https://github.com/mgyucht/jsonnet-mode -;; Package-Version: 20180822.1619 +;; Package-Version: 20181211.1853 ;; Package-X-Original-Version: 0.0.1 ;; Keywords: languages ;; Package-Requires: ((emacs "24")) @@ -153,7 +153,7 @@ If not inside of a multiline string, return nil." ;; Experimental algorithm (defun jsonnet--indent-in-parens () "Compute the indent of the current line, given it is inside parentheses." - (if (jsonnet--line-matches-regex-p "^\s*)") 0 4)) + (if (jsonnet--line-matches-regex-p "^\s*)") 0 2)) (defun jsonnet--indent-in-braces () "Compute the indent of the current line, given it is inside braces." diff --git a/packages/julia-mode-20180816.2117.el b/packages/julia-mode-20180816.2117.el deleted file mode 100644 index 4551dd1..0000000 --- a/packages/julia-mode-20180816.2117.el +++ /dev/null @@ -1,3302 +0,0 @@ -;;; julia-mode.el --- Major mode for editing Julia source code - -;; Copyright (C) 2009-2014 Julia contributors -;; URL: https://github.com/JuliaLang/julia -;; Package-Version: 20180816.2117 -;; Version: 0.3 -;; Keywords: languages - -;;; Usage: -;; Put the following code in your .emacs, site-load.el, or other relevant file -;; (add-to-list 'load-path "path-to-julia-mode") -;; (require 'julia-mode) - -;;; Commentary: -;; This is the official Emacs mode for editing Julia programs. - -;;; License: -;; Permission is hereby granted, free of charge, to any person obtaining -;; a copy of this software and associated documentation files (the -;; "Software"), to deal in the Software without restriction, including -;; without limitation the rights to use, copy, modify, merge, publish, -;; distribute, sublicense, and/or sell copies of the Software, and to -;; permit persons to whom the Software is furnished to do so, subject to -;; the following conditions: -;; -;; The above copyright notice and this permission notice shall be -;; included in all copies or substantial portions of the Software. -;; -;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -;; LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -;; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -;; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -;;; Code: - -;; We can't use cl-lib whilst supporting Emacs 23 users who don't use -;; ELPA. -(with-no-warnings - (require 'cl)) ;; incf, decf, plusp - -(defvar julia-mode-hook nil) - -(defgroup julia () - "Major mode for the julia programming language." - :group 'languages - :prefix "julia-") - -(defcustom julia-indent-offset 4 - "Number of spaces per indentation level." - :type 'integer - :group 'julia) - -(defface julia-macro-face - '((t :inherit font-lock-preprocessor-face)) - "Face for Julia macro invocations." - :group 'julia-mode) - -(defface julia-quoted-symbol-face - '((t :inherit font-lock-preprocessor-face)) - "Face for quoted Julia symbols, e.g. :foo." - :group 'julia-mode) - - -;;;###autoload -(add-to-list 'auto-mode-alist '("\\.jl\\'" . julia-mode)) - -;; define ignore-errors macro if it isn't present -;; (necessary for emacs 22 compatibility) -(when (not (fboundp 'ignore-errors)) - (defmacro ignore-errors (body) `(condition-case nil ,body (error nil)))) - -(defun julia--regexp-opt (strings &optional paren) - "Emacs 23 provides `regexp-opt', but it does not support PAREN taking the value 'symbols. -This function provides equivalent functionality, but makes no efforts to optimise the regexp." - (cond - ((>= emacs-major-version 24) - (regexp-opt strings paren)) - ((not (eq paren 'symbols)) - (regexp-opt strings paren)) - ((null strings) - "") - ('t - (rx-to-string `(seq symbol-start (or ,@strings) symbol-end))))) - -(defvar julia-mode-syntax-table - (let ((table (make-syntax-table))) - (modify-syntax-entry ?_ "_" table) - (modify-syntax-entry ?@ "_" table) - (modify-syntax-entry ?! "_" table) - (modify-syntax-entry ?# "< 14" table) ; # single-line and multiline start - (modify-syntax-entry ?= ". 23bn" table) - (modify-syntax-entry ?\n ">" table) ; \n single-line comment end - (modify-syntax-entry ?\{ "(} " table) - (modify-syntax-entry ?\} "){ " table) - (modify-syntax-entry ?\[ "(] " table) - (modify-syntax-entry ?\] ")[ " table) - (modify-syntax-entry ?\( "() " table) - (modify-syntax-entry ?\) ")( " table) - ;; Here, we treat ' as punctuation (when it's used for transpose), - ;; see our use of `julia-char-regex' for handling ' as a character - ;; delimiter - (modify-syntax-entry ?' "." table) - (modify-syntax-entry ?\" "\"" table) - (modify-syntax-entry ?` "\"" table) - (modify-syntax-entry ?\\ "\\" table) - - (modify-syntax-entry ?. "." table) - (modify-syntax-entry ?? "." table) - (modify-syntax-entry ?$ "." table) - (modify-syntax-entry ?& "." table) - (modify-syntax-entry ?* "." table) - (modify-syntax-entry ?/ "." table) - (modify-syntax-entry ?+ "." table) - (modify-syntax-entry ?- "." table) - (modify-syntax-entry ?< "." table) - (modify-syntax-entry ?> "." table) - (modify-syntax-entry ?% "." table) - table) - "Syntax table for `julia-mode'.") - -(eval-when-compile - (defconst julia-char-regex - (rx (or (any "-" ";" "\\" "^" "!" "|" "?" "*" "<" "%" "," "=" ">" "+" "/" "&" "$" "~" ":") - (syntax open-parenthesis) - (syntax whitespace) - bol) - (group "'") - (group - (or (repeat 0 8 (not (any "'"))) (not (any "\\")) - "\\\\")) - (group "'")))) - -(defconst julia-hanging-operator-regexp - ;; taken from julia-parser.scm - (concat "^[^#\n]+ " - (regexp-opt - '( ;; conditional - "?" - ;; assignment - "=" ":=" "+=" "-=" "*=" "/=" "//=" ".//=" ".*=" "./=" "\\=" ".\\=" - "^=" ".^=" "÷=" ".÷=" "%=" ".%=" "|=" "&=" "$=" "=>" "<<=" ">>=" - ">>>=" "~" ".+=" ".-=" - ;; arrow - "--" "-->" "â†" "→" "↔" "↚" "↛" "↠" "↣" "↦" "↮" "⇎" "â‡" "⇒" "⇔" "⇴" - "⇶" "⇷" "⇸" "⇹" "⇺" "⇻" "⇼" "⇽" "⇾" "⇿" "⟵" "⟶" "⟷" "⟷" "⟹" - "⟺" "⟻" "⟼" "⟽" "⟾" "⟿" "⤀" "â¤" "⤂" "⤃" "⤄" "⤅" "⤆" "⤇" "⤌" - "â¤" "⤎" "â¤" "â¤" "⤑" "⤔" "⤕" "⤖" "⤗" "⤘" "â¤" "⤞" "⤟" "⤠" "⥄" "⥅" - "⥆" "⥇" "⥈" "⥊" "⥋" "⥎" "â¥" "⥒" "⥓" "⥖" "⥗" "⥚" "⥛" "⥞" "⥟" "⥢" - "⥤" "⥦" "⥧" "⥨" "⥩" "⥪" "⥫" "⥬" "⥭" "⥰" "⧴" "⬱" "⬰" "⬲" "⬳" "⬴" - "⬵" "⬶" "⬷" "⬸" "⬹" "⬺" "⬻" "⬼" "⬽" "⬾" "⬿" "â­€" "â­" "â­‚" "â­ƒ" "â­„" - "â­‡" "â­ˆ" "â­‰" "â­Š" "â­‹" "â­Œ" "ï¿©" "ï¿«" - ;; or and and - "&&" "||" - ;; comparison - ">" "<" ">=" "≥" "<=" "≤" "==" "===" "≡" "!=" "≠" "!==" "≢" ".>" - ".<" ".>=" ".≥" ".<=" ".≤" ".==" ".!=" ".≠" ".=" ".!" "<:" ">:" "∈" - "∉" "∋" "∌" "⊆" "⊈" "⊂" "⊄" "⊊" "âˆ" "∊" "âˆ" "∥" "∦" "∷" "∺" "∻" "∽" - "∾" "â‰" "≃" "≄" "≅" "≆" "≇" "≈" "≉" "≊" "≋" "≌" "â‰" "≎" "â‰" "≑" "≒" - "≓" "≔" "≕" "≖" "≗" "≘" "≙" "≚" "≛" "≜" "â‰" "≞" "≟" "≣" "≦" "≧" "≨" - "≩" "≪" "≫" "≬" "≭" "≮" "≯" "≰" "≱" "≲" "≳" "≴" "≵" "≶" "≷" "≸" "≹" - "≺" "≻" "≼" "≽" "≾" "≿" "⊀" "âŠ" "⊃" "⊅" "⊇" "⊉" "⊋" "âŠ" "âŠ" "⊑" "⊒" - "⊜" "⊩" "⊬" "⊮" "⊰" "⊱" "⊲" "⊳" "⊴" "⊵" "⊶" "⊷" "â‹" "â‹" "â‹‘" "â‹•" "â‹–" - "â‹—" "⋘" "â‹™" "â‹š" "â‹›" "â‹œ" "â‹" "â‹ž" "â‹Ÿ" "â‹ " "â‹¡" "â‹¢" "â‹£" "⋤" "â‹¥" "⋦" "⋧" - "⋨" "â‹©" "⋪" "â‹«" "⋬" "â‹­" "⋲" "⋳" "â‹´" "⋵" "⋶" "â‹·" "⋸" "⋹" "⋺" "â‹»" "⋼" - "⋽" "⋾" "â‹¿" "⟈" "⟉" "⟒" "⦷" "⧀" "â§" "⧡" "⧣" "⧤" "⧥" "⩦" "⩧" "⩪" "â©«" - "⩬" "â©­" "â©®" "⩯" "â©°" "⩱" "⩲" "⩳" "â©´" "⩵" "⩶" "â©·" "⩸" "⩹" "⩺" "â©»" "⩼" - "⩽" "⩾" "â©¿" "⪀" "âª" "⪂" "⪃" "⪄" "⪅" "⪆" "⪇" "⪈" "⪉" "⪊" "⪋" "⪌" "âª" - "⪎" "âª" "âª" "⪑" "⪒" "⪓" "⪔" "⪕" "⪖" "⪗" "⪘" "⪙" "⪚" "⪛" "⪜" "âª" "⪞" - "⪟" "⪠" "⪡" "⪢" "⪣" "⪤" "⪥" "⪦" "⪧" "⪨" "⪩" "⪪" "⪫" "⪬" "⪭" "⪮" "⪯" - "⪰" "⪱" "⪲" "⪳" "⪴" "⪵" "⪶" "⪷" "⪸" "⪹" "⪺" "⪻" "⪼" "⪽" "⪾" "⪿" "â«€" - "â«" "â«‚" "⫃" "â«„" "â«…" "⫆" "⫇" "⫈" "⫉" "â«Š" "â«‹" "â«Œ" "â«" "â«Ž" "â«" "â«" "â«‘" - "â«’" "â«“" "â«”" "â«•" "â«–" "â«—" "⫘" "â«™" "â«·" "⫸" "⫹" "⫺" "⊢" "⊣" - ;; pipe, colon - "|>" "<|" ":" ".." - ;; plus - "+" "-" "⊕" "⊖" "⊞" "⊟" ".+" ".-" "++" "|" "∪" "∨" "$" "⊔" "±" "∓" - "∔" "∸" "≂" "â‰" "⊎" "⊻" "⊽" "â‹Ž" "â‹“" "⧺" "⧻" "⨈" "⨢" "⨣" "⨤" "⨥" "⨦" - "⨧" "⨨" "⨩" "⨪" "⨫" "⨬" "⨭" "⨮" "⨹" "⨺" "â©" "â©‚" "â©…" "â©Š" "â©Œ" "â©" "â©" - "â©’" "â©”" "â©–" "â©—" "â©›" "â©" "â©¡" "â©¢" "â©£" - ;; bitshift - "<<" ">>" ">>>" ".<<" ".>>" ".>>>" - ;; times - "*" "/" "./" "÷" ".÷" "%" "â‹…" "∘" "×" ".%" ".*" "\\" - ".\\" "&" "∩" "∧" "⊗" "⊘" "⊙" "⊚" "⊛" "⊠" "⊡" "⊓" "∗" "∙" "∤" "â…‹" - "≀" "⊼" "â‹„" "⋆" "⋇" "⋉" "â‹Š" "â‹‹" "â‹Œ" "â‹" "â‹’" "⟑" "⦸" "⦼" "⦾" "⦿" "⧶" - "⧷" "⨇" "⨰" "⨱" "⨲" "⨳" "⨴" "⨵" "⨶" "⨷" "⨸" "⨻" "⨼" "⨽" "â©€" "⩃" "â©„" - "â©‹" "â©" "â©Ž" "â©‘" "â©“" "â©•" "⩘" "â©š" "â©œ" "â©ž" "â©Ÿ" "â© " "â«›" "âŠ" "â–·" "â¨" "⟕" - "⟖" "⟗" - ;; rational - "//" ".//" - ;; power - "^" ".^" "↑" "↓" "⇵" "⟰" "⟱" "⤈" "⤉" "⤊" "⤋" "⤒" "⤓" "⥉" "⥌" "â¥" - "â¥" "⥑" "⥔" "⥕" "⥘" "⥙" "⥜" "â¥" "⥠" "⥡" "⥣" "⥥" "⥮" "⥯" "↑" "↓" - ;; decl, dot - "::" ".")) - (regexp-opt '(" #" " \n" "#" "\n")))) - -(defconst julia-triple-quoted-string-regex - ;; We deliberately put a group on the first and last delimiter, so - ;; we can mark these as string delimiters for font-lock. - (rx (group "\"") - (group "\"\"" - ;; After the delimiter, we're a sequence of - ;; non-backslashes or blackslashes paired with something. - (*? (or (not (any "\\")) - (seq "\\" anything))) - "\"\"") - (group "\""))) - -(defconst julia-unquote-regex - "\\(\\s(\\|\\s-\\|-\\|[,%=<>\\+*/?&|!\\^~\\\\;:]\\|^\\)\\($[a-zA-Z0-9_]+\\)") - -(defconst julia-forloop-in-regex - "for +.*[^ -].* \\(in\\)\\(\\s-\\|$\\)+") - -(defconst julia-function-regex - (rx line-start (* (or space "@inline" "@noinline")) symbol-start - "function" - (1+ space) - ;; Don't highlight module names in function declarations: - (* (seq (1+ (or word (syntax symbol))) ".")) - ;; The function name itself - (group (1+ (or word (syntax symbol)))))) - -(defconst julia-function-assignment-regex - (rx line-start (* (or space "@inline" "@noinline")) symbol-start - (* (seq (1+ (or word (syntax symbol))) ".")) ; module name - (group (1+ (or word (syntax symbol)))) - (? "{" (* (not (any "}"))) "}") - "(" (* (or - (seq "(" (* (not (any "(" ")"))) ")") - (not (any "(" ")")))) - ")" - (* space) - (? "::" (* space) (1+ (not (any space)))) - (* space) - (* (seq "where" (or "{" (+ space)) (+ (not (any "="))))) - "=" - (not (any "=")))) - -(defconst julia-type-regex - (rx symbol-start (or "immutable" "type" ;; remove after 0.6 - "abstract type" "primitive type" "struct" "mutable struct") - (1+ space) (group (1+ (or word (syntax symbol)))))) - -(defconst julia-type-annotation-regex - (rx "::" (0+ space) (group (1+ (or word (syntax symbol)))))) - -;;(defconst julia-type-parameter-regex -;; (rx symbol-start (1+ (or (or word (syntax symbol)) ?_)) "{" (group (1+ (or (or word (syntax symbol)) ?_))) "}")) - -(defconst julia-subtype-regex - (rx "<:" (0+ space) (group (1+ (or word (syntax symbol)))) (0+ space) (or "\n" "{" "}" "end"))) - -(defconst julia-macro-regex - (rx symbol-start (group "@" (1+ (or word (syntax symbol)))))) - -(defconst julia-keyword-regex - (julia--regexp-opt - '("if" "else" "elseif" "while" "for" "begin" "end" "quote" - "try" "catch" "return" "local" "function" "macro" "ccall" - "finally" "break" "continue" "global" "where" - "module" "using" "import" "export" "const" "let" "do" "in" - "baremodule" "importall" - "immutable" "type" "bitstype" "abstract" "typealias" ;; remove after 0.6 - "abstract type" "primitive type" "struct" "mutable struct") - 'symbols)) - -(defconst julia-builtin-regex - (julia--regexp-opt - ;;'("error" "throw") - '() - 'symbols)) - -(defconst julia-builtin-types-regex - (julia--regexp-opt - '("Number" "Real" "BigInt" "Integer" - "UInt" "UInt8" "UInt16" "UInt32" "UInt64" "UInt128" - "Int" "Int8" "Int16" "Int32" "Int64" "Int128" - "BigFloat" "AbstractFloat" "Float16" "Float32" "Float64" - "Complex128" "Complex64" - "Bool" - "Cuchar" "Cshort" "Cushort" "Cint" "Cuint" "Clonglong" "Culonglong" "Cintmax_t" "Cuintmax_t" - "Cfloat" "Cdouble" "Cptrdiff_t" "Cssize_t" "Csize_t" - "Cchar" "Clong" "Culong" "Cwchar_t" - "Char" "String" "SubString" - "Array" "DArray" "AbstractArray" "AbstractVector" "AbstractMatrix" "AbstractSparseMatrix" "SubArray" "StridedArray" "StridedVector" "StridedMatrix" "VecOrMat" "StridedVecOrMat" "DenseArray" "SparseMatrixCSC" "BitArray" - "Range" "OrdinalRange" "StepRange" "UnitRange" "FloatRange" - "Tuple" "NTuple" "Vararg" - "DataType" "Symbol" "Function" "Vector" "Matrix" "Union" "Type" "Any" "Complex" "AbstractString" "Ptr" "Void" "Exception" "Task" "Signed" "Unsigned" "Associative" "Dict" "IO" "IOStream" "Rational" "Regex" "RegexMatch" "Set" "IntSet" "Expr" "WeakRef" "ObjectIdDict" - "AbstractRNG" "MersenneTwister" - ) - 'symbols)) - -(defconst julia-quoted-symbol-regex - ;; :foo and :foo2 are valid, but :123 is not. - (rx (or bol whitespace "(" "[" "," "=") - (group ":" (or letter (syntax symbol)) (0+ (or word (syntax symbol)))))) - -(defconst julia-font-lock-keywords - (list - ;; Ensure :: and <: aren't highlighted, so we don't confuse ::Foo with :foo. - ;; (in Emacs, keywords don't overlap). - (cons (rx (or "::" "<:")) ''default) - ;; Highlight quoted symbols before keywords, so :function is not - ;; highlighted as a keyword. - (list julia-quoted-symbol-regex 1 ''julia-quoted-symbol-face) - (cons julia-builtin-types-regex 'font-lock-type-face) - (cons julia-keyword-regex 'font-lock-keyword-face) - (cons julia-macro-regex ''julia-macro-face) - (cons - (julia--regexp-opt - '("true" "false" "C_NULL" "Inf" "NaN" "Inf32" "NaN32" "nothing") - 'symbols) - 'font-lock-constant-face) - (list julia-unquote-regex 2 'font-lock-constant-face) - (list julia-forloop-in-regex 1 'font-lock-keyword-face) - (list julia-function-regex 1 'font-lock-function-name-face) - (list julia-function-assignment-regex 1 'font-lock-function-name-face) - (list julia-type-regex 1 'font-lock-type-face) - (list julia-type-annotation-regex 1 'font-lock-type-face) - ;;(list julia-type-parameter-regex 1 'font-lock-type-face) - (list julia-subtype-regex 1 'font-lock-type-face) - (list julia-builtin-regex 1 'font-lock-builtin-face) - )) - -(defconst julia-block-start-keywords - (list "if" "while" "for" "begin" "try" "function" "let" "macro" - "quote" "do" "module" - "immutable" "type" ;; remove after 0.6 - "abstract type" "primitive type" "struct" "mutable struct")) - -;; For keywords that begin a block without additional indentation -(defconst julia-block-start-keywords-no-indent - (list "module")) - -(defconst julia-block-end-keywords - (list "end" "else" "elseif" "catch" "finally")) - -(defun julia-stringify-triple-quote () - "Put `syntax-table' property on triple-quoted string delimiters. - -Based on `python-syntax-stringify'." - (let* ((string-start-pos (- (point) 3)) - (string-end-pos (point)) - (ppss (prog2 - (backward-char 3) - (syntax-ppss) - (forward-char 3))) - (in-comment (nth 4 ppss)) - (in-string (nth 8 ppss))) - (unless in-comment - (if in-string - ;; We're in a string, so this must be the closing triple-quote. - ;; Put | on the last " character. - (put-text-property (1- string-end-pos) string-end-pos - 'syntax-table (string-to-syntax "|")) - ;; We're not in a string, so this is the opening triple-quote. - ;; Put | on the first " character. - (put-text-property string-start-pos (1+ string-start-pos) - 'syntax-table (string-to-syntax "|")))))) - -(unless (< emacs-major-version 24) - (defconst julia-syntax-propertize-function - (syntax-propertize-rules - ("\"\"\"" - (0 (ignore (julia-stringify-triple-quote)))) - (julia-char-regex - (1 "\"") ; Treat ' as a string delimiter. - (2 ".") ; Don't highlight anything between. - (3 "\""))))) ; Treat the last " in """ as a string delimiter. - -(defun julia-in-comment () - "Return non-nil if point is inside a comment. -Handles both single-line and multi-line comments." - (nth 4 (syntax-ppss))) - -(defun julia-in-string () - "Return non-nil if point is inside a string. -Note this is Emacs' notion of what is highlighted as a string. -As a result, it is true inside \"foo\", `foo` and 'f'." - (nth 3 (syntax-ppss))) - -(defun julia-in-brackets () - "Return non-nil if point is inside square brackets." - (let ((start-pos (point)) - (open-count 0)) - ;; Count all the [ and ] characters on the current line. - (save-excursion - (beginning-of-line) - - (while (< (point) start-pos) - ;; Don't count [ or ] inside strings, characters or comments. - (unless (or (julia-in-string) (julia-in-comment)) - - (when (looking-at (rx "[")) - (incf open-count)) - (when (looking-at (rx "]")) - (decf open-count))) - - (forward-char 1))) - - ;; If we've opened more than we've closed, we're inside brackets. - (plusp open-count))) - -(defun julia-at-keyword (kw-list) - "Return the word at point if it matches any keyword in KW-LIST. -KW-LIST is a list of strings. The word at point is not considered -a keyword if used as a field name, X.word, or quoted, :word." - (and (or (= (point) 1) - (and (not (equal (char-before (point)) ?.)) - (not (equal (char-before (point)) ?:)))) - (not (looking-at "(")) ; handle "function(" when on ( - (member (current-word t) kw-list) - ;; 'end' is not a keyword when used for indexing, e.g. foo[end-2] - (or (not (equal (current-word t) "end")) - (not (julia-in-brackets))) - (not (julia-in-comment)))) - -;; if backward-sexp gives an error, move back 1 char to move over the '(' -(defun julia-safe-backward-sexp () - (if (condition-case nil (backward-sexp) (error t)) - (ignore-errors (backward-char)))) - -(defun julia-following-import-export-using () - "If the current line follows an `export` or `import` keyword -with valid syntax, return the position of the keyword, otherwise -`nil`. Works by stepping backwards through comma-separated -symbol, gives up when this is not true." - ;; Implementation accepts a single Module: right after the keyword, and saves - ;; the module name for future use, but does not enforce that `export` has no - ;; module name. - (let ((done nil) ; find keyword or give up - (module nil)) ; found "Module:" - (save-excursion - (beginning-of-line) - (while (and (not done) (< (point-min) (point))) - (julia-safe-backward-sexp) - (cond - ((looking-at (rx (or "import" "export" "using"))) - (setf done (point))) - ((looking-at (rx (group (* (or word (syntax symbol)))) (0+ space) ":")) - (if module - (setf done 'broken) - (setf module (match-string-no-properties 1)))) - ((looking-at (rx (* (or word (syntax symbol))) (0+ space) ",")) - (when module (setf done 'broken))) - (t (setf done 'broken))))) - (if (eq done 'broken) - nil - done))) - -(defun julia-last-open-block-pos (min) - "Return the position of the last open block, if one found. -Do not move back beyond position MIN." - (save-excursion - (let ((count 0)) - (while (not (or (> count 0) (<= (point) min))) - (julia-safe-backward-sexp) - (setq count - (cond ((julia-at-keyword julia-block-start-keywords) - (+ count 1)) - ((and (equal (current-word t) "end") - (not (julia-in-comment))) - (- count 1)) - (t count)))) - (if (> count 0) - (point) - nil)))) - -(defun julia-last-open-block (min) - "Move back and return indentation level for last open block. -Do not move back beyond MIN." - ;; Ensure MIN is not before the start of the buffer. - (setq min (max min (point-min))) - (let ((pos (julia-last-open-block-pos min))) - (and pos - (progn - (goto-char pos) - (+ julia-indent-offset (current-indentation)))))) - -(defsubst julia--safe-backward-char () - "Move back one character, but don't error if we're at the -beginning of the buffer." - (unless (eq (point) (point-min)) - (backward-char))) - -(defcustom julia-max-block-lookback 5000 - "When indenting, don't look back more than this -many characters to see if there are unclosed blocks. - -This variable has a moderate effect on indent performance if set too -high, but stops indenting in the middle of long blocks if set too low." - :type 'integer - :group 'julia) - -(defun julia-paren-indent () - "Return the column of the text following the innermost -containing paren before point, so we can align succeeding code -with it. Returns nil if we're not within nested parens." - (save-excursion - (beginning-of-line) - (let ((parser-state (syntax-ppss))) - (cond ((nth 3 parser-state) nil) ;; strings - ((= (nth 0 parser-state) 0) nil) ;; top level - (t - (ignore-errors ;; return nil if any of these movements fail - (beginning-of-line) - (skip-syntax-forward " ") - (let ((possibly-close-paren-point (point))) - (backward-up-list) - (let ((open-paren-point (point))) - (forward-char) - (skip-syntax-forward " ") - (if (eolp) - (progn - (up-list) - (backward-char) - (let ((paren-closed (= (point) possibly-close-paren-point))) - (goto-char open-paren-point) - (beginning-of-line) - (skip-syntax-forward " ") - (+ (current-column) - (if paren-closed - 0 - julia-indent-offset)))) - (current-column)))))))))) - -(defun julia-prev-line-skip-blank-or-comment () - "Move point to beginning of previous line skipping blank lines -and lines including only comments. Returns number of lines moved. -A return of -1 signals that we moved to the first line of -the (possibly narrowed) buffer, so there is nowhere else to go." - (catch 'result - (let ((moved 0) this-move) - (while t - (setq this-move (forward-line -1)) - (cond - ;; moved into comment or blank - ((and (= 0 this-move) - (or (looking-at-p "^\\s-*\\(?:#.*\\)*$") - (julia-in-comment))) - (incf moved)) - ;; success - ((= 0 this-move) - (throw 'result (1+ moved))) - ;; on first line and in comment - ((and (bobp) - (or (looking-at-p "^\\s-*\\(?:#.*\\)*$") - (julia-in-comment))) - (throw 'result -1)) - ((bobp) - (throw 'result moved)) - (t - (throw 'result 0))))))) - -(defun julia-indent-hanging () - "Calculate indentation for lines that follow \"hanging\" -operators (operators that end the previous line) as defined in -`julia-hanging-operator-regexp'. An assignment operator ending -the previous line increases the indent as do the other operators -unless another operator is found two lines up. Previous line -means previous line after skipping blank lines and lines with -only comments." - (let (prev-indent) - (save-excursion - (when (> (julia-prev-line-skip-blank-or-comment) 0) - (setq prev-indent (current-indentation)) - (when (looking-at-p julia-hanging-operator-regexp) - (if (and (> (julia-prev-line-skip-blank-or-comment) 0) - (looking-at-p julia-hanging-operator-regexp)) - ;; two preceding hanging operators => indent same as line - ;; above - prev-indent - ;; one preceding hanging operator => increase indent from line - ;; above - (+ julia-indent-offset prev-indent))))))) - -(defun julia-indent-in-string () - "Indentation inside strings with newlines is \"manual\", -meaning always increase indent on TAB and decrease on S-TAB." - (save-excursion - (beginning-of-line) - (when (julia-in-string) - (if (member this-command '(julia-latexsub-or-indent - ess-indent-or-complete)) - (+ julia-indent-offset (current-indentation)) - ;; return the current indentation to prevent other functions from - ;; indenting inside strings - (current-indentation))))) - -(defun julia-indent-import-export-using () - "Indent offset for lines that follow `import` or `export`, otherwise nil." - (when (julia-following-import-export-using) - julia-indent-offset)) - -(defun julia-indent-line () - "Indent current line of julia code." - (interactive) - (let* ((point-offset (- (current-column) (current-indentation)))) - (indent-line-to - (or - ;; note: if this first function returns nil the beginning of the line - ;; cannot be in a string - (julia-indent-in-string) - ;; If we're inside an open paren, indent to line up arguments. After this, - ;; we cannot be inside parens which includes brackets - (julia-paren-indent) - ;; indent due to hanging operators (lines ending in an operator) - (julia-indent-hanging) - ;; indent for import and export - (julia-indent-import-export-using) - ;; Indent according to how many nested blocks we are in. - (save-excursion - (beginning-of-line) - ;; jump out of any comments - (let ((state (syntax-ppss))) - (when (nth 4 state) - (goto-char (nth 8 state)))) - (forward-to-indentation 0) - (let ((endtok (julia-at-keyword julia-block-end-keywords)) - (last-open-block (julia-last-open-block (- (point) julia-max-block-lookback)))) - (max 0 (+ (or last-open-block 0) - (if (or endtok - (julia-at-keyword julia-block-start-keywords-no-indent)) - (- julia-indent-offset) 0))))))) - ;; Point is now at the beginning of indentation, restore it - ;; to its original position (relative to indentation). - (when (>= point-offset 0) - (move-to-column (+ (current-indentation) point-offset))))) - -(defalias 'julia-mode-prog-mode - (if (fboundp 'prog-mode) - 'prog-mode - 'fundamental-mode)) - -;;; IMENU -(defvar julia-imenu-generic-expression - ;; don't use syntax classes, screws egrep - '(("Function (_)" "[ \t]*function[ \t]+\\(_[^ \t\n]*\\)" 1) - ("Function" "^[ \t]*function[ \t]+\\([^_][^\t\n]*\\)" 1) - ("Const" "[ \t]*const \\([^ \t\n]*\\)" 1) - ("Type" "^[ \t]*[a-zA-Z0-9_]*type[a-zA-Z0-9_]* \\([^ \t\n]*\\)" 1) - ("Require" " *\\(\\brequire\\)(\\([^ \t\n)]*\\)" 2) - ("Include" " *\\(\\binclude\\)(\\([^ \t\n)]*\\)" 2) - ;; ("Classes" "^.*setClass(\\(.*\\)," 1) - ;; ("Coercions" "^.*setAs(\\([^,]+,[^,]*\\)," 1) ; show from and to - ;; ("Generics" "^.*setGeneric(\\([^,]*\\)," 1) - ;; ("Methods" "^.*set\\(Group\\|Replace\\)?Method(\"\\(.+\\)\"," 2) - ;; ;;[ ]*\\(signature=\\)?(\\(.*,?\\)*\\)," 1) - ;; ;; - ;; ;;("Other" "^\\(.+\\)\\s-*<-[ \t\n]*[^\\(function\\|read\\|.*data\.frame\\)]" 1) - ;; ("Package" "^.*\\(library\\|require\\)(\\(.*\\)," 2) - ;; ("Data" "^\\(.+\\)\\s-*<-[ \t\n]*\\(read\\|.*data\.frame\\).*(" 1))) - )) - -;;;###autoload -(define-derived-mode julia-mode julia-mode-prog-mode "Julia" - "Major mode for editing julia code." - (set-syntax-table julia-mode-syntax-table) - (set (make-local-variable 'comment-start) "# ") - (set (make-local-variable 'comment-start-skip) "#+\\s-*") - (set (make-local-variable 'font-lock-defaults) '(julia-font-lock-keywords)) - (if (< emacs-major-version 24) - ;; Emacs 23 doesn't have syntax-propertize-function - (set (make-local-variable 'font-lock-syntactic-keywords) - (list - `(,julia-char-regex - (1 "\"") ; Treat ' as a string delimiter. - (2 ".") ; Don't highlight anything between the open and close '. - (3 "\"")); Treat the close ' as a string delimiter. - `(,julia-triple-quoted-string-regex - (1 "\"") ; Treat the first " in """ as a string delimiter. - (2 ".") ; Don't highlight anything between. - (3 "\"")))) ; Treat the last " in """ as a string delimiter. - ;; Emacs 24 and later has syntax-propertize-function, so use that instead. - (set (make-local-variable 'syntax-propertize-function) - julia-syntax-propertize-function)) - (set (make-local-variable 'indent-line-function) 'julia-indent-line) - (setq indent-tabs-mode nil) - (setq imenu-generic-expression julia-imenu-generic-expression) - (imenu-add-to-menubar "Imenu")) - -(defun julia-manual-deindent () - "Deindent by `julia-indent-offset' regardless of current -indentation context. To be used to manually indent inside -strings." - (interactive) - (indent-line-to (max 0 (- (current-indentation) julia-indent-offset)))) -(define-key julia-mode-map (kbd "") 'julia-manual-deindent) - -(defvar julia-latexsubs (make-hash-table :test 'equal)) - -(defun julia-latexsub () - "Perform a LaTeX-like Unicode symbol substitution." - (interactive "*i") - (let ((orig-pt (point))) - (while (not (or (bobp) (= ?\\ (char-before)) - (= ?\s (char-syntax (char-before))))) - (backward-char)) - (if (and (not (bobp)) (= ?\\ (char-before))) - (progn - (backward-char) - (let ((sub (gethash (buffer-substring (point) orig-pt) julia-latexsubs))) - (if sub - (progn - (delete-region (point) orig-pt) - (insert sub)) - (goto-char orig-pt)))) - (goto-char orig-pt)))) - -(defalias 'latexsub 'julia-latexsub) - -(defun julia-latexsub-or-indent (arg) - "Either indent according to mode or perform a LaTeX-like symbol substution" - (interactive "*i") - (if (latexsub) - (indent-for-tab-command arg))) -(define-key julia-mode-map (kbd "TAB") 'julia-latexsub-or-indent) - -(defalias 'latexsub-or-indent 'julia-latexsub-or-indent) - -; LaTeX-like symbol substitutions, equivalent to those in the Julia REPL, -; generated by: -;for (k,v) in sort!(collect(Base.REPLCompletions.latex_symbols), by=x->x[2]) -; ks = escape_string(k) -; vs = escape_string(v) -; if ismatch(r"^\\U[0-9A-Fa-f]+$", vs) -; # codepoints outside the BMP can be problematic in older Emacsen -; cp = vs[3:end] -; println("(let ((c (decode-char 'ucs #x$cp)))\n", -; " (if c (puthash \"$ks\" (char-to-string c) julia-latexsubs)))") -; else -; println("(puthash \"$ks\" \"$vs\" julia-latexsubs)") -; end -;end -; (See Julia issue #8947 for why we don't use the Emacs tex input mode.) -(puthash "\\textexclamdown" "¡" julia-latexsubs) -(puthash "\\sterling" "£" julia-latexsubs) -(puthash "\\yen" "Â¥" julia-latexsubs) -(puthash "\\textbrokenbar" "¦" julia-latexsubs) -(puthash "\\S" "§" julia-latexsubs) -(puthash "\\textasciidieresis" "¨" julia-latexsubs) -(puthash "\\copyright" "©" julia-latexsubs) -(puthash "\\textordfeminine" "ª" julia-latexsubs) -(puthash "\\neg" "¬" julia-latexsubs) -(puthash "\\circledR" "®" julia-latexsubs) -(puthash "\\textasciimacron" "¯" julia-latexsubs) -(puthash "\\degree" "°" julia-latexsubs) -(puthash "\\pm" "±" julia-latexsubs) -(puthash "\\^2" "²" julia-latexsubs) -(puthash "\\^3" "³" julia-latexsubs) -(puthash "\\textasciiacute" "´" julia-latexsubs) -(puthash "\\P" "¶" julia-latexsubs) -(puthash "\\cdotp" "·" julia-latexsubs) -(puthash "\\^1" "¹" julia-latexsubs) -(puthash "\\textordmasculine" "º" julia-latexsubs) -(puthash "\\textonequarter" "¼" julia-latexsubs) -(puthash "\\textonehalf" "½" julia-latexsubs) -(puthash "\\textthreequarters" "¾" julia-latexsubs) -(puthash "\\textquestiondown" "¿" julia-latexsubs) -(puthash "\\AA" "Ã…" julia-latexsubs) -(puthash "\\AE" "Æ" julia-latexsubs) -(puthash "\\DH" "Ã" julia-latexsubs) -(puthash "\\times" "×" julia-latexsubs) -(puthash "\\O" "Ø" julia-latexsubs) -(puthash "\\TH" "Þ" julia-latexsubs) -(puthash "\\ss" "ß" julia-latexsubs) -(puthash "\\aa" "Ã¥" julia-latexsubs) -(puthash "\\ae" "æ" julia-latexsubs) -(puthash "\\eth" "ð" julia-latexsubs) -(puthash "\\div" "÷" julia-latexsubs) -(puthash "\\o" "ø" julia-latexsubs) -(puthash "\\th" "þ" julia-latexsubs) -(puthash "\\DJ" "Ä" julia-latexsubs) -(puthash "\\dj" "Ä‘" julia-latexsubs) -(puthash "\\Elzxh" "ħ" julia-latexsubs) -(puthash "\\hbar" "ħ" julia-latexsubs) -(puthash "\\L" "Å" julia-latexsubs) -(puthash "\\l" "Å‚" julia-latexsubs) -(puthash "\\NG" "ÅŠ" julia-latexsubs) -(puthash "\\ng" "Å‹" julia-latexsubs) -(puthash "\\OE" "Å’" julia-latexsubs) -(puthash "\\oe" "Å“" julia-latexsubs) -(puthash "\\texthvlig" "Æ•" julia-latexsubs) -(puthash "\\textnrleg" "Æž" julia-latexsubs) -(puthash "\\Zbar" "Ƶ" julia-latexsubs) -(puthash "\\textdoublepipe" "Ç‚" julia-latexsubs) -(puthash "\\Elztrna" "É" julia-latexsubs) -(puthash "\\Elztrnsa" "É’" julia-latexsubs) -(puthash "\\Elzopeno" "É”" julia-latexsubs) -(puthash "\\Elzrtld" "É–" julia-latexsubs) -(puthash "\\Elzschwa" "É™" julia-latexsubs) -(puthash "\\Elzpgamma" "É£" julia-latexsubs) -(puthash "\\Elzpbgam" "ɤ" julia-latexsubs) -(puthash "\\Elztrnh" "É¥" julia-latexsubs) -(puthash "\\Elzbtdl" "ɬ" julia-latexsubs) -(puthash "\\Elzrtll" "É­" julia-latexsubs) -(puthash "\\Elztrnm" "ɯ" julia-latexsubs) -(puthash "\\Elztrnmlr" "É°" julia-latexsubs) -(puthash "\\Elzltlmr" "ɱ" julia-latexsubs) -(puthash "\\Elzltln" "ɲ" julia-latexsubs) -(puthash "\\Elzrtln" "ɳ" julia-latexsubs) -(puthash "\\Elzclomeg" "É·" julia-latexsubs) -(puthash "\\textphi" "ɸ" julia-latexsubs) -(puthash "\\Elztrnr" "ɹ" julia-latexsubs) -(puthash "\\Elztrnrl" "ɺ" julia-latexsubs) -(puthash "\\Elzrttrnr" "É»" julia-latexsubs) -(puthash "\\Elzrl" "ɼ" julia-latexsubs) -(puthash "\\Elzrtlr" "ɽ" julia-latexsubs) -(puthash "\\Elzfhr" "ɾ" julia-latexsubs) -(puthash "\\Elzrtls" "Ê‚" julia-latexsubs) -(puthash "\\Elzesh" "ʃ" julia-latexsubs) -(puthash "\\Elztrnt" "ʇ" julia-latexsubs) -(puthash "\\Elzrtlt" "ʈ" julia-latexsubs) -(puthash "\\Elzpupsil" "ÊŠ" julia-latexsubs) -(puthash "\\Elzpscrv" "Ê‹" julia-latexsubs) -(puthash "\\Elzinvv" "ÊŒ" julia-latexsubs) -(puthash "\\Elzinvw" "Ê" julia-latexsubs) -(puthash "\\Elztrny" "ÊŽ" julia-latexsubs) -(puthash "\\Elzrtlz" "Ê" julia-latexsubs) -(puthash "\\Elzyogh" "Ê’" julia-latexsubs) -(puthash "\\Elzglst" "Ê”" julia-latexsubs) -(puthash "\\Elzreglst" "Ê•" julia-latexsubs) -(puthash "\\Elzinglst" "Ê–" julia-latexsubs) -(puthash "\\textturnk" "Êž" julia-latexsubs) -(puthash "\\Elzdyogh" "ʤ" julia-latexsubs) -(puthash "\\Elztesh" "ʧ" julia-latexsubs) -(puthash "\\^h" "Ê°" julia-latexsubs) -(puthash "\\^j" "ʲ" julia-latexsubs) -(puthash "\\^r" "ʳ" julia-latexsubs) -(puthash "\\^w" "Ê·" julia-latexsubs) -(puthash "\\^y" "ʸ" julia-latexsubs) -(puthash "\\rasp" "ʼ" julia-latexsubs) -(puthash "\\textasciicaron" "ˇ" julia-latexsubs) -(puthash "\\Elzverts" "ˈ" julia-latexsubs) -(puthash "\\Elzverti" "ËŒ" julia-latexsubs) -(puthash "\\Elzlmrk" "Ë" julia-latexsubs) -(puthash "\\Elzhlmrk" "Ë‘" julia-latexsubs) -(puthash "\\Elzsbrhr" "Ë’" julia-latexsubs) -(puthash "\\Elzsblhr" "Ë“" julia-latexsubs) -(puthash "\\Elzrais" "Ë”" julia-latexsubs) -(puthash "\\Elzlow" "Ë•" julia-latexsubs) -(puthash "\\u" "˘" julia-latexsubs) -(puthash "\\texttildelow" "Ëœ" julia-latexsubs) -(puthash "\\^l" "Ë¡" julia-latexsubs) -(puthash "\\^s" "Ë¢" julia-latexsubs) -(puthash "\\^x" "Ë£" julia-latexsubs) -(puthash "\\grave" "Ì€" julia-latexsubs) -(puthash "\\acute" "Ì" julia-latexsubs) -(puthash "\\hat" "Ì‚" julia-latexsubs) -(puthash "\\tilde" "̃" julia-latexsubs) -(puthash "\\bar" "Ì„" julia-latexsubs) -(puthash "\\overbar" "Ì…" julia-latexsubs) -(puthash "\\breve" "̆" julia-latexsubs) -(puthash "\\dot" "̇" julia-latexsubs) -(puthash "\\ddot" "̈" julia-latexsubs) -(puthash "\\ovhook" "̉" julia-latexsubs) -(puthash "\\ocirc" "ÌŠ" julia-latexsubs) -(puthash "\\H" "Ì‹" julia-latexsubs) -(puthash "\\check" "ÌŒ" julia-latexsubs) -(puthash "\\candra" "Ì" julia-latexsubs) -(puthash "\\oturnedcomma" "Ì’" julia-latexsubs) -(puthash "\\ocommatopright" "Ì•" julia-latexsubs) -(puthash "\\droang" "Ìš" julia-latexsubs) -(puthash "\\Elzpalh" "Ì¡" julia-latexsubs) -(puthash "\\Elzrh" "Ì¢" julia-latexsubs) -(puthash "\\c" "̧" julia-latexsubs) -(puthash "\\k" "̨" julia-latexsubs) -(puthash "\\Elzsbbrg" "̪" julia-latexsubs) -(puthash "\\wideutilde" "Ì°" julia-latexsubs) -(puthash "\\underbar" "̲" julia-latexsubs) -(puthash "\\Elzxl" "̵" julia-latexsubs) -(puthash "\\Elzbar" "̶" julia-latexsubs) -(puthash "\\sout" "̶" julia-latexsubs) -(puthash "\\not" "̸" julia-latexsubs) -(puthash "\\underleftrightarrow" "Í" julia-latexsubs) -(puthash "\\Alpha" "Α" julia-latexsubs) -(puthash "\\Beta" "Î’" julia-latexsubs) -(puthash "\\Gamma" "Γ" julia-latexsubs) -(puthash "\\Delta" "Δ" julia-latexsubs) -(puthash "\\Epsilon" "Ε" julia-latexsubs) -(puthash "\\Zeta" "Ζ" julia-latexsubs) -(puthash "\\Eta" "Η" julia-latexsubs) -(puthash "\\Theta" "Θ" julia-latexsubs) -(puthash "\\Iota" "Ι" julia-latexsubs) -(puthash "\\Kappa" "Κ" julia-latexsubs) -(puthash "\\Lambda" "Λ" julia-latexsubs) -(puthash "\\upMu" "Îœ" julia-latexsubs) -(puthash "\\upNu" "Î" julia-latexsubs) -(puthash "\\Xi" "Ξ" julia-latexsubs) -(puthash "\\upOmicron" "Ο" julia-latexsubs) -(puthash "\\Pi" "Π" julia-latexsubs) -(puthash "\\Rho" "Ρ" julia-latexsubs) -(puthash "\\Sigma" "Σ" julia-latexsubs) -(puthash "\\Tau" "Τ" julia-latexsubs) -(puthash "\\Upsilon" "Î¥" julia-latexsubs) -(puthash "\\Phi" "Φ" julia-latexsubs) -(puthash "\\Chi" "Χ" julia-latexsubs) -(puthash "\\Psi" "Ψ" julia-latexsubs) -(puthash "\\Omega" "Ω" julia-latexsubs) -(puthash "\\alpha" "α" julia-latexsubs) -(puthash "\\beta" "β" julia-latexsubs) -(puthash "\\gamma" "γ" julia-latexsubs) -(puthash "\\delta" "δ" julia-latexsubs) -(puthash "\\upepsilon" "ε" julia-latexsubs) -(puthash "\\varepsilon" "ε" julia-latexsubs) -(puthash "\\zeta" "ζ" julia-latexsubs) -(puthash "\\eta" "η" julia-latexsubs) -(puthash "\\theta" "θ" julia-latexsubs) -(puthash "\\iota" "ι" julia-latexsubs) -(puthash "\\kappa" "κ" julia-latexsubs) -(puthash "\\lambda" "λ" julia-latexsubs) -(puthash "\\mu" "μ" julia-latexsubs) -(puthash "\\nu" "ν" julia-latexsubs) -(puthash "\\xi" "ξ" julia-latexsubs) -(puthash "\\upomicron" "ο" julia-latexsubs) -(puthash "\\pi" "Ï€" julia-latexsubs) -(puthash "\\rho" "Ï" julia-latexsubs) -(puthash "\\varsigma" "Ï‚" julia-latexsubs) -(puthash "\\sigma" "σ" julia-latexsubs) -(puthash "\\tau" "Ï„" julia-latexsubs) -(puthash "\\upsilon" "Ï…" julia-latexsubs) -(puthash "\\varphi" "φ" julia-latexsubs) -(puthash "\\chi" "χ" julia-latexsubs) -(puthash "\\psi" "ψ" julia-latexsubs) -(puthash "\\omega" "ω" julia-latexsubs) -(puthash "\\upvarbeta" "Ï" julia-latexsubs) -(puthash "\\vartheta" "Ï‘" julia-latexsubs) -(puthash "\\phi" "Ï•" julia-latexsubs) -(puthash "\\varpi" "Ï–" julia-latexsubs) -(puthash "\\upoldKoppa" "Ϙ" julia-latexsubs) -(puthash "\\upoldkoppa" "Ï™" julia-latexsubs) -(puthash "\\Stigma" "Ïš" julia-latexsubs) -(puthash "\\upstigma" "Ï›" julia-latexsubs) -(puthash "\\Digamma" "Ïœ" julia-latexsubs) -(puthash "\\digamma" "Ï" julia-latexsubs) -(puthash "\\Koppa" "Ïž" julia-latexsubs) -(puthash "\\upkoppa" "ÏŸ" julia-latexsubs) -(puthash "\\Sampi" "Ï " julia-latexsubs) -(puthash "\\upsampi" "Ï¡" julia-latexsubs) -(puthash "\\varkappa" "Ï°" julia-latexsubs) -(puthash "\\varrho" "ϱ" julia-latexsubs) -(puthash "\\textTheta" "Ï´" julia-latexsubs) -(puthash "\\epsilon" "ϵ" julia-latexsubs) -(puthash "\\backepsilon" "϶" julia-latexsubs) -(puthash "\\^A" "á´¬" julia-latexsubs) -(puthash "\\^B" "á´®" julia-latexsubs) -(puthash "\\^D" "á´°" julia-latexsubs) -(puthash "\\^E" "á´±" julia-latexsubs) -(puthash "\\^G" "á´³" julia-latexsubs) -(puthash "\\^H" "á´´" julia-latexsubs) -(puthash "\\^I" "á´µ" julia-latexsubs) -(puthash "\\^J" "á´¶" julia-latexsubs) -(puthash "\\^K" "á´·" julia-latexsubs) -(puthash "\\^L" "á´¸" julia-latexsubs) -(puthash "\\^M" "á´¹" julia-latexsubs) -(puthash "\\^N" "á´º" julia-latexsubs) -(puthash "\\^O" "á´¼" julia-latexsubs) -(puthash "\\^P" "á´¾" julia-latexsubs) -(puthash "\\^R" "á´¿" julia-latexsubs) -(puthash "\\^T" "áµ€" julia-latexsubs) -(puthash "\\^U" "áµ" julia-latexsubs) -(puthash "\\^W" "ᵂ" julia-latexsubs) -(puthash "\\^a" "ᵃ" julia-latexsubs) -(puthash "\\^alpha" "áµ…" julia-latexsubs) -(puthash "\\^b" "ᵇ" julia-latexsubs) -(puthash "\\^d" "ᵈ" julia-latexsubs) -(puthash "\\^e" "ᵉ" julia-latexsubs) -(puthash "\\^epsilon" "ᵋ" julia-latexsubs) -(puthash "\\^g" "áµ" julia-latexsubs) -(puthash "\\^k" "áµ" julia-latexsubs) -(puthash "\\^m" "áµ" julia-latexsubs) -(puthash "\\^o" "áµ’" julia-latexsubs) -(puthash "\\^p" "áµ–" julia-latexsubs) -(puthash "\\^t" "áµ—" julia-latexsubs) -(puthash "\\^u" "ᵘ" julia-latexsubs) -(puthash "\\^v" "áµ›" julia-latexsubs) -(puthash "\\^beta" "áµ" julia-latexsubs) -(puthash "\\^gamma" "ᵞ" julia-latexsubs) -(puthash "\\^delta" "ᵟ" julia-latexsubs) -(puthash "\\^phi" "áµ " julia-latexsubs) -(puthash "\\^chi" "ᵡ" julia-latexsubs) -(puthash "\\_i" "áµ¢" julia-latexsubs) -(puthash "\\_r" "áµ£" julia-latexsubs) -(puthash "\\_u" "ᵤ" julia-latexsubs) -(puthash "\\_v" "áµ¥" julia-latexsubs) -(puthash "\\_beta" "ᵦ" julia-latexsubs) -(puthash "\\_gamma" "ᵧ" julia-latexsubs) -(puthash "\\_rho" "ᵨ" julia-latexsubs) -(puthash "\\_phi" "ᵩ" julia-latexsubs) -(puthash "\\_chi" "ᵪ" julia-latexsubs) -(puthash "\\^c" "ᶜ" julia-latexsubs) -(puthash "\\^f" "ᶠ" julia-latexsubs) -(puthash "\\^iota" "ᶥ" julia-latexsubs) -(puthash "\\^Phi" "ᶲ" julia-latexsubs) -(puthash "\\^z" "ᶻ" julia-latexsubs) -(puthash "\\^theta" "ᶿ" julia-latexsubs) -(puthash "\\enspace" " " julia-latexsubs) -(puthash "\\quad" " " julia-latexsubs) -(puthash "\\thickspace" " " julia-latexsubs) -(puthash "\\thinspace" " " julia-latexsubs) -(puthash "\\hspace" " " julia-latexsubs) -(puthash "\\endash" "–" julia-latexsubs) -(puthash "\\emdash" "—" julia-latexsubs) -(puthash "\\Vert" "‖" julia-latexsubs) -(puthash "\\lq" "‘" julia-latexsubs) -(puthash "\\rq" "’" julia-latexsubs) -(puthash "\\Elzreapos" "‛" julia-latexsubs) -(puthash "\\textquotedblleft" "“" julia-latexsubs) -(puthash "\\textquotedblright" "â€" julia-latexsubs) -(puthash "\\dagger" "†" julia-latexsubs) -(puthash "\\ddagger" "‡" julia-latexsubs) -(puthash "\\bullet" "•" julia-latexsubs) -(puthash "\\dots" "…" julia-latexsubs) -(puthash "\\ldots" "…" julia-latexsubs) -(puthash "\\textperthousand" "‰" julia-latexsubs) -(puthash "\\textpertenthousand" "‱" julia-latexsubs) -(puthash "\\prime" "′" julia-latexsubs) -(puthash "\\pprime" "″" julia-latexsubs) -(puthash "\\ppprime" "‴" julia-latexsubs) -(puthash "\\backprime" "‵" julia-latexsubs) -(puthash "\\backpprime" "‶" julia-latexsubs) -(puthash "\\backppprime" "‷" julia-latexsubs) -(puthash "\\guilsinglleft" "‹" julia-latexsubs) -(puthash "\\guilsinglright" "›" julia-latexsubs) -(puthash "\\tieconcat" "â€" julia-latexsubs) -(puthash "\\pppprime" "â—" julia-latexsubs) -(puthash "\\nolinebreak" "\u2060" julia-latexsubs) -(puthash "\\^0" "â°" julia-latexsubs) -(puthash "\\^i" "â±" julia-latexsubs) -(puthash "\\^4" "â´" julia-latexsubs) -(puthash "\\^5" "âµ" julia-latexsubs) -(puthash "\\^6" "â¶" julia-latexsubs) -(puthash "\\^7" "â·" julia-latexsubs) -(puthash "\\^8" "â¸" julia-latexsubs) -(puthash "\\^9" "â¹" julia-latexsubs) -(puthash "\\^+" "âº" julia-latexsubs) -(puthash "\\^-" "â»" julia-latexsubs) -(puthash "\\^=" "â¼" julia-latexsubs) -(puthash "\\^(" "â½" julia-latexsubs) -(puthash "\\^)" "â¾" julia-latexsubs) -(puthash "\\^n" "â¿" julia-latexsubs) -(puthash "\\_0" "â‚€" julia-latexsubs) -(puthash "\\_1" "â‚" julia-latexsubs) -(puthash "\\_2" "â‚‚" julia-latexsubs) -(puthash "\\_3" "₃" julia-latexsubs) -(puthash "\\_4" "â‚„" julia-latexsubs) -(puthash "\\_5" "â‚…" julia-latexsubs) -(puthash "\\_6" "₆" julia-latexsubs) -(puthash "\\_7" "₇" julia-latexsubs) -(puthash "\\_8" "₈" julia-latexsubs) -(puthash "\\_9" "₉" julia-latexsubs) -(puthash "\\_+" "â‚Š" julia-latexsubs) -(puthash "\\_-" "â‚‹" julia-latexsubs) -(puthash "\\_=" "â‚Œ" julia-latexsubs) -(puthash "\\_(" "â‚" julia-latexsubs) -(puthash "\\_)" "â‚Ž" julia-latexsubs) -(puthash "\\_a" "â‚" julia-latexsubs) -(puthash "\\_e" "â‚‘" julia-latexsubs) -(puthash "\\_o" "â‚’" julia-latexsubs) -(puthash "\\_x" "â‚“" julia-latexsubs) -(puthash "\\_schwa" "â‚”" julia-latexsubs) -(puthash "\\_h" "â‚•" julia-latexsubs) -(puthash "\\_k" "â‚–" julia-latexsubs) -(puthash "\\_l" "â‚—" julia-latexsubs) -(puthash "\\_m" "ₘ" julia-latexsubs) -(puthash "\\_n" "â‚™" julia-latexsubs) -(puthash "\\_p" "â‚š" julia-latexsubs) -(puthash "\\_s" "â‚›" julia-latexsubs) -(puthash "\\_t" "â‚œ" julia-latexsubs) -(puthash "\\Elzpes" "₧" julia-latexsubs) -(puthash "\\euro" "€" julia-latexsubs) -(puthash "\\leftharpoonaccent" "âƒ" julia-latexsubs) -(puthash "\\rightharpoonaccent" "⃑" julia-latexsubs) -(puthash "\\vertoverlay" "⃒" julia-latexsubs) -(puthash "\\overleftarrow" "⃖" julia-latexsubs) -(puthash "\\vec" "⃗" julia-latexsubs) -(puthash "\\dddot" "⃛" julia-latexsubs) -(puthash "\\ddddot" "⃜" julia-latexsubs) -(puthash "\\enclosecircle" "âƒ" julia-latexsubs) -(puthash "\\enclosesquare" "⃞" julia-latexsubs) -(puthash "\\enclosediamond" "⃟" julia-latexsubs) -(puthash "\\overleftrightarrow" "⃡" julia-latexsubs) -(puthash "\\enclosetriangle" "⃤" julia-latexsubs) -(puthash "\\annuity" "⃧" julia-latexsubs) -(puthash "\\threeunderdot" "⃨" julia-latexsubs) -(puthash "\\widebridgeabove" "⃩" julia-latexsubs) -(puthash "\\underrightharpoondown" "⃬" julia-latexsubs) -(puthash "\\underleftharpoondown" "⃭" julia-latexsubs) -(puthash "\\underleftarrow" "⃮" julia-latexsubs) -(puthash "\\underrightarrow" "⃯" julia-latexsubs) -(puthash "\\asteraccent" "⃰" julia-latexsubs) -(puthash "\\BbbC" "â„‚" julia-latexsubs) -(puthash "\\Eulerconst" "ℇ" julia-latexsubs) -(puthash "\\mscrg" "â„Š" julia-latexsubs) -(puthash "\\mscrH" "â„‹" julia-latexsubs) -(puthash "\\mfrakH" "â„Œ" julia-latexsubs) -(puthash "\\BbbH" "â„" julia-latexsubs) -(puthash "\\Planckconst" "â„Ž" julia-latexsubs) -(puthash "\\hslash" "â„" julia-latexsubs) -(puthash "\\mscrI" "â„" julia-latexsubs) -(puthash "\\Im" "â„‘" julia-latexsubs) -(puthash "\\mscrL" "â„’" julia-latexsubs) -(puthash "\\ell" "â„“" julia-latexsubs) -(puthash "\\BbbN" "â„•" julia-latexsubs) -(puthash "\\textnumero" "â„–" julia-latexsubs) -(puthash "\\wp" "℘" julia-latexsubs) -(puthash "\\BbbP" "â„™" julia-latexsubs) -(puthash "\\BbbQ" "â„š" julia-latexsubs) -(puthash "\\mscrR" "â„›" julia-latexsubs) -(puthash "\\Re" "â„œ" julia-latexsubs) -(puthash "\\BbbR" "â„" julia-latexsubs) -(puthash "\\Elzxrat" "â„ž" julia-latexsubs) -(puthash "\\texttrademark" "â„¢" julia-latexsubs) -(puthash "\\BbbZ" "ℤ" julia-latexsubs) -(puthash "\\mho" "℧" julia-latexsubs) -(puthash "\\mfrakZ" "ℨ" julia-latexsubs) -(puthash "\\turnediota" "â„©" julia-latexsubs) -(puthash "\\Angstrom" "â„«" julia-latexsubs) -(puthash "\\mscrB" "ℬ" julia-latexsubs) -(puthash "\\mfrakC" "â„­" julia-latexsubs) -(puthash "\\mscre" "ℯ" julia-latexsubs) -(puthash "\\euler" "ℯ" julia-latexsubs) -(puthash "\\mscrE" "â„°" julia-latexsubs) -(puthash "\\mscrF" "ℱ" julia-latexsubs) -(puthash "\\Finv" "Ⅎ" julia-latexsubs) -(puthash "\\mscrM" "ℳ" julia-latexsubs) -(puthash "\\mscro" "â„´" julia-latexsubs) -(puthash "\\aleph" "ℵ" julia-latexsubs) -(puthash "\\beth" "ℶ" julia-latexsubs) -(puthash "\\gimel" "â„·" julia-latexsubs) -(puthash "\\daleth" "ℸ" julia-latexsubs) -(puthash "\\Bbbpi" "ℼ" julia-latexsubs) -(puthash "\\Bbbgamma" "ℽ" julia-latexsubs) -(puthash "\\BbbGamma" "ℾ" julia-latexsubs) -(puthash "\\BbbPi" "â„¿" julia-latexsubs) -(puthash "\\bbsum" "â…€" julia-latexsubs) -(puthash "\\Game" "â…" julia-latexsubs) -(puthash "\\sansLturned" "â…‚" julia-latexsubs) -(puthash "\\sansLmirrored" "â…ƒ" julia-latexsubs) -(puthash "\\Yup" "â…„" julia-latexsubs) -(puthash "\\mitBbbD" "â……" julia-latexsubs) -(puthash "\\mitBbbd" "â…†" julia-latexsubs) -(puthash "\\mitBbbe" "â…‡" julia-latexsubs) -(puthash "\\mitBbbi" "â…ˆ" julia-latexsubs) -(puthash "\\mitBbbj" "â…‰" julia-latexsubs) -(puthash "\\PropertyLine" "â…Š" julia-latexsubs) -(puthash "\\upand" "â…‹" julia-latexsubs) -(puthash "\\leftarrow" "â†" julia-latexsubs) -(puthash "\\uparrow" "↑" julia-latexsubs) -(puthash "\\to" "→" julia-latexsubs) -(puthash "\\rightarrow" "→" julia-latexsubs) -(puthash "\\downarrow" "↓" julia-latexsubs) -(puthash "\\leftrightarrow" "↔" julia-latexsubs) -(puthash "\\updownarrow" "↕" julia-latexsubs) -(puthash "\\nwarrow" "↖" julia-latexsubs) -(puthash "\\nearrow" "↗" julia-latexsubs) -(puthash "\\searrow" "↘" julia-latexsubs) -(puthash "\\swarrow" "↙" julia-latexsubs) -(puthash "\\nleftarrow" "↚" julia-latexsubs) -(puthash "\\nrightarrow" "↛" julia-latexsubs) -(puthash "\\leftwavearrow" "↜" julia-latexsubs) -(puthash "\\rightwavearrow" "â†" julia-latexsubs) -(puthash "\\twoheadleftarrow" "↞" julia-latexsubs) -(puthash "\\twoheaduparrow" "↟" julia-latexsubs) -(puthash "\\twoheadrightarrow" "↠" julia-latexsubs) -(puthash "\\twoheaddownarrow" "↡" julia-latexsubs) -(puthash "\\leftarrowtail" "↢" julia-latexsubs) -(puthash "\\rightarrowtail" "↣" julia-latexsubs) -(puthash "\\mapsfrom" "↤" julia-latexsubs) -(puthash "\\mapsup" "↥" julia-latexsubs) -(puthash "\\mapsto" "↦" julia-latexsubs) -(puthash "\\mapsdown" "↧" julia-latexsubs) -(puthash "\\updownarrowbar" "↨" julia-latexsubs) -(puthash "\\hookleftarrow" "↩" julia-latexsubs) -(puthash "\\hookrightarrow" "↪" julia-latexsubs) -(puthash "\\looparrowleft" "↫" julia-latexsubs) -(puthash "\\looparrowright" "↬" julia-latexsubs) -(puthash "\\leftrightsquigarrow" "↭" julia-latexsubs) -(puthash "\\nleftrightarrow" "↮" julia-latexsubs) -(puthash "\\downzigzagarrow" "↯" julia-latexsubs) -(puthash "\\Lsh" "↰" julia-latexsubs) -(puthash "\\Rsh" "↱" julia-latexsubs) -(puthash "\\Ldsh" "↲" julia-latexsubs) -(puthash "\\Rdsh" "↳" julia-latexsubs) -(puthash "\\linefeed" "↴" julia-latexsubs) -(puthash "\\carriagereturn" "↵" julia-latexsubs) -(puthash "\\curvearrowleft" "↶" julia-latexsubs) -(puthash "\\curvearrowright" "↷" julia-latexsubs) -(puthash "\\barovernorthwestarrow" "↸" julia-latexsubs) -(puthash "\\barleftarrowrightarrowbar" "↹" julia-latexsubs) -(puthash "\\circlearrowleft" "↺" julia-latexsubs) -(puthash "\\circlearrowright" "↻" julia-latexsubs) -(puthash "\\leftharpoonup" "↼" julia-latexsubs) -(puthash "\\leftharpoondown" "↽" julia-latexsubs) -(puthash "\\upharpoonleft" "↾" julia-latexsubs) -(puthash "\\upharpoonright" "↿" julia-latexsubs) -(puthash "\\rightharpoonup" "⇀" julia-latexsubs) -(puthash "\\rightharpoondown" "â‡" julia-latexsubs) -(puthash "\\downharpoonright" "⇂" julia-latexsubs) -(puthash "\\downharpoonleft" "⇃" julia-latexsubs) -(puthash "\\rightleftarrows" "⇄" julia-latexsubs) -(puthash "\\dblarrowupdown" "⇅" julia-latexsubs) -(puthash "\\leftrightarrows" "⇆" julia-latexsubs) -(puthash "\\leftleftarrows" "⇇" julia-latexsubs) -(puthash "\\upuparrows" "⇈" julia-latexsubs) -(puthash "\\rightrightarrows" "⇉" julia-latexsubs) -(puthash "\\downdownarrows" "⇊" julia-latexsubs) -(puthash "\\leftrightharpoons" "⇋" julia-latexsubs) -(puthash "\\rightleftharpoons" "⇌" julia-latexsubs) -(puthash "\\nLeftarrow" "â‡" julia-latexsubs) -(puthash "\\nLeftrightarrow" "⇎" julia-latexsubs) -(puthash "\\nRightarrow" "â‡" julia-latexsubs) -(puthash "\\Leftarrow" "â‡" julia-latexsubs) -(puthash "\\Uparrow" "⇑" julia-latexsubs) -(puthash "\\Rightarrow" "⇒" julia-latexsubs) -(puthash "\\Downarrow" "⇓" julia-latexsubs) -(puthash "\\Leftrightarrow" "⇔" julia-latexsubs) -(puthash "\\Updownarrow" "⇕" julia-latexsubs) -(puthash "\\Nwarrow" "⇖" julia-latexsubs) -(puthash "\\Nearrow" "⇗" julia-latexsubs) -(puthash "\\Searrow" "⇘" julia-latexsubs) -(puthash "\\Swarrow" "⇙" julia-latexsubs) -(puthash "\\Lleftarrow" "⇚" julia-latexsubs) -(puthash "\\Rrightarrow" "⇛" julia-latexsubs) -(puthash "\\leftsquigarrow" "⇜" julia-latexsubs) -(puthash "\\rightsquigarrow" "â‡" julia-latexsubs) -(puthash "\\nHuparrow" "⇞" julia-latexsubs) -(puthash "\\nHdownarrow" "⇟" julia-latexsubs) -(puthash "\\leftdasharrow" "⇠" julia-latexsubs) -(puthash "\\updasharrow" "⇡" julia-latexsubs) -(puthash "\\rightdasharrow" "⇢" julia-latexsubs) -(puthash "\\downdasharrow" "⇣" julia-latexsubs) -(puthash "\\barleftarrow" "⇤" julia-latexsubs) -(puthash "\\rightarrowbar" "⇥" julia-latexsubs) -(puthash "\\leftwhitearrow" "⇦" julia-latexsubs) -(puthash "\\upwhitearrow" "⇧" julia-latexsubs) -(puthash "\\rightwhitearrow" "⇨" julia-latexsubs) -(puthash "\\downwhitearrow" "⇩" julia-latexsubs) -(puthash "\\whitearrowupfrombar" "⇪" julia-latexsubs) -(puthash "\\circleonrightarrow" "⇴" julia-latexsubs) -(puthash "\\DownArrowUpArrow" "⇵" julia-latexsubs) -(puthash "\\rightthreearrows" "⇶" julia-latexsubs) -(puthash "\\nvleftarrow" "⇷" julia-latexsubs) -(puthash "\\nvrightarrow" "⇸" julia-latexsubs) -(puthash "\\nvleftrightarrow" "⇹" julia-latexsubs) -(puthash "\\nVleftarrow" "⇺" julia-latexsubs) -(puthash "\\nVrightarrow" "⇻" julia-latexsubs) -(puthash "\\nVleftrightarrow" "⇼" julia-latexsubs) -(puthash "\\leftarrowtriangle" "⇽" julia-latexsubs) -(puthash "\\rightarrowtriangle" "⇾" julia-latexsubs) -(puthash "\\leftrightarrowtriangle" "⇿" julia-latexsubs) -(puthash "\\forall" "∀" julia-latexsubs) -(puthash "\\complement" "âˆ" julia-latexsubs) -(puthash "\\partial" "∂" julia-latexsubs) -(puthash "\\exists" "∃" julia-latexsubs) -(puthash "\\nexists" "∄" julia-latexsubs) -(puthash "\\varnothing" "∅" julia-latexsubs) -(puthash "\\emptyset" "∅" julia-latexsubs) -(puthash "\\increment" "∆" julia-latexsubs) -(puthash "\\del" "∇" julia-latexsubs) -(puthash "\\nabla" "∇" julia-latexsubs) -(puthash "\\in" "∈" julia-latexsubs) -(puthash "\\notin" "∉" julia-latexsubs) -(puthash "\\smallin" "∊" julia-latexsubs) -(puthash "\\ni" "∋" julia-latexsubs) -(puthash "\\nni" "∌" julia-latexsubs) -(puthash "\\smallni" "âˆ" julia-latexsubs) -(puthash "\\QED" "∎" julia-latexsubs) -(puthash "\\prod" "âˆ" julia-latexsubs) -(puthash "\\coprod" "âˆ" julia-latexsubs) -(puthash "\\sum" "∑" julia-latexsubs) -(puthash "\\minus" "−" julia-latexsubs) -(puthash "\\mp" "∓" julia-latexsubs) -(puthash "\\dotplus" "∔" julia-latexsubs) -(puthash "\\setminus" "∖" julia-latexsubs) -(puthash "\\ast" "∗" julia-latexsubs) -(puthash "\\circ" "∘" julia-latexsubs) -(puthash "\\vysmblkcircle" "∙" julia-latexsubs) -(puthash "\\surd" "√" julia-latexsubs) -(puthash "\\sqrt" "√" julia-latexsubs) -(puthash "\\cbrt" "∛" julia-latexsubs) -(puthash "\\fourthroot" "∜" julia-latexsubs) -(puthash "\\propto" "âˆ" julia-latexsubs) -(puthash "\\infty" "∞" julia-latexsubs) -(puthash "\\rightangle" "∟" julia-latexsubs) -(puthash "\\angle" "∠" julia-latexsubs) -(puthash "\\measuredangle" "∡" julia-latexsubs) -(puthash "\\sphericalangle" "∢" julia-latexsubs) -(puthash "\\mid" "∣" julia-latexsubs) -(puthash "\\nmid" "∤" julia-latexsubs) -(puthash "\\parallel" "∥" julia-latexsubs) -(puthash "\\nparallel" "∦" julia-latexsubs) -(puthash "\\wedge" "∧" julia-latexsubs) -(puthash "\\vee" "∨" julia-latexsubs) -(puthash "\\cap" "∩" julia-latexsubs) -(puthash "\\cup" "∪" julia-latexsubs) -(puthash "\\int" "∫" julia-latexsubs) -(puthash "\\iint" "∬" julia-latexsubs) -(puthash "\\iiint" "∭" julia-latexsubs) -(puthash "\\oint" "∮" julia-latexsubs) -(puthash "\\oiint" "∯" julia-latexsubs) -(puthash "\\oiiint" "∰" julia-latexsubs) -(puthash "\\clwintegral" "∱" julia-latexsubs) -(puthash "\\varointclockwise" "∲" julia-latexsubs) -(puthash "\\ointctrclockwise" "∳" julia-latexsubs) -(puthash "\\therefore" "∴" julia-latexsubs) -(puthash "\\because" "∵" julia-latexsubs) -(puthash "\\Colon" "∷" julia-latexsubs) -(puthash "\\dotminus" "∸" julia-latexsubs) -(puthash "\\dotsminusdots" "∺" julia-latexsubs) -(puthash "\\kernelcontraction" "∻" julia-latexsubs) -(puthash "\\sim" "∼" julia-latexsubs) -(puthash "\\backsim" "∽" julia-latexsubs) -(puthash "\\lazysinv" "∾" julia-latexsubs) -(puthash "\\sinewave" "∿" julia-latexsubs) -(puthash "\\wr" "≀" julia-latexsubs) -(puthash "\\nsim" "â‰" julia-latexsubs) -(puthash "\\eqsim" "≂" julia-latexsubs) -(puthash "\\neqsim" "≂̸" julia-latexsubs) -(puthash "\\simeq" "≃" julia-latexsubs) -(puthash "\\nsime" "≄" julia-latexsubs) -(puthash "\\cong" "≅" julia-latexsubs) -(puthash "\\approxnotequal" "≆" julia-latexsubs) -(puthash "\\ncong" "≇" julia-latexsubs) -(puthash "\\approx" "≈" julia-latexsubs) -(puthash "\\napprox" "≉" julia-latexsubs) -(puthash "\\approxeq" "≊" julia-latexsubs) -(puthash "\\tildetrpl" "≋" julia-latexsubs) -(puthash "\\allequal" "≌" julia-latexsubs) -(puthash "\\asymp" "â‰" julia-latexsubs) -(puthash "\\Bumpeq" "≎" julia-latexsubs) -(puthash "\\nBumpeq" "≎̸" julia-latexsubs) -(puthash "\\bumpeq" "â‰" julia-latexsubs) -(puthash "\\nbumpeq" "â‰Ì¸" julia-latexsubs) -(puthash "\\doteq" "â‰" julia-latexsubs) -(puthash "\\Doteq" "≑" julia-latexsubs) -(puthash "\\fallingdotseq" "≒" julia-latexsubs) -(puthash "\\risingdotseq" "≓" julia-latexsubs) -(puthash "\\coloneq" "≔" julia-latexsubs) -(puthash "\\eqcolon" "≕" julia-latexsubs) -(puthash "\\eqcirc" "≖" julia-latexsubs) -(puthash "\\circeq" "≗" julia-latexsubs) -(puthash "\\arceq" "≘" julia-latexsubs) -(puthash "\\wedgeq" "≙" julia-latexsubs) -(puthash "\\veeeq" "≚" julia-latexsubs) -(puthash "\\starequal" "≛" julia-latexsubs) -(puthash "\\triangleq" "≜" julia-latexsubs) -(puthash "\\eqdef" "â‰" julia-latexsubs) -(puthash "\\measeq" "≞" julia-latexsubs) -(puthash "\\questeq" "≟" julia-latexsubs) -(puthash "\\ne" "≠" julia-latexsubs) -(puthash "\\equiv" "≡" julia-latexsubs) -(puthash "\\nequiv" "≢" julia-latexsubs) -(puthash "\\Equiv" "≣" julia-latexsubs) -(puthash "\\le" "≤" julia-latexsubs) -(puthash "\\ge" "≥" julia-latexsubs) -(puthash "\\leqq" "≦" julia-latexsubs) -(puthash "\\geqq" "≧" julia-latexsubs) -(puthash "\\lneqq" "≨" julia-latexsubs) -(puthash "\\lvertneqq" "≨︀" julia-latexsubs) -(puthash "\\gneqq" "≩" julia-latexsubs) -(puthash "\\gvertneqq" "≩︀" julia-latexsubs) -(puthash "\\ll" "≪" julia-latexsubs) -(puthash "\\NotLessLess" "≪̸" julia-latexsubs) -(puthash "\\gg" "≫" julia-latexsubs) -(puthash "\\NotGreaterGreater" "≫̸" julia-latexsubs) -(puthash "\\between" "≬" julia-latexsubs) -(puthash "\\nasymp" "≭" julia-latexsubs) -(puthash "\\nless" "≮" julia-latexsubs) -(puthash "\\ngtr" "≯" julia-latexsubs) -(puthash "\\nleq" "≰" julia-latexsubs) -(puthash "\\ngeq" "≱" julia-latexsubs) -(puthash "\\lesssim" "≲" julia-latexsubs) -(puthash "\\gtrsim" "≳" julia-latexsubs) -(puthash "\\nlesssim" "≴" julia-latexsubs) -(puthash "\\ngtrsim" "≵" julia-latexsubs) -(puthash "\\lessgtr" "≶" julia-latexsubs) -(puthash "\\gtrless" "≷" julia-latexsubs) -(puthash "\\notlessgreater" "≸" julia-latexsubs) -(puthash "\\notgreaterless" "≹" julia-latexsubs) -(puthash "\\prec" "≺" julia-latexsubs) -(puthash "\\succ" "≻" julia-latexsubs) -(puthash "\\preccurlyeq" "≼" julia-latexsubs) -(puthash "\\succcurlyeq" "≽" julia-latexsubs) -(puthash "\\precsim" "≾" julia-latexsubs) -(puthash "\\nprecsim" "≾̸" julia-latexsubs) -(puthash "\\succsim" "≿" julia-latexsubs) -(puthash "\\nsuccsim" "≿̸" julia-latexsubs) -(puthash "\\nprec" "⊀" julia-latexsubs) -(puthash "\\nsucc" "âŠ" julia-latexsubs) -(puthash "\\subset" "⊂" julia-latexsubs) -(puthash "\\supset" "⊃" julia-latexsubs) -(puthash "\\nsubset" "⊄" julia-latexsubs) -(puthash "\\nsupset" "⊅" julia-latexsubs) -(puthash "\\subseteq" "⊆" julia-latexsubs) -(puthash "\\supseteq" "⊇" julia-latexsubs) -(puthash "\\nsubseteq" "⊈" julia-latexsubs) -(puthash "\\nsupseteq" "⊉" julia-latexsubs) -(puthash "\\subsetneq" "⊊" julia-latexsubs) -(puthash "\\varsubsetneqq" "⊊︀" julia-latexsubs) -(puthash "\\supsetneq" "⊋" julia-latexsubs) -(puthash "\\varsupsetneq" "⊋︀" julia-latexsubs) -(puthash "\\cupdot" "âŠ" julia-latexsubs) -(puthash "\\uplus" "⊎" julia-latexsubs) -(puthash "\\sqsubset" "âŠ" julia-latexsubs) -(puthash "\\NotSquareSubset" "âŠÌ¸" julia-latexsubs) -(puthash "\\sqsupset" "âŠ" julia-latexsubs) -(puthash "\\NotSquareSuperset" "âŠÌ¸" julia-latexsubs) -(puthash "\\sqsubseteq" "⊑" julia-latexsubs) -(puthash "\\sqsupseteq" "⊒" julia-latexsubs) -(puthash "\\sqcap" "⊓" julia-latexsubs) -(puthash "\\sqcup" "⊔" julia-latexsubs) -(puthash "\\oplus" "⊕" julia-latexsubs) -(puthash "\\ominus" "⊖" julia-latexsubs) -(puthash "\\otimes" "⊗" julia-latexsubs) -(puthash "\\oslash" "⊘" julia-latexsubs) -(puthash "\\odot" "⊙" julia-latexsubs) -(puthash "\\circledcirc" "⊚" julia-latexsubs) -(puthash "\\circledast" "⊛" julia-latexsubs) -(puthash "\\circledequal" "⊜" julia-latexsubs) -(puthash "\\circleddash" "âŠ" julia-latexsubs) -(puthash "\\boxplus" "⊞" julia-latexsubs) -(puthash "\\boxminus" "⊟" julia-latexsubs) -(puthash "\\boxtimes" "⊠" julia-latexsubs) -(puthash "\\boxdot" "⊡" julia-latexsubs) -(puthash "\\vdash" "⊢" julia-latexsubs) -(puthash "\\dashv" "⊣" julia-latexsubs) -(puthash "\\top" "⊤" julia-latexsubs) -(puthash "\\bot" "⊥" julia-latexsubs) -(puthash "\\models" "⊧" julia-latexsubs) -(puthash "\\vDash" "⊨" julia-latexsubs) -(puthash "\\Vdash" "⊩" julia-latexsubs) -(puthash "\\Vvdash" "⊪" julia-latexsubs) -(puthash "\\VDash" "⊫" julia-latexsubs) -(puthash "\\nvdash" "⊬" julia-latexsubs) -(puthash "\\nvDash" "⊭" julia-latexsubs) -(puthash "\\nVdash" "⊮" julia-latexsubs) -(puthash "\\nVDash" "⊯" julia-latexsubs) -(puthash "\\prurel" "⊰" julia-latexsubs) -(puthash "\\scurel" "⊱" julia-latexsubs) -(puthash "\\vartriangleleft" "⊲" julia-latexsubs) -(puthash "\\vartriangleright" "⊳" julia-latexsubs) -(puthash "\\trianglelefteq" "⊴" julia-latexsubs) -(puthash "\\trianglerighteq" "⊵" julia-latexsubs) -(puthash "\\original" "⊶" julia-latexsubs) -(puthash "\\image" "⊷" julia-latexsubs) -(puthash "\\multimap" "⊸" julia-latexsubs) -(puthash "\\hermitconjmatrix" "⊹" julia-latexsubs) -(puthash "\\intercal" "⊺" julia-latexsubs) -(puthash "\\veebar" "⊻" julia-latexsubs) -(puthash "\\xor" "⊻" julia-latexsubs) -(puthash "\\barwedge" "⊼" julia-latexsubs) -(puthash "\\barvee" "⊽" julia-latexsubs) -(puthash "\\rightanglearc" "⊾" julia-latexsubs) -(puthash "\\varlrtriangle" "⊿" julia-latexsubs) -(puthash "\\bigwedge" "â‹€" julia-latexsubs) -(puthash "\\bigvee" "â‹" julia-latexsubs) -(puthash "\\bigcap" "â‹‚" julia-latexsubs) -(puthash "\\bigcup" "⋃" julia-latexsubs) -(puthash "\\diamond" "â‹„" julia-latexsubs) -(puthash "\\cdot" "â‹…" julia-latexsubs) -(puthash "\\star" "⋆" julia-latexsubs) -(puthash "\\divideontimes" "⋇" julia-latexsubs) -(puthash "\\bowtie" "⋈" julia-latexsubs) -(puthash "\\ltimes" "⋉" julia-latexsubs) -(puthash "\\rtimes" "â‹Š" julia-latexsubs) -(puthash "\\leftthreetimes" "â‹‹" julia-latexsubs) -(puthash "\\rightthreetimes" "â‹Œ" julia-latexsubs) -(puthash "\\backsimeq" "â‹" julia-latexsubs) -(puthash "\\curlyvee" "â‹Ž" julia-latexsubs) -(puthash "\\curlywedge" "â‹" julia-latexsubs) -(puthash "\\Subset" "â‹" julia-latexsubs) -(puthash "\\Supset" "â‹‘" julia-latexsubs) -(puthash "\\Cap" "â‹’" julia-latexsubs) -(puthash "\\Cup" "â‹“" julia-latexsubs) -(puthash "\\pitchfork" "â‹”" julia-latexsubs) -(puthash "\\equalparallel" "â‹•" julia-latexsubs) -(puthash "\\lessdot" "â‹–" julia-latexsubs) -(puthash "\\gtrdot" "â‹—" julia-latexsubs) -(puthash "\\verymuchless" "⋘" julia-latexsubs) -(puthash "\\ggg" "â‹™" julia-latexsubs) -(puthash "\\lesseqgtr" "â‹š" julia-latexsubs) -(puthash "\\gtreqless" "â‹›" julia-latexsubs) -(puthash "\\eqless" "â‹œ" julia-latexsubs) -(puthash "\\eqgtr" "â‹" julia-latexsubs) -(puthash "\\curlyeqprec" "â‹ž" julia-latexsubs) -(puthash "\\curlyeqsucc" "â‹Ÿ" julia-latexsubs) -(puthash "\\npreccurlyeq" "â‹ " julia-latexsubs) -(puthash "\\nsucccurlyeq" "â‹¡" julia-latexsubs) -(puthash "\\nsqsubseteq" "â‹¢" julia-latexsubs) -(puthash "\\nsqsupseteq" "â‹£" julia-latexsubs) -(puthash "\\sqsubsetneq" "⋤" julia-latexsubs) -(puthash "\\Elzsqspne" "â‹¥" julia-latexsubs) -(puthash "\\lnsim" "⋦" julia-latexsubs) -(puthash "\\gnsim" "⋧" julia-latexsubs) -(puthash "\\precnsim" "⋨" julia-latexsubs) -(puthash "\\succnsim" "â‹©" julia-latexsubs) -(puthash "\\ntriangleleft" "⋪" julia-latexsubs) -(puthash "\\ntriangleright" "â‹«" julia-latexsubs) -(puthash "\\ntrianglelefteq" "⋬" julia-latexsubs) -(puthash "\\ntrianglerighteq" "â‹­" julia-latexsubs) -(puthash "\\vdots" "â‹®" julia-latexsubs) -(puthash "\\cdots" "⋯" julia-latexsubs) -(puthash "\\adots" "â‹°" julia-latexsubs) -(puthash "\\ddots" "⋱" julia-latexsubs) -(puthash "\\disin" "⋲" julia-latexsubs) -(puthash "\\varisins" "⋳" julia-latexsubs) -(puthash "\\isins" "â‹´" julia-latexsubs) -(puthash "\\isindot" "⋵" julia-latexsubs) -(puthash "\\varisinobar" "⋶" julia-latexsubs) -(puthash "\\isinobar" "â‹·" julia-latexsubs) -(puthash "\\isinvb" "⋸" julia-latexsubs) -(puthash "\\isinE" "⋹" julia-latexsubs) -(puthash "\\nisd" "⋺" julia-latexsubs) -(puthash "\\varnis" "â‹»" julia-latexsubs) -(puthash "\\nis" "⋼" julia-latexsubs) -(puthash "\\varniobar" "⋽" julia-latexsubs) -(puthash "\\niobar" "⋾" julia-latexsubs) -(puthash "\\bagmember" "â‹¿" julia-latexsubs) -(puthash "\\diameter" "⌀" julia-latexsubs) -(puthash "\\house" "⌂" julia-latexsubs) -(puthash "\\varbarwedge" "⌅" julia-latexsubs) -(puthash "\\vardoublebarwedge" "⌆" julia-latexsubs) -(puthash "\\lceil" "⌈" julia-latexsubs) -(puthash "\\rceil" "⌉" julia-latexsubs) -(puthash "\\lfloor" "⌊" julia-latexsubs) -(puthash "\\rfloor" "⌋" julia-latexsubs) -(puthash "\\invnot" "âŒ" julia-latexsubs) -(puthash "\\sqlozenge" "⌑" julia-latexsubs) -(puthash "\\profline" "⌒" julia-latexsubs) -(puthash "\\profsurf" "⌓" julia-latexsubs) -(puthash "\\recorder" "⌕" julia-latexsubs) -(puthash "\\viewdata" "⌗" julia-latexsubs) -(puthash "\\turnednot" "⌙" julia-latexsubs) -(puthash "\\ulcorner" "⌜" julia-latexsubs) -(puthash "\\urcorner" "âŒ" julia-latexsubs) -(puthash "\\llcorner" "⌞" julia-latexsubs) -(puthash "\\lrcorner" "⌟" julia-latexsubs) -(puthash "\\frown" "⌢" julia-latexsubs) -(puthash "\\smile" "⌣" julia-latexsubs) -(puthash "\\varhexagonlrbonds" "⌬" julia-latexsubs) -(puthash "\\conictaper" "⌲" julia-latexsubs) -(puthash "\\topbot" "⌶" julia-latexsubs) -(puthash "\\obar" "⌽" julia-latexsubs) -(puthash "\\APLnotslash" "⌿" julia-latexsubs) -(puthash "\\APLnotbackslash" "â€" julia-latexsubs) -(puthash "\\APLboxupcaret" "â“" julia-latexsubs) -(puthash "\\APLboxquestion" "â°" julia-latexsubs) -(puthash "\\hexagon" "⎔" julia-latexsubs) -(puthash "\\Elzdlcorn" "⎣" julia-latexsubs) -(puthash "\\lmoustache" "⎰" julia-latexsubs) -(puthash "\\rmoustache" "⎱" julia-latexsubs) -(puthash "\\overbracket" "⎴" julia-latexsubs) -(puthash "\\underbracket" "⎵" julia-latexsubs) -(puthash "\\bbrktbrk" "⎶" julia-latexsubs) -(puthash "\\sqrtbottom" "⎷" julia-latexsubs) -(puthash "\\lvboxline" "⎸" julia-latexsubs) -(puthash "\\rvboxline" "⎹" julia-latexsubs) -(puthash "\\varcarriagereturn" "âŽ" julia-latexsubs) -(puthash "\\overbrace" "âž" julia-latexsubs) -(puthash "\\underbrace" "âŸ" julia-latexsubs) -(puthash "\\trapezium" "â¢" julia-latexsubs) -(puthash "\\benzenr" "â£" julia-latexsubs) -(puthash "\\strns" "â¤" julia-latexsubs) -(puthash "\\fltns" "â¥" julia-latexsubs) -(puthash "\\accurrent" "â¦" julia-latexsubs) -(puthash "\\elinters" "â§" julia-latexsubs) -(puthash "\\blanksymbol" "â¢" julia-latexsubs) -(puthash "\\textvisiblespace" "â£" julia-latexsubs) -(puthash "\\circledS" "Ⓢ" julia-latexsubs) -(puthash "\\Elzdshfnc" "┆" julia-latexsubs) -(puthash "\\Elzsqfnw" "â”™" julia-latexsubs) -(puthash "\\diagup" "╱" julia-latexsubs) -(puthash "\\diagdown" "╲" julia-latexsubs) -(puthash "\\blockuphalf" "â–€" julia-latexsubs) -(puthash "\\blocklowhalf" "â–„" julia-latexsubs) -(puthash "\\blockfull" "â–ˆ" julia-latexsubs) -(puthash "\\blocklefthalf" "â–Œ" julia-latexsubs) -(puthash "\\blockrighthalf" "â–" julia-latexsubs) -(puthash "\\blockqtrshaded" "â–‘" julia-latexsubs) -(puthash "\\blockhalfshaded" "â–’" julia-latexsubs) -(puthash "\\blockthreeqtrshaded" "â–“" julia-latexsubs) -(puthash "\\blacksquare" "â– " julia-latexsubs) -(puthash "\\square" "â–¡" julia-latexsubs) -(puthash "\\squoval" "â–¢" julia-latexsubs) -(puthash "\\blackinwhitesquare" "â–£" julia-latexsubs) -(puthash "\\squarehfill" "â–¤" julia-latexsubs) -(puthash "\\squarevfill" "â–¥" julia-latexsubs) -(puthash "\\squarehvfill" "â–¦" julia-latexsubs) -(puthash "\\squarenwsefill" "â–§" julia-latexsubs) -(puthash "\\squareneswfill" "â–¨" julia-latexsubs) -(puthash "\\squarecrossfill" "â–©" julia-latexsubs) -(puthash "\\smblksquare" "â–ª" julia-latexsubs) -(puthash "\\smwhtsquare" "â–«" julia-latexsubs) -(puthash "\\hrectangleblack" "â–¬" julia-latexsubs) -(puthash "\\hrectangle" "â–­" julia-latexsubs) -(puthash "\\vrectangleblack" "â–®" julia-latexsubs) -(puthash "\\Elzvrecto" "â–¯" julia-latexsubs) -(puthash "\\parallelogramblack" "â–°" julia-latexsubs) -(puthash "\\parallelogram" "â–±" julia-latexsubs) -(puthash "\\bigblacktriangleup" "â–²" julia-latexsubs) -(puthash "\\bigtriangleup" "â–³" julia-latexsubs) -(puthash "\\blacktriangle" "â–´" julia-latexsubs) -(puthash "\\vartriangle" "â–µ" julia-latexsubs) -(puthash "\\blacktriangleright" "â–¶" julia-latexsubs) -(puthash "\\triangleright" "â–·" julia-latexsubs) -(puthash "\\smallblacktriangleright" "â–¸" julia-latexsubs) -(puthash "\\smalltriangleright" "â–¹" julia-latexsubs) -(puthash "\\blackpointerright" "â–º" julia-latexsubs) -(puthash "\\whitepointerright" "â–»" julia-latexsubs) -(puthash "\\bigblacktriangledown" "â–¼" julia-latexsubs) -(puthash "\\bigtriangledown" "â–½" julia-latexsubs) -(puthash "\\blacktriangledown" "â–¾" julia-latexsubs) -(puthash "\\triangledown" "â–¿" julia-latexsubs) -(puthash "\\blacktriangleleft" "â—€" julia-latexsubs) -(puthash "\\triangleleft" "â—" julia-latexsubs) -(puthash "\\smallblacktriangleleft" "â—‚" julia-latexsubs) -(puthash "\\smalltriangleleft" "â—ƒ" julia-latexsubs) -(puthash "\\blackpointerleft" "â—„" julia-latexsubs) -(puthash "\\whitepointerleft" "â—…" julia-latexsubs) -(puthash "\\mdlgblkdiamond" "â—†" julia-latexsubs) -(puthash "\\mdlgwhtdiamond" "â—‡" julia-latexsubs) -(puthash "\\blackinwhitediamond" "â—ˆ" julia-latexsubs) -(puthash "\\fisheye" "â—‰" julia-latexsubs) -(puthash "\\lozenge" "â—Š" julia-latexsubs) -(puthash "\\bigcirc" "â—‹" julia-latexsubs) -(puthash "\\dottedcircle" "â—Œ" julia-latexsubs) -(puthash "\\circlevertfill" "â—" julia-latexsubs) -(puthash "\\bullseye" "â—Ž" julia-latexsubs) -(puthash "\\mdlgblkcircle" "â—" julia-latexsubs) -(puthash "\\Elzcirfl" "â—" julia-latexsubs) -(puthash "\\Elzcirfr" "â—‘" julia-latexsubs) -(puthash "\\Elzcirfb" "â—’" julia-latexsubs) -(puthash "\\circletophalfblack" "â—“" julia-latexsubs) -(puthash "\\circleurquadblack" "â—”" julia-latexsubs) -(puthash "\\blackcircleulquadwhite" "â—•" julia-latexsubs) -(puthash "\\blacklefthalfcircle" "â—–" julia-latexsubs) -(puthash "\\blackrighthalfcircle" "â——" julia-latexsubs) -(puthash "\\Elzrvbull" "â—˜" julia-latexsubs) -(puthash "\\inversewhitecircle" "â—™" julia-latexsubs) -(puthash "\\invwhiteupperhalfcircle" "â—š" julia-latexsubs) -(puthash "\\invwhitelowerhalfcircle" "â—›" julia-latexsubs) -(puthash "\\ularc" "â—œ" julia-latexsubs) -(puthash "\\urarc" "â—" julia-latexsubs) -(puthash "\\lrarc" "â—ž" julia-latexsubs) -(puthash "\\llarc" "â—Ÿ" julia-latexsubs) -(puthash "\\topsemicircle" "â— " julia-latexsubs) -(puthash "\\botsemicircle" "â—¡" julia-latexsubs) -(puthash "\\lrblacktriangle" "â—¢" julia-latexsubs) -(puthash "\\llblacktriangle" "â—£" julia-latexsubs) -(puthash "\\ulblacktriangle" "â—¤" julia-latexsubs) -(puthash "\\urblacktriangle" "â—¥" julia-latexsubs) -(puthash "\\smwhtcircle" "â—¦" julia-latexsubs) -(puthash "\\Elzsqfl" "â—§" julia-latexsubs) -(puthash "\\Elzsqfr" "â—¨" julia-latexsubs) -(puthash "\\squareulblack" "â—©" julia-latexsubs) -(puthash "\\Elzsqfse" "â—ª" julia-latexsubs) -(puthash "\\boxbar" "â—«" julia-latexsubs) -(puthash "\\trianglecdot" "â—¬" julia-latexsubs) -(puthash "\\triangleleftblack" "â—­" julia-latexsubs) -(puthash "\\trianglerightblack" "â—®" julia-latexsubs) -(puthash "\\lgwhtcircle" "â—¯" julia-latexsubs) -(puthash "\\squareulquad" "â—°" julia-latexsubs) -(puthash "\\squarellquad" "â—±" julia-latexsubs) -(puthash "\\squarelrquad" "â—²" julia-latexsubs) -(puthash "\\squareurquad" "â—³" julia-latexsubs) -(puthash "\\circleulquad" "â—´" julia-latexsubs) -(puthash "\\circlellquad" "â—µ" julia-latexsubs) -(puthash "\\circlelrquad" "â—¶" julia-latexsubs) -(puthash "\\circleurquad" "â—·" julia-latexsubs) -(puthash "\\ultriangle" "â—¸" julia-latexsubs) -(puthash "\\urtriangle" "â—¹" julia-latexsubs) -(puthash "\\lltriangle" "â—º" julia-latexsubs) -(puthash "\\mdwhtsquare" "â—»" julia-latexsubs) -(puthash "\\mdblksquare" "â—¼" julia-latexsubs) -(puthash "\\mdsmwhtsquare" "â—½" julia-latexsubs) -(puthash "\\mdsmblksquare" "â—¾" julia-latexsubs) -(puthash "\\lrtriangle" "â—¿" julia-latexsubs) -(puthash "\\bigstar" "★" julia-latexsubs) -(puthash "\\bigwhitestar" "☆" julia-latexsubs) -(puthash "\\astrosun" "☉" julia-latexsubs) -(puthash "\\danger" "☡" julia-latexsubs) -(puthash "\\blacksmiley" "☻" julia-latexsubs) -(puthash "\\sun" "☼" julia-latexsubs) -(puthash "\\rightmoon" "☽" julia-latexsubs) -(puthash "\\leftmoon" "☾" julia-latexsubs) -(puthash "\\mercury" "☿" julia-latexsubs) -(puthash "\\venus" "♀" julia-latexsubs) -(puthash "\\female" "♀" julia-latexsubs) -(puthash "\\male" "♂" julia-latexsubs) -(puthash "\\mars" "♂" julia-latexsubs) -(puthash "\\jupiter" "♃" julia-latexsubs) -(puthash "\\saturn" "♄" julia-latexsubs) -(puthash "\\uranus" "â™…" julia-latexsubs) -(puthash "\\neptune" "♆" julia-latexsubs) -(puthash "\\pluto" "♇" julia-latexsubs) -(puthash "\\aries" "♈" julia-latexsubs) -(puthash "\\taurus" "♉" julia-latexsubs) -(puthash "\\gemini" "♊" julia-latexsubs) -(puthash "\\cancer" "♋" julia-latexsubs) -(puthash "\\leo" "♌" julia-latexsubs) -(puthash "\\virgo" "â™" julia-latexsubs) -(puthash "\\libra" "♎" julia-latexsubs) -(puthash "\\scorpio" "â™" julia-latexsubs) -(puthash "\\sagittarius" "â™" julia-latexsubs) -(puthash "\\capricornus" "♑" julia-latexsubs) -(puthash "\\aquarius" "â™’" julia-latexsubs) -(puthash "\\pisces" "♓" julia-latexsubs) -(puthash "\\spadesuit" "â™ " julia-latexsubs) -(puthash "\\heartsuit" "♡" julia-latexsubs) -(puthash "\\diamondsuit" "♢" julia-latexsubs) -(puthash "\\clubsuit" "♣" julia-latexsubs) -(puthash "\\varspadesuit" "♤" julia-latexsubs) -(puthash "\\varheartsuit" "♥" julia-latexsubs) -(puthash "\\vardiamondsuit" "♦" julia-latexsubs) -(puthash "\\varclubsuit" "♧" julia-latexsubs) -(puthash "\\quarternote" "♩" julia-latexsubs) -(puthash "\\eighthnote" "♪" julia-latexsubs) -(puthash "\\twonotes" "♫" julia-latexsubs) -(puthash "\\flat" "â™­" julia-latexsubs) -(puthash "\\natural" "â™®" julia-latexsubs) -(puthash "\\sharp" "♯" julia-latexsubs) -(puthash "\\acidfree" "♾" julia-latexsubs) -(puthash "\\dicei" "⚀" julia-latexsubs) -(puthash "\\diceii" "âš" julia-latexsubs) -(puthash "\\diceiii" "âš‚" julia-latexsubs) -(puthash "\\diceiv" "⚃" julia-latexsubs) -(puthash "\\dicev" "âš„" julia-latexsubs) -(puthash "\\dicevi" "âš…" julia-latexsubs) -(puthash "\\circledrightdot" "⚆" julia-latexsubs) -(puthash "\\circledtwodots" "⚇" julia-latexsubs) -(puthash "\\blackcircledrightdot" "⚈" julia-latexsubs) -(puthash "\\blackcircledtwodots" "⚉" julia-latexsubs) -(puthash "\\Hermaphrodite" "⚥" julia-latexsubs) -(puthash "\\mdwhtcircle" "⚪" julia-latexsubs) -(puthash "\\mdblkcircle" "âš«" julia-latexsubs) -(puthash "\\mdsmwhtcircle" "⚬" julia-latexsubs) -(puthash "\\neuter" "âš²" julia-latexsubs) -(puthash "\\checkmark" "✓" julia-latexsubs) -(puthash "\\maltese" "✠" julia-latexsubs) -(puthash "\\circledstar" "✪" julia-latexsubs) -(puthash "\\varstar" "✶" julia-latexsubs) -(puthash "\\dingasterisk" "✽" julia-latexsubs) -(puthash "\\draftingarrow" "âž›" julia-latexsubs) -(puthash "\\threedangle" "⟀" julia-latexsubs) -(puthash "\\whiteinwhitetriangle" "âŸ" julia-latexsubs) -(puthash "\\perp" "⟂" julia-latexsubs) -(puthash "\\bsolhsub" "⟈" julia-latexsubs) -(puthash "\\suphsol" "⟉" julia-latexsubs) -(puthash "\\wedgedot" "⟑" julia-latexsubs) -(puthash "\\upin" "⟒" julia-latexsubs) -(puthash "\\leftouterjoin" "⟕" julia-latexsubs) -(puthash "\\rightouterjoin" "⟖" julia-latexsubs) -(puthash "\\fullouterjoin" "⟗" julia-latexsubs) -(puthash "\\bigbot" "⟘" julia-latexsubs) -(puthash "\\bigtop" "⟙" julia-latexsubs) -(puthash "\\llbracket" "⟦" julia-latexsubs) -(puthash "\\openbracketleft" "⟦" julia-latexsubs) -(puthash "\\openbracketright" "⟧" julia-latexsubs) -(puthash "\\rrbracket" "⟧" julia-latexsubs) -(puthash "\\langle" "⟨" julia-latexsubs) -(puthash "\\rangle" "⟩" julia-latexsubs) -(puthash "\\UUparrow" "⟰" julia-latexsubs) -(puthash "\\DDownarrow" "⟱" julia-latexsubs) -(puthash "\\longleftarrow" "⟵" julia-latexsubs) -(puthash "\\longrightarrow" "⟶" julia-latexsubs) -(puthash "\\longleftrightarrow" "⟷" julia-latexsubs) -(puthash "\\impliedby" "⟸" julia-latexsubs) -(puthash "\\Longleftarrow" "⟸" julia-latexsubs) -(puthash "\\implies" "⟹" julia-latexsubs) -(puthash "\\Longrightarrow" "⟹" julia-latexsubs) -(puthash "\\Longleftrightarrow" "⟺" julia-latexsubs) -(puthash "\\iff" "⟺" julia-latexsubs) -(puthash "\\longmapsfrom" "⟻" julia-latexsubs) -(puthash "\\longmapsto" "⟼" julia-latexsubs) -(puthash "\\Longmapsfrom" "⟽" julia-latexsubs) -(puthash "\\Longmapsto" "⟾" julia-latexsubs) -(puthash "\\longrightsquigarrow" "⟿" julia-latexsubs) -(puthash "\\nvtwoheadrightarrow" "⤀" julia-latexsubs) -(puthash "\\nVtwoheadrightarrow" "â¤" julia-latexsubs) -(puthash "\\nvLeftarrow" "⤂" julia-latexsubs) -(puthash "\\nvRightarrow" "⤃" julia-latexsubs) -(puthash "\\nvLeftrightarrow" "⤄" julia-latexsubs) -(puthash "\\twoheadmapsto" "⤅" julia-latexsubs) -(puthash "\\Mapsfrom" "⤆" julia-latexsubs) -(puthash "\\Mapsto" "⤇" julia-latexsubs) -(puthash "\\downarrowbarred" "⤈" julia-latexsubs) -(puthash "\\uparrowbarred" "⤉" julia-latexsubs) -(puthash "\\Uuparrow" "⤊" julia-latexsubs) -(puthash "\\Ddownarrow" "⤋" julia-latexsubs) -(puthash "\\leftbkarrow" "⤌" julia-latexsubs) -(puthash "\\bkarow" "â¤" julia-latexsubs) -(puthash "\\leftdbkarrow" "⤎" julia-latexsubs) -(puthash "\\dbkarow" "â¤" julia-latexsubs) -(puthash "\\drbkarrow" "â¤" julia-latexsubs) -(puthash "\\rightdotarrow" "⤑" julia-latexsubs) -(puthash "\\UpArrowBar" "⤒" julia-latexsubs) -(puthash "\\DownArrowBar" "⤓" julia-latexsubs) -(puthash "\\nvrightarrowtail" "⤔" julia-latexsubs) -(puthash "\\nVrightarrowtail" "⤕" julia-latexsubs) -(puthash "\\twoheadrightarrowtail" "⤖" julia-latexsubs) -(puthash "\\nvtwoheadrightarrowtail" "⤗" julia-latexsubs) -(puthash "\\nVtwoheadrightarrowtail" "⤘" julia-latexsubs) -(puthash "\\diamondleftarrow" "â¤" julia-latexsubs) -(puthash "\\rightarrowdiamond" "⤞" julia-latexsubs) -(puthash "\\diamondleftarrowbar" "⤟" julia-latexsubs) -(puthash "\\barrightarrowdiamond" "⤠" julia-latexsubs) -(puthash "\\hksearow" "⤥" julia-latexsubs) -(puthash "\\hkswarow" "⤦" julia-latexsubs) -(puthash "\\tona" "⤧" julia-latexsubs) -(puthash "\\toea" "⤨" julia-latexsubs) -(puthash "\\tosa" "⤩" julia-latexsubs) -(puthash "\\towa" "⤪" julia-latexsubs) -(puthash "\\rdiagovfdiag" "⤫" julia-latexsubs) -(puthash "\\fdiagovrdiag" "⤬" julia-latexsubs) -(puthash "\\seovnearrow" "⤭" julia-latexsubs) -(puthash "\\neovsearrow" "⤮" julia-latexsubs) -(puthash "\\fdiagovnearrow" "⤯" julia-latexsubs) -(puthash "\\rdiagovsearrow" "⤰" julia-latexsubs) -(puthash "\\neovnwarrow" "⤱" julia-latexsubs) -(puthash "\\nwovnearrow" "⤲" julia-latexsubs) -(puthash "\\ElzRlarr" "⥂" julia-latexsubs) -(puthash "\\ElzrLarr" "⥄" julia-latexsubs) -(puthash "\\rightarrowplus" "⥅" julia-latexsubs) -(puthash "\\leftarrowplus" "⥆" julia-latexsubs) -(puthash "\\Elzrarrx" "⥇" julia-latexsubs) -(puthash "\\leftrightarrowcircle" "⥈" julia-latexsubs) -(puthash "\\twoheaduparrowcircle" "⥉" julia-latexsubs) -(puthash "\\leftrightharpoonupdown" "⥊" julia-latexsubs) -(puthash "\\leftrightharpoondownup" "⥋" julia-latexsubs) -(puthash "\\updownharpoonrightleft" "⥌" julia-latexsubs) -(puthash "\\updownharpoonleftright" "â¥" julia-latexsubs) -(puthash "\\LeftRightVector" "⥎" julia-latexsubs) -(puthash "\\RightUpDownVector" "â¥" julia-latexsubs) -(puthash "\\DownLeftRightVector" "â¥" julia-latexsubs) -(puthash "\\LeftUpDownVector" "⥑" julia-latexsubs) -(puthash "\\LeftVectorBar" "⥒" julia-latexsubs) -(puthash "\\RightVectorBar" "⥓" julia-latexsubs) -(puthash "\\RightUpVectorBar" "⥔" julia-latexsubs) -(puthash "\\RightDownVectorBar" "⥕" julia-latexsubs) -(puthash "\\DownLeftVectorBar" "⥖" julia-latexsubs) -(puthash "\\DownRightVectorBar" "⥗" julia-latexsubs) -(puthash "\\LeftUpVectorBar" "⥘" julia-latexsubs) -(puthash "\\LeftDownVectorBar" "⥙" julia-latexsubs) -(puthash "\\LeftTeeVector" "⥚" julia-latexsubs) -(puthash "\\RightTeeVector" "⥛" julia-latexsubs) -(puthash "\\RightUpTeeVector" "⥜" julia-latexsubs) -(puthash "\\RightDownTeeVector" "â¥" julia-latexsubs) -(puthash "\\DownLeftTeeVector" "⥞" julia-latexsubs) -(puthash "\\DownRightTeeVector" "⥟" julia-latexsubs) -(puthash "\\LeftUpTeeVector" "⥠" julia-latexsubs) -(puthash "\\LeftDownTeeVector" "⥡" julia-latexsubs) -(puthash "\\leftharpoonsupdown" "⥢" julia-latexsubs) -(puthash "\\upharpoonsleftright" "⥣" julia-latexsubs) -(puthash "\\rightharpoonsupdown" "⥤" julia-latexsubs) -(puthash "\\downharpoonsleftright" "⥥" julia-latexsubs) -(puthash "\\leftrightharpoonsup" "⥦" julia-latexsubs) -(puthash "\\leftrightharpoonsdown" "⥧" julia-latexsubs) -(puthash "\\rightleftharpoonsup" "⥨" julia-latexsubs) -(puthash "\\rightleftharpoonsdown" "⥩" julia-latexsubs) -(puthash "\\leftharpoonupdash" "⥪" julia-latexsubs) -(puthash "\\dashleftharpoondown" "⥫" julia-latexsubs) -(puthash "\\rightharpoonupdash" "⥬" julia-latexsubs) -(puthash "\\dashrightharpoondown" "⥭" julia-latexsubs) -(puthash "\\UpEquilibrium" "⥮" julia-latexsubs) -(puthash "\\ReverseUpEquilibrium" "⥯" julia-latexsubs) -(puthash "\\RoundImplies" "⥰" julia-latexsubs) -(puthash "\\Vvert" "⦀" julia-latexsubs) -(puthash "\\Elroang" "⦆" julia-latexsubs) -(puthash "\\Elzddfnc" "⦙" julia-latexsubs) -(puthash "\\measuredangleleft" "⦛" julia-latexsubs) -(puthash "\\Angle" "⦜" julia-latexsubs) -(puthash "\\rightanglemdot" "â¦" julia-latexsubs) -(puthash "\\angles" "⦞" julia-latexsubs) -(puthash "\\angdnr" "⦟" julia-latexsubs) -(puthash "\\Elzlpargt" "⦠" julia-latexsubs) -(puthash "\\sphericalangleup" "⦡" julia-latexsubs) -(puthash "\\turnangle" "⦢" julia-latexsubs) -(puthash "\\revangle" "⦣" julia-latexsubs) -(puthash "\\angleubar" "⦤" julia-latexsubs) -(puthash "\\revangleubar" "⦥" julia-latexsubs) -(puthash "\\wideangledown" "⦦" julia-latexsubs) -(puthash "\\wideangleup" "⦧" julia-latexsubs) -(puthash "\\measanglerutone" "⦨" julia-latexsubs) -(puthash "\\measanglelutonw" "⦩" julia-latexsubs) -(puthash "\\measanglerdtose" "⦪" julia-latexsubs) -(puthash "\\measangleldtosw" "⦫" julia-latexsubs) -(puthash "\\measangleurtone" "⦬" julia-latexsubs) -(puthash "\\measangleultonw" "⦭" julia-latexsubs) -(puthash "\\measangledrtose" "⦮" julia-latexsubs) -(puthash "\\measangledltosw" "⦯" julia-latexsubs) -(puthash "\\revemptyset" "⦰" julia-latexsubs) -(puthash "\\emptysetobar" "⦱" julia-latexsubs) -(puthash "\\emptysetocirc" "⦲" julia-latexsubs) -(puthash "\\emptysetoarr" "⦳" julia-latexsubs) -(puthash "\\emptysetoarrl" "⦴" julia-latexsubs) -(puthash "\\circledparallel" "⦷" julia-latexsubs) -(puthash "\\obslash" "⦸" julia-latexsubs) -(puthash "\\odotslashdot" "⦼" julia-latexsubs) -(puthash "\\circledwhitebullet" "⦾" julia-latexsubs) -(puthash "\\circledbullet" "⦿" julia-latexsubs) -(puthash "\\olessthan" "⧀" julia-latexsubs) -(puthash "\\ogreaterthan" "â§" julia-latexsubs) -(puthash "\\boxdiag" "⧄" julia-latexsubs) -(puthash "\\boxbslash" "⧅" julia-latexsubs) -(puthash "\\boxast" "⧆" julia-latexsubs) -(puthash "\\boxcircle" "⧇" julia-latexsubs) -(puthash "\\ElzLap" "⧊" julia-latexsubs) -(puthash "\\Elzdefas" "⧋" julia-latexsubs) -(puthash "\\LeftTriangleBar" "â§" julia-latexsubs) -(puthash "\\NotLeftTriangleBar" "â§Ì¸" julia-latexsubs) -(puthash "\\RightTriangleBar" "â§" julia-latexsubs) -(puthash "\\NotRightTriangleBar" "â§Ì¸" julia-latexsubs) -(puthash "\\dualmap" "⧟" julia-latexsubs) -(puthash "\\lrtriangleeq" "⧡" julia-latexsubs) -(puthash "\\shuffle" "⧢" julia-latexsubs) -(puthash "\\eparsl" "⧣" julia-latexsubs) -(puthash "\\smeparsl" "⧤" julia-latexsubs) -(puthash "\\eqvparsl" "⧥" julia-latexsubs) -(puthash "\\blacklozenge" "⧫" julia-latexsubs) -(puthash "\\RuleDelayed" "⧴" julia-latexsubs) -(puthash "\\dsol" "⧶" julia-latexsubs) -(puthash "\\rsolbar" "⧷" julia-latexsubs) -(puthash "\\doubleplus" "⧺" julia-latexsubs) -(puthash "\\tripleplus" "⧻" julia-latexsubs) -(puthash "\\bigodot" "⨀" julia-latexsubs) -(puthash "\\bigoplus" "â¨" julia-latexsubs) -(puthash "\\bigotimes" "⨂" julia-latexsubs) -(puthash "\\bigcupdot" "⨃" julia-latexsubs) -(puthash "\\biguplus" "⨄" julia-latexsubs) -(puthash "\\bigsqcap" "⨅" julia-latexsubs) -(puthash "\\bigsqcup" "⨆" julia-latexsubs) -(puthash "\\conjquant" "⨇" julia-latexsubs) -(puthash "\\disjquant" "⨈" julia-latexsubs) -(puthash "\\bigtimes" "⨉" julia-latexsubs) -(puthash "\\modtwosum" "⨊" julia-latexsubs) -(puthash "\\sumint" "⨋" julia-latexsubs) -(puthash "\\iiiint" "⨌" julia-latexsubs) -(puthash "\\intbar" "â¨" julia-latexsubs) -(puthash "\\intBar" "⨎" julia-latexsubs) -(puthash "\\clockoint" "â¨" julia-latexsubs) -(puthash "\\cirfnint" "â¨" julia-latexsubs) -(puthash "\\awint" "⨑" julia-latexsubs) -(puthash "\\rppolint" "⨒" julia-latexsubs) -(puthash "\\scpolint" "⨓" julia-latexsubs) -(puthash "\\npolint" "⨔" julia-latexsubs) -(puthash "\\pointint" "⨕" julia-latexsubs) -(puthash "\\sqrint" "⨖" julia-latexsubs) -(puthash "\\intx" "⨘" julia-latexsubs) -(puthash "\\intcap" "⨙" julia-latexsubs) -(puthash "\\intcup" "⨚" julia-latexsubs) -(puthash "\\upint" "⨛" julia-latexsubs) -(puthash "\\lowint" "⨜" julia-latexsubs) -(puthash "\\Join" "â¨" julia-latexsubs) -(puthash "\\ringplus" "⨢" julia-latexsubs) -(puthash "\\plushat" "⨣" julia-latexsubs) -(puthash "\\simplus" "⨤" julia-latexsubs) -(puthash "\\plusdot" "⨥" julia-latexsubs) -(puthash "\\plussim" "⨦" julia-latexsubs) -(puthash "\\plussubtwo" "⨧" julia-latexsubs) -(puthash "\\plustrif" "⨨" julia-latexsubs) -(puthash "\\commaminus" "⨩" julia-latexsubs) -(puthash "\\minusdot" "⨪" julia-latexsubs) -(puthash "\\minusfdots" "⨫" julia-latexsubs) -(puthash "\\minusrdots" "⨬" julia-latexsubs) -(puthash "\\opluslhrim" "⨭" julia-latexsubs) -(puthash "\\oplusrhrim" "⨮" julia-latexsubs) -(puthash "\\ElzTimes" "⨯" julia-latexsubs) -(puthash "\\dottimes" "⨰" julia-latexsubs) -(puthash "\\timesbar" "⨱" julia-latexsubs) -(puthash "\\btimes" "⨲" julia-latexsubs) -(puthash "\\smashtimes" "⨳" julia-latexsubs) -(puthash "\\otimeslhrim" "⨴" julia-latexsubs) -(puthash "\\otimesrhrim" "⨵" julia-latexsubs) -(puthash "\\otimeshat" "⨶" julia-latexsubs) -(puthash "\\Otimes" "⨷" julia-latexsubs) -(puthash "\\odiv" "⨸" julia-latexsubs) -(puthash "\\triangleplus" "⨹" julia-latexsubs) -(puthash "\\triangleminus" "⨺" julia-latexsubs) -(puthash "\\triangletimes" "⨻" julia-latexsubs) -(puthash "\\intprod" "⨼" julia-latexsubs) -(puthash "\\intprodr" "⨽" julia-latexsubs) -(puthash "\\amalg" "⨿" julia-latexsubs) -(puthash "\\capdot" "â©€" julia-latexsubs) -(puthash "\\uminus" "â©" julia-latexsubs) -(puthash "\\barcup" "â©‚" julia-latexsubs) -(puthash "\\barcap" "⩃" julia-latexsubs) -(puthash "\\capwedge" "â©„" julia-latexsubs) -(puthash "\\cupvee" "â©…" julia-latexsubs) -(puthash "\\twocups" "â©Š" julia-latexsubs) -(puthash "\\twocaps" "â©‹" julia-latexsubs) -(puthash "\\closedvarcup" "â©Œ" julia-latexsubs) -(puthash "\\closedvarcap" "â©" julia-latexsubs) -(puthash "\\Sqcap" "â©Ž" julia-latexsubs) -(puthash "\\Sqcup" "â©" julia-latexsubs) -(puthash "\\closedvarcupsmashprod" "â©" julia-latexsubs) -(puthash "\\wedgeodot" "â©‘" julia-latexsubs) -(puthash "\\veeodot" "â©’" julia-latexsubs) -(puthash "\\ElzAnd" "â©“" julia-latexsubs) -(puthash "\\ElzOr" "â©”" julia-latexsubs) -(puthash "\\wedgeonwedge" "â©•" julia-latexsubs) -(puthash "\\ElOr" "â©–" julia-latexsubs) -(puthash "\\bigslopedvee" "â©—" julia-latexsubs) -(puthash "\\bigslopedwedge" "⩘" julia-latexsubs) -(puthash "\\wedgemidvert" "â©š" julia-latexsubs) -(puthash "\\veemidvert" "â©›" julia-latexsubs) -(puthash "\\midbarwedge" "â©œ" julia-latexsubs) -(puthash "\\midbarvee" "â©" julia-latexsubs) -(puthash "\\perspcorrespond" "â©ž" julia-latexsubs) -(puthash "\\Elzminhat" "â©Ÿ" julia-latexsubs) -(puthash "\\wedgedoublebar" "â© " julia-latexsubs) -(puthash "\\varveebar" "â©¡" julia-latexsubs) -(puthash "\\doublebarvee" "â©¢" julia-latexsubs) -(puthash "\\veedoublebar" "â©£" julia-latexsubs) -(puthash "\\eqdot" "⩦" julia-latexsubs) -(puthash "\\dotequiv" "⩧" julia-latexsubs) -(puthash "\\dotsim" "⩪" julia-latexsubs) -(puthash "\\simrdots" "â©«" julia-latexsubs) -(puthash "\\simminussim" "⩬" julia-latexsubs) -(puthash "\\congdot" "â©­" julia-latexsubs) -(puthash "\\asteq" "â©®" julia-latexsubs) -(puthash "\\hatapprox" "⩯" julia-latexsubs) -(puthash "\\approxeqq" "â©°" julia-latexsubs) -(puthash "\\eqqplus" "⩱" julia-latexsubs) -(puthash "\\pluseqq" "⩲" julia-latexsubs) -(puthash "\\eqqsim" "⩳" julia-latexsubs) -(puthash "\\Coloneq" "â©´" julia-latexsubs) -(puthash "\\Equal" "⩵" julia-latexsubs) -(puthash "\\eqeqeq" "⩶" julia-latexsubs) -(puthash "\\ddotseq" "â©·" julia-latexsubs) -(puthash "\\equivDD" "⩸" julia-latexsubs) -(puthash "\\ltcir" "⩹" julia-latexsubs) -(puthash "\\gtcir" "⩺" julia-latexsubs) -(puthash "\\ltquest" "â©»" julia-latexsubs) -(puthash "\\gtquest" "⩼" julia-latexsubs) -(puthash "\\leqslant" "⩽" julia-latexsubs) -(puthash "\\nleqslant" "⩽̸" julia-latexsubs) -(puthash "\\geqslant" "⩾" julia-latexsubs) -(puthash "\\ngeqslant" "⩾̸" julia-latexsubs) -(puthash "\\lesdot" "â©¿" julia-latexsubs) -(puthash "\\gesdot" "⪀" julia-latexsubs) -(puthash "\\lesdoto" "âª" julia-latexsubs) -(puthash "\\gesdoto" "⪂" julia-latexsubs) -(puthash "\\lesdotor" "⪃" julia-latexsubs) -(puthash "\\gesdotol" "⪄" julia-latexsubs) -(puthash "\\lessapprox" "⪅" julia-latexsubs) -(puthash "\\gtrapprox" "⪆" julia-latexsubs) -(puthash "\\lneq" "⪇" julia-latexsubs) -(puthash "\\gneq" "⪈" julia-latexsubs) -(puthash "\\lnapprox" "⪉" julia-latexsubs) -(puthash "\\gnapprox" "⪊" julia-latexsubs) -(puthash "\\lesseqqgtr" "⪋" julia-latexsubs) -(puthash "\\gtreqqless" "⪌" julia-latexsubs) -(puthash "\\lsime" "âª" julia-latexsubs) -(puthash "\\gsime" "⪎" julia-latexsubs) -(puthash "\\lsimg" "âª" julia-latexsubs) -(puthash "\\gsiml" "âª" julia-latexsubs) -(puthash "\\lgE" "⪑" julia-latexsubs) -(puthash "\\glE" "⪒" julia-latexsubs) -(puthash "\\lesges" "⪓" julia-latexsubs) -(puthash "\\gesles" "⪔" julia-latexsubs) -(puthash "\\eqslantless" "⪕" julia-latexsubs) -(puthash "\\eqslantgtr" "⪖" julia-latexsubs) -(puthash "\\elsdot" "⪗" julia-latexsubs) -(puthash "\\egsdot" "⪘" julia-latexsubs) -(puthash "\\eqqless" "⪙" julia-latexsubs) -(puthash "\\eqqgtr" "⪚" julia-latexsubs) -(puthash "\\eqqslantless" "⪛" julia-latexsubs) -(puthash "\\eqqslantgtr" "⪜" julia-latexsubs) -(puthash "\\simless" "âª" julia-latexsubs) -(puthash "\\simgtr" "⪞" julia-latexsubs) -(puthash "\\simlE" "⪟" julia-latexsubs) -(puthash "\\simgE" "⪠" julia-latexsubs) -(puthash "\\NestedLessLess" "⪡" julia-latexsubs) -(puthash "\\NotNestedLessLess" "⪡̸" julia-latexsubs) -(puthash "\\NestedGreaterGreater" "⪢" julia-latexsubs) -(puthash "\\NotNestedGreaterGreater" "⪢̸" julia-latexsubs) -(puthash "\\partialmeetcontraction" "⪣" julia-latexsubs) -(puthash "\\glj" "⪤" julia-latexsubs) -(puthash "\\gla" "⪥" julia-latexsubs) -(puthash "\\ltcc" "⪦" julia-latexsubs) -(puthash "\\gtcc" "⪧" julia-latexsubs) -(puthash "\\lescc" "⪨" julia-latexsubs) -(puthash "\\gescc" "⪩" julia-latexsubs) -(puthash "\\smt" "⪪" julia-latexsubs) -(puthash "\\lat" "⪫" julia-latexsubs) -(puthash "\\smte" "⪬" julia-latexsubs) -(puthash "\\late" "⪭" julia-latexsubs) -(puthash "\\bumpeqq" "⪮" julia-latexsubs) -(puthash "\\preceq" "⪯" julia-latexsubs) -(puthash "\\npreceq" "⪯̸" julia-latexsubs) -(puthash "\\succeq" "⪰" julia-latexsubs) -(puthash "\\nsucceq" "⪰̸" julia-latexsubs) -(puthash "\\precneq" "⪱" julia-latexsubs) -(puthash "\\succneq" "⪲" julia-latexsubs) -(puthash "\\preceqq" "⪳" julia-latexsubs) -(puthash "\\succeqq" "⪴" julia-latexsubs) -(puthash "\\precneqq" "⪵" julia-latexsubs) -(puthash "\\succneqq" "⪶" julia-latexsubs) -(puthash "\\precapprox" "⪷" julia-latexsubs) -(puthash "\\succapprox" "⪸" julia-latexsubs) -(puthash "\\precnapprox" "⪹" julia-latexsubs) -(puthash "\\succnapprox" "⪺" julia-latexsubs) -(puthash "\\Prec" "⪻" julia-latexsubs) -(puthash "\\Succ" "⪼" julia-latexsubs) -(puthash "\\subsetdot" "⪽" julia-latexsubs) -(puthash "\\supsetdot" "⪾" julia-latexsubs) -(puthash "\\subsetplus" "⪿" julia-latexsubs) -(puthash "\\supsetplus" "â«€" julia-latexsubs) -(puthash "\\submult" "â«" julia-latexsubs) -(puthash "\\supmult" "â«‚" julia-latexsubs) -(puthash "\\subedot" "⫃" julia-latexsubs) -(puthash "\\supedot" "â«„" julia-latexsubs) -(puthash "\\subseteqq" "â«…" julia-latexsubs) -(puthash "\\nsubseteqq" "⫅̸" julia-latexsubs) -(puthash "\\supseteqq" "⫆" julia-latexsubs) -(puthash "\\nsupseteqq" "⫆̸" julia-latexsubs) -(puthash "\\subsim" "⫇" julia-latexsubs) -(puthash "\\supsim" "⫈" julia-latexsubs) -(puthash "\\subsetapprox" "⫉" julia-latexsubs) -(puthash "\\supsetapprox" "â«Š" julia-latexsubs) -(puthash "\\subsetneqq" "â«‹" julia-latexsubs) -(puthash "\\supsetneqq" "â«Œ" julia-latexsubs) -(puthash "\\lsqhook" "â«" julia-latexsubs) -(puthash "\\rsqhook" "â«Ž" julia-latexsubs) -(puthash "\\csub" "â«" julia-latexsubs) -(puthash "\\csup" "â«" julia-latexsubs) -(puthash "\\csube" "â«‘" julia-latexsubs) -(puthash "\\csupe" "â«’" julia-latexsubs) -(puthash "\\subsup" "â«“" julia-latexsubs) -(puthash "\\supsub" "â«”" julia-latexsubs) -(puthash "\\subsub" "â«•" julia-latexsubs) -(puthash "\\supsup" "â«–" julia-latexsubs) -(puthash "\\suphsub" "â«—" julia-latexsubs) -(puthash "\\supdsub" "⫘" julia-latexsubs) -(puthash "\\forkv" "â«™" julia-latexsubs) -(puthash "\\mlcp" "â«›" julia-latexsubs) -(puthash "\\forks" "â«œ" julia-latexsubs) -(puthash "\\forksnot" "â«" julia-latexsubs) -(puthash "\\dashV" "â«£" julia-latexsubs) -(puthash "\\Dashv" "⫤" julia-latexsubs) -(puthash "\\interleave" "â«´" julia-latexsubs) -(puthash "\\Elztdcol" "⫶" julia-latexsubs) -(puthash "\\lllnest" "â«·" julia-latexsubs) -(puthash "\\gggnest" "⫸" julia-latexsubs) -(puthash "\\leqqslant" "⫹" julia-latexsubs) -(puthash "\\geqqslant" "⫺" julia-latexsubs) -(puthash "\\squaretopblack" "⬒" julia-latexsubs) -(puthash "\\squarebotblack" "⬓" julia-latexsubs) -(puthash "\\squareurblack" "⬔" julia-latexsubs) -(puthash "\\squarellblack" "⬕" julia-latexsubs) -(puthash "\\diamondleftblack" "⬖" julia-latexsubs) -(puthash "\\diamondrightblack" "⬗" julia-latexsubs) -(puthash "\\diamondtopblack" "⬘" julia-latexsubs) -(puthash "\\diamondbotblack" "⬙" julia-latexsubs) -(puthash "\\dottedsquare" "⬚" julia-latexsubs) -(puthash "\\lgblksquare" "⬛" julia-latexsubs) -(puthash "\\lgwhtsquare" "⬜" julia-latexsubs) -(puthash "\\vysmblksquare" "â¬" julia-latexsubs) -(puthash "\\vysmwhtsquare" "⬞" julia-latexsubs) -(puthash "\\pentagonblack" "⬟" julia-latexsubs) -(puthash "\\pentagon" "⬠" julia-latexsubs) -(puthash "\\varhexagon" "⬡" julia-latexsubs) -(puthash "\\varhexagonblack" "⬢" julia-latexsubs) -(puthash "\\hexagonblack" "⬣" julia-latexsubs) -(puthash "\\lgblkcircle" "⬤" julia-latexsubs) -(puthash "\\mdblkdiamond" "⬥" julia-latexsubs) -(puthash "\\mdwhtdiamond" "⬦" julia-latexsubs) -(puthash "\\mdblklozenge" "⬧" julia-latexsubs) -(puthash "\\mdwhtlozenge" "⬨" julia-latexsubs) -(puthash "\\smblkdiamond" "⬩" julia-latexsubs) -(puthash "\\smblklozenge" "⬪" julia-latexsubs) -(puthash "\\smwhtlozenge" "⬫" julia-latexsubs) -(puthash "\\blkhorzoval" "⬬" julia-latexsubs) -(puthash "\\whthorzoval" "⬭" julia-latexsubs) -(puthash "\\blkvertoval" "⬮" julia-latexsubs) -(puthash "\\whtvertoval" "⬯" julia-latexsubs) -(puthash "\\circleonleftarrow" "⬰" julia-latexsubs) -(puthash "\\leftthreearrows" "⬱" julia-latexsubs) -(puthash "\\leftarrowonoplus" "⬲" julia-latexsubs) -(puthash "\\longleftsquigarrow" "⬳" julia-latexsubs) -(puthash "\\nvtwoheadleftarrow" "⬴" julia-latexsubs) -(puthash "\\nVtwoheadleftarrow" "⬵" julia-latexsubs) -(puthash "\\twoheadmapsfrom" "⬶" julia-latexsubs) -(puthash "\\twoheadleftdbkarrow" "⬷" julia-latexsubs) -(puthash "\\leftdotarrow" "⬸" julia-latexsubs) -(puthash "\\nvleftarrowtail" "⬹" julia-latexsubs) -(puthash "\\nVleftarrowtail" "⬺" julia-latexsubs) -(puthash "\\twoheadleftarrowtail" "⬻" julia-latexsubs) -(puthash "\\nvtwoheadleftarrowtail" "⬼" julia-latexsubs) -(puthash "\\nVtwoheadleftarrowtail" "⬽" julia-latexsubs) -(puthash "\\leftarrowx" "⬾" julia-latexsubs) -(puthash "\\leftcurvedarrow" "⬿" julia-latexsubs) -(puthash "\\equalleftarrow" "â­€" julia-latexsubs) -(puthash "\\bsimilarleftarrow" "â­" julia-latexsubs) -(puthash "\\leftarrowbackapprox" "â­‚" julia-latexsubs) -(puthash "\\rightarrowgtr" "â­ƒ" julia-latexsubs) -(puthash "\\rightarrowsupset" "â­„" julia-latexsubs) -(puthash "\\LLeftarrow" "â­…" julia-latexsubs) -(puthash "\\RRightarrow" "â­†" julia-latexsubs) -(puthash "\\bsimilarrightarrow" "â­‡" julia-latexsubs) -(puthash "\\rightarrowbackapprox" "â­ˆ" julia-latexsubs) -(puthash "\\similarleftarrow" "â­‰" julia-latexsubs) -(puthash "\\leftarrowapprox" "â­Š" julia-latexsubs) -(puthash "\\leftarrowbsimilar" "â­‹" julia-latexsubs) -(puthash "\\rightarrowbsimilar" "â­Œ" julia-latexsubs) -(puthash "\\medwhitestar" "â­" julia-latexsubs) -(puthash "\\medblackstar" "â­‘" julia-latexsubs) -(puthash "\\smwhitestar" "â­’" julia-latexsubs) -(puthash "\\rightpentagonblack" "â­“" julia-latexsubs) -(puthash "\\rightpentagon" "â­”" julia-latexsubs) -(puthash "\\_j" "â±¼" julia-latexsubs) -(puthash "\\^V" "â±½" julia-latexsubs) -(puthash "\\postalmark" "〒" julia-latexsubs) -(puthash "\\mbfA" "ð€" julia-latexsubs) -(puthash "\\mbfB" "ð" julia-latexsubs) -(puthash "\\mbfC" "ð‚" julia-latexsubs) -(puthash "\\mbfD" "ðƒ" julia-latexsubs) -(puthash "\\mbfE" "ð„" julia-latexsubs) -(puthash "\\mbfF" "ð…" julia-latexsubs) -(puthash "\\mbfG" "ð†" julia-latexsubs) -(puthash "\\mbfH" "ð‡" julia-latexsubs) -(puthash "\\mbfI" "ðˆ" julia-latexsubs) -(puthash "\\mbfJ" "ð‰" julia-latexsubs) -(puthash "\\mbfK" "ðŠ" julia-latexsubs) -(puthash "\\mbfL" "ð‹" julia-latexsubs) -(puthash "\\mbfM" "ðŒ" julia-latexsubs) -(puthash "\\mbfN" "ð" julia-latexsubs) -(puthash "\\mbfO" "ðŽ" julia-latexsubs) -(puthash "\\mbfP" "ð" julia-latexsubs) -(puthash "\\mbfQ" "ð" julia-latexsubs) -(puthash "\\mbfR" "ð‘" julia-latexsubs) -(puthash "\\mbfS" "ð’" julia-latexsubs) -(puthash "\\mbfT" "ð“" julia-latexsubs) -(puthash "\\mbfU" "ð”" julia-latexsubs) -(puthash "\\mbfV" "ð•" julia-latexsubs) -(puthash "\\mbfW" "ð–" julia-latexsubs) -(puthash "\\mbfX" "ð—" julia-latexsubs) -(puthash "\\mbfY" "ð˜" julia-latexsubs) -(puthash "\\mbfZ" "ð™" julia-latexsubs) -(puthash "\\mbfa" "ðš" julia-latexsubs) -(puthash "\\mbfb" "ð›" julia-latexsubs) -(puthash "\\mbfc" "ðœ" julia-latexsubs) -(puthash "\\mbfd" "ð" julia-latexsubs) -(puthash "\\mbfe" "ðž" julia-latexsubs) -(puthash "\\mbff" "ðŸ" julia-latexsubs) -(puthash "\\mbfg" "ð " julia-latexsubs) -(puthash "\\mbfh" "ð¡" julia-latexsubs) -(puthash "\\mbfi" "ð¢" julia-latexsubs) -(puthash "\\mbfj" "ð£" julia-latexsubs) -(puthash "\\mbfk" "ð¤" julia-latexsubs) -(puthash "\\mbfl" "ð¥" julia-latexsubs) -(puthash "\\mbfm" "ð¦" julia-latexsubs) -(puthash "\\mbfn" "ð§" julia-latexsubs) -(puthash "\\mbfo" "ð¨" julia-latexsubs) -(puthash "\\mbfp" "ð©" julia-latexsubs) -(puthash "\\mbfq" "ðª" julia-latexsubs) -(puthash "\\mbfr" "ð«" julia-latexsubs) -(puthash "\\mbfs" "ð¬" julia-latexsubs) -(puthash "\\mbft" "ð­" julia-latexsubs) -(puthash "\\mbfu" "ð®" julia-latexsubs) -(puthash "\\mbfv" "ð¯" julia-latexsubs) -(puthash "\\mbfw" "ð°" julia-latexsubs) -(puthash "\\mbfx" "ð±" julia-latexsubs) -(puthash "\\mbfy" "ð²" julia-latexsubs) -(puthash "\\mbfz" "ð³" julia-latexsubs) -(puthash "\\mitA" "ð´" julia-latexsubs) -(puthash "\\mitB" "ðµ" julia-latexsubs) -(puthash "\\mitC" "ð¶" julia-latexsubs) -(puthash "\\mitD" "ð·" julia-latexsubs) -(puthash "\\mitE" "ð¸" julia-latexsubs) -(puthash "\\mitF" "ð¹" julia-latexsubs) -(puthash "\\mitG" "ðº" julia-latexsubs) -(puthash "\\mitH" "ð»" julia-latexsubs) -(puthash "\\mitI" "ð¼" julia-latexsubs) -(puthash "\\mitJ" "ð½" julia-latexsubs) -(puthash "\\mitK" "ð¾" julia-latexsubs) -(puthash "\\mitL" "ð¿" julia-latexsubs) -(puthash "\\mitM" "ð‘€" julia-latexsubs) -(puthash "\\mitN" "ð‘" julia-latexsubs) -(puthash "\\mitO" "ð‘‚" julia-latexsubs) -(puthash "\\mitP" "ð‘ƒ" julia-latexsubs) -(puthash "\\mitQ" "ð‘„" julia-latexsubs) -(puthash "\\mitR" "ð‘…" julia-latexsubs) -(puthash "\\mitS" "ð‘†" julia-latexsubs) -(puthash "\\mitT" "ð‘‡" julia-latexsubs) -(puthash "\\mitU" "ð‘ˆ" julia-latexsubs) -(puthash "\\mitV" "ð‘‰" julia-latexsubs) -(puthash "\\mitW" "ð‘Š" julia-latexsubs) -(puthash "\\mitX" "ð‘‹" julia-latexsubs) -(puthash "\\mitY" "ð‘Œ" julia-latexsubs) -(puthash "\\mitZ" "ð‘" julia-latexsubs) -(puthash "\\mita" "ð‘Ž" julia-latexsubs) -(puthash "\\mitb" "ð‘" julia-latexsubs) -(puthash "\\mitc" "ð‘" julia-latexsubs) -(puthash "\\mitd" "ð‘‘" julia-latexsubs) -(puthash "\\mite" "ð‘’" julia-latexsubs) -(puthash "\\mitf" "ð‘“" julia-latexsubs) -(puthash "\\mitg" "ð‘”" julia-latexsubs) -(puthash "\\miti" "ð‘–" julia-latexsubs) -(puthash "\\mitj" "ð‘—" julia-latexsubs) -(puthash "\\mitk" "ð‘˜" julia-latexsubs) -(puthash "\\mitl" "ð‘™" julia-latexsubs) -(puthash "\\mitm" "ð‘š" julia-latexsubs) -(puthash "\\mitn" "ð‘›" julia-latexsubs) -(puthash "\\mito" "ð‘œ" julia-latexsubs) -(puthash "\\mitp" "ð‘" julia-latexsubs) -(puthash "\\mitq" "ð‘ž" julia-latexsubs) -(puthash "\\mitr" "ð‘Ÿ" julia-latexsubs) -(puthash "\\mits" "ð‘ " julia-latexsubs) -(puthash "\\mitt" "ð‘¡" julia-latexsubs) -(puthash "\\mitu" "ð‘¢" julia-latexsubs) -(puthash "\\mitv" "ð‘£" julia-latexsubs) -(puthash "\\mitw" "ð‘¤" julia-latexsubs) -(puthash "\\mitx" "ð‘¥" julia-latexsubs) -(puthash "\\mity" "ð‘¦" julia-latexsubs) -(puthash "\\mitz" "ð‘§" julia-latexsubs) -(puthash "\\mbfitA" "ð‘¨" julia-latexsubs) -(puthash "\\mbfitB" "ð‘©" julia-latexsubs) -(puthash "\\mbfitC" "ð‘ª" julia-latexsubs) -(puthash "\\mbfitD" "ð‘«" julia-latexsubs) -(puthash "\\mbfitE" "ð‘¬" julia-latexsubs) -(puthash "\\mbfitF" "ð‘­" julia-latexsubs) -(puthash "\\mbfitG" "ð‘®" julia-latexsubs) -(puthash "\\mbfitH" "ð‘¯" julia-latexsubs) -(puthash "\\mbfitI" "ð‘°" julia-latexsubs) -(puthash "\\mbfitJ" "ð‘±" julia-latexsubs) -(puthash "\\mbfitK" "ð‘²" julia-latexsubs) -(puthash "\\mbfitL" "ð‘³" julia-latexsubs) -(puthash "\\mbfitM" "ð‘´" julia-latexsubs) -(puthash "\\mbfitN" "ð‘µ" julia-latexsubs) -(puthash "\\mbfitO" "ð‘¶" julia-latexsubs) -(puthash "\\mbfitP" "ð‘·" julia-latexsubs) -(puthash "\\mbfitQ" "ð‘¸" julia-latexsubs) -(puthash "\\mbfitR" "ð‘¹" julia-latexsubs) -(puthash "\\mbfitS" "ð‘º" julia-latexsubs) -(puthash "\\mbfitT" "ð‘»" julia-latexsubs) -(puthash "\\mbfitU" "ð‘¼" julia-latexsubs) -(puthash "\\mbfitV" "ð‘½" julia-latexsubs) -(puthash "\\mbfitW" "ð‘¾" julia-latexsubs) -(puthash "\\mbfitX" "ð‘¿" julia-latexsubs) -(puthash "\\mbfitY" "ð’€" julia-latexsubs) -(puthash "\\mbfitZ" "ð’" julia-latexsubs) -(puthash "\\mbfita" "ð’‚" julia-latexsubs) -(puthash "\\mbfitb" "ð’ƒ" julia-latexsubs) -(puthash "\\mbfitc" "ð’„" julia-latexsubs) -(puthash "\\mbfitd" "ð’…" julia-latexsubs) -(puthash "\\mbfite" "ð’†" julia-latexsubs) -(puthash "\\mbfitf" "ð’‡" julia-latexsubs) -(puthash "\\mbfitg" "ð’ˆ" julia-latexsubs) -(puthash "\\mbfith" "ð’‰" julia-latexsubs) -(puthash "\\mbfiti" "ð’Š" julia-latexsubs) -(puthash "\\mbfitj" "ð’‹" julia-latexsubs) -(puthash "\\mbfitk" "ð’Œ" julia-latexsubs) -(puthash "\\mbfitl" "ð’" julia-latexsubs) -(puthash "\\mbfitm" "ð’Ž" julia-latexsubs) -(puthash "\\mbfitn" "ð’" julia-latexsubs) -(puthash "\\mbfito" "ð’" julia-latexsubs) -(puthash "\\mbfitp" "ð’‘" julia-latexsubs) -(puthash "\\mbfitq" "ð’’" julia-latexsubs) -(puthash "\\mbfitr" "ð’“" julia-latexsubs) -(puthash "\\mbfits" "ð’”" julia-latexsubs) -(puthash "\\mbfitt" "ð’•" julia-latexsubs) -(puthash "\\mbfitu" "ð’–" julia-latexsubs) -(puthash "\\mbfitv" "ð’—" julia-latexsubs) -(puthash "\\mbfitw" "ð’˜" julia-latexsubs) -(puthash "\\mbfitx" "ð’™" julia-latexsubs) -(puthash "\\mbfity" "ð’š" julia-latexsubs) -(puthash "\\mbfitz" "ð’›" julia-latexsubs) -(puthash "\\mscrA" "ð’œ" julia-latexsubs) -(puthash "\\mscrC" "ð’ž" julia-latexsubs) -(puthash "\\mscrD" "ð’Ÿ" julia-latexsubs) -(puthash "\\mscrG" "ð’¢" julia-latexsubs) -(puthash "\\mscrJ" "ð’¥" julia-latexsubs) -(puthash "\\mscrK" "ð’¦" julia-latexsubs) -(puthash "\\mscrN" "ð’©" julia-latexsubs) -(puthash "\\mscrO" "ð’ª" julia-latexsubs) -(puthash "\\mscrP" "ð’«" julia-latexsubs) -(puthash "\\mscrQ" "ð’¬" julia-latexsubs) -(puthash "\\mscrS" "ð’®" julia-latexsubs) -(puthash "\\mscrT" "ð’¯" julia-latexsubs) -(puthash "\\mscrU" "ð’°" julia-latexsubs) -(puthash "\\mscrV" "ð’±" julia-latexsubs) -(puthash "\\mscrW" "ð’²" julia-latexsubs) -(puthash "\\mscrX" "ð’³" julia-latexsubs) -(puthash "\\mscrY" "ð’´" julia-latexsubs) -(puthash "\\mscrZ" "ð’µ" julia-latexsubs) -(puthash "\\mscra" "ð’¶" julia-latexsubs) -(puthash "\\mscrb" "ð’·" julia-latexsubs) -(puthash "\\mscrc" "ð’¸" julia-latexsubs) -(puthash "\\mscrd" "ð’¹" julia-latexsubs) -(puthash "\\mscrf" "ð’»" julia-latexsubs) -(puthash "\\mscrh" "ð’½" julia-latexsubs) -(puthash "\\mscri" "ð’¾" julia-latexsubs) -(puthash "\\mscrj" "ð’¿" julia-latexsubs) -(puthash "\\mscrk" "ð“€" julia-latexsubs) -(puthash "\\mscrl" "ð“" julia-latexsubs) -(puthash "\\mscrm" "ð“‚" julia-latexsubs) -(puthash "\\mscrn" "ð“ƒ" julia-latexsubs) -(puthash "\\mscrp" "ð“…" julia-latexsubs) -(puthash "\\mscrq" "ð“†" julia-latexsubs) -(puthash "\\mscrr" "ð“‡" julia-latexsubs) -(puthash "\\mscrs" "ð“ˆ" julia-latexsubs) -(puthash "\\mscrt" "ð“‰" julia-latexsubs) -(puthash "\\mscru" "ð“Š" julia-latexsubs) -(puthash "\\mscrv" "ð“‹" julia-latexsubs) -(puthash "\\mscrw" "ð“Œ" julia-latexsubs) -(puthash "\\mscrx" "ð“" julia-latexsubs) -(puthash "\\mscry" "ð“Ž" julia-latexsubs) -(puthash "\\mscrz" "ð“" julia-latexsubs) -(puthash "\\mbfscrA" "ð“" julia-latexsubs) -(puthash "\\mbfscrB" "ð“‘" julia-latexsubs) -(puthash "\\mbfscrC" "ð“’" julia-latexsubs) -(puthash "\\mbfscrD" "ð““" julia-latexsubs) -(puthash "\\mbfscrE" "ð“”" julia-latexsubs) -(puthash "\\mbfscrF" "ð“•" julia-latexsubs) -(puthash "\\mbfscrG" "ð“–" julia-latexsubs) -(puthash "\\mbfscrH" "ð“—" julia-latexsubs) -(puthash "\\mbfscrI" "ð“˜" julia-latexsubs) -(puthash "\\mbfscrJ" "ð“™" julia-latexsubs) -(puthash "\\mbfscrK" "ð“š" julia-latexsubs) -(puthash "\\mbfscrL" "ð“›" julia-latexsubs) -(puthash "\\mbfscrM" "ð“œ" julia-latexsubs) -(puthash "\\mbfscrN" "ð“" julia-latexsubs) -(puthash "\\mbfscrO" "ð“ž" julia-latexsubs) -(puthash "\\mbfscrP" "ð“Ÿ" julia-latexsubs) -(puthash "\\mbfscrQ" "ð“ " julia-latexsubs) -(puthash "\\mbfscrR" "ð“¡" julia-latexsubs) -(puthash "\\mbfscrS" "ð“¢" julia-latexsubs) -(puthash "\\mbfscrT" "ð“£" julia-latexsubs) -(puthash "\\mbfscrU" "ð“¤" julia-latexsubs) -(puthash "\\mbfscrV" "ð“¥" julia-latexsubs) -(puthash "\\mbfscrW" "ð“¦" julia-latexsubs) -(puthash "\\mbfscrX" "ð“§" julia-latexsubs) -(puthash "\\mbfscrY" "ð“¨" julia-latexsubs) -(puthash "\\mbfscrZ" "ð“©" julia-latexsubs) -(puthash "\\mbfscra" "ð“ª" julia-latexsubs) -(puthash "\\mbfscrb" "ð“«" julia-latexsubs) -(puthash "\\mbfscrc" "ð“¬" julia-latexsubs) -(puthash "\\mbfscrd" "ð“­" julia-latexsubs) -(puthash "\\mbfscre" "ð“®" julia-latexsubs) -(puthash "\\mbfscrf" "ð“¯" julia-latexsubs) -(puthash "\\mbfscrg" "ð“°" julia-latexsubs) -(puthash "\\mbfscrh" "ð“±" julia-latexsubs) -(puthash "\\mbfscri" "ð“²" julia-latexsubs) -(puthash "\\mbfscrj" "ð“³" julia-latexsubs) -(puthash "\\mbfscrk" "ð“´" julia-latexsubs) -(puthash "\\mbfscrl" "ð“µ" julia-latexsubs) -(puthash "\\mbfscrm" "ð“¶" julia-latexsubs) -(puthash "\\mbfscrn" "ð“·" julia-latexsubs) -(puthash "\\mbfscro" "ð“¸" julia-latexsubs) -(puthash "\\mbfscrp" "ð“¹" julia-latexsubs) -(puthash "\\mbfscrq" "ð“º" julia-latexsubs) -(puthash "\\mbfscrr" "ð“»" julia-latexsubs) -(puthash "\\mbfscrs" "ð“¼" julia-latexsubs) -(puthash "\\mbfscrt" "ð“½" julia-latexsubs) -(puthash "\\mbfscru" "ð“¾" julia-latexsubs) -(puthash "\\mbfscrv" "ð“¿" julia-latexsubs) -(puthash "\\mbfscrw" "ð”€" julia-latexsubs) -(puthash "\\mbfscrx" "ð”" julia-latexsubs) -(puthash "\\mbfscry" "ð”‚" julia-latexsubs) -(puthash "\\mbfscrz" "ð”ƒ" julia-latexsubs) -(puthash "\\mfrakA" "ð”„" julia-latexsubs) -(puthash "\\mfrakB" "ð”…" julia-latexsubs) -(puthash "\\mfrakD" "ð”‡" julia-latexsubs) -(puthash "\\mfrakE" "ð”ˆ" julia-latexsubs) -(puthash "\\mfrakF" "ð”‰" julia-latexsubs) -(puthash "\\mfrakG" "ð”Š" julia-latexsubs) -(puthash "\\mfrakJ" "ð”" julia-latexsubs) -(puthash "\\mfrakK" "ð”Ž" julia-latexsubs) -(puthash "\\mfrakL" "ð”" julia-latexsubs) -(puthash "\\mfrakM" "ð”" julia-latexsubs) -(puthash "\\mfrakN" "ð”‘" julia-latexsubs) -(puthash "\\mfrakO" "ð”’" julia-latexsubs) -(puthash "\\mfrakP" "ð”“" julia-latexsubs) -(puthash "\\mfrakQ" "ð””" julia-latexsubs) -(puthash "\\mfrakS" "ð”–" julia-latexsubs) -(puthash "\\mfrakT" "ð”—" julia-latexsubs) -(puthash "\\mfrakU" "ð”˜" julia-latexsubs) -(puthash "\\mfrakV" "ð”™" julia-latexsubs) -(puthash "\\mfrakW" "ð”š" julia-latexsubs) -(puthash "\\mfrakX" "ð”›" julia-latexsubs) -(puthash "\\mfrakY" "ð”œ" julia-latexsubs) -(puthash "\\mfraka" "ð”ž" julia-latexsubs) -(puthash "\\mfrakb" "ð”Ÿ" julia-latexsubs) -(puthash "\\mfrakc" "ð” " julia-latexsubs) -(puthash "\\mfrakd" "ð”¡" julia-latexsubs) -(puthash "\\mfrake" "ð”¢" julia-latexsubs) -(puthash "\\mfrakf" "ð”£" julia-latexsubs) -(puthash "\\mfrakg" "ð”¤" julia-latexsubs) -(puthash "\\mfrakh" "ð”¥" julia-latexsubs) -(puthash "\\mfraki" "ð”¦" julia-latexsubs) -(puthash "\\mfrakj" "ð”§" julia-latexsubs) -(puthash "\\mfrakk" "ð”¨" julia-latexsubs) -(puthash "\\mfrakl" "ð”©" julia-latexsubs) -(puthash "\\mfrakm" "ð”ª" julia-latexsubs) -(puthash "\\mfrakn" "ð”«" julia-latexsubs) -(puthash "\\mfrako" "ð”¬" julia-latexsubs) -(puthash "\\mfrakp" "ð”­" julia-latexsubs) -(puthash "\\mfrakq" "ð”®" julia-latexsubs) -(puthash "\\mfrakr" "ð”¯" julia-latexsubs) -(puthash "\\mfraks" "ð”°" julia-latexsubs) -(puthash "\\mfrakt" "ð”±" julia-latexsubs) -(puthash "\\mfraku" "ð”²" julia-latexsubs) -(puthash "\\mfrakv" "ð”³" julia-latexsubs) -(puthash "\\mfrakw" "ð”´" julia-latexsubs) -(puthash "\\mfrakx" "ð”µ" julia-latexsubs) -(puthash "\\mfraky" "ð”¶" julia-latexsubs) -(puthash "\\mfrakz" "ð”·" julia-latexsubs) -(puthash "\\BbbA" "ð”¸" julia-latexsubs) -(puthash "\\BbbB" "ð”¹" julia-latexsubs) -(puthash "\\BbbD" "ð”»" julia-latexsubs) -(puthash "\\BbbE" "ð”¼" julia-latexsubs) -(puthash "\\BbbF" "ð”½" julia-latexsubs) -(puthash "\\BbbG" "ð”¾" julia-latexsubs) -(puthash "\\BbbI" "ð•€" julia-latexsubs) -(puthash "\\BbbJ" "ð•" julia-latexsubs) -(puthash "\\BbbK" "ð•‚" julia-latexsubs) -(puthash "\\BbbL" "ð•ƒ" julia-latexsubs) -(puthash "\\BbbM" "ð•„" julia-latexsubs) -(puthash "\\BbbO" "ð•†" julia-latexsubs) -(puthash "\\BbbS" "ð•Š" julia-latexsubs) -(puthash "\\BbbT" "ð•‹" julia-latexsubs) -(puthash "\\BbbU" "ð•Œ" julia-latexsubs) -(puthash "\\BbbV" "ð•" julia-latexsubs) -(puthash "\\BbbW" "ð•Ž" julia-latexsubs) -(puthash "\\BbbX" "ð•" julia-latexsubs) -(puthash "\\BbbY" "ð•" julia-latexsubs) -(puthash "\\Bbba" "ð•’" julia-latexsubs) -(puthash "\\Bbbb" "ð•“" julia-latexsubs) -(puthash "\\Bbbc" "ð•”" julia-latexsubs) -(puthash "\\Bbbd" "ð••" julia-latexsubs) -(puthash "\\Bbbe" "ð•–" julia-latexsubs) -(puthash "\\Bbbf" "ð•—" julia-latexsubs) -(puthash "\\Bbbg" "ð•˜" julia-latexsubs) -(puthash "\\Bbbh" "ð•™" julia-latexsubs) -(puthash "\\Bbbi" "ð•š" julia-latexsubs) -(puthash "\\Bbbj" "ð•›" julia-latexsubs) -(puthash "\\Bbbk" "ð•œ" julia-latexsubs) -(puthash "\\Bbbl" "ð•" julia-latexsubs) -(puthash "\\Bbbm" "ð•ž" julia-latexsubs) -(puthash "\\Bbbn" "ð•Ÿ" julia-latexsubs) -(puthash "\\Bbbo" "ð• " julia-latexsubs) -(puthash "\\Bbbp" "ð•¡" julia-latexsubs) -(puthash "\\Bbbq" "ð•¢" julia-latexsubs) -(puthash "\\Bbbr" "ð•£" julia-latexsubs) -(puthash "\\Bbbs" "ð•¤" julia-latexsubs) -(puthash "\\Bbbt" "ð•¥" julia-latexsubs) -(puthash "\\Bbbu" "ð•¦" julia-latexsubs) -(puthash "\\Bbbv" "ð•§" julia-latexsubs) -(puthash "\\Bbbw" "ð•¨" julia-latexsubs) -(puthash "\\Bbbx" "ð•©" julia-latexsubs) -(puthash "\\Bbby" "ð•ª" julia-latexsubs) -(puthash "\\Bbbz" "ð•«" julia-latexsubs) -(puthash "\\mbffrakA" "ð•¬" julia-latexsubs) -(puthash "\\mbffrakB" "ð•­" julia-latexsubs) -(puthash "\\mbffrakC" "ð•®" julia-latexsubs) -(puthash "\\mbffrakD" "ð•¯" julia-latexsubs) -(puthash "\\mbffrakE" "ð•°" julia-latexsubs) -(puthash "\\mbffrakF" "ð•±" julia-latexsubs) -(puthash "\\mbffrakG" "ð•²" julia-latexsubs) -(puthash "\\mbffrakH" "ð•³" julia-latexsubs) -(puthash "\\mbffrakI" "ð•´" julia-latexsubs) -(puthash "\\mbffrakJ" "ð•µ" julia-latexsubs) -(puthash "\\mbffrakK" "ð•¶" julia-latexsubs) -(puthash "\\mbffrakL" "ð•·" julia-latexsubs) -(puthash "\\mbffrakM" "ð•¸" julia-latexsubs) -(puthash "\\mbffrakN" "ð•¹" julia-latexsubs) -(puthash "\\mbffrakO" "ð•º" julia-latexsubs) -(puthash "\\mbffrakP" "ð•»" julia-latexsubs) -(puthash "\\mbffrakQ" "ð•¼" julia-latexsubs) -(puthash "\\mbffrakR" "ð•½" julia-latexsubs) -(puthash "\\mbffrakS" "ð•¾" julia-latexsubs) -(puthash "\\mbffrakT" "ð•¿" julia-latexsubs) -(puthash "\\mbffrakU" "ð–€" julia-latexsubs) -(puthash "\\mbffrakV" "ð–" julia-latexsubs) -(puthash "\\mbffrakW" "ð–‚" julia-latexsubs) -(puthash "\\mbffrakX" "ð–ƒ" julia-latexsubs) -(puthash "\\mbffrakY" "ð–„" julia-latexsubs) -(puthash "\\mbffrakZ" "ð–…" julia-latexsubs) -(puthash "\\mbffraka" "ð–†" julia-latexsubs) -(puthash "\\mbffrakb" "ð–‡" julia-latexsubs) -(puthash "\\mbffrakc" "ð–ˆ" julia-latexsubs) -(puthash "\\mbffrakd" "ð–‰" julia-latexsubs) -(puthash "\\mbffrake" "ð–Š" julia-latexsubs) -(puthash "\\mbffrakf" "ð–‹" julia-latexsubs) -(puthash "\\mbffrakg" "ð–Œ" julia-latexsubs) -(puthash "\\mbffrakh" "ð–" julia-latexsubs) -(puthash "\\mbffraki" "ð–Ž" julia-latexsubs) -(puthash "\\mbffrakj" "ð–" julia-latexsubs) -(puthash "\\mbffrakk" "ð–" julia-latexsubs) -(puthash "\\mbffrakl" "ð–‘" julia-latexsubs) -(puthash "\\mbffrakm" "ð–’" julia-latexsubs) -(puthash "\\mbffrakn" "ð–“" julia-latexsubs) -(puthash "\\mbffrako" "ð–”" julia-latexsubs) -(puthash "\\mbffrakp" "ð–•" julia-latexsubs) -(puthash "\\mbffrakq" "ð––" julia-latexsubs) -(puthash "\\mbffrakr" "ð–—" julia-latexsubs) -(puthash "\\mbffraks" "ð–˜" julia-latexsubs) -(puthash "\\mbffrakt" "ð–™" julia-latexsubs) -(puthash "\\mbffraku" "ð–š" julia-latexsubs) -(puthash "\\mbffrakv" "ð–›" julia-latexsubs) -(puthash "\\mbffrakw" "ð–œ" julia-latexsubs) -(puthash "\\mbffrakx" "ð–" julia-latexsubs) -(puthash "\\mbffraky" "ð–ž" julia-latexsubs) -(puthash "\\mbffrakz" "ð–Ÿ" julia-latexsubs) -(puthash "\\msansA" "ð– " julia-latexsubs) -(puthash "\\msansB" "ð–¡" julia-latexsubs) -(puthash "\\msansC" "ð–¢" julia-latexsubs) -(puthash "\\msansD" "ð–£" julia-latexsubs) -(puthash "\\msansE" "ð–¤" julia-latexsubs) -(puthash "\\msansF" "ð–¥" julia-latexsubs) -(puthash "\\msansG" "ð–¦" julia-latexsubs) -(puthash "\\msansH" "ð–§" julia-latexsubs) -(puthash "\\msansI" "ð–¨" julia-latexsubs) -(puthash "\\msansJ" "ð–©" julia-latexsubs) -(puthash "\\msansK" "ð–ª" julia-latexsubs) -(puthash "\\msansL" "ð–«" julia-latexsubs) -(puthash "\\msansM" "ð–¬" julia-latexsubs) -(puthash "\\msansN" "ð–­" julia-latexsubs) -(puthash "\\msansO" "ð–®" julia-latexsubs) -(puthash "\\msansP" "ð–¯" julia-latexsubs) -(puthash "\\msansQ" "ð–°" julia-latexsubs) -(puthash "\\msansR" "ð–±" julia-latexsubs) -(puthash "\\msansS" "ð–²" julia-latexsubs) -(puthash "\\msansT" "ð–³" julia-latexsubs) -(puthash "\\msansU" "ð–´" julia-latexsubs) -(puthash "\\msansV" "ð–µ" julia-latexsubs) -(puthash "\\msansW" "ð–¶" julia-latexsubs) -(puthash "\\msansX" "ð–·" julia-latexsubs) -(puthash "\\msansY" "ð–¸" julia-latexsubs) -(puthash "\\msansZ" "ð–¹" julia-latexsubs) -(puthash "\\msansa" "ð–º" julia-latexsubs) -(puthash "\\msansb" "ð–»" julia-latexsubs) -(puthash "\\msansc" "ð–¼" julia-latexsubs) -(puthash "\\msansd" "ð–½" julia-latexsubs) -(puthash "\\msanse" "ð–¾" julia-latexsubs) -(puthash "\\msansf" "ð–¿" julia-latexsubs) -(puthash "\\msansg" "ð—€" julia-latexsubs) -(puthash "\\msansh" "ð—" julia-latexsubs) -(puthash "\\msansi" "ð—‚" julia-latexsubs) -(puthash "\\msansj" "ð—ƒ" julia-latexsubs) -(puthash "\\msansk" "ð—„" julia-latexsubs) -(puthash "\\msansl" "ð—…" julia-latexsubs) -(puthash "\\msansm" "ð—†" julia-latexsubs) -(puthash "\\msansn" "ð—‡" julia-latexsubs) -(puthash "\\msanso" "ð—ˆ" julia-latexsubs) -(puthash "\\msansp" "ð—‰" julia-latexsubs) -(puthash "\\msansq" "ð—Š" julia-latexsubs) -(puthash "\\msansr" "ð—‹" julia-latexsubs) -(puthash "\\msanss" "ð—Œ" julia-latexsubs) -(puthash "\\msanst" "ð—" julia-latexsubs) -(puthash "\\msansu" "ð—Ž" julia-latexsubs) -(puthash "\\msansv" "ð—" julia-latexsubs) -(puthash "\\msansw" "ð—" julia-latexsubs) -(puthash "\\msansx" "ð—‘" julia-latexsubs) -(puthash "\\msansy" "ð—’" julia-latexsubs) -(puthash "\\msansz" "ð—“" julia-latexsubs) -(puthash "\\mbfsansA" "ð—”" julia-latexsubs) -(puthash "\\mbfsansB" "ð—•" julia-latexsubs) -(puthash "\\mbfsansC" "ð—–" julia-latexsubs) -(puthash "\\mbfsansD" "ð——" julia-latexsubs) -(puthash "\\mbfsansE" "ð—˜" julia-latexsubs) -(puthash "\\mbfsansF" "ð—™" julia-latexsubs) -(puthash "\\mbfsansG" "ð—š" julia-latexsubs) -(puthash "\\mbfsansH" "ð—›" julia-latexsubs) -(puthash "\\mbfsansI" "ð—œ" julia-latexsubs) -(puthash "\\mbfsansJ" "ð—" julia-latexsubs) -(puthash "\\mbfsansK" "ð—ž" julia-latexsubs) -(puthash "\\mbfsansL" "ð—Ÿ" julia-latexsubs) -(puthash "\\mbfsansM" "ð— " julia-latexsubs) -(puthash "\\mbfsansN" "ð—¡" julia-latexsubs) -(puthash "\\mbfsansO" "ð—¢" julia-latexsubs) -(puthash "\\mbfsansP" "ð—£" julia-latexsubs) -(puthash "\\mbfsansQ" "ð—¤" julia-latexsubs) -(puthash "\\mbfsansR" "ð—¥" julia-latexsubs) -(puthash "\\mbfsansS" "ð—¦" julia-latexsubs) -(puthash "\\mbfsansT" "ð—§" julia-latexsubs) -(puthash "\\mbfsansU" "ð—¨" julia-latexsubs) -(puthash "\\mbfsansV" "ð—©" julia-latexsubs) -(puthash "\\mbfsansW" "ð—ª" julia-latexsubs) -(puthash "\\mbfsansX" "ð—«" julia-latexsubs) -(puthash "\\mbfsansY" "ð—¬" julia-latexsubs) -(puthash "\\mbfsansZ" "ð—­" julia-latexsubs) -(puthash "\\mbfsansa" "ð—®" julia-latexsubs) -(puthash "\\mbfsansb" "ð—¯" julia-latexsubs) -(puthash "\\mbfsansc" "ð—°" julia-latexsubs) -(puthash "\\mbfsansd" "ð—±" julia-latexsubs) -(puthash "\\mbfsanse" "ð—²" julia-latexsubs) -(puthash "\\mbfsansf" "ð—³" julia-latexsubs) -(puthash "\\mbfsansg" "ð—´" julia-latexsubs) -(puthash "\\mbfsansh" "ð—µ" julia-latexsubs) -(puthash "\\mbfsansi" "ð—¶" julia-latexsubs) -(puthash "\\mbfsansj" "ð—·" julia-latexsubs) -(puthash "\\mbfsansk" "ð—¸" julia-latexsubs) -(puthash "\\mbfsansl" "ð—¹" julia-latexsubs) -(puthash "\\mbfsansm" "ð—º" julia-latexsubs) -(puthash "\\mbfsansn" "ð—»" julia-latexsubs) -(puthash "\\mbfsanso" "ð—¼" julia-latexsubs) -(puthash "\\mbfsansp" "ð—½" julia-latexsubs) -(puthash "\\mbfsansq" "ð—¾" julia-latexsubs) -(puthash "\\mbfsansr" "ð—¿" julia-latexsubs) -(puthash "\\mbfsanss" "ð˜€" julia-latexsubs) -(puthash "\\mbfsanst" "ð˜" julia-latexsubs) -(puthash "\\mbfsansu" "ð˜‚" julia-latexsubs) -(puthash "\\mbfsansv" "ð˜ƒ" julia-latexsubs) -(puthash "\\mbfsansw" "ð˜„" julia-latexsubs) -(puthash "\\mbfsansx" "ð˜…" julia-latexsubs) -(puthash "\\mbfsansy" "ð˜†" julia-latexsubs) -(puthash "\\mbfsansz" "ð˜‡" julia-latexsubs) -(puthash "\\mitsansA" "ð˜ˆ" julia-latexsubs) -(puthash "\\mitsansB" "ð˜‰" julia-latexsubs) -(puthash "\\mitsansC" "ð˜Š" julia-latexsubs) -(puthash "\\mitsansD" "ð˜‹" julia-latexsubs) -(puthash "\\mitsansE" "ð˜Œ" julia-latexsubs) -(puthash "\\mitsansF" "ð˜" julia-latexsubs) -(puthash "\\mitsansG" "ð˜Ž" julia-latexsubs) -(puthash "\\mitsansH" "ð˜" julia-latexsubs) -(puthash "\\mitsansI" "ð˜" julia-latexsubs) -(puthash "\\mitsansJ" "ð˜‘" julia-latexsubs) -(puthash "\\mitsansK" "ð˜’" julia-latexsubs) -(puthash "\\mitsansL" "ð˜“" julia-latexsubs) -(puthash "\\mitsansM" "ð˜”" julia-latexsubs) -(puthash "\\mitsansN" "ð˜•" julia-latexsubs) -(puthash "\\mitsansO" "ð˜–" julia-latexsubs) -(puthash "\\mitsansP" "ð˜—" julia-latexsubs) -(puthash "\\mitsansQ" "ð˜˜" julia-latexsubs) -(puthash "\\mitsansR" "ð˜™" julia-latexsubs) -(puthash "\\mitsansS" "ð˜š" julia-latexsubs) -(puthash "\\mitsansT" "ð˜›" julia-latexsubs) -(puthash "\\mitsansU" "ð˜œ" julia-latexsubs) -(puthash "\\mitsansV" "ð˜" julia-latexsubs) -(puthash "\\mitsansW" "ð˜ž" julia-latexsubs) -(puthash "\\mitsansX" "ð˜Ÿ" julia-latexsubs) -(puthash "\\mitsansY" "ð˜ " julia-latexsubs) -(puthash "\\mitsansZ" "ð˜¡" julia-latexsubs) -(puthash "\\mitsansa" "ð˜¢" julia-latexsubs) -(puthash "\\mitsansb" "ð˜£" julia-latexsubs) -(puthash "\\mitsansc" "ð˜¤" julia-latexsubs) -(puthash "\\mitsansd" "ð˜¥" julia-latexsubs) -(puthash "\\mitsanse" "ð˜¦" julia-latexsubs) -(puthash "\\mitsansf" "ð˜§" julia-latexsubs) -(puthash "\\mitsansg" "ð˜¨" julia-latexsubs) -(puthash "\\mitsansh" "ð˜©" julia-latexsubs) -(puthash "\\mitsansi" "ð˜ª" julia-latexsubs) -(puthash "\\mitsansj" "ð˜«" julia-latexsubs) -(puthash "\\mitsansk" "ð˜¬" julia-latexsubs) -(puthash "\\mitsansl" "ð˜­" julia-latexsubs) -(puthash "\\mitsansm" "ð˜®" julia-latexsubs) -(puthash "\\mitsansn" "ð˜¯" julia-latexsubs) -(puthash "\\mitsanso" "ð˜°" julia-latexsubs) -(puthash "\\mitsansp" "ð˜±" julia-latexsubs) -(puthash "\\mitsansq" "ð˜²" julia-latexsubs) -(puthash "\\mitsansr" "ð˜³" julia-latexsubs) -(puthash "\\mitsanss" "ð˜´" julia-latexsubs) -(puthash "\\mitsanst" "ð˜µ" julia-latexsubs) -(puthash "\\mitsansu" "ð˜¶" julia-latexsubs) -(puthash "\\mitsansv" "ð˜·" julia-latexsubs) -(puthash "\\mitsansw" "ð˜¸" julia-latexsubs) -(puthash "\\mitsansx" "ð˜¹" julia-latexsubs) -(puthash "\\mitsansy" "ð˜º" julia-latexsubs) -(puthash "\\mitsansz" "ð˜»" julia-latexsubs) -(puthash "\\mbfitsansA" "ð˜¼" julia-latexsubs) -(puthash "\\mbfitsansB" "ð˜½" julia-latexsubs) -(puthash "\\mbfitsansC" "ð˜¾" julia-latexsubs) -(puthash "\\mbfitsansD" "ð˜¿" julia-latexsubs) -(puthash "\\mbfitsansE" "ð™€" julia-latexsubs) -(puthash "\\mbfitsansF" "ð™" julia-latexsubs) -(puthash "\\mbfitsansG" "ð™‚" julia-latexsubs) -(puthash "\\mbfitsansH" "ð™ƒ" julia-latexsubs) -(puthash "\\mbfitsansI" "ð™„" julia-latexsubs) -(puthash "\\mbfitsansJ" "ð™…" julia-latexsubs) -(puthash "\\mbfitsansK" "ð™†" julia-latexsubs) -(puthash "\\mbfitsansL" "ð™‡" julia-latexsubs) -(puthash "\\mbfitsansM" "ð™ˆ" julia-latexsubs) -(puthash "\\mbfitsansN" "ð™‰" julia-latexsubs) -(puthash "\\mbfitsansO" "ð™Š" julia-latexsubs) -(puthash "\\mbfitsansP" "ð™‹" julia-latexsubs) -(puthash "\\mbfitsansQ" "ð™Œ" julia-latexsubs) -(puthash "\\mbfitsansR" "ð™" julia-latexsubs) -(puthash "\\mbfitsansS" "ð™Ž" julia-latexsubs) -(puthash "\\mbfitsansT" "ð™" julia-latexsubs) -(puthash "\\mbfitsansU" "ð™" julia-latexsubs) -(puthash "\\mbfitsansV" "ð™‘" julia-latexsubs) -(puthash "\\mbfitsansW" "ð™’" julia-latexsubs) -(puthash "\\mbfitsansX" "ð™“" julia-latexsubs) -(puthash "\\mbfitsansY" "ð™”" julia-latexsubs) -(puthash "\\mbfitsansZ" "ð™•" julia-latexsubs) -(puthash "\\mbfitsansa" "ð™–" julia-latexsubs) -(puthash "\\mbfitsansb" "ð™—" julia-latexsubs) -(puthash "\\mbfitsansc" "ð™˜" julia-latexsubs) -(puthash "\\mbfitsansd" "ð™™" julia-latexsubs) -(puthash "\\mbfitsanse" "ð™š" julia-latexsubs) -(puthash "\\mbfitsansf" "ð™›" julia-latexsubs) -(puthash "\\mbfitsansg" "ð™œ" julia-latexsubs) -(puthash "\\mbfitsansh" "ð™" julia-latexsubs) -(puthash "\\mbfitsansi" "ð™ž" julia-latexsubs) -(puthash "\\mbfitsansj" "ð™Ÿ" julia-latexsubs) -(puthash "\\mbfitsansk" "ð™ " julia-latexsubs) -(puthash "\\mbfitsansl" "ð™¡" julia-latexsubs) -(puthash "\\mbfitsansm" "ð™¢" julia-latexsubs) -(puthash "\\mbfitsansn" "ð™£" julia-latexsubs) -(puthash "\\mbfitsanso" "ð™¤" julia-latexsubs) -(puthash "\\mbfitsansp" "ð™¥" julia-latexsubs) -(puthash "\\mbfitsansq" "ð™¦" julia-latexsubs) -(puthash "\\mbfitsansr" "ð™§" julia-latexsubs) -(puthash "\\mbfitsanss" "ð™¨" julia-latexsubs) -(puthash "\\mbfitsanst" "ð™©" julia-latexsubs) -(puthash "\\mbfitsansu" "ð™ª" julia-latexsubs) -(puthash "\\mbfitsansv" "ð™«" julia-latexsubs) -(puthash "\\mbfitsansw" "ð™¬" julia-latexsubs) -(puthash "\\mbfitsansx" "ð™­" julia-latexsubs) -(puthash "\\mbfitsansy" "ð™®" julia-latexsubs) -(puthash "\\mbfitsansz" "ð™¯" julia-latexsubs) -(puthash "\\mttA" "ð™°" julia-latexsubs) -(puthash "\\mttB" "ð™±" julia-latexsubs) -(puthash "\\mttC" "ð™²" julia-latexsubs) -(puthash "\\mttD" "ð™³" julia-latexsubs) -(puthash "\\mttE" "ð™´" julia-latexsubs) -(puthash "\\mttF" "ð™µ" julia-latexsubs) -(puthash "\\mttG" "ð™¶" julia-latexsubs) -(puthash "\\mttH" "ð™·" julia-latexsubs) -(puthash "\\mttI" "ð™¸" julia-latexsubs) -(puthash "\\mttJ" "ð™¹" julia-latexsubs) -(puthash "\\mttK" "ð™º" julia-latexsubs) -(puthash "\\mttL" "ð™»" julia-latexsubs) -(puthash "\\mttM" "ð™¼" julia-latexsubs) -(puthash "\\mttN" "ð™½" julia-latexsubs) -(puthash "\\mttO" "ð™¾" julia-latexsubs) -(puthash "\\mttP" "ð™¿" julia-latexsubs) -(puthash "\\mttQ" "ðš€" julia-latexsubs) -(puthash "\\mttR" "ðš" julia-latexsubs) -(puthash "\\mttS" "ðš‚" julia-latexsubs) -(puthash "\\mttT" "ðšƒ" julia-latexsubs) -(puthash "\\mttU" "ðš„" julia-latexsubs) -(puthash "\\mttV" "ðš…" julia-latexsubs) -(puthash "\\mttW" "ðš†" julia-latexsubs) -(puthash "\\mttX" "ðš‡" julia-latexsubs) -(puthash "\\mttY" "ðšˆ" julia-latexsubs) -(puthash "\\mttZ" "ðš‰" julia-latexsubs) -(puthash "\\mtta" "ðšŠ" julia-latexsubs) -(puthash "\\mttb" "ðš‹" julia-latexsubs) -(puthash "\\mttc" "ðšŒ" julia-latexsubs) -(puthash "\\mttd" "ðš" julia-latexsubs) -(puthash "\\mtte" "ðšŽ" julia-latexsubs) -(puthash "\\mttf" "ðš" julia-latexsubs) -(puthash "\\mttg" "ðš" julia-latexsubs) -(puthash "\\mtth" "ðš‘" julia-latexsubs) -(puthash "\\mtti" "ðš’" julia-latexsubs) -(puthash "\\mttj" "ðš“" julia-latexsubs) -(puthash "\\mttk" "ðš”" julia-latexsubs) -(puthash "\\mttl" "ðš•" julia-latexsubs) -(puthash "\\mttm" "ðš–" julia-latexsubs) -(puthash "\\mttn" "ðš—" julia-latexsubs) -(puthash "\\mtto" "ðš˜" julia-latexsubs) -(puthash "\\mttp" "ðš™" julia-latexsubs) -(puthash "\\mttq" "ðšš" julia-latexsubs) -(puthash "\\mttr" "ðš›" julia-latexsubs) -(puthash "\\mtts" "ðšœ" julia-latexsubs) -(puthash "\\mttt" "ðš" julia-latexsubs) -(puthash "\\mttu" "ðšž" julia-latexsubs) -(puthash "\\mttv" "ðšŸ" julia-latexsubs) -(puthash "\\mttw" "ðš " julia-latexsubs) -(puthash "\\mttx" "ðš¡" julia-latexsubs) -(puthash "\\mtty" "ðš¢" julia-latexsubs) -(puthash "\\mttz" "ðš£" julia-latexsubs) -(puthash "\\imath" "ðš¤" julia-latexsubs) -(puthash "\\jmath" "ðš¥" julia-latexsubs) -(puthash "\\mbfAlpha" "ðš¨" julia-latexsubs) -(puthash "\\mbfBeta" "ðš©" julia-latexsubs) -(puthash "\\mbfGamma" "ðšª" julia-latexsubs) -(puthash "\\mbfDelta" "ðš«" julia-latexsubs) -(puthash "\\mbfEpsilon" "ðš¬" julia-latexsubs) -(puthash "\\mbfZeta" "ðš­" julia-latexsubs) -(puthash "\\mbfEta" "ðš®" julia-latexsubs) -(puthash "\\mbfTheta" "ðš¯" julia-latexsubs) -(puthash "\\mbfIota" "ðš°" julia-latexsubs) -(puthash "\\mbfKappa" "ðš±" julia-latexsubs) -(puthash "\\mbfLambda" "ðš²" julia-latexsubs) -(puthash "\\mbfMu" "ðš³" julia-latexsubs) -(puthash "\\mbfNu" "ðš´" julia-latexsubs) -(puthash "\\mbfXi" "ðšµ" julia-latexsubs) -(puthash "\\mbfOmicron" "ðš¶" julia-latexsubs) -(puthash "\\mbfPi" "ðš·" julia-latexsubs) -(puthash "\\mbfRho" "ðš¸" julia-latexsubs) -(puthash "\\mbfvarTheta" "ðš¹" julia-latexsubs) -(puthash "\\mbfSigma" "ðšº" julia-latexsubs) -(puthash "\\mbfTau" "ðš»" julia-latexsubs) -(puthash "\\mbfUpsilon" "ðš¼" julia-latexsubs) -(puthash "\\mbfPhi" "ðš½" julia-latexsubs) -(puthash "\\mbfChi" "ðš¾" julia-latexsubs) -(puthash "\\mbfPsi" "ðš¿" julia-latexsubs) -(puthash "\\mbfOmega" "ð›€" julia-latexsubs) -(puthash "\\mbfnabla" "ð›" julia-latexsubs) -(puthash "\\mbfalpha" "ð›‚" julia-latexsubs) -(puthash "\\mbfbeta" "ð›ƒ" julia-latexsubs) -(puthash "\\mbfgamma" "ð›„" julia-latexsubs) -(puthash "\\mbfdelta" "ð›…" julia-latexsubs) -(puthash "\\mbfepsilon" "ð›†" julia-latexsubs) -(puthash "\\mbfzeta" "ð›‡" julia-latexsubs) -(puthash "\\mbfeta" "ð›ˆ" julia-latexsubs) -(puthash "\\mbftheta" "ð›‰" julia-latexsubs) -(puthash "\\mbfiota" "ð›Š" julia-latexsubs) -(puthash "\\mbfkappa" "ð›‹" julia-latexsubs) -(puthash "\\mbflambda" "ð›Œ" julia-latexsubs) -(puthash "\\mbfmu" "ð›" julia-latexsubs) -(puthash "\\mbfnu" "ð›Ž" julia-latexsubs) -(puthash "\\mbfxi" "ð›" julia-latexsubs) -(puthash "\\mbfomicron" "ð›" julia-latexsubs) -(puthash "\\mbfpi" "ð›‘" julia-latexsubs) -(puthash "\\mbfrho" "ð›’" julia-latexsubs) -(puthash "\\mbfvarsigma" "ð›“" julia-latexsubs) -(puthash "\\mbfsigma" "ð›”" julia-latexsubs) -(puthash "\\mbftau" "ð›•" julia-latexsubs) -(puthash "\\mbfupsilon" "ð›–" julia-latexsubs) -(puthash "\\mbfvarphi" "ð›—" julia-latexsubs) -(puthash "\\mbfchi" "ð›˜" julia-latexsubs) -(puthash "\\mbfpsi" "ð›™" julia-latexsubs) -(puthash "\\mbfomega" "ð›š" julia-latexsubs) -(puthash "\\mbfpartial" "ð››" julia-latexsubs) -(puthash "\\mbfvarepsilon" "ð›œ" julia-latexsubs) -(puthash "\\mbfvartheta" "ð›" julia-latexsubs) -(puthash "\\mbfvarkappa" "ð›ž" julia-latexsubs) -(puthash "\\mbfphi" "ð›Ÿ" julia-latexsubs) -(puthash "\\mbfvarrho" "ð› " julia-latexsubs) -(puthash "\\mbfvarpi" "ð›¡" julia-latexsubs) -(puthash "\\mitAlpha" "ð›¢" julia-latexsubs) -(puthash "\\mitBeta" "ð›£" julia-latexsubs) -(puthash "\\mitGamma" "ð›¤" julia-latexsubs) -(puthash "\\mitDelta" "ð›¥" julia-latexsubs) -(puthash "\\mitEpsilon" "ð›¦" julia-latexsubs) -(puthash "\\mitZeta" "ð›§" julia-latexsubs) -(puthash "\\mitEta" "ð›¨" julia-latexsubs) -(puthash "\\mitTheta" "ð›©" julia-latexsubs) -(puthash "\\mitIota" "ð›ª" julia-latexsubs) -(puthash "\\mitKappa" "ð›«" julia-latexsubs) -(puthash "\\mitLambda" "ð›¬" julia-latexsubs) -(puthash "\\mitMu" "ð›­" julia-latexsubs) -(puthash "\\mitNu" "ð›®" julia-latexsubs) -(puthash "\\mitXi" "ð›¯" julia-latexsubs) -(puthash "\\mitOmicron" "ð›°" julia-latexsubs) -(puthash "\\mitPi" "ð›±" julia-latexsubs) -(puthash "\\mitRho" "ð›²" julia-latexsubs) -(puthash "\\mitvarTheta" "ð›³" julia-latexsubs) -(puthash "\\mitSigma" "ð›´" julia-latexsubs) -(puthash "\\mitTau" "ð›µ" julia-latexsubs) -(puthash "\\mitUpsilon" "ð›¶" julia-latexsubs) -(puthash "\\mitPhi" "ð›·" julia-latexsubs) -(puthash "\\mitChi" "ð›¸" julia-latexsubs) -(puthash "\\mitPsi" "ð›¹" julia-latexsubs) -(puthash "\\mitOmega" "ð›º" julia-latexsubs) -(puthash "\\mitnabla" "ð›»" julia-latexsubs) -(puthash "\\mitalpha" "ð›¼" julia-latexsubs) -(puthash "\\mitbeta" "ð›½" julia-latexsubs) -(puthash "\\mitgamma" "ð›¾" julia-latexsubs) -(puthash "\\mitdelta" "ð›¿" julia-latexsubs) -(puthash "\\mitepsilon" "ðœ€" julia-latexsubs) -(puthash "\\mitzeta" "ðœ" julia-latexsubs) -(puthash "\\miteta" "ðœ‚" julia-latexsubs) -(puthash "\\mittheta" "ðœƒ" julia-latexsubs) -(puthash "\\mitiota" "ðœ„" julia-latexsubs) -(puthash "\\mitkappa" "ðœ…" julia-latexsubs) -(puthash "\\mitlambda" "ðœ†" julia-latexsubs) -(puthash "\\mitmu" "ðœ‡" julia-latexsubs) -(puthash "\\mitnu" "ðœˆ" julia-latexsubs) -(puthash "\\mitxi" "ðœ‰" julia-latexsubs) -(puthash "\\mitomicron" "ðœŠ" julia-latexsubs) -(puthash "\\mitpi" "ðœ‹" julia-latexsubs) -(puthash "\\mitrho" "ðœŒ" julia-latexsubs) -(puthash "\\mitvarsigma" "ðœ" julia-latexsubs) -(puthash "\\mitsigma" "ðœŽ" julia-latexsubs) -(puthash "\\mittau" "ðœ" julia-latexsubs) -(puthash "\\mitupsilon" "ðœ" julia-latexsubs) -(puthash "\\mitphi" "ðœ‘" julia-latexsubs) -(puthash "\\mitchi" "ðœ’" julia-latexsubs) -(puthash "\\mitpsi" "ðœ“" julia-latexsubs) -(puthash "\\mitomega" "ðœ”" julia-latexsubs) -(puthash "\\mitpartial" "ðœ•" julia-latexsubs) -(puthash "\\mitvarepsilon" "ðœ–" julia-latexsubs) -(puthash "\\mitvartheta" "ðœ—" julia-latexsubs) -(puthash "\\mitvarkappa" "ðœ˜" julia-latexsubs) -(puthash "\\mitvarphi" "ðœ™" julia-latexsubs) -(puthash "\\mitvarrho" "ðœš" julia-latexsubs) -(puthash "\\mitvarpi" "ðœ›" julia-latexsubs) -(puthash "\\mbfitAlpha" "ðœœ" julia-latexsubs) -(puthash "\\mbfitBeta" "ðœ" julia-latexsubs) -(puthash "\\mbfitGamma" "ðœž" julia-latexsubs) -(puthash "\\mbfitDelta" "ðœŸ" julia-latexsubs) -(puthash "\\mbfitEpsilon" "ðœ " julia-latexsubs) -(puthash "\\mbfitZeta" "ðœ¡" julia-latexsubs) -(puthash "\\mbfitEta" "ðœ¢" julia-latexsubs) -(puthash "\\mbfitTheta" "ðœ£" julia-latexsubs) -(puthash "\\mbfitIota" "ðœ¤" julia-latexsubs) -(puthash "\\mbfitKappa" "ðœ¥" julia-latexsubs) -(puthash "\\mbfitLambda" "ðœ¦" julia-latexsubs) -(puthash "\\mbfitMu" "ðœ§" julia-latexsubs) -(puthash "\\mbfitNu" "ðœ¨" julia-latexsubs) -(puthash "\\mbfitXi" "ðœ©" julia-latexsubs) -(puthash "\\mbfitOmicron" "ðœª" julia-latexsubs) -(puthash "\\mbfitPi" "ðœ«" julia-latexsubs) -(puthash "\\mbfitRho" "ðœ¬" julia-latexsubs) -(puthash "\\mbfitvarTheta" "ðœ­" julia-latexsubs) -(puthash "\\mbfitSigma" "ðœ®" julia-latexsubs) -(puthash "\\mbfitTau" "ðœ¯" julia-latexsubs) -(puthash "\\mbfitUpsilon" "ðœ°" julia-latexsubs) -(puthash "\\mbfitPhi" "ðœ±" julia-latexsubs) -(puthash "\\mbfitChi" "ðœ²" julia-latexsubs) -(puthash "\\mbfitPsi" "ðœ³" julia-latexsubs) -(puthash "\\mbfitOmega" "ðœ´" julia-latexsubs) -(puthash "\\mbfitnabla" "ðœµ" julia-latexsubs) -(puthash "\\mbfitalpha" "ðœ¶" julia-latexsubs) -(puthash "\\mbfitbeta" "ðœ·" julia-latexsubs) -(puthash "\\mbfitgamma" "ðœ¸" julia-latexsubs) -(puthash "\\mbfitdelta" "ðœ¹" julia-latexsubs) -(puthash "\\mbfitepsilon" "ðœº" julia-latexsubs) -(puthash "\\mbfitzeta" "ðœ»" julia-latexsubs) -(puthash "\\mbfiteta" "ðœ¼" julia-latexsubs) -(puthash "\\mbfittheta" "ðœ½" julia-latexsubs) -(puthash "\\mbfitiota" "ðœ¾" julia-latexsubs) -(puthash "\\mbfitkappa" "ðœ¿" julia-latexsubs) -(puthash "\\mbfitlambda" "ð€" julia-latexsubs) -(puthash "\\mbfitmu" "ð" julia-latexsubs) -(puthash "\\mbfitnu" "ð‚" julia-latexsubs) -(puthash "\\mbfitxi" "ðƒ" julia-latexsubs) -(puthash "\\mbfitomicron" "ð„" julia-latexsubs) -(puthash "\\mbfitpi" "ð…" julia-latexsubs) -(puthash "\\mbfitrho" "ð†" julia-latexsubs) -(puthash "\\mbfitvarsigma" "ð‡" julia-latexsubs) -(puthash "\\mbfitsigma" "ðˆ" julia-latexsubs) -(puthash "\\mbfittau" "ð‰" julia-latexsubs) -(puthash "\\mbfitupsilon" "ðŠ" julia-latexsubs) -(puthash "\\mbfitphi" "ð‹" julia-latexsubs) -(puthash "\\mbfitchi" "ðŒ" julia-latexsubs) -(puthash "\\mbfitpsi" "ð" julia-latexsubs) -(puthash "\\mbfitomega" "ðŽ" julia-latexsubs) -(puthash "\\mbfitpartial" "ð" julia-latexsubs) -(puthash "\\mbfitvarepsilon" "ð" julia-latexsubs) -(puthash "\\mbfitvartheta" "ð‘" julia-latexsubs) -(puthash "\\mbfitvarkappa" "ð’" julia-latexsubs) -(puthash "\\mbfitvarphi" "ð“" julia-latexsubs) -(puthash "\\mbfitvarrho" "ð”" julia-latexsubs) -(puthash "\\mbfitvarpi" "ð•" julia-latexsubs) -(puthash "\\mbfsansAlpha" "ð–" julia-latexsubs) -(puthash "\\mbfsansBeta" "ð—" julia-latexsubs) -(puthash "\\mbfsansGamma" "ð˜" julia-latexsubs) -(puthash "\\mbfsansDelta" "ð™" julia-latexsubs) -(puthash "\\mbfsansEpsilon" "ðš" julia-latexsubs) -(puthash "\\mbfsansZeta" "ð›" julia-latexsubs) -(puthash "\\mbfsansEta" "ðœ" julia-latexsubs) -(puthash "\\mbfsansTheta" "ð" julia-latexsubs) -(puthash "\\mbfsansIota" "ðž" julia-latexsubs) -(puthash "\\mbfsansKappa" "ðŸ" julia-latexsubs) -(puthash "\\mbfsansLambda" "ð " julia-latexsubs) -(puthash "\\mbfsansMu" "ð¡" julia-latexsubs) -(puthash "\\mbfsansNu" "ð¢" julia-latexsubs) -(puthash "\\mbfsansXi" "ð£" julia-latexsubs) -(puthash "\\mbfsansOmicron" "ð¤" julia-latexsubs) -(puthash "\\mbfsansPi" "ð¥" julia-latexsubs) -(puthash "\\mbfsansRho" "ð¦" julia-latexsubs) -(puthash "\\mbfsansvarTheta" "ð§" julia-latexsubs) -(puthash "\\mbfsansSigma" "ð¨" julia-latexsubs) -(puthash "\\mbfsansTau" "ð©" julia-latexsubs) -(puthash "\\mbfsansUpsilon" "ðª" julia-latexsubs) -(puthash "\\mbfsansPhi" "ð«" julia-latexsubs) -(puthash "\\mbfsansChi" "ð¬" julia-latexsubs) -(puthash "\\mbfsansPsi" "ð­" julia-latexsubs) -(puthash "\\mbfsansOmega" "ð®" julia-latexsubs) -(puthash "\\mbfsansnabla" "ð¯" julia-latexsubs) -(puthash "\\mbfsansalpha" "ð°" julia-latexsubs) -(puthash "\\mbfsansbeta" "ð±" julia-latexsubs) -(puthash "\\mbfsansgamma" "ð²" julia-latexsubs) -(puthash "\\mbfsansdelta" "ð³" julia-latexsubs) -(puthash "\\mbfsansepsilon" "ð´" julia-latexsubs) -(puthash "\\mbfsanszeta" "ðµ" julia-latexsubs) -(puthash "\\mbfsanseta" "ð¶" julia-latexsubs) -(puthash "\\mbfsanstheta" "ð·" julia-latexsubs) -(puthash "\\mbfsansiota" "ð¸" julia-latexsubs) -(puthash "\\mbfsanskappa" "ð¹" julia-latexsubs) -(puthash "\\mbfsanslambda" "ðº" julia-latexsubs) -(puthash "\\mbfsansmu" "ð»" julia-latexsubs) -(puthash "\\mbfsansnu" "ð¼" julia-latexsubs) -(puthash "\\mbfsansxi" "ð½" julia-latexsubs) -(puthash "\\mbfsansomicron" "ð¾" julia-latexsubs) -(puthash "\\mbfsanspi" "ð¿" julia-latexsubs) -(puthash "\\mbfsansrho" "ðž€" julia-latexsubs) -(puthash "\\mbfsansvarsigma" "ðž" julia-latexsubs) -(puthash "\\mbfsanssigma" "ðž‚" julia-latexsubs) -(puthash "\\mbfsanstau" "ðžƒ" julia-latexsubs) -(puthash "\\mbfsansupsilon" "ðž„" julia-latexsubs) -(puthash "\\mbfsansphi" "ðž…" julia-latexsubs) -(puthash "\\mbfsanschi" "ðž†" julia-latexsubs) -(puthash "\\mbfsanspsi" "ðž‡" julia-latexsubs) -(puthash "\\mbfsansomega" "ðžˆ" julia-latexsubs) -(puthash "\\mbfsanspartial" "ðž‰" julia-latexsubs) -(puthash "\\mbfsansvarepsilon" "ðžŠ" julia-latexsubs) -(puthash "\\mbfsansvartheta" "ðž‹" julia-latexsubs) -(puthash "\\mbfsansvarkappa" "ðžŒ" julia-latexsubs) -(puthash "\\mbfsansvarphi" "ðž" julia-latexsubs) -(puthash "\\mbfsansvarrho" "ðžŽ" julia-latexsubs) -(puthash "\\mbfsansvarpi" "ðž" julia-latexsubs) -(puthash "\\mbfitsansAlpha" "ðž" julia-latexsubs) -(puthash "\\mbfitsansBeta" "ðž‘" julia-latexsubs) -(puthash "\\mbfitsansGamma" "ðž’" julia-latexsubs) -(puthash "\\mbfitsansDelta" "ðž“" julia-latexsubs) -(puthash "\\mbfitsansEpsilon" "ðž”" julia-latexsubs) -(puthash "\\mbfitsansZeta" "ðž•" julia-latexsubs) -(puthash "\\mbfitsansEta" "ðž–" julia-latexsubs) -(puthash "\\mbfitsansTheta" "ðž—" julia-latexsubs) -(puthash "\\mbfitsansIota" "ðž˜" julia-latexsubs) -(puthash "\\mbfitsansKappa" "ðž™" julia-latexsubs) -(puthash "\\mbfitsansLambda" "ðžš" julia-latexsubs) -(puthash "\\mbfitsansMu" "ðž›" julia-latexsubs) -(puthash "\\mbfitsansNu" "ðžœ" julia-latexsubs) -(puthash "\\mbfitsansXi" "ðž" julia-latexsubs) -(puthash "\\mbfitsansOmicron" "ðžž" julia-latexsubs) -(puthash "\\mbfitsansPi" "ðžŸ" julia-latexsubs) -(puthash "\\mbfitsansRho" "ðž " julia-latexsubs) -(puthash "\\mbfitsansvarTheta" "ðž¡" julia-latexsubs) -(puthash "\\mbfitsansSigma" "ðž¢" julia-latexsubs) -(puthash "\\mbfitsansTau" "ðž£" julia-latexsubs) -(puthash "\\mbfitsansUpsilon" "ðž¤" julia-latexsubs) -(puthash "\\mbfitsansPhi" "ðž¥" julia-latexsubs) -(puthash "\\mbfitsansChi" "ðž¦" julia-latexsubs) -(puthash "\\mbfitsansPsi" "ðž§" julia-latexsubs) -(puthash "\\mbfitsansOmega" "ðž¨" julia-latexsubs) -(puthash "\\mbfitsansnabla" "ðž©" julia-latexsubs) -(puthash "\\mbfitsansalpha" "ðžª" julia-latexsubs) -(puthash "\\mbfitsansbeta" "ðž«" julia-latexsubs) -(puthash "\\mbfitsansgamma" "ðž¬" julia-latexsubs) -(puthash "\\mbfitsansdelta" "ðž­" julia-latexsubs) -(puthash "\\mbfitsansepsilon" "ðž®" julia-latexsubs) -(puthash "\\mbfitsanszeta" "ðž¯" julia-latexsubs) -(puthash "\\mbfitsanseta" "ðž°" julia-latexsubs) -(puthash "\\mbfitsanstheta" "ðž±" julia-latexsubs) -(puthash "\\mbfitsansiota" "ðž²" julia-latexsubs) -(puthash "\\mbfitsanskappa" "ðž³" julia-latexsubs) -(puthash "\\mbfitsanslambda" "ðž´" julia-latexsubs) -(puthash "\\mbfitsansmu" "ðžµ" julia-latexsubs) -(puthash "\\mbfitsansnu" "ðž¶" julia-latexsubs) -(puthash "\\mbfitsansxi" "ðž·" julia-latexsubs) -(puthash "\\mbfitsansomicron" "ðž¸" julia-latexsubs) -(puthash "\\mbfitsanspi" "ðž¹" julia-latexsubs) -(puthash "\\mbfitsansrho" "ðžº" julia-latexsubs) -(puthash "\\mbfitsansvarsigma" "ðž»" julia-latexsubs) -(puthash "\\mbfitsanssigma" "ðž¼" julia-latexsubs) -(puthash "\\mbfitsanstau" "ðž½" julia-latexsubs) -(puthash "\\mbfitsansupsilon" "ðž¾" julia-latexsubs) -(puthash "\\mbfitsansphi" "ðž¿" julia-latexsubs) -(puthash "\\mbfitsanschi" "ðŸ€" julia-latexsubs) -(puthash "\\mbfitsanspsi" "ðŸ" julia-latexsubs) -(puthash "\\mbfitsansomega" "ðŸ‚" julia-latexsubs) -(puthash "\\mbfitsanspartial" "ðŸƒ" julia-latexsubs) -(puthash "\\mbfitsansvarepsilon" "ðŸ„" julia-latexsubs) -(puthash "\\mbfitsansvartheta" "ðŸ…" julia-latexsubs) -(puthash "\\mbfitsansvarkappa" "ðŸ†" julia-latexsubs) -(puthash "\\mbfitsansvarphi" "ðŸ‡" julia-latexsubs) -(puthash "\\mbfitsansvarrho" "ðŸˆ" julia-latexsubs) -(puthash "\\mbfitsansvarpi" "ðŸ‰" julia-latexsubs) -(puthash "\\mbfDigamma" "ðŸŠ" julia-latexsubs) -(puthash "\\mbfdigamma" "ðŸ‹" julia-latexsubs) -(puthash "\\mbfzero" "ðŸŽ" julia-latexsubs) -(puthash "\\mbfone" "ðŸ" julia-latexsubs) -(puthash "\\mbftwo" "ðŸ" julia-latexsubs) -(puthash "\\mbfthree" "ðŸ‘" julia-latexsubs) -(puthash "\\mbffour" "ðŸ’" julia-latexsubs) -(puthash "\\mbffive" "ðŸ“" julia-latexsubs) -(puthash "\\mbfsix" "ðŸ”" julia-latexsubs) -(puthash "\\mbfseven" "ðŸ•" julia-latexsubs) -(puthash "\\mbfeight" "ðŸ–" julia-latexsubs) -(puthash "\\mbfnine" "ðŸ—" julia-latexsubs) -(puthash "\\Bbbzero" "ðŸ˜" julia-latexsubs) -(puthash "\\Bbbone" "ðŸ™" julia-latexsubs) -(puthash "\\Bbbtwo" "ðŸš" julia-latexsubs) -(puthash "\\Bbbthree" "ðŸ›" julia-latexsubs) -(puthash "\\Bbbfour" "ðŸœ" julia-latexsubs) -(puthash "\\Bbbfive" "ðŸ" julia-latexsubs) -(puthash "\\Bbbsix" "ðŸž" julia-latexsubs) -(puthash "\\Bbbseven" "ðŸŸ" julia-latexsubs) -(puthash "\\Bbbeight" "ðŸ " julia-latexsubs) -(puthash "\\Bbbnine" "ðŸ¡" julia-latexsubs) -(puthash "\\msanszero" "ðŸ¢" julia-latexsubs) -(puthash "\\msansone" "ðŸ£" julia-latexsubs) -(puthash "\\msanstwo" "ðŸ¤" julia-latexsubs) -(puthash "\\msansthree" "ðŸ¥" julia-latexsubs) -(puthash "\\msansfour" "ðŸ¦" julia-latexsubs) -(puthash "\\msansfive" "ðŸ§" julia-latexsubs) -(puthash "\\msanssix" "ðŸ¨" julia-latexsubs) -(puthash "\\msansseven" "ðŸ©" julia-latexsubs) -(puthash "\\msanseight" "ðŸª" julia-latexsubs) -(puthash "\\msansnine" "ðŸ«" julia-latexsubs) -(puthash "\\mbfsanszero" "ðŸ¬" julia-latexsubs) -(puthash "\\mbfsansone" "ðŸ­" julia-latexsubs) -(puthash "\\mbfsanstwo" "ðŸ®" julia-latexsubs) -(puthash "\\mbfsansthree" "ðŸ¯" julia-latexsubs) -(puthash "\\mbfsansfour" "ðŸ°" julia-latexsubs) -(puthash "\\mbfsansfive" "ðŸ±" julia-latexsubs) -(puthash "\\mbfsanssix" "ðŸ²" julia-latexsubs) -(puthash "\\mbfsansseven" "ðŸ³" julia-latexsubs) -(puthash "\\mbfsanseight" "ðŸ´" julia-latexsubs) -(puthash "\\mbfsansnine" "ðŸµ" julia-latexsubs) -(puthash "\\mttzero" "ðŸ¶" julia-latexsubs) -(puthash "\\mttone" "ðŸ·" julia-latexsubs) -(puthash "\\mtttwo" "ðŸ¸" julia-latexsubs) -(puthash "\\mttthree" "ðŸ¹" julia-latexsubs) -(puthash "\\mttfour" "ðŸº" julia-latexsubs) -(puthash "\\mttfive" "ðŸ»" julia-latexsubs) -(puthash "\\mttsix" "ðŸ¼" julia-latexsubs) -(puthash "\\mttseven" "ðŸ½" julia-latexsubs) -(puthash "\\mtteight" "ðŸ¾" julia-latexsubs) -(puthash "\\mttnine" "ðŸ¿" julia-latexsubs) - -;; Math insertion in julia. Use it with -;; (add-hook 'julia-mode-hook 'julia-math-mode) -;; (add-hook 'inferior-julia-mode-hook 'julia-math-mode) - -(when (require 'latex nil t) - (defun julia-math-insert (s) - "Inserts math symbol given by `s'" - (when s - (let ((sym (gethash (concat "\\" s) julia-latexsubs))) - (when sym - (insert sym))))) - - (define-minor-mode julia-math-mode - "A minor mode with easy access to TeX math commands. The -command is only entered if it is supported in Julia. The -following commands are defined: - -\\{LaTeX-math-mode-map}" - nil nil (list (cons (LaTeX-math-abbrev-prefix) LaTeX-math-keymap)) - (if julia-math-mode - (set (make-local-variable 'LaTeX-math-insert-function) 'julia-math-insert)))) - -;; Code for `inferior-julia-mode' -(require 'comint) - -(defcustom julia-program "julia" - "Path to the program used by `inferior-julia'." - :type 'string - :group 'julia) - -(defcustom julia-arguments '("-i" "--color=yes") - "Commandline arguments to pass to `julia-program'." - :type '(repeat (string :tag "argument")) - :group 'julia) - -(defvar julia-prompt-regexp "^\\w*> " - "Regexp for matching `inferior-julia' prompt.") - -(defvar inferior-julia-mode-map - (let ((map (nconc (make-sparse-keymap) comint-mode-map))) - ;; example definition - (define-key map (kbd "TAB") 'julia-latexsub-or-indent) - map) - "Basic mode map for `inferior-julia-mode'.") - -;;;###autoload -(defun inferior-julia () - "Run an inferior instance of `julia' inside Emacs." - (interactive) - (let ((julia-program julia-program) - (buffer (get-buffer-create "*Julia*"))) - (when (not (comint-check-proc "*Julia*")) - (apply #'make-comint-in-buffer "Julia" "*Julia*" - julia-program nil julia-arguments)) - (pop-to-buffer-same-window "*Julia*") - (inferior-julia-mode))) - -(defun inferior-julia--initialize () - "Helper function to initialize `inferior-julia'." - (setq comint-use-prompt-regexp t)) - -(define-derived-mode inferior-julia-mode comint-mode "Julia" - "Major mode for `inferior-julia'. - -\\" - nil "Julia" - (setq comint-prompt-regexp julia-prompt-regexp) - (setq comint-prompt-read-only t) - (set (make-local-variable 'font-lock-defaults) '(julia-font-lock-keywords t)) - (set (make-local-variable 'paragraph-start) julia-prompt-regexp) - (set (make-local-variable 'indent-line-function) 'julia-indent-line)) - -(add-hook 'inferior-julia-mode-hook 'inferior-julia--initialize) - -;;;###autoload -(defalias 'run-julia #'inferior-julia - "Run an inferior instance of `julia' inside Emacs.") - -(provide 'julia-mode) - -;; Local Variables: -;; coding: utf-8 -;; byte-compile-warnings: (not obsolete) -;; End: -;;; julia-mode.el ends here diff --git a/packages/julia-mode-20190813.1326.tar b/packages/julia-mode-20190813.1326.tar new file mode 100644 index 0000000..6f03ae4 Binary files /dev/null and b/packages/julia-mode-20190813.1326.tar differ diff --git a/packages/julia-repl-20180923.1124.el b/packages/julia-repl-20190420.1455.el similarity index 94% rename from packages/julia-repl-20180923.1124.el rename to packages/julia-repl-20190420.1455.el index cfaf3bd..b3aea33 100644 --- a/packages/julia-repl-20180923.1124.el +++ b/packages/julia-repl-20190420.1455.el @@ -3,7 +3,7 @@ ;; Copyright (C) 2016 Tamas K. Papp ;; Author: Tamas Papp ;; Keywords: languages -;; Package-Version: 20180923.1124 +;; Package-Version: 20190420.1455 ;; Version: 0.0.1 ;; Package-Requires: ((emacs "25")) ;; URL: https://github.com/tpapp/julia-repl @@ -43,9 +43,12 @@ (require 'term) (require 'subr-x) (require 'cl-lib) +(require 'compile) +(require 'seq) - +;; ;; customizations +;; (defgroup julia-repl nil "A minor mode for a Julia REPL" @@ -75,8 +78,9 @@ Note that this affects all buffers using the ‘ansi-term’ map." :type 'boolean :group 'julia-repl) - +;; ;; global variables +;; (defvar julia-repl--compilation-regexp-alist '(;; matches "while loading /tmp/Foo.jl, in expression starting on line 2" @@ -84,7 +88,7 @@ Note that this affects all buffers using the ‘ansi-term’ map." ;; matches "around /tmp/Foo.jl:2", also starting with "at" or "Revise" (julia-loc . ("\\(around\\|at\\|Revise\\) \\([^ ><()\t\n,'\";:]+\\):\\([0-9]+\\)" 2 3)) ;; matches "omitting file /tmp/Foo.jl due to parsing error near line 2", from Revise.parse_source! - (julia-warn-revise . ("omitting file ([^ ><()\t\n,'\";:]+\\) due to parsing error near line \\([0-9]+\\)" 1 2)) + (julia-warn-revise . ("omitting file \\([^ ><()\t\n,'\";:]+\\) due to parsing error near line \\([0-9]+\\)" 1 2)) ) "Specifications for highlighting error locations. @@ -141,8 +145,9 @@ generate a buffer name.") Valid values are NIL or a string. These take effect the next time a new Julia process is started.") - +;; ;; REPL buffer creation and setup +;; (cl-defun julia-repl--inferior-buffer-name (&optional (executable-key (julia-repl--get-executable-key)) @@ -193,7 +198,7 @@ Queries and appends missing information if necessary. Note: when cannot capture the base dir, it is set to NIL to prevent further attempts." (unless (plist-member (cddr executable-record) :basedir) - (let* ((executable-path (second executable-record)) + (let* ((executable-path (cl-second executable-record)) (basedir (julia-repl--capture-basedir executable-path))) (nconc executable-record `(:basedir ,basedir)) (unless basedir @@ -274,7 +279,7 @@ Return the buffer. Buffer is not raised." (let ((executable-record (julia-repl--executable-record executable-key)) (inferior-buffer-name (julia-repl--inferior-buffer-name executable-key suffix))) (julia-repl--complete-executable-record! executable-record) - (let* ((executable-path (second executable-record)) + (let* ((executable-path (cl-second executable-record)) (basedir (plist-get (cddr executable-record) :basedir)) (inferior-buffer (julia-repl--start-inferior inferior-buffer-name executable-path))) @@ -301,8 +306,9 @@ raised if not found." (when (term-check-proc inferior-buffer) inferior-buffer))) - +;; ;; prompting for executable-key and suffix +;; (defun julia-repl--matching-inferior-buffers (executable-key) "A list of macthing inferior buffers for the current source buffer. @@ -334,12 +340,12 @@ See ‘julia-repl--inferior-buffer-name’." buffer) buffer)) matching-inferior-buffers)) - (suffix-buffer-alist (stable-sort suffix-buffer-alist - (lambda (x y) - (or (not x) - (string< (prin1-to-string x) - (prin1-to-string y)))) - :key #'car)) + (suffix-buffer-alist (cl-stable-sort suffix-buffer-alist + (lambda (x y) + (or (not x) + (string< (prin1-to-string x) + (prin1-to-string y)))) + :key #'car)) (suffix (completing-read "julia-repl inferior buffer name suffix: " suffix-buffer-alist))) (message "suffix buffer alist %s" suffix) @@ -353,7 +359,7 @@ See ‘julia-repl--inferior-buffer-name’." (while (get-buffer (julia-repl--add-earmuffs (julia-repl--inferior-buffer-name executable-key index))) - (incf index)) + (cl-incf index)) index)) (defun julia-repl-prompt-set-inferior-buffer-name-suffix (arg) @@ -376,7 +382,7 @@ Both of these happen without prompting." ((integerp arg) arg) ((listp arg) - (first arg))))) + (cl-first arg))))) (setq julia-repl-inferior-buffer-name-suffix suffix) (message "julia-repl-inferior-buffer-name-suffix set to %s" suffix))) @@ -405,8 +411,9 @@ Valid keys are the first items in ‘julia-repl-executable-records’." (message "julia-repl-executable-key set to %s" (propertize (symbol-name key) 'face 'font-lock-constant-face)))) - +;; ;; high-level functions +;; (defun julia-repl-inferior-buffer () "Return the Julia REPL inferior buffer, creating one if it does not exist." @@ -423,8 +430,9 @@ This is the standard entry point for using this package." (interactive) (switch-to-buffer-other-window (julia-repl-inferior-buffer))) - +;; ;; sending to the REPL +;; (defun julia-repl--send-string (string &optional no-newline no-bracketed-paste) "Send STRING to the Julia REPL term buffer. @@ -521,8 +529,10 @@ this with a prefix argument ARG." (defun julia-repl-cd () "Change directory to the directory of the current buffer (if applicable)." (interactive) - (if-let ((filename (buffer-file-name))) - (julia-repl--send-string (concat "cd(\"" (file-name-directory filename) "\")")) + (if-let ((directory (file-name-directory (buffer-file-name)))) + (progn + (julia-repl--send-string (concat "cd(\"" directory "\")")) + (with-current-buffer (julia-repl-inferior-buffer) (cd directory))) (warn "buffer not associated with a file"))) (defun julia-repl-activate-parent (arg) @@ -545,6 +555,16 @@ When called with a prefix argument, activate the home project." (expand-file-name (file-name-directory projectfile)) "\")"))) (message "could not find project file"))))) +(defun julia-repl-set-julia-editor (editor) + "Set the JULIA_EDITOR environment variable." + (interactive) + (julia-repl--send-string (format "ENV[\"JULIA_EDITOR\"] = \"%s\";" editor))) + +(defun julia-repl-use-emacsclient () + "Use emacsclient as the JULIA_EDITOR." + (interactive) + (julia-repl--send-string "ENV[\"JULIA_EDITOR\"] = \"emacsclient\";")) + ;;;###autoload (define-minor-mode julia-repl-mode "Minor mode for interacting with a Julia REPL running inside a term." diff --git a/packages/kaolin-themes-20181117.836.tar b/packages/kaolin-themes-20190812.1835.tar similarity index 64% rename from packages/kaolin-themes-20181117.836.tar rename to packages/kaolin-themes-20190812.1835.tar index b73149b..bc5238f 100644 Binary files a/packages/kaolin-themes-20181117.836.tar and b/packages/kaolin-themes-20190812.1835.tar differ diff --git a/packages/know-your-http-well-20160208.2304.tar b/packages/know-your-http-well-20160208.2304.tar index 797ec40..6fd7a65 100644 Binary files a/packages/know-your-http-well-20160208.2304.tar and b/packages/know-your-http-well-20160208.2304.tar differ diff --git a/packages/kotlin-mode-20181109.1818.el b/packages/kotlin-mode-20190116.2055.el similarity index 98% rename from packages/kotlin-mode-20181109.1818.el rename to packages/kotlin-mode-20190116.2055.el index 6141d40..e1fdb0a 100644 --- a/packages/kotlin-mode-20181109.1818.el +++ b/packages/kotlin-mode-20190116.2055.el @@ -4,7 +4,7 @@ ;; Author: Shodai Yokoyama (quantumcars@gmail.com) ;; Keywords: languages -;; Package-Version: 20181109.1818 +;; Package-Version: 20190116.2055 ;; Package-Requires: ((emacs "24.3")) ;; This program is free software; you can redistribute it and/or modify @@ -215,7 +215,7 @@ ;; Types (,(rx-to-string - `(and bow upper (group (* (or word "<" ">" "." "?" "!")))) + `(and bow upper (group (* (or word "<" ">" "." "?" "!" "*")))) t) 0 font-lock-type-face) @@ -414,7 +414,7 @@ :syntax-table kotlin-mode-syntax-table) ;;;###autoload -(add-to-list 'auto-mode-alist '("\\.kt\\'" . kotlin-mode) t) +(add-to-list 'auto-mode-alist '("\\.kts?\\'" . kotlin-mode) t) (provide 'kotlin-mode) ;;; kotlin-mode.el ends here diff --git a/packages/ledger-mode-20181107.1942.tar b/packages/ledger-mode-20190811.2340.tar similarity index 92% rename from packages/ledger-mode-20181107.1942.tar rename to packages/ledger-mode-20190811.2340.tar index 70ff64a..02241d0 100644 Binary files a/packages/ledger-mode-20181107.1942.tar and b/packages/ledger-mode-20190811.2340.tar differ diff --git a/packages/let-alist-1.0.5.el b/packages/let-alist-1.0.6.el similarity index 96% rename from packages/let-alist-1.0.5.el rename to packages/let-alist-1.0.6.el index 43973c2..96b397f 100644 --- a/packages/let-alist-1.0.5.el +++ b/packages/let-alist-1.0.6.el @@ -1,10 +1,10 @@ ;;; let-alist.el --- Easily let-bind values of an assoc-list by their names -*- lexical-binding: t; -*- -;; Copyright (C) 2014-2017 Free Software Foundation, Inc. +;; Copyright (C) 2014-2019 Free Software Foundation, Inc. ;; Author: Artur Malabarba ;; Package-Requires: ((emacs "24.1")) -;; Version: 1.0.5 +;; Version: 1.0.6 ;; Keywords: extensions lisp ;; Prefix: let-alist ;; Separator: - @@ -25,7 +25,7 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . +;; along with GNU Emacs. If not, see . ;;; Commentary: @@ -75,6 +75,8 @@ symbol, and each cdr is the same symbol without the `.'." ;; Return the cons cell inside a list, so it can be appended ;; with other results in the clause below. (list (cons data (intern (replace-match "" nil nil name))))))) + ((vectorp data) + (apply #'nconc (mapcar #'let-alist--deep-dot-search data))) ((not (consp data)) nil) ((eq (car data) 'let-alist) ;; For nested ‘let-alist’ forms, ignore symbols appearing in the diff --git a/packages/link-hint-20180519.2130.el b/packages/link-hint-20190721.1844.el similarity index 94% rename from packages/link-hint-20180519.2130.el rename to packages/link-hint-20190721.1844.el index d55a47c..02fc592 100644 --- a/packages/link-hint-20180519.2130.el +++ b/packages/link-hint-20190721.1844.el @@ -1,8 +1,8 @@ ;;; link-hint.el --- Use avy to open, copy, etc. visible links. -*- lexical-binding: t -*- -;; Author: Fox Kiester +;; Author: Fox Kiester ;; URL: https://github.com/noctuid/link-hint.el -;; Package-Version: 20180519.2130 +;; Package-Version: 20190721.1844 ;; Keywords: convenience url avy link links hyperlink ;; Package-Requires: ((avy "0.4.0") (emacs "24.1") (cl-lib "0.5")) ;; Version: 0.1 @@ -69,6 +69,7 @@ link-hint-w3m-link link-hint-w3m-message-link link-hint-woman-button + link-hint-treemacs link-hint-nov-link ;; link-hint-customize-widget ;; generic @@ -364,7 +365,7 @@ Only search the range between just after the point and BOUND." :next #'link-hint--next-button :at-point-p #'link-hint--button-at-point-p ;; TODO add more - :not-vars '(woman-mode) + :not-vars '(woman-mode treemacs-mode) :open #'push-button :copy #'kill-new) @@ -419,6 +420,33 @@ Only search the range between just after the point and BOUND." :open-multiple t :copy #'kill-new) +;; ** Treemacs Link +(defun link-hint--open-treemacs-button () + "Open an entry in a treemacs buffer." + (if (string-prefix-p " *Treemacs-" (buffer-name)) + (treemacs-visit-node-in-most-recently-used-window) + (treemacs-visit-node-default))) + +(defun link-hint--copy-treemacs () + "Copy an entry in a treemacs buffer." + (kill-new (format "%s" + (treemacs-button-get + (treemacs-node-at-point) :key)))) + +(defun link-hint--treemacs-at-point-p() + "`:at-point-p' for treemacs buffers." + (let ((node (treemacs-node-at-point))) + (when node + (format "%s" (treemacs-button-get node :key))))) + +(link-hint-define-type 'treemacs + :next #'link-hint--next-button + :at-point-p #'link-hint--treemacs-at-point-p + :vars '(treemacs-mode) + :open #'link-hint--open-treemacs-button + :open-multiple t + :copy #'link-hint--copy-treemacs) + ;; ** Markdown Link (declare-function markdown-next-link "markdown-mode") (defun link-hint--next-markdown-link (&optional bound) @@ -998,20 +1026,30 @@ If the point/window are not intentionally changed by the action, restore them." (setq new-win-buffer (window-buffer (selected-window))) (cond ((and (eq new-win-buffer link-buffer) (= (point) link-pos)) - ;; when buffer and position don't change, restore position and - ;; window (no side effects have occurred) + ;; when the buffer doesn't change and the point is still at the + ;; link, restore the position and window (no side effects have + ;; occurred) (goto-char link-buffer-original-pos) - (select-window original-win)) - ((not (eq new-win-buffer link-buffer)) - ;; when buffer changes, restore position in old buffer - (with-selected-window link-win - ;; so will only change position if link-win still holds - ;; link-buffer TODO cannot change point using - ;; `with-current-buffer' unless the selected window holds the - ;; buffer; use a temporary window if it doesn't (unlikely - ;; scenario)? - (with-current-buffer link-buffer - (goto-char link-buffer-original-pos)))) + (when (window-valid-p original-win) + (select-window original-win))) + ((and (buffer-live-p link-buffer) + (not (eq new-win-buffer link-buffer))) + ;; when the buffer changes and the old buffer still exists, restore + ;; the original position in the old buffer + (if (and + ;; old window still exists + (window-valid-p link-win) + ;; old window still holds original buffer + (eq link-buffer (window-buffer link-win))) + ;; restore the point in that window + (set-window-point link-win link-buffer-original-pos) + ;; `save-excursion' to prevent altering the current window's + ;; point; only set the buffer's point since it is no longer + ;; displayed in the old window + ;; see https://www.gnu.org/software/emacs/manual/html_node/elisp/Point.html#Point + (save-excursion + (with-current-buffer link-buffer + (goto-char link-buffer-original-pos))))) ;; when buffer doesn't change but position does (e.g. local org ;; link), do nothing )) diff --git a/packages/live-py-mode-20181116.536.tar b/packages/live-py-mode-20190614.433.tar similarity index 88% rename from packages/live-py-mode-20181116.536.tar rename to packages/live-py-mode-20190614.433.tar index 088c9c6..a4ba65c 100644 Binary files a/packages/live-py-mode-20181116.536.tar and b/packages/live-py-mode-20190614.433.tar differ diff --git a/packages/load-relative-20170526.1010.tar b/packages/load-relative-20190601.1221.tar similarity index 90% rename from packages/load-relative-20170526.1010.tar rename to packages/load-relative-20190601.1221.tar index ee0fb3c..6a4934c 100644 Binary files a/packages/load-relative-20170526.1010.tar and b/packages/load-relative-20190601.1221.tar differ diff --git a/packages/lorem-ipsum-20140911.2108.el b/packages/lorem-ipsum-20190819.2042.el similarity index 95% rename from packages/lorem-ipsum-20140911.2108.el rename to packages/lorem-ipsum-20190819.2042.el index 5d0d29d..021aa6b 100644 --- a/packages/lorem-ipsum-20140911.2108.el +++ b/packages/lorem-ipsum-20190819.2042.el @@ -4,7 +4,7 @@ ;; Author: Jean-Philippe Theberge (jphil21@sourceforge.net) ;; Maintainer: Joe Schafer (joe@jschaf.com) -;; Package-Version: 20140911.2108 +;; Package-Version: 20190819.2042 ;; Package-X-Original-Version: 0.2 ;; Keywords: tools, language, convenience @@ -198,13 +198,13 @@ If NUM is non-nil, insert NUM sentences." If NUM is non-nil, insert NUM list items." (interactive "p") (if (not num)(setq num 1)) - (if (> num 0) - (progn - (let ((para (nth (random (length lorem-ipsum-text)) lorem-ipsum-text))) - (insert (concat lorem-ipsum-list-bullet - (nth (random (length para)) para) - lorem-ipsum-list-item-end))) - (lorem-ipsum-insert-list (- num 1))) + (when (> num 0) + (insert lorem-ipsum-list-beginning) + (dotimes (i num) + (let ((para (nth (random (length lorem-ipsum-text)) lorem-ipsum-text))) + (insert (concat lorem-ipsum-list-bullet + (nth (random (length para)) para) + lorem-ipsum-list-item-end)))) (insert lorem-ipsum-list-end))) ;;;###autoload diff --git a/packages/lsp-go-20180914.515.el b/packages/lsp-go-20180914.515.el deleted file mode 100644 index cbc2575..0000000 --- a/packages/lsp-go-20180914.515.el +++ /dev/null @@ -1,83 +0,0 @@ -;;; lsp-go.el --- Go support for lsp-mode - -;; Copyright (C) 2017 Vibhav Pant - -;; Author: Vibhav Pant -;; Version: 1.0 -;; Package-Version: 20180914.515 -;; Package-Requires: ((lsp-mode "3.0")) -;; Keywords: go, golang -;; URL: https://github.com/emacs-lsp/lsp-go - -(require 'lsp-mode) - -(defgroup lsp-go nil - "lsp-go settings" - :group 'tools) - -(defcustom lsp-go-executable-path (executable-find "go-langserver") - "Path to the go-langserver executable." - :type 'string - :group 'lsp-go) - -(defcustom lsp-go-language-server-flags '("-gocodecompletion") - "Extra arguments for the go-langserver." - :type '(repeat string) - :group 'lsp-go) - -(defcustom lsp-go-func-snippet-enabled t - "Enable the returning of argument snippets on `func' completions, eg. -`func(foo string, arg2 bar)'. Requires code completion to be enabled." - :type 'bool - :group 'lsp-go) - -(defcustom lsp-go-gocode-completion-enabled t - "Enable code completion feature (using gocode)." - :type 'bool - :group 'lsp-go) - -(defcustom lsp-go-format-tool "goimports" - "The tool to be used for formatting documents. Defaults to `goimports' if nil." - :type '(choice (const :tag "goimports" "goimports") - (const :tag "gofmt" "gofmt")) - :group 'lsp-go) - -(defcustom lsp-go-imports-local-prefix "" - "The local prefix (comma-separated string) that goimports will use." - :type 'string - :group 'lsp-go) - -(defcustom lsp-go-max-parallelism nil - "The maximum number of goroutines that should be used to fulfill requests. -This is useful in editor environments where users do not want results ASAP, -but rather just semi quickly without eating all of their CPU. When nil, -defaults to half of your CPU cores." - :type '(choice integer (const nil "Half of CPU cores.")) - :group 'lsp-go) - -(defcustom lsp-go-use-binary-pkg-cache t - "Whether or not $GOPATH/pkg binary .a files should be used." - :type 'bool - :group 'lsp-go) - -(define-inline lsp-go--bool-to-json (val) - (inline-quote (if ,val t :json-false))) - -(defun lsp-go--make-init-options (_) - `(:funcSnippetEnabled ,(lsp-go--bool-to-json lsp-go-func-snippet-enabled) - :gocodeCompletionEnabled ,(lsp-go--bool-to-json lsp-go-gocode-completion-enabled) - :formatTool ,lsp-go-format-tool - :goimportsLocalPrefix ,lsp-go-imports-local-prefix - :maxParallelism ,lsp-go-max-parallelism - :useBinaryPkgCache ,lsp-go-use-binary-pkg-cache)) - -(lsp-define-stdio-client lsp-go "go" #'(lambda () default-directory) - `(,lsp-go-executable-path - "-mode=stdio" - ,@lsp-go-language-server-flags) - :ignore-regexps - '("^langserver-go: reading on stdin, writing on stdout$") - :extra-init-params #'lsp-go--make-init-options) - -(provide 'lsp-go) -;;; lsp-go.el ends here diff --git a/packages/lsp-haskell-20190602.825.el b/packages/lsp-haskell-20190602.825.el new file mode 100644 index 0000000..c27cfd7 --- /dev/null +++ b/packages/lsp-haskell-20190602.825.el @@ -0,0 +1,294 @@ +;;; lsp-haskell.el --- Haskell support for lsp-mode + +;; Version: 1.0 +;; Package-Version: 20190602.825 +;; Package-Requires: ((lsp-mode "3.0") (haskell-mode "1.0")) +;; Keywords: haskell +;; URL: https://github.com/emacs-lsp/lsp-haskell + +;;; License +;; +;; 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; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. + +;;; Code: + +(require 'haskell) +(require 'lsp-mode) +(require 'projectile nil 'noerror) + +;; --------------------------------------------------------------------- +;; Configuration + +;;;###autoload +(defgroup lsp-haskell nil + "Customization group for ‘lsp-haskell’." + :group 'lsp-mode) + +;;;###autoload +(defcustom lsp-haskell-process-path-hie + ;; "hie" + "hie-wrapper" + "The path for starting the haskell-ide-engine +server. hie-wrapper exists on HIE master from 2018-06-10" + :group 'lsp-haskell + :type '(choice string)) + +;;;###autoload +(defcustom lsp-haskell-process-args-hie + '("-d" "-l" "/tmp/hie.log") + "The arguments for starting the haskell-ide-engine server. +For a debug log, use `-d -l /tmp/hie.log'." + :group 'lsp-haskell + :type '(repeat (string :tag "Argument"))) + +;;;###autoload +(defcustom lsp-haskell-process-wrapper-function + #'identity + "Use this to wrap the haskell-ide-engine process started by lsp-haskell. + +For example, use the following the start the hie process in a nix-shell: + +(lambda (argv) + (append + (append (list \"nix-shell\" \"-I\" \".\" \"--command\" ) + (list (mapconcat 'identity argv \" \")) + ) + (list (concat (lsp-haskell--get-root) \"/shell.nix\")) + ) + )" + :group 'lsp-haskell + :type '(choice + (function-item :tag "None" :value identity) + (function :tag "Custom function"))) + +;; --------------------------------------------------------------------- +;; HaRe functions + +(defun lsp-demote () + "Demote a function to the level it is used" + (interactive) + (lsp--cur-workspace-check) + (lsp--send-execute-command + "hare:demote" + (vector `(:file ,(concat "file://" buffer-file-name) + :pos ,(lsp-point-to-position (point)))))) + +(defun lsp-duplicate-definition (newname) + "Duplicate a definition" + (interactive "sNew definition name: ") + (lsp--cur-workspace-check) + (lsp--send-execute-command + "hare:dupdef" + (vector `(:file ,(concat "file://" buffer-file-name) + :pos ,(lsp-point-to-position (point)) + :text ,newname)))) + +(defun lsp-if-to-case () + "Convert an if statement to a case statement" + (interactive) + (lsp--cur-workspace-check) + (lsp--send-execute-command + "hare:iftocase" + (vector `(:file ,(concat "file://" buffer-file-name) + :start_pos ,(lsp-get-start-position) + :end_pos ,(lsp-get-end-position))))) + +(defun lsp-lift-level () + "Lift a function to the top level" + (interactive) + (lsp--cur-workspace-check) + (lsp--send-execute-command + "hare:liftonelevel" + (vector `(:file ,(concat "file://" buffer-file-name) + :pos ,(lsp-point-to-position (point)))))) + +(defun lsp-lift-to-top () + "Lift a function to the top level" + (interactive) + (lsp--cur-workspace-check) + (lsp--send-execute-command + "hare:lifttotoplevel" + (vector `(:file ,(concat "file://" buffer-file-name) + :pos ,(lsp-point-to-position (point)))))) + +(defun lsp-delete-definition () + "Delete a definition" + (interactive) + (lsp--cur-workspace-check) + (lsp--send-execute-command + "hare:deletedef" + (vector `(:file ,(concat "file://" buffer-file-name) + :pos ,(lsp-point-to-position (point)))))) + +(defun lsp-generalise-applicative () + "Generalise a monadic function to use applicative" + (interactive) + (lsp--cur-workspace-check) + (lsp--send-execute-command + "hare:genapplicative" + (vector `(:file ,(concat "file://" buffer-file-name) + :pos ,(lsp-point-to-position (point)))))) + +;; --------------------------------------------------------------------- + +(defun lsp-haskell--session-cabal-dir () + "Get the session cabal-dir." + (let* ((cabal-file (haskell-cabal-find-file)) + (cabal-dir (if cabal-file + (file-name-directory cabal-file) + "." ;; no cabal file, use directory only + ))) + (progn + (message "cabal-dir: %s" cabal-dir) + cabal-dir))) + +(defun lsp-haskell--get-root () + "Get project root directory. + +First searches for root via projectile. Tries to find cabal file +if projectile way fails" + ;; (if (and (fboundp 'projectile-project-root) (projectile-project-root)) + (if nil + (projectile-project-root) + (let ((dir (lsp-haskell--session-cabal-dir))) + (if (string= dir "/") + (user-error (concat "Couldn't find cabal file, using:" dir)) + dir)))) + +;; --------------------------------------------------------------------- + +(defun lsp--haskell-hie-command () + "Comamnd and arguments for launching the inferior hie process. +These are assembled from the customizable variables + `lsp-haskell-process-path-hie' and + `lsp-haskell-process-args-hie'. If the hie executable is + installed via its Makefile, there will be compiler-specific + versions with names like 'hie-8.0.2' or 'hie-8.2.2'." + (append (list lsp-haskell-process-path-hie "--lsp") lsp-haskell-process-args-hie) ) + +;; --------------------------------------------------------------------- +;; Supporting the new lsp.el operation, as per +;; https://github.com/emacs-lsp/lsp-mode/blob/master/README-NEXT.md + +(eval-after-load 'lsp '(lsp-register-client + (make-lsp--client + :new-connection (lsp-stdio-connection (lambda () (lsp-haskell--hie-command))) + :major-modes '(haskell-mode) + :server-id 'hie + ;; :multi-root t + :initialization-options 'lsp-haskell--make-init-options))) + +(defun lsp-haskell--hie-command () + (funcall lsp-haskell-process-wrapper-function (lsp--haskell-hie-command))) + +(cl-defmethod lsp-initialization-options ((_server (eql hie))) + "Initialization options for haskell." + `(:languageServerHaskell ,lsp-haskell--config-options)) + +;; --------------------------------------------------------------------- + +(defvar lsp-haskell--config-options (make-hash-table)) + +;; --------------------------------------------------------------------- + +(defun lsp-haskell--set-configuration () + (lsp--set-configuration `(:languageServerHaskell ,lsp-haskell--config-options))) + +(add-hook 'lsp-after-initialize-hook 'lsp-haskell--set-configuration) + +(defun lsp-haskell-set-config (name option) + "Set config option NAME to value OPTION in the haskell lsp server." + (puthash name option lsp-haskell--config-options)) + + ;; parseJSON = withObject "Config" $ \v -> do + ;; s <- v .: "languageServerHaskell" + ;; flip (withObject "Config.settings") s $ \o -> Config + ;; <$> o .:? "hlintOn" .!= True + ;; <*> o .:? "maxNumberOfProblems" .!= 100 + ;; <*> o .:? "liquidOn" .!= False + ;; <*> o .:? "completionSnippetsOn" .!= True + +;; ------------------------------------- + +(defun lsp-haskell-set-hlint (val) + "Enable(t)/Disable(nil) running hlint." + (lsp-haskell-set-config "hlintOn" val)) + +(defun lsp-haskell-set-hlint-on () + "Enable running hlint haskell." + (interactive) + (lsp-haskell-set-hlint t) + (lsp-haskell--set-configuration)) + +(defun lsp-haskell-set-hlint-off () + "Disable running hlint." + (interactive) + (lsp-haskell-set-hlint :json-false) + (lsp-haskell--set-configuration)) + +;; ------------------------------------- + +(defun lsp-haskell-set-max-problems (val) + "Set maximum number of problems reported to VAL." + (lsp-haskell-set-config "maxNumberOfProblems" val)) + +(defun lsp-haskell-set-max-number-of-problems (val) + "Set maximum number of problems reported to VAL." + (interactive "nMax number of problems to report: ") + (lsp-haskell-set-max-problems val) + (lsp-haskell--set-configuration)) + +;; ------------------------------------- + +(defun lsp-haskell-set-liquid (val) + "Enable(t)/Disable(nil) running liquid haskell on save." + (lsp-haskell-set-config "liquidOn" val)) + +(defun lsp-haskell-set-liquid-on () + "Enable running liquid haskell on save." + (interactive) + (lsp-haskell-set-liquid t) + (lsp-haskell--set-configuration)) + +(defun lsp-haskell-set-liquid-off () + "Disable running liquid haskell on save." + (interactive) + (lsp-haskell-set-liquid :json-false) + (lsp-haskell--set-configuration)) + +;; ------------------------------------- + +(defun lsp-haskell-set-completion-snippets (val) + "Enable(t)/Disable(nil) providing completion snippets." + (lsp-haskell-set-config "completionSnippetsOn" val)) + +(defun lsp-haskell-set-completion-snippets-on () + "Enable providing completion snippets." + (interactive) + (lsp-haskell-set-completion-snippets t) + (lsp-haskell--set-configuration)) + +(defun lsp-haskell-set-completion-snippets-off () + "Disable providing completion snippets." + (interactive) + (lsp-haskell-set-completion-snippets :json-false) + (lsp-haskell--set-configuration)) + + +;; --------------------------------------------------------------------- + +(provide 'lsp-haskell) +;;; lsp-haskell.el ends here diff --git a/packages/lsp-java-20181102.1943.tar b/packages/lsp-java-20181102.1943.tar deleted file mode 100644 index 17c9bd0..0000000 Binary files a/packages/lsp-java-20181102.1943.tar and /dev/null differ diff --git a/packages/lsp-java-20190817.1436.tar b/packages/lsp-java-20190817.1436.tar new file mode 100644 index 0000000..38fb298 Binary files /dev/null and b/packages/lsp-java-20190817.1436.tar differ diff --git a/packages/lsp-javascript-typescript-20180614.2011.el b/packages/lsp-javascript-typescript-20180614.2011.el deleted file mode 100644 index 99e07f3..0000000 --- a/packages/lsp-javascript-typescript-20180614.2011.el +++ /dev/null @@ -1,86 +0,0 @@ -;;; lsp-javascript-typescript.el --- Javascript/Typescript support for lsp-mode -*- lexical-binding: t; -*- - -;; Copyright (C) 2017 George Pittarelli - -;; Author: George Pittarelli -;; Version: 1.0 -;; Package-Version: 20180614.2011 -;; Package-Requires: ((lsp-mode "3.0") (typescript-mode "0.1") (emacs "25.1")) -;; Keywords: languages tools -;; URL: https://github.com/emacs-lsp/lsp-javascript - -;; 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 . - -;;; Commentary: - -;; Javascript and Typescript support for lsp-mode using Sourcegraph's -;; javascript-typescript-langserver server. - -;;; Code: - -(require 'lsp-mode) -(require 'typescript-mode) - -;;;###autoload -(defcustom lsp-javascript-typescript-server - "javascript-typescript-stdio" - "The javascript-typescript-stdio executable to use. -Leave as just the executable name to use the default behavior of -finding the executable with `exec-path'." - :group 'lsp-javascript-typescript - :risky t - :type 'file) - -;;;###autoload -(defcustom lsp-javascript-typescript-server-args - '() - "Extra arguments for the javascript-typescript-stdio language server" - :group 'lsp-javascript-typescript - :risky t - :type '(repeat string)) - -(defconst lsp-javascript-typescript--get-root - (lsp-make-traverser #'(lambda (dir) - (directory-files dir nil "package.json")))) - -(defun lsp-javascript-typescript--ls-command () - "Generate the language server startup command." - `(,lsp-javascript-typescript-server - ,@lsp-javascript-typescript-server-args)) - -(defun lsp-javascript-typescript--render-string (str) - (condition-case nil - (with-temp-buffer - (delay-mode-hooks (typescript-mode)) - (insert str) - (font-lock-ensure) - (buffer-string)) - (error str))) - -(defun lsp-javascript-typescript--initialize-client (client) - (lsp-provide-marked-string-renderer - client "typescript" 'lsp-javascript-typescript--render-string) - (lsp-provide-marked-string-renderer - client "javascript" 'lsp-javascript-typescript--render-string)) - -(lsp-define-stdio-client - lsp-javascript-typescript "javascript" - lsp-javascript-typescript--get-root - nil - :ignore-messages '("readFile .*? requested by TypeScript but content not available") - :initialize 'lsp-javascript-typescript--initialize-client - :command-fn 'lsp-javascript-typescript--ls-command) - -(provide 'lsp-javascript-typescript) -;;; lsp-javascript-typescript.el ends here diff --git a/packages/lsp-mode-20181115.308.tar b/packages/lsp-mode-20181115.308.tar deleted file mode 100644 index f63cc1a..0000000 Binary files a/packages/lsp-mode-20181115.308.tar and /dev/null differ diff --git a/packages/lsp-mode-20190821.848.tar b/packages/lsp-mode-20190821.848.tar new file mode 100644 index 0000000..6c406e1 Binary files /dev/null and b/packages/lsp-mode-20190821.848.tar differ diff --git a/packages/lsp-python-20181108.754.el b/packages/lsp-python-20181108.754.el deleted file mode 100644 index f58677f..0000000 --- a/packages/lsp-python-20181108.754.el +++ /dev/null @@ -1,42 +0,0 @@ -;;; lsp-python.el --- Python support for lsp-mode -*- lexical-binding: t -*- - -;; Copyright (C) 2017 Vibhav Pant - -;; Author: Vibhav Pant -;; Version: 1.0 -;; Package-Version: 20181108.754 -;; Package-Requires: ((lsp-mode "3.0")) -;; Keywords: python -;; URL: https://github.com/emacs-lsp/lsp-python - -;;; Code: -(require 'lsp-mode) -(require 'lsp-common) - -(defcustom lsp-python-server-args - '() - "Extra arguments for the python-stdio language server" - :group 'lsp-python - :risky t - :type '(repeat string)) - -(defcustom lsp-python-use-init-for-project-root - nil - "Set to t to look for __init__.py files to determine a project's root. - -The first directory not containing an __init__.py file (looking -upwards from the directory the open python file is in) is set as -the project root for the lsp server. -" - :group 'lsp-python - :type 'boolean) - -(defun lsp-python--ls-command () - "Generate the language server startup command." - `("pyls" ,@lsp-python-server-args)) - -(lsp-define-stdio-client lsp-python "python" nil nil - :command-fn 'lsp-python--ls-command) - -(provide 'lsp-python) -;;; lsp-python.el ends here diff --git a/packages/lsp-python-ms-20190809.640.el b/packages/lsp-python-ms-20190809.640.el new file mode 100644 index 0000000..3488f1c --- /dev/null +++ b/packages/lsp-python-ms-20190809.640.el @@ -0,0 +1,310 @@ +;;; lsp-python-ms.el --- lsp-mode client for Microsoft python-language-server -*- lexical-binding: t -*- + +;; Author: Charl Botha +;; Maintainer: Andrew Christianson +;; Version: 0.2.0 +;; Package-Version: 20190809.640 +;; Package-Requires: ((cl-lib "0.6.1") (lsp-mode "6.0") (python "0.26.1") (json "1.4") (emacs "24.4")) +;; Homepage: https://github.com/andrew-christianson/lsp-python-ms +;; Keywords: languages tools + + +;; This file is not 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 . + + +;;; Commentary: + +;; from https://vxlabs.com/2018/11/19/configuring-emacs-lsp-mode-and-microsofts-visual-studio-code-python-language-server/ + +;;; Code: +(require 'cl-lib) +(require 'lsp-mode) +(require 'python) +(require 'json) +(require 'projectile nil 'noerror) +(require 'find-file-in-project nil 'noerror) + +;; forward declare variable +(defvar lsp-render-markdown-markup-content) + +(defvar lsp-python-ms-dir (expand-file-name "mspyls/" user-emacs-directory) + "Path to language server directory. + +This is the directory containing Microsoft.Python.LanguageServer.dll.") + +;; not used since ms-pyls 0.2.92+ +;; see https://github.com/microsoft/vscode-python/blob/master/src/client/activation/languageServer/analysisOptions.ts#L93 +;; (defvar lsp-python-ms-cache-dir +;; (directory-file-name (locate-user-emacs-file ".lsp-python/")) +;; "Path to directory where the server will write cache files. + +;; If this is nil, the language server will write cache files in a directory +;; sibling to the root of every project you visit") + +(defvar lsp-python-ms-extra-paths '() + "A list of additional paths to search for python packages. + +This should be a list of paths corresponding to additional python +library directories you want to search for completions. Paths +should be as they are (or would appear) in sys.path. Paths will +be prepended to the search path, and so will shadow duplicate +names in search paths returned by the interpreter.") + +(defvar lsp-python-executable-cmd "python" + "Command to specify the python command for ms-pyls. + +Similar to the `python-shell-interpreter', but used only with `ms-pyls'. +Useful when there are multiple python versions in system. +e.g, there are `python2' and `python3', both in system PATH, +and the default `python' links to python2, +set as `python3' to let ms-pyls use python 3 environments.") + +(defvar lsp-python-ms-executable (concat lsp-python-ms-dir + "Microsoft.Python.LanguageServer" + (and (eq system-type 'windows-nt) ".exe")) + "Path to Microsoft.Python.LanguageServer.exe.") + +(defvar lsp-python-ms-nupkg-channel "stable" + "The channel of nupkg for Microsoft Python Language Server: +stable, beta or daily.") + +(defun lsp-python-ms-latest-nupkg-url (&optional channel) + "Get the nupkg url of the latest Microsoft Python Language Server." + (let ((channel (or channel "stable"))) + (unless (member channel '("stable" "beta" "daily")) + (error (format "Unknown channel: %s" channel))) + (with-current-buffer + (url-retrieve-synchronously + (format "https://pvsc.blob.core.windows.net/python-language-server-%s\ +?restype=container&comp=list&prefix=Python-Language-Server-%s-x64" + channel + (cond ((eq system-type 'darwin) "osx") + ((eq system-type 'gnu/linux) "linux") + ((eq system-type 'windows-nt) "win") + (t (error (format "Unsupported system: %s" system-type)))))) + (goto-char (point-min)) + (re-search-forward "\n\n") + (pcase (xml-parse-region (point) (point-max)) + (`((EnumerationResults + ((ContainerName . ,_)) + (Prefix nil ,_) + (Blobs nil . ,blobs) + (NextMarker nil))) + (cdar + (sort + (mapcar (lambda (blob) + (pcase blob + (`(Blob + nil + (Name nil ,_) + (Url nil ,url) + (Properties nil (Last-Modified nil ,last-modified) . ,_)) + (cons (apply #'encode-time (parse-time-string last-modified)) url)))) + blobs) + (lambda (t1 t2) + (time-less-p (car t2) (car t1)))))))))) + +(defun lsp-python-ms-setup (&optional forced) + "Downloading Microsoft Python Language Server to path specified. +With prefix, FORCED to redownload the server." + (interactive "P") + (unless (and (not forced) + (executable-find lsp-python-ms-executable)) + (let ((temp-file (make-temp-file "mspyls" nil ".zip")) + (unzip-script (cond ((executable-find "powershell") + "powershell -noprofile -noninteractive \ +-nologo -ex bypass Expand-Archive -path '%s' -dest '%s'") + ((executable-find "unzip") + "bash -c 'mkdir -p %2$s && unzip -qq %1$s -d %2$s'") + (t (error "Unable to unzip! You may need to install the `unzip` executable."))))) + (message "Downloading Microsoft Python Language Server...") + + (url-copy-file (lsp-python-ms-latest-nupkg-url lsp-python-ms-nupkg-channel) + temp-file 'overwrite) + (when (file-exists-p lsp-python-ms-dir) + (delete-directory lsp-python-ms-dir 'recursive)) + (shell-command (format unzip-script temp-file lsp-python-ms-dir)) + (when (file-exists-p lsp-python-ms-executable) + (chmod lsp-python-ms-executable #o755)) + + (message "Downloaded Microsoft Python Language Server!")))) + +(defun lsp-python-ms-update-server () + "Update Microsoft Python Language Server. + +On Windows, if the server is running, the updating will fail. +After stopping or killing the process, retry to update." + (interactive) + (message "Server update started...") + (lsp-python-ms-setup t) + (message "Server update finished...")) + +;; it's crucial that we send the correct Python version to MS PYLS, +;; else it returns no docs in many cases furthermore, we send the +;; current Python's (can be virtualenv) sys.path as searchPaths +(defun lsp-python-ms--get-python-ver-and-syspath (workspace-root) + "Return list with pyver-string and list of python search paths. + +The WORKSPACE-ROOT will be prepended to the list of python search +paths and then the entire list will be json-encoded." + (let ((python (executable-find lsp-python-executable-cmd)) + (init "from __future__ import print_function; import sys; import json;") + (ver "print(\"%s.%s\" % (sys.version_info[0], sys.version_info[1]));") + (sp (concat "sys.path.insert(0, '" workspace-root "'); print(json.dumps(sys.path))"))) + (with-temp-buffer + (call-process python nil t nil "-c" (concat init ver sp)) + (cl-subseq (split-string (buffer-string) "\n") 0 2)))) + +(defun lsp-python-ms--workspace-root () + "Get the path of the root of the current workspace. + +Use `lsp-workspace-root', which is pressent in the \"new\" +lsp-mode and works when there's an active session. Next try ffip +or projectile, or just return `default-directory'." + (cond + ((and (fboundp #'lsp-workspace-root) (lsp-workspace-root))) + ((fboundp #'ffip-get-project-root-directory) (ffip-get-project-root-directory)) + ((fboundp #'projectile-project-root) (projectile-project-root)) + (t default-directory))) + +;; I based most of this on the vs.code implementation: +;; https://github.com/Microsoft/vscode-python/blob/master/src/client/activation/languageServer/languageServer.ts#L219 +;; (it still took quite a while to get right, but here we are!) +(defun lsp-python-ms--extra-init-params (&optional workspace) + "Return form describing parameters for language server. + +Old lsp will pass in a WORKSPACE, new lsp has a global +lsp-workspace-root function that finds the current buffer's +workspace root. If nothing works, default to the current file's +directory" + (let ((workspace-root (if workspace (lsp--workspace-root workspace) (lsp-python-ms--workspace-root)))) + (cl-destructuring-bind (pyver _pysyspath) + (lsp-python-ms--get-python-ver-and-syspath workspace-root) + `(:interpreter + (:properties (:InterpreterPath + ,(executable-find lsp-python-executable-cmd) + ;; this database dir will be created if required + ;; :DatabasePath ,(expand-file-name (directory-file-name lsp-python-ms-cache-dir)) + :Version ,pyver)) + ;; preferredFormat "markdown" or "plaintext" + ;; experiment to find what works best -- over here mostly plaintext + :displayOptions ( + :preferredFormat "markdown" + :trimDocumentationLines :json-false + :maxDocumentationLineLength 0 + :trimDocumentationText :json-false + :maxDocumentationTextLength 0) + :searchPaths ,(if lsp-python-ms-extra-paths + (vconcat lsp-python-ms-extra-paths nil) + []) + :analysisUpdates t + :asyncStartup t + :typeStubSearchPaths ,(vector (concat lsp-python-ms-dir "Typeshed")))))) + +(defun lsp-python-ms--filter-nbsp (str) + "Filter nbsp entities from STR." + (let ((rx " ")) + (when (eq system-type 'windows-nt) + (setq rx (concat rx "\\|\r"))) + (when str + (replace-regexp-in-string rx " " str)))) + +(defun lsp-python-ms--language-server-started-callback (workspace _params) + "Handle the python/languageServerStarted message. + +WORKSPACE is just used for logging and _PARAMS is unused." +  (lsp-workspace-status "::Started" workspace) +  (message "Python language server started")) + +(defun lsp-python-ms--client-initialized (client) +  "Callback to register and configure client after it's initialized. + +After CLIENT is initialized, this function is called to configure +other handlers. " +  (lsp-client-on-notification client "python/languageServerStarted" + #'lsp-python-ms--language-server-started-callback) + (lsp-client-on-notification client "telemetry/event" #'ignore)) + +;; this gets called when we do lsp-describe-thing-at-point +;; see lsp-methods.el. As always, remove Microsoft's unwanted entities :( +(setq lsp-render-markdown-markup-content #'lsp-python-ms--filter-nbsp) + +;; lsp-ui-doc--extract gets called when hover docs are requested +;; as always, we have to remove Microsoft's unnecessary   entities +(advice-add 'lsp-ui-doc--extract + :filter-return #'lsp-python-ms--filter-nbsp) + +;; lsp-ui-sideline--format-info gets called when lsp-ui wants to show +;; hover info in the sideline again   has to be removed +(advice-add 'lsp-ui-sideline--format-info + :filter-return #'lsp-python-ms--filter-nbsp) + +(defun lsp-python-ms--command-string () + "Return the command to start the server." + ;; Try to download server if it doesn't exists + (unless (executable-find lsp-python-ms-executable) + (lsp-python-ms-setup)) + + (if (executable-find lsp-python-ms-executable) + lsp-python-ms-executable + (error (concat "Cannot find Microsoft Python Language Server executable! It's expected to be " + lsp-python-ms-executable)))) + +(defgroup lsp-mspyls nil + "LSP support for Python, using Microsoft Python Language Server." + :group 'lsp-mode + :link '(url-link "https://github.com/emacs-lsp/lsp-python-ms")) + +;; See https://github.com/microsoft/python-language-server for more diagnostics +(defcustom lsp-mspyls-errors ["unknown-parameter-name" + "undefined-variable" + "parameter-missing" + "positional-argument-after-keyword" + "too-many-function-arguments"] + "Microsoft Python LSP Error types." + :group 'lsp-mspyls + :type 'vector) + +(defcustom lsp-mspyls-warnings ["unresolved-import" + "parameter-already-specified" + "too-many-positional-arguments-before-star"] + "Microsoft Python LSP Warning types." + :group 'lsp-mspyls + :type 'vector) + +(lsp-register-custom-settings '(("python.analysis.errors" lsp-mspyls-errors))) +(lsp-register-custom-settings '(("python.analysis.warnings" lsp-mspyls-warnings))) + +(lsp-register-client + (make-lsp-client + :new-connection (lsp-stdio-connection 'lsp-python-ms--command-string) + :major-modes '(python-mode) + :server-id 'mspyls + :priority 1 + :initialization-options 'lsp-python-ms--extra-init-params + :notification-handlers (lsp-ht ("python/languageServerStarted" 'lsp-python-ms--language-server-started-callback) + ("telemetry/event" 'ignore) + ;; TODO handle this more gracefully + ("python/reportProgress" 'ignore) + ("python/beginProgress" 'ignore) + ("python/endProgress" 'ignore)) + :initialized-fn (lambda (workspace) + (with-lsp-workspace workspace + (lsp--set-configuration (lsp-configuration-section "python")))))) + +(provide 'lsp-python-ms) + +;;; lsp-python-ms.el ends here diff --git a/packages/lsp-rust-20180305.1308.el b/packages/lsp-rust-20180305.1308.el deleted file mode 100644 index e2bd040..0000000 --- a/packages/lsp-rust-20180305.1308.el +++ /dev/null @@ -1,202 +0,0 @@ -;;; lsp-rust.el --- Rust support for lsp-mode -*- lexical-binding: t; -*- - -;; Copyright (C) 2017 Vibhav Pant - -;; Author: Vibhav Pant -;; Version: 1.0 -;; Package-Version: 20180305.1308 -;; Package-Requires: ((emacs "25") (lsp-mode "3.0") (rust-mode "0.3.0") (dash "1.0") (markdown-mode "2.3")) -;; Keywords: rust -;; URL: https://github.com/emacs-lsp/lsp-rust - -;;; Commentary: - -;; lsp-mode client for the Rust Language Server (RLS). -;; See https://github.com/rust-lang-nursery/rls -;; -;; # Setup -;; -;; You can load lsp-rust after lsp-mode by adding the following to your init -;; file: -;; -;; (with-eval-after-load 'lsp-mode -;; (require 'lsp-rust) -;; (add-hook 'rust-mode-hook #'lsp-rust-enable)) -;; -;; You may want to customize the command that lsp-rust uses to launch the RLS. -;; See `lsp-rust-rust-command'. - -;;; Code: - -(require 'lsp-mode) -(require 'cl-lib) -(require 'json) -(require 'font-lock) -(require 'xref) -(require 'dash) -(require 'markdown-mode) - -(defvar lsp-rust--config-options (make-hash-table)) -(defvar lsp-rust--diag-counters (make-hash-table)) -(defvar lsp-rust--running-progress (make-hash-table)) - -(defcustom lsp-rust-rls-command '("rls") - "The command used to launch the RLS. - -This should be a list of strings, the first string being the -executable, and the remaining strings being the arguments to this -executable. - -If this variable is nil, lsp-rust will try to use the RLS located -at the environment variable RLS_ROOT, if set." - :type '(repeat (string))) - -(defun lsp-rust-explain-error-at-point () - "Explain the error at point. -The explaination comes from 'rustc --explain=ID'." - (interactive) - (unless (memq (bound-and-true-p flycheck-checker) '(lsp-ui lsp)) - (user-error "You need to enable lsp-ui-flycheck")) - (-if-let* ((current-window (selected-window)) - (id (-> (car (flycheck-overlay-errors-at (point))) - (flycheck-error-id)))) - (pop-to-buffer - (with-current-buffer (get-buffer-create "*rustc error*") - (let ((buffer-read-only nil)) - (erase-buffer) - (insert (shell-command-to-string (concat "rustc --explain=" id)))) - (if (fboundp 'markdown-view-mode) - (markdown-view-mode) - (markdown-mode)) - (setq-local markdown-fontify-code-blocks-natively t) - (setq-local markdown-fontify-code-block-default-mode 'rust-mode) - (setq-local kill-buffer-hook (lambda nil - (quit-restore-window) - (when (window-live-p current-window) - (select-window current-window)))) - (setq header-line-format - (concat (propertize " rustc" 'face 'error) - (propertize " " 'display - `(space :align-to (- right-fringe ,(1+ (length id))))) - (propertize id 'face 'error))) - (markdown-toggle-markup-hiding 1) - (font-lock-ensure) - (goto-char 1) - (current-buffer))) - (message "explain-error: No error at point"))) - -(defun lsp-rust-find-implementations () - "List all implementation blocks for a trait, struct, or enum at point." - (interactive) - (let* ((impls (lsp--send-request (lsp--make-request - "rustDocument/implementations" - (lsp--text-document-position-params)))) - (items (lsp--locations-to-xref-items impls))) - (if items - (xref--show-xrefs items nil) - (message "No implementation found for: %s" (thing-at-point 'symbol t))))) - -(defun lsp-rust--rls-command () - "Return the command used to start the RLS for defining the LSP Rust client." - (or lsp-rust-rls-command - (-when-let (rls-root (getenv "RLS_ROOT")) - `("cargo" "+nightly" "run" "--quiet" - ,(concat "--manifest-path=" - (concat - (file-name-as-directory (expand-file-name rls-root)) - "Cargo.toml")) - "--release")))) - -(defun lsp-rust--get-root () - (let (dir) - (unless - (ignore-errors - (let* ((output (shell-command-to-string "cargo locate-project")) - (js (json-read-from-string output))) - (setq dir (cdr (assq 'root js))))) - (error "Couldn't find root for project at %s" default-directory)) - (file-name-directory dir))) - -(define-inline lsp-rust--as-percent (fraction) - (inline-quote (format "%d%%" (round (* ,fraction 100))))) - -(defconst lsp-rust--handlers - '(("window/progress" . - (lambda (workspace progress) - (let ((id (gethash "id" progress)) - (message (gethash "message" progress)) - (percentage (gethash "percentage" progress)) - (title (gethash "title" progress)) - (workspace-progress (gethash workspace lsp-rust--running-progress))) - (if (gethash "done" progress) - (setq workspace-progress (delete id workspace-progress)) - (delete-dups workspace-progress) - (push id workspace-progress)) - (puthash workspace workspace-progress lsp-rust--running-progress) - (setq lsp-status - (if workspace-progress - (cond - ((numberp percentage) (lsp-rust--as-percent percentage)) - (message (format "(%s)" message)) - (title (format "(%s)" (downcase title)))) - nil))))) - ;; From rls-vscode: - ;; FIXME these are legacy notifications used by RLS ca jan 2018. - ;; remove once we're certain we've progress on. - ("rustDocument/diagnosticsBegin" . (lambda (_w _p))) - ("rustDocument/diagnosticsEnd" . - (lambda (w _p) - (when (<= (cl-decf (gethash w lsp-rust--diag-counters 0)) 0) - (setq lsp-status nil)))) - ("rustDocument/beginBuild" . - (lambda (w _p) - (cl-incf (gethash w lsp-rust--diag-counters 0)) - (setq lsp-status "(building)"))))) - -(defun lsp-rust--render-string (str) - (condition-case nil - (with-temp-buffer - (delay-mode-hooks (rust-mode)) - (insert str) - (font-lock-ensure) - (buffer-string)) - (error str))) - -(defun lsp-rust--initialize-client (client) - (mapcar #'(lambda (p) (lsp-client-on-notification client (car p) (cdr p))) - lsp-rust--handlers) - (lsp-provide-marked-string-renderer client "rust" #'lsp-rust--render-string)) - -(lsp-define-stdio-client lsp-rust "rust" #'lsp-rust--get-root nil - :command-fn #'lsp-rust--rls-command - :initialize #'lsp-rust--initialize-client) - -(defun lsp-rust--set-configuration () - (lsp--set-configuration `(:rust ,lsp-rust--config-options))) - -(add-hook 'lsp-after-initialize-hook 'lsp-rust--set-configuration) - -(defun lsp-rust-set-config (name option) - "Set a config option in the rust lsp server." - (puthash name option lsp-rust--config-options)) - -(defun lsp-rust-set-build-lib (build) - "Enable(t)/Disable(nil) building the lib target." - (lsp-rust-set-config "build_lib" build)) - -(defun lsp-rust-set-build-bin (build) - "The bin target to build." - (lsp-rust-set-config "build_bin" build)) - -(defun lsp-rust-set-cfg-test (val) - "Enable(t)/Disable(nil) #[cfg(test)]." - (lsp-rust-set-config "cfg_test" val)) - -(defun lsp-rust-set-goto-def-racer-fallback (val) - "Enable(t)/Disable(nil) goto-definition should use racer as fallback." - (lsp-rust-set-config "goto_def_racer_fallback" val)) - -(provide 'lsp-rust) -;;; lsp-rust ends here - -;;; lsp-rust.el ends here diff --git a/packages/lsp-treemacs-20190817.1904.tar b/packages/lsp-treemacs-20190817.1904.tar new file mode 100644 index 0000000..f8d4694 Binary files /dev/null and b/packages/lsp-treemacs-20190817.1904.tar differ diff --git a/packages/lsp-ui-20181031.2002.tar b/packages/lsp-ui-20190809.1907.tar similarity index 78% rename from packages/lsp-ui-20181031.2002.tar rename to packages/lsp-ui-20190809.1907.tar index 1bbd127..a41ee7f 100644 Binary files a/packages/lsp-ui-20181031.2002.tar and b/packages/lsp-ui-20190809.1907.tar differ diff --git a/packages/lua-mode-20180323.1021.tar b/packages/lua-mode-20190113.1050.tar similarity index 98% rename from packages/lua-mode-20180323.1021.tar rename to packages/lua-mode-20190113.1050.tar index 8126ba9..416c0a8 100644 Binary files a/packages/lua-mode-20180323.1021.tar and b/packages/lua-mode-20190113.1050.tar differ diff --git a/packages/lv-20190821.947.el b/packages/lv-20190821.947.el new file mode 100644 index 0000000..14a6b51 --- /dev/null +++ b/packages/lv-20190821.947.el @@ -0,0 +1,124 @@ +;;; lv.el --- Other echo area +;; Package-Version: 20190821.947 + +;; Copyright (C) 2015 Free Software Foundation, Inc. + +;; Author: Oleh Krehel + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: +;; +;; This package provides `lv-message' intended to be used in place of +;; `message' when semi-permanent hints are needed, in order to not +;; interfere with Echo Area. +;; +;; "Я тихо-тихо пiдглÑдаю, +;; І Ñ‚iшуÑÑ Ñобi, Ñк бачу то, +;; Шо Ñтрашить i не пiдпуÑкає, +;; Ð iншi п’ють тебе, Ñк воду пiÑок." +;; -- Ðндрій Кузьменко, L.V. + +;;; Code: + +(defgroup lv nil + "The other echo area." + :group 'minibuffer + :group 'hydra) + +(defcustom lv-use-separator nil + "Whether to draw a line between the LV window and the Echo Area." + :group 'lv + :type 'boolean) + +(defface lv-separator + '((((class color) (background light)) :background "grey80") + (((class color) (background dark)) :background "grey30")) + "Face used to draw line between the lv window and the echo area. +This is only used if option `lv-use-separator' is non-nil. +Only the background color is significant." + :group 'lv) + +(defvar lv-wnd nil + "Holds the current LV window.") + +(defvar display-line-numbers) +(defvar display-fill-column-indicator) + +(defun lv-window () + "Ensure that LV window is live and return it." + (if (window-live-p lv-wnd) + lv-wnd + (let ((ori (selected-window)) + buf) + (prog1 (setq lv-wnd + (select-window + (let ((ignore-window-parameters t)) + (split-window + (frame-root-window) -1 'below)))) + (if (setq buf (get-buffer " *LV*")) + (switch-to-buffer buf) + (switch-to-buffer " *LV*") + (set-window-hscroll lv-wnd 0) + (setq window-size-fixed t) + (setq mode-line-format nil) + (setq header-line-format nil) + (setq cursor-type nil) + (setq display-line-numbers nil) + (setq display-fill-column-indicator nil) + (set-window-dedicated-p lv-wnd t) + (set-window-parameter lv-wnd 'no-other-window t)) + (select-window ori))))) + +(defvar golden-ratio-mode) + +(defvar lv-force-update nil + "When non-nil, `lv-message' will refresh even for the same string.") + +(defun lv-message (format-string &rest args) + "Set LV window contents to (`format' FORMAT-STRING ARGS)." + (let* ((str (apply #'format format-string args)) + (n-lines (cl-count ?\n str)) + deactivate-mark + golden-ratio-mode) + (with-selected-window (lv-window) + (unless (and (string= (buffer-string) str) + (null lv-force-update)) + (delete-region (point-min) (point-max)) + (insert str) + (when (and (window-system) lv-use-separator) + (unless (looking-back "\n" nil) + (insert "\n")) + (insert + (propertize "__" 'face 'lv-separator 'display '(space :height (1))) + (propertize "\n" 'face 'lv-separator 'line-height t))) + (set (make-local-variable 'window-min-height) n-lines) + (setq truncate-lines (> n-lines 1)) + (let ((window-resize-pixelwise t) + (window-size-fixed nil)) + (fit-window-to-buffer nil nil 1))) + (goto-char (point-min))))) + +(defun lv-delete-window () + "Delete LV window and kill its buffer." + (when (window-live-p lv-wnd) + (let ((buf (window-buffer lv-wnd))) + (delete-window lv-wnd) + (kill-buffer buf)))) + +(provide 'lv) + +;;; lv.el ends here diff --git a/packages/macrostep-20161120.2106.tar b/packages/macrostep-20161120.2106.tar index dcf431e..e2ce2ed 100644 Binary files a/packages/macrostep-20161120.2106.tar and b/packages/macrostep-20161120.2106.tar differ diff --git a/packages/magit-20181116.1412.tar b/packages/magit-20190819.1414.tar similarity index 76% rename from packages/magit-20181116.1412.tar rename to packages/magit-20190819.1414.tar index 3ed4528..9130384 100644 Binary files a/packages/magit-20181116.1412.tar and b/packages/magit-20190819.1414.tar differ diff --git a/packages/magit-gh-pulls-20180716.1636.el b/packages/magit-gh-pulls-20180716.1636.el deleted file mode 100644 index a073644..0000000 --- a/packages/magit-gh-pulls-20180716.1636.el +++ /dev/null @@ -1,629 +0,0 @@ -;;; magit-gh-pulls.el --- GitHub pull requests extension for Magit - -;; Copyright (C) 2011-2017 Yann Hodique, Alexander Yakushev - -;; Author: Yann Hodique -;; Keywords: git tools -;; Package-Version: 20180716.1636 -;; Version: 0.5.3 -;; URL: https://github.com/sigma/magit-gh-pulls -;; Package-Requires: ((emacs "24.4") (gh "0.9.1") (magit "2.12.0") (pcache "0.2.3") (s "1.6.1")) - -;; 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 2, or (at your option) -;; any later version. - -;; This file is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; This is a Magit extension for manipulating GitHub pull requests - -;; No configuration is needed in the repository if any of your remotes contain a -;; URL to Github's remote repository. If for some reason you don't have any -;; Github remotes in your config, you can specify username and repository -;; explicitly: - -;; $ git config magit.gh-pulls-repo / # your github repository - -;; Add these lines to your init.el: - -;; (require 'magit-gh-pulls) -;; (add-hook 'magit-mode-hook 'turn-on-magit-gh-pulls) - -;; These are the bindings for pull requests, defined in magit-gh-pulls-mode-map: -;; # g --- refreshes the list of pull requests -;; # f --- fetches the commits associated with the pull request at point -;; # b --- helps you creating a topic branch from a review request -;; # m --- merges the PR on top of the current branch -;; # c --- creates a PR from the current branch -;; # o --- opens a pull request on GitHub in your default browser - -;; Then, you can do whatever you want with the commit objects associated with -;; the pull request (merge, cherry-pick, diff, ...) - -;; When you create a new pull request, you can enable -w option to automatically -;; open it on GitHub in your default browser. - -;;; Code: - -(require 'eieio) - -(require 'magit) -(require 'git-commit) -(require 'gh) -(require 'gh-pulls) -(require 'pcache) -(require 's) -(require 'cl-lib) -(require 'subr-x) - -(defgroup magit-gh-pulls nil - "Github.com pull-requests for Magit." - :group 'magit-extensions) - -(defcustom magit-gh-pulls-open-new-pr-in-browser nil - "DEPRECATED: use magit switch instead." - :group 'magit-gh-pulls - :type 'boolean) - -(defvar magit-gh-pulls-maybe-filter-pulls 'identity - "Filter function which should validate pulls you want to be - viewed in magit. It receives a list of pull requests and should - return a list of pull requests.") - -(defvar magit-gh-pulls-collapse-commits t - "Collapse commits in pull requests listing.") - -(defvar magit-gh-pulls-pull-detail-limit 10 - "Pull in additional information for each pull request in the - status buffer only if the total number of open PRs is <= - this number. Additional information includes individual - commits in each PR and highlighting based on the merge - status of the PR. Increasing this number may adversely - affect performance on repos with many PRs.") - -(defvar magit-gh-pulls-status-documentation nil - "Info string to be shown in magit status buffer when there are - no PRs to be listed. - -When nil, default string is constructed.") - -(defvar-local magit-gh-pulls-previous-winconf nil) - -(defvar magit-gh-pulls-editor-mode-map - (let ((map (make-keymap))) - (define-key map (kbd "C-c C-c") 'magit-gh-pulls-pull-editor-finish) - (define-key map (kbd "C-c C-k") 'magit-gh-pulls-pull-editor-quit) - map)) - -(define-minor-mode magit-gh-pulls-editor-mode "Magit GitHub Pulls Editor" - :lighter " PR-editor" - :keymap 'magit-gh-pulls-editor-mode-map) - -(easy-menu-define magit-gh-pulls-editor-mode-menu magit-gh-pulls-editor-mode-map - "Magit GitHub Pulls Editor Menu" - '("Magit GitHub Pulls" - ["Submit Pull Request" magit-gh-pulls-pull-editor-finish t] - ["Cancel" magit-gh-pulls-pull-editor-quit t])) - -(defun magit-gh-pulls-get-api () - (gh-pulls-api "api" :sync t :num-retries 1 :cache (gh-cache "cache"))) - -(defun magit-gh-pulls-get-repo-from-config () - "Return (user . project) pair read from magit.gh-pulls-repo -config option." - (let* ((cfg (magit-get "magit" "gh-pulls-repo"))) - (when cfg - (let* ((split (split-string cfg "/"))) - (cons (car split) (cadr split)))))) - - -;;Find all the Hostname Lines until we hit the end of config-lines or the -;;next Host line. Return '(remaining-config-lines list-of-hostnames) -(defun magit-gh-pulls-collect-hostnames (config-lines) - (let ((cur-line (car config-lines)) - (rest config-lines) - (result '())) - (while (and cur-line (not (string= (cadr cur-line) "Host"))) - (setq result (cons (cadr (cdr cur-line)) result)) - (setq rest (cdr rest)) - (setq cur-line (car rest))) - (list rest result))) - - -(defun magit-gh-pulls-get-host-hostnames (config-lines) - (let (result-alist - (curline (car config-lines)) - (rest-lines (cdr config-lines))) - (while rest-lines - (if (string= (cadr curline) "Host") - (let ((hosts (s-split "\\s*" (cadr (cdr curline)))) ;;List of the host aliases - (rest-result (magit-gh-pulls-collect-hostnames rest-lines))) - (dolist (host hosts) - ;;Host must be lowercase because the url parser lowercases the string - (setq result-alist (cons (cons (downcase host) (cadr rest-result)) result-alist))) - (setq curline (caar rest-result)) - (setq rest-lines (cdar rest-result))) - (progn - (setq curline (car rest-lines)) - (setq rest-lines (cdr rest-lines))))) - result-alist)) - -(defun -magit-gh-pulls-filter-and-split-host-lines (lines) - (delq nil - (mapcar (lambda (line) - (s-match "^[ \t]*\\(Host\\|HostName\\|Hostname\\)[ \t]+\\(.+\\)$" line)) - lines))) - - -;; Port of github/hub's SSHConfig -(defun magit-gh-pulls-get-ssh-config-hosts () - (let* ((file-lines (mapcar (lambda (path) - (if (file-exists-p path) - (with-temp-buffer - (insert-file-contents path) - (split-string (buffer-string) "\n" t)) - '())) - (list - (concat (file-name-as-directory (getenv "HOME")) ".ssh/config") - "/etc/ssh_config" - "/etc/ssh/ssh_config"))) - (all-lines (apply #'append file-lines)) - (matched-lines (-magit-gh-pulls-filter-and-split-host-lines all-lines))) - (magit-gh-pulls-get-host-hostnames matched-lines))) - - -;; Port of github/hub's ParseURL, with modifications to align with existing parse-url -(defun magit-gh-pulls-parse-url (url ssh-config-hosts) - (let* ((fixed-url (if (and (not (s-matches? "^[a-zA-Z_-]+://" url)) - (s-matches? ":" url) - (not (s-matches? "\\\\\\\\" url))) ;;Two literal backlashes - (concat "ssh://" (s-replace ":" "/" url)) - url)) - (parsed-url (url-generic-parse-url fixed-url)) - (ssh-host (when (string= (url-type parsed-url) "ssh") - (assoc (url-host parsed-url) ssh-config-hosts)))) - (when (and ssh-host (cadr ssh-host)) - (setf (url-host parsed-url) (cadr ssh-host))) - (when (and - (string= (url-host parsed-url) "github.com") - (s-matches? "\\(git\\|ssh\\|https?\\)" (url-type parsed-url))) - (let ((creds (s-match "/\\(.+\\)/\\([^/]+\\)/?$" (url-filename parsed-url)))) - (when creds - (cons (cadr creds) (s-chop-suffix ".git" (cadr (cdr creds))))))))) - - -(defun magit-gh-pulls-guess-repo-from-origin () - "Return (user . project) pair inferred from remotes in -.git/config." - (let ((creds nil) - (ssh-config-hosts (magit-gh-pulls-get-ssh-config-hosts))) - (dolist (remote (magit-git-lines "remote") creds) - (let ((url (magit-get "remote" remote "url"))) - (if url - (let ((parsed (magit-gh-pulls-parse-url url ssh-config-hosts))) - (when parsed - (setq creds parsed))) - (message "Warning: no URL for remote %s" remote)))))) - -(defun magit-gh-pulls-guess-repo () - "Return (user . project) pair obtained either from explicit -option, or inferred from remotes." - (or (magit-gh-pulls-get-repo-from-config) - (magit-gh-pulls-guess-repo-from-origin))) - -(defun magit-gh-pulls-requests-cached-p (api user proj) - "Returns T if the API request to the given USER and PROJ is cached." - (let ((cache-repo (format "/repos/%s/%s/pulls" user proj)) - (cached? nil)) - (pcache-map (oref api :cache) - (lambda (key _) (when (equal (car key) cache-repo) - (setq cached? t)))) - cached?)) - -(defvar magit-pull-section-map - (let ((map (make-sparse-keymap))) - (define-key map [remap magit-visit-thing] 'magit-gh-pulls-diff-pull-request) - map) - "Keymap for pull-request sections.") - -(defvar magit-unfetched-pull-section-map - (let ((map (make-sparse-keymap))) - (define-key map [remap magit-visit-thing] 'magit-gh-pulls-fetch-commits) - map) - "Keymap for unfetched pull-request sections.") - -(defun magit-gh-pulls-insert-gh-pulls () - (condition-case-unless-debug print-section - (progn - (let* ((repo (magit-gh-pulls-guess-repo))) - (when repo - (let* ((api (magit-gh-pulls-get-api)) - (user (car repo)) - (proj (cdr repo)) - (cached? (magit-gh-pulls-requests-cached-p api user proj)) - (stubs (when cached? - (funcall magit-gh-pulls-maybe-filter-pulls - (oref (gh-pulls-list api user proj) :data)))) - (num-total-stubs (length stubs)) - (i 0) - (branch (magit-get-current-branch))) - (when (or (> (length stubs) 0) (not cached?)) - (magit-insert-section (pulls) - (magit-insert-heading "Pull Requests:") - (dolist (stub stubs) - (cl-incf i) - (let* ((id (oref stub :number)) - (base-sha (oref (oref stub :base) :sha)) - (base-ref (oref (oref stub :base) :ref)) - (head-sha (oref (oref stub :head) :sha)) - ;; branch has been deleted in the meantime... - (invalid (equal (oref (oref stub :head) :ref) head-sha)) - (have-commits - (and (>= magit-gh-pulls-pull-detail-limit i) - (eql 0 (magit-git-exit-code "cat-file" "-e" base-sha)) - (eql 0 (magit-git-exit-code "cat-file" "-e" head-sha)))) - (applied (and have-commits - (magit-git-string "branch" branch - (format "--contains=%s" head-sha)))) - (heading - (format "[%s@%s] %s\n" - (propertize (number-to-string id) - 'face 'magit-tag) - (if (string= base-ref branch) - (propertize base-ref - 'face 'magit-branch-local) - base-ref) - (propertize - (oref stub :title) 'face - (cond (applied 'magit-cherry-equivalent) - (have-commits nil) - (invalid 'error) - (t 'italic))))) - (info (list user proj id))) - (cond - (have-commits - (magit-insert-section - (pull info magit-gh-pulls-collapse-commits) - (insert heading) - (magit-insert-heading) - (when (and have-commits (not applied)) - (magit-git-wash - (apply-partially 'magit-log-wash-log 'cherry) - "cherry" "-v" (magit-abbrev-arg) - base-sha head-sha)))) - (invalid - (magit-insert-section (invalid-pull info) - (insert heading))) - (t - (magit-insert-section (unfetched-pull info) - (insert heading)))))) - (when (not cached?) - (insert (if (bound-and-true-p magit-gh-pulls-status-documentation) - magit-gh-pulls-status-documentation - (format "Press `%s %s` to update the pull request list." - (substitute-command-keys "\\\\[magit-gh-pulls-popup]") - (char-to-string - (car - (seq-find - (lambda (entry) - (eq (nth 2 entry) 'magit-gh-pulls-reload)) - (plist-get magit-gh-pulls-popup :actions))))))) - (insert "\n\n")) - (when (> (length stubs) 0) - (insert "\n")))))))) - (error nil))) - -(defun magit-gh-pulls-guess-topic-name (req) - (let ((user (oref (oref req :user) :login)) - (topic (oref (oref req :head) :ref))) - (format "%s/%s" user topic))) - -(defun magit-gh-section-req-data (&optional section) - (oref (apply #'gh-pulls-get - (magit-gh-pulls-get-api) - (oref (or section (magit-current-section)) value)) - :data)) - -(defun magit-gh-pulls-diff-pull-request () - (interactive) - (magit-section-case - (pull - (let* ((req (magit-gh-section-req-data)) - (inhibit-magit-refresh t)) - (magit-diff (concat (oref (oref req :base) :sha) ".." - (oref (oref req :head) :sha)))) - (magit-refresh)) - (unfetched-pull - (error "Please fetch pull request commits first")) - (invalid-pull - (error "This pull request refers to invalid reference")))) - - -(defun magit-gh-pulls-create-branch () - (interactive) - (magit-section-case - (pull - (let* ((req (magit-gh-section-req-data)) - (branch (read-from-minibuffer - "Branch name: " (magit-gh-pulls-guess-topic-name req))) - (base (magit-read-branch-or-commit - "Branch base: " - (oref (oref req :base) :ref))) - (inhibit-magit-refresh t)) - (magit-branch-and-checkout branch base) - (magit-merge (oref (oref req :head) :sha))) - (magit-refresh)) - (unfetched-pull - (error "Please fetch pull request commits first")) - (invalid-pull - (error "This pull request refers to invalid reference")))) - -(defun magit-gh-pulls-github-merge-message (pr) - "Generate a default merge commit message, the same as Github does." - (format "Merge pull request #%d from %s/%s\n\n%s" - (oref pr :number) - (oref (oref (oref pr :head) :user) :login) - (oref (oref pr :head) :ref) - (oref pr :title))) - -(defun magit-gh-pulls-merge-pull-request () - (interactive) - (magit-section-case - (pull - (let* ((req (magit-gh-section-req-data)) - (base (oref (oref req :base) :ref)) - (inhibit-magit-refresh t)) - (magit-checkout base) - (magit-merge (oref (oref req :head) :sha) - (append (list "-m" (magit-gh-pulls-github-merge-message req)) - (when (member "--no-ff" (magit-gh-pulls-arguments)) - '("--no-ff"))))) - (magit-refresh)) - (unfetched-pull - (error "Please fetch pull request commits first")) - (invalid-pull - (error "This pull request refers to invalid reference")))) - -(defun magit-gh-pulls-fetch-commits () - (interactive) - (magit-section-case - (unfetched-pull - (let* ((req (magit-gh-section-req-data)) - (head (oref req :head))) - (magit-run-git "fetch" (oref (oref head :repo) :ssh-url) - (oref head :ref)))) - (pull nil) - (invalid-pull - (error "This pull request refers to invalid reference")))) - -(defun magit-gh-pulls-url-for-pull (info) - "Return github url for a pull request using INFO." - (let ((url "https://github.com/%s/%s/pull/%s")) - (apply 'format url info))) - -(defun magit-gh-pulls-open-in-browser () - (interactive) - (let ((info (oref (magit-current-section) value))) - (magit-section-case - (pull (browse-url (magit-gh-pulls-url-for-pull info))) - (unfetched-pull (browse-url (magit-gh-pulls-url-for-pull info)))))) - -(defun magit-gh-pulls-purge-cache () - (let* ((api (magit-gh-pulls-get-api)) - (cache (oref api :cache)) - (repo (magit-gh-pulls-guess-repo))) - (pcache-map cache (lambda (k v) - (when (string-match - (format "/repos/%s/%s/" (car repo) (cdr repo)) - (car k)) - (pcache-invalidate cache k)))))) - -;;; Pull request creation - -(defun magit-gh-pulls-ensure-branch-pushed (branch) - "Checks if the BRANCH has a remote branch (either an upstream - or a push-remote), and that their tips match. If the remote - branch is behind the local branch, poll user to push the - changes." - (let* ((remote-ref (or (magit-get-push-branch branch) - (magit-get-upstream-branch branch))) - (pushed-p (and remote-ref (magit-branch-p remote-ref) - (null (magit-git-lines "diff" (concat remote-ref ".." branch)))))) - (unless pushed-p - (if remote-ref - (when (yes-or-no-p - (format "Branch %s lags behind its remote. Push the local commits to %s?" - branch remote-ref)) - (call-interactively (if (magit-get-push-branch branch) - 'magit-push-current-to-pushremote - 'magit-push-current-to-upstream))) - (when (yes-or-no-p - (format "%s doesn't have a push-remote or upstream. Set the push-remote and push it?" - branch)) - (call-interactively 'magit-push-current-to-pushremote)))))) - -(defun magit-gh-pulls-pr-template-file () - "Returns the path to the PULL_REQUEST_TEMPLATE file in the - current repository. Returns nil if there is not a pull request - template file. A pull request template file can be placed in - the repository root directory, or in a .github/ directory." - (car (or (directory-files (magit-toplevel) t "^PULL_REQUEST_TEMPLATE") - (ignore-errors (directory-files (format "%s.github/" (magit-toplevel)) - t "^PULL_REQUEST_TEMPLATE"))))) - -(defun magit-gh-pulls-init-pull-editor (proj base head callback) - "Create a new buffer for editing this pull request and switch - to it. Save CALLBACK to be called with the submitted PR text." - (let ((winconf (current-window-configuration)) - (default-title (magit-git-string "log" (format "%s..%s" base head) - "--format=%s" "--reverse")) - (default-body (s-join "\n" (magit-git-items "log" (format "%s..%s" base head) - "--reverse" "--format=**%s**%n%b")))) - (split-window-vertically) - (other-window 1) - (switch-to-buffer (get-buffer-create (format "*magit-gh-pulls: %s*" proj))) - (funcall (if (functionp 'markdown-mode) - 'markdown-mode 'text-mode)) - (funcall 'magit-gh-pulls-editor-mode) - (insert (or default-title "") "\n\n") ; Title - (if (magit-gh-pulls-pr-template-file) ; Body - (insert-file-contents (magit-gh-pulls-pr-template-file)) - (insert default-body)) - (goto-char (point-min)) - (message "Opening pull request editor. C-c C-c to finish, C-c C-k to quit.") - (setq-local magit-gh-pulls-editor-callback callback) - (setq magit-gh-pulls-previous-winconf winconf))) - -(defun magit-gh-pulls-pull-editor-finish () - "Finish editing the current pull request and call the saved - callback. This should be called interactively from within a - pull request editor buffer." - (interactive) - (if (eq nil magit-gh-pulls-editor-callback) - (message "This function can only be run in a pull editor buffer.") - (let* ((end-of-first-line (save-excursion - (beginning-of-buffer) - (line-end-position))) - (title (s-trim (buffer-substring-no-properties 1 end-of-first-line))) - (body (s-trim (buffer-substring-no-properties end-of-first-line (point-max))))) - (funcall magit-gh-pulls-editor-callback title body) - (magit-gh-pulls-pull-editor-quit)))) - -(defun magit-gh-pulls-pull-editor-quit () - "Cleanup the current pull request editor and restore - the previous window config." - (interactive) - (if (eq nil magit-gh-pulls-editor-callback) - (message "This function can only be run in a pull editor buffer.") - (let ((winconf magit-gh-pulls-previous-winconf)) - (kill-buffer) - (kill-local-variable 'magit-gh-pulls-previous-winconf) - (when winconf - (set-window-configuration winconf))))) - -(defun magit-gh-pulls-build-req (user proj base-branch head-branch title body) - "Builds a request entity for a new pull request." - (let* ((user (make-instance 'gh-users-user :name user)) - (repo (make-instance 'gh-repos-repo :name proj)) - (base (make-instance 'gh-repos-ref :user user :repo repo :ref base-branch)) - (head (make-instance 'gh-repos-ref :user user :repo repo :ref head-branch))) - (make-instance 'gh-pulls-request :head head :base base :title title :body body))) - -(defun magit-gh-pulls-submit-pull-request (api user proj req) - "Endpoint for creating a new pull request. Actually sends the - PR creation API request to Github." - (let* ((a (gh-pulls-new api user proj req))) - (if (not (= (oref a :http-status) 201)) - (message "Error creating pull-request: %s. Have you pushed the branch to github?" (cdr (assoc "Status" (oref a :headers)))) - (let ((url (oref (oref a :data) :html-url))) - (message (concat "Created pull-request and copied URL to kill ring: " url)) - (when (member "--open-new-in-browser" (magit-gh-pulls-arguments)) - (browse-url url)) - (kill-new url))))) - -(defun magit-gh-pulls-create-pull-request () - "Entrypoint for creating a new pull request." - (interactive) - (when-let (repo (magit-gh-pulls-guess-repo)) - (lexical-let* ((user (car repo)) - (proj (cdr repo)) - (base-branch (magit-read-branch-or-commit "Base" "master")) - (head-branch (magit-read-branch-or-commit "Head" (magit-get-current-branch)))) - (magit-gh-pulls-ensure-branch-pushed head-branch) - (magit-gh-pulls-init-pull-editor - proj base-branch head-branch - (lambda (title body) - (let ((api (magit-gh-pulls-get-api)) - (req (magit-gh-pulls-build-req user proj base-branch head-branch title body))) - (magit-gh-pulls-submit-pull-request api user proj req))))))) - -(defun magit-gh-pulls-reload () - (interactive) - (let ((creds (magit-gh-pulls-guess-repo))) - (if (not (and creds (car creds) (cdr creds))) - (message "Remote repository is not configured or incorrect.") - (magit-gh-pulls-purge-cache) - (gh-pulls-list (magit-gh-pulls-get-api) (car creds) (cdr creds)) - (magit-refresh)))) - -(easy-menu-define magit-gh-pulls-extension-menu - nil - "GitHub Pull Requests extension menu" - '("GitHub Pull Requests" - :visible magit-gh-pulls-mode - ["Reload pull request" magit-gh-pulls-reload] - ["Create pull request branch" magit-gh-pulls-create-branch] - ["Fetch pull request commits" magit-gh-pulls-fetch-commits] - ["Open pull request in browser" magit-gh-pulls-open-in-browser] - )) - -(easy-menu-add-item 'magit-mode-menu - '("Extensions") - magit-gh-pulls-extension-menu) - -(magit-define-section-jumper magit-jump-to-pulls "Pull Requests" pulls) -(define-key magit-status-mode-map (kbd "jq") 'magit-jump-to-pulls) - -(defvar magit-gh-pulls-mode-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "#") 'magit-gh-pulls-popup) - map)) - -(defvar magit-gh-pulls-mode-lighter " Pulls") - -;;;###autoload -(define-minor-mode magit-gh-pulls-mode "Pull requests support for Magit" - :lighter magit-gh-pulls-mode-lighter - :require 'magit-gh-pulls - :keymap 'magit-gh-pulls-mode-map - (or (derived-mode-p 'magit-mode) - (error "This mode only makes sense with magit")) - (if magit-gh-pulls-mode - (progn - (magit-add-section-hook - 'magit-status-sections-hook - 'magit-gh-pulls-insert-gh-pulls - 'magit-insert-stashes) - (magit-define-popup-action 'magit-dispatch-popup - ?# "Github PR" 'magit-gh-pulls-popup ?!)) - (progn - (remove-hook 'magit-status-sections-hook 'magit-gh-pulls-insert-gh-pulls) - (magit-remove-popup-key 'magit-dispatch-popup :action ?#))) - (when (called-interactively-p 'any) - (magit-refresh))) - -;;;###autoload -(defun turn-on-magit-gh-pulls () - "Unconditionally turn on `magit-pulls-mode'." - (magit-gh-pulls-mode 1)) - -(magit-define-popup magit-gh-pulls-popup - "Show popup buffer featuring Github Pull Requests commands." - 'magit-commands - :switches '((?c "Produce merge commit" "--no-ff") - (?w "Open new PR in browser" "--open-new-in-browser")) - :actions '((?g "Reload" magit-gh-pulls-reload) - (?f "Fetch" magit-gh-pulls-fetch-commits) - (?d "Diff" magit-gh-pulls-diff-pull-request) - (?b "Make branch" magit-gh-pulls-create-branch) - (?m "Merge" magit-gh-pulls-merge-pull-request) - (?c "Create new PR" magit-gh-pulls-create-pull-request) - (?o "Open in browser" magit-gh-pulls-open-in-browser)) - :default-action 'magit-gh-pulls-reload) - -(provide 'magit-gh-pulls) -;; Local Variables: -;; indent-tabs-mode: nil -;; End: -;;; magit-gh-pulls.el ends here diff --git a/packages/magit-popup-20181003.921.tar b/packages/magit-popup-20190223.2234.tar similarity index 86% rename from packages/magit-popup-20181003.921.tar rename to packages/magit-popup-20190223.2234.tar index e3e09f9..a5fcb0c 100644 Binary files a/packages/magit-popup-20181003.921.tar and b/packages/magit-popup-20190223.2234.tar differ diff --git a/packages/magit-svn-20170213.1233.el b/packages/magit-svn-20190324.1459.el similarity index 90% rename from packages/magit-svn-20170213.1233.el rename to packages/magit-svn-20190324.1459.el index 37f2f62..5f611c5 100644 --- a/packages/magit-svn-20170213.1233.el +++ b/packages/magit-svn-20190324.1459.el @@ -1,10 +1,10 @@ ;;; magit-svn.el --- Git-Svn extension for Magit -;; Copyright (C) 2010-2017 The Magit Project Contributors +;; Copyright (C) 2010-2019 The Magit Project Contributors ;; Author: Phil Jackson ;; Keywords: vc tools -;; Package-Version: 20170213.1233 +;; Package-Version: 20190324.1459 ;; Package: magit-svn ;; Package-Requires: ((emacs "24.4") (magit "2.1.0")) @@ -35,9 +35,9 @@ ;; When `magit-svn-mode' is turned on then the unpushed and unpulled ;; commit relative to the Subversion repository are displayed in the -;; status buffer, and `N' is bound to a popup with commands that wrap -;; the `git svn' subcommands fetch, rebase, dcommit, branch and tag, -;; as well as a few extras. +;; status buffer, and "N" is bound to a transient command with +;; suffixes that wrap the `git-svn' subcommands fetch, rebase, +;; dcommit, branch and tag, as well as a few extras. ;; To enable the mode in a particular repository use: ;; @@ -52,11 +52,16 @@ ;; ;; (add-hook 'magit-mode-hook 'magit-svn-mode) +;; This package is unmaintained see the README for more information. + ;;; Code: (require 'cl-lib) (require 'dash) +(eval-when-compile + (require 'subr-x)) + (require 'magit) (declare-function find-lisp-find-files-internal 'find-lisp) @@ -173,18 +178,19 @@ If USE-CACHE is non-nil, use the cached information." ;;; Commands -(magit-define-popup magit-svn-popup - "Popup console for svn commands." - 'magit +(define-transient-command magit-svn () + "Invoke `git-svn' commands." :man-page "git-svn" - :switches '((?n "Dry run" "--dry-run")) - :actions '((?c "DCommit" magit-svn-dcommit) - (?r "Rebase" magit-svn-rebase) - (?f "Fetch" magit-svn-fetch) - (?x "Fetch Externals" magit-svn-fetch-externals) - (?s "Show commit" magit-svn-show-commit) - (?b "Create branch" magit-svn-create-branch) - (?t "Create tag" magit-svn-create-tag))) + ["Arguments" + ("-n" "Dry run" "--dry-run")] + ["Actions" + ("c" "DCommit" magit-svn-dcommit) + ("r" "Rebase" magit-svn-rebase) + ("f" "Fetch" magit-svn-fetch) + ("x" "Fetch Externals" magit-svn-fetch-externals) + ("s" "Show commit" magit-svn-show-commit) + ("b" "Create branch" magit-svn-create-branch) + ("t" "Create tag" magit-svn-create-tag)]) ;;;###autoload (defun magit-svn-show-commit (rev &optional branch) @@ -201,28 +207,30 @@ With a prefix argument also read a branch to search in." (defun magit-svn-create-branch (name &optional args) "Create svn branch NAME. \n(git svn branch [--dry-run] NAME)" - (interactive (list (read-string "Branch name: ") magit-current-popup-args)) + (interactive (list (read-string "Branch name: ") + (transient-args))) (magit-run-git "svn" "branch" args name)) ;;;###autoload (defun magit-svn-create-tag (name &optional args) "Create svn tag NAME. \n(git svn tag [--dry-run] NAME)" - (interactive (list (read-string "Tag name: ") magit-current-popup-args)) + (interactive (list (read-string "Tag name: ") + (transient-args))) (magit-run-git "svn" "tag" args name)) ;;;###autoload (defun magit-svn-rebase (&optional args) "Fetch revisions from Svn and rebase the current Git commits. \n(git svn rebase [--dry-run])" - (interactive (list magit-current-popup-args)) + (interactive (list (transient-args))) (magit-run-git-async "svn" "rebase" args)) ;;;###autoload (defun magit-svn-dcommit (&optional args) "Run git-svn dcommit. \n(git svn dcommit [--dry-run])" - (interactive (list magit-current-popup-args)) + (interactive (list (transient-args))) (magit-run-git-async "svn" "dcommit" args)) ;;;###autoload @@ -255,7 +263,7 @@ in `magit-svn-external-directories' and runs (defvar magit-svn-mode-map (let ((map (make-sparse-keymap))) - (define-key map (kbd "N") 'magit-svn-popup) + (define-key map (kbd "N") 'magit-svn) map)) ;;;###autoload diff --git a/packages/magithub-20181116.1355.tar b/packages/magithub-20181116.1355.tar deleted file mode 100644 index b18c111..0000000 Binary files a/packages/magithub-20181116.1355.tar and /dev/null differ diff --git a/packages/majapahit-theme-20160817.1848.tar b/packages/majapahit-theme-20160817.1848.tar index 69931be..bf4c066 100644 Binary files a/packages/majapahit-theme-20160817.1848.tar and b/packages/majapahit-theme-20160817.1848.tar differ diff --git a/packages/markdown-mode-20181112.1529.el b/packages/markdown-mode-20190802.2215.el similarity index 99% rename from packages/markdown-mode-20181112.1529.el rename to packages/markdown-mode-20190802.2215.el index d402963..0f9b43c 100644 --- a/packages/markdown-mode-20181112.1529.el +++ b/packages/markdown-mode-20190802.2215.el @@ -7,7 +7,7 @@ ;; Maintainer: Jason R. Blevins ;; Created: May 24, 2007 ;; Version: 2.4-dev -;; Package-Version: 20181112.1529 +;; Package-Version: 20190802.2215 ;; Package-Requires: ((emacs "24.4") (cl-lib "0.5")) ;; Keywords: Markdown, GitHub Flavored Markdown, itex ;; URL: https://jblevins.org/projects/markdown-mode/ @@ -579,7 +579,7 @@ requires Emacs to be built with ImageMagick support." (const :tag "No maximum height" nil))))) -;;; Markdown-Specific `rx' Macro +;;; Markdown-Specific `rx' Macro ============================================== ;; Based on python-rx from python.el. (eval-and-compile @@ -1649,7 +1649,7 @@ START and END delimit region to propertize." (markdown-syntax-propertize-comments start end)))) -;;; Markup Hiding +;;; Markup Hiding ============================================================= (defconst markdown-markup-properties '(face markdown-markup-face invisible markdown-markup) @@ -2123,6 +2123,14 @@ Depending on your font, some reasonable choices are: ,@(when markdown-hide-markup `(display ,markdown-footnote-display)))) +(define-obsolete-variable-alias + 'gfm-font-lock-keywords + 'markdown-mode-font-lock-keywords "v2.4") + +(define-obsolete-variable-alias + 'markdown-mode-font-lock-keywords-basic + 'markdown-mode-font-lock-keywords "v2.4") + (defvar markdown-mode-font-lock-keywords `((markdown-match-yaml-metadata-begin . ((1 'markdown-markup-face))) (markdown-match-yaml-metadata-end . ((1 'markdown-markup-face))) @@ -2228,10 +2236,6 @@ Depending on your font, some reasonable choices are: (markdown-match-wiki-link . ((0 'markdown-link-face prepend)))) "Syntax highlighting for Markdown files.") -(define-obsolete-variable-alias - 'markdown-mode-font-lock-keywords-basic - 'markdown-mode-font-lock-keywords "v2.4") - ;; Footnotes (defvar markdown-footnote-counter 0 "Counter for footnote numbers.") @@ -4517,7 +4521,7 @@ at the beginning of the block." (goto-char (next-single-property-change (point) prop))))))) -;;; Footnotes ================================================================== +;;; Footnotes ================================================================= (defun markdown-footnote-counter-inc () "Increment `markdown-footnote-counter' and return the new value." @@ -4833,7 +4837,7 @@ text to kill ring), and list items." (kill-region (point) (progn (markdown-forward-block) (point))))) -;;; Indentation ==================================================================== +;;; Indentation =============================================================== (defun markdown-indent-find-next-position (cur-pos positions) "Return the position after the index of CUR-POS in POSITIONS. @@ -5443,7 +5447,7 @@ Assumes match data is available for `markdown-regex-italic'." See also `markdown-mode-map'.") -;;; Menu ================================================================== +;;; Menu ====================================================================== (easy-menu-define markdown-mode-menu markdown-mode-map "Menu for Markdown mode" @@ -8437,7 +8441,7 @@ BEG and END are the limits of scanned region." (remove-overlays nil nil 'face 'markdown-gfm-checkbox-face)))) -;;; Display inline image ================================================= +;;; Display inline image ====================================================== (defvar markdown-inline-image-overlays nil) (make-variable-buffer-local 'markdown-inline-image-overlays) @@ -8450,6 +8454,33 @@ or \\[markdown-toggle-inline-images]." (mapc #'delete-overlay markdown-inline-image-overlays) (setq markdown-inline-image-overlays nil)) +(defcustom markdown-display-remote-images nil + "If non-nil, download and display remote images. +See also `markdown-inline-image-overlays'. + +Only image URLs specified with a protocol listed in +`markdown-remote-image-protocols' are displayed." + :group 'markdown + :type 'boolean) + +(defcustom markdown-remote-image-protocols '("https") + "List of protocols to use to download remote images. +See also `markdown-display-remote-images'." + :group 'markdown + :type '(repeat string)) + +(defvar markdown--remote-image-cache + (make-hash-table :test 'equal) + "A map from URLs to image paths.") + +(defun markdown--get-remote-image (url) + "Retrieve the image path for a given URL." + (or (gethash url markdown--remote-image-cache) + (let ((dl-path (make-temp-file "markdown-mode--image"))) + (require 'url) + (url-copy-file url dl-path t) + (puthash url dl-path markdown--remote-image-cache)))) + (defun markdown-display-inline-images () "Add inline image overlays to image links in the buffer. This can be toggled with `markdown-toggle-inline-images' @@ -8467,24 +8498,29 @@ or \\[markdown-toggle-inline-images]." (end (match-end 0)) (file (match-string-no-properties 6))) (when (and imagep - (not (zerop (length file))) - (file-exists-p file)) - (let* ((abspath (if (file-name-absolute-p file) - file - (concat default-directory file))) - (image - (if (and markdown-max-image-size - (image-type-available-p 'imagemagick)) - (create-image - abspath 'imagemagick nil - :max-width (car markdown-max-image-size) - :max-height (cdr markdown-max-image-size)) - (create-image abspath)))) - (when image - (let ((ov (make-overlay start end))) - (overlay-put ov 'display image) - (overlay-put ov 'face 'default) - (push ov markdown-inline-image-overlays)))))))))) + (not (zerop (length file)))) + (unless (file-exists-p file) + (when (and markdown-display-remote-images + (member (downcase (url-type (url-generic-parse-url file))) + markdown-remote-image-protocols)) + (setq file (markdown--get-remote-image file)))) + (when (file-exists-p file) + (let* ((abspath (if (file-name-absolute-p file) + file + (concat default-directory file))) + (image + (if (and markdown-max-image-size + (image-type-available-p 'imagemagick)) + (create-image + abspath 'imagemagick nil + :max-width (car markdown-max-image-size) + :max-height (cdr markdown-max-image-size)) + (create-image abspath)))) + (when image + (let ((ov (make-overlay start end))) + (overlay-put ov 'display image) + (overlay-put ov 'face 'default) + (push ov markdown-inline-image-overlays))))))))))) (defun markdown-toggle-inline-images () "Toggle inline image overlays in the buffer." @@ -8665,7 +8701,7 @@ position." (markdown-edit-code-block)))))) -;;; Table Editing +;;; Table Editing ============================================================= ;; These functions were originally adapted from `org-table.el'. @@ -8820,7 +8856,8 @@ This function assumes point is on a table." (while (and (not (bobp)) (markdown-table-at-point-p)) (forward-line -1)) - (unless (eobp) + (unless (or (eobp) + (markdown-table-at-point-p)) (forward-line 1)) (point))) @@ -9384,7 +9421,7 @@ rows and columns and the column alignment." (markdown-table-forward-cell))) -;;; ElDoc Support +;;; ElDoc Support ============================================================= (defun markdown-eldoc-function () "Return a helpful string when appropriate based on context. @@ -9595,12 +9632,8 @@ rows and columns and the column alignment." (setq-local markdown-table-at-point-p-function 'gfm--table-at-point-p) (markdown-gfm-parse-buffer-for-languages)) -(define-obsolete-variable-alias - 'gfm-font-lock-keywords - 'markdown-mode-font-lock-keywords "v2.4") - -;;; Viewing modes +;;; Viewing modes ============================================================= (defcustom markdown-hide-markup-in-view-modes t "Enable hidden markup mode in `markdown-view-mode' and `gfm-view-mode'." @@ -9641,7 +9674,7 @@ rows and columns and the column alignment." (read-only-mode 1)) -;;; Live Preview Mode ============================================ +;;; Live Preview Mode ======================================================== ;;;###autoload (define-minor-mode markdown-live-preview-mode "Toggle native previewing on save for a specific markdown file." diff --git a/packages/markdown-toc-20170711.1949.tar b/packages/markdown-toc-20170711.1949.tar index 2e5406c..55f4605 100644 Binary files a/packages/markdown-toc-20170711.1949.tar and b/packages/markdown-toc-20170711.1949.tar differ diff --git a/packages/material-theme-20171123.1840.tar b/packages/material-theme-20171123.1840.tar index 837f096..2fb87e0 100644 Binary files a/packages/material-theme-20171123.1840.tar and b/packages/material-theme-20171123.1840.tar differ diff --git a/packages/math-symbol-lists-20170221.1353.tar b/packages/math-symbol-lists-20190605.2058.tar similarity index 97% rename from packages/math-symbol-lists-20170221.1353.tar rename to packages/math-symbol-lists-20190605.2058.tar index aa4ba6f..7b97887 100644 Binary files a/packages/math-symbol-lists-20170221.1353.tar and b/packages/math-symbol-lists-20190605.2058.tar differ diff --git a/packages/matlab-mode-20180928.1526.tar b/packages/matlab-mode-20180928.1526.tar index 53401e8..501a5c3 100644 Binary files a/packages/matlab-mode-20180928.1526.tar and b/packages/matlab-mode-20180928.1526.tar differ diff --git a/packages/meghanada-20181116.1302.tar b/packages/meghanada-20190526.548.tar similarity index 94% rename from packages/meghanada-20181116.1302.tar rename to packages/meghanada-20190526.548.tar index 81c64f4..f15b9d9 100644 Binary files a/packages/meghanada-20181116.1302.tar and b/packages/meghanada-20190526.548.tar differ diff --git a/packages/merlin-20180816.815.tar b/packages/merlin-20190718.1023.tar similarity index 85% rename from packages/merlin-20180816.815.tar rename to packages/merlin-20190718.1023.tar index bb2847e..496dd41 100644 Binary files a/packages/merlin-20180816.815.tar and b/packages/merlin-20190718.1023.tar differ diff --git a/packages/migemo-20160924.1441.el b/packages/migemo-20190112.516.el similarity index 54% rename from packages/migemo-20160924.1441.el rename to packages/migemo-20190112.516.el index e3cbd3d..f9215d9 100644 --- a/packages/migemo-20160924.1441.el +++ b/packages/migemo-20190112.516.el @@ -5,8 +5,8 @@ ;; Author: Satoru Takabayashi ;; URL: https://github.com/emacs-jp/migemo -;; Package-Version: 20160924.1441 -;; Version: 1.9.1 +;; Package-Version: 20190112.516 +;; Version: 1.9.2 ;; Keywords: ;; Package-Requires: ((cl-lib "0.5")) @@ -37,34 +37,33 @@ "migemo - Japanese incremental search trough dynamic pattern expansion." :group 'matching) -(defcustom migemo-command "ruby" +(defcustom migemo-command "cmigemo" "*Name or full path of the executable for running migemo." :group 'migemo - :type '(choice (const :tag "Ruby Migemo" "ruby") - (const :tag "CMIGEMO" "cmigemo") - (string :tag "Other"))) + :type '(choice + (const :tag "CMIGEMO" "cmigemo") + (const :tag "Ruby Migemo" "ruby") + (string :tag "Other"))) -;; -t emacs for specifying the type of regular expression. -;; "-i" "\a" for searching a word over multi-lines. -(defcustom migemo-options '("-S" "migemo" "-t" "emacs" "-i" "\a") +(defcustom migemo-options '("-q" "--emacs") "*Options for migemo command." :group 'migemo :type '(repeat string)) -(defcustom migemo-white-space-regexp "[ ¡¡\t\r\n]*" +(defcustom migemo-white-space-regexp "[  \t\r\n]*" "*Regexp representing white spaces." :group 'migemo :type 'string) -;; for C/Migemo -;; (setq migemo-command "cmigemo") -;; (setq migemo-options '("-q" "--emacs" "-i" "\g")) -;; (setq migemo-dictionary "somewhere/migemo/euc-jp/migemo-dict") +;; for Ruby/Migemo +;; (setq migemo-command "ruby") +;; (setq migemo-options '("-S" "migemo" "-t" "emacs" "-i" "\a")) +;; (setq migemo-dictionary "somewhere/migemo/utf-8/migemo-dict") ;; (setq migemo-user-dictionary nil) -;; (setq migemo-regex-dictionary nil)) +;; (setq migemo-regex-dictionary nil) -(defcustom migemo-directory "@pkgdatadir@" - "*Directory where migemo files are placed" +(defcustom migemo-directory nil + "*Directory where migemo files are placed." :group 'migemo :type 'directory) @@ -86,38 +85,33 @@ (defcustom migemo-user-dictionary (expand-file-name "user-dict" migemo-directory) "*Migemo user dictionary file." :group 'migemo - :type '(choice (file :must-match t) - (const :tag "Do not use" nil))) + :type '(choice + (file :must-match t) + (const :tag "Do not use" nil))) (defcustom migemo-regex-dictionary (expand-file-name "regex-dict" migemo-directory) "*Migemo regex dictionary file." :group 'migemo - :type '(choice (file :must-match t) - (const :tag "Do not use" nil))) + :type '(choice + (file :must-match t) + (const :tag "Do not use" nil))) (defcustom migemo-pre-conv-function nil "*Function of migemo pre-conversion." :group 'migemo - :type '(choice (const :tag "Do not use" nil) - function)) + :type '(choice + (const :tag "Do not use" nil) + function)) (defcustom migemo-after-conv-function nil "*Function of migemo after-conversion." :group 'migemo - :type '(choice (const :tag "Do not use" nil) - function)) - -(defcustom migemo-coding-system - (with-no-warnings - (if (>= emacs-major-version 20) - (if (featurep 'mule) - (if (string-match "XEmacs" emacs-version) - (cond - ((memq 'euc-japan-unix (coding-system-list)) 'euc-japan-unix) - ((memq 'euc-jp-unix (coding-system-list)) 'euc-jp-unix)) - 'euc-japan-unix)) - (and (boundp 'MULE) *euc-japan*unix))) - "*Default coding system for migemo.el" + :type '(choice + (const :tag "Do not use" nil) + function)) + +(defcustom migemo-coding-system 'utf-8-unix + "*Default coding system for migemo.el." :group 'migemo :type 'coding-system) @@ -136,12 +130,14 @@ :group 'migemo :type 'integer) -(defcustom migemo-pattern-alist-file "~/.migemo-pattern" +(defcustom migemo-pattern-alist-file + (locate-user-emacs-file "migemo-pattern" ".migemo-pattern") "*Path of migemo alist file. If nil, don't save and restore the file." :group 'migemo :type 'file) -(defcustom migemo-frequent-pattern-alist-file "~/.migemo-frequent" +(defcustom migemo-frequent-pattern-alist-file + (locate-user-emacs-file "migemo-frequent" ".migemo-freqent") "*Path of migemo frequent alist file. If nil, don't save and restore the file." :group 'migemo :type 'file) @@ -156,9 +152,6 @@ :group 'migemo :type 'integer) -(defconst migemo-mw32-input-method (and (featurep 'meadow) "MW32-IME") - "Support \"MW32-IME\" for Meadow.") - ;; internal variables (defvar migemo-process nil) (defvar migemo-buffer nil) @@ -168,7 +161,6 @@ (defvar migemo-search-pattern nil) (defvar migemo-pattern-alist nil) (defvar migemo-frequent-pattern-alist nil) -(defconst migemo-emacs21p (and (> emacs-major-version 20) (not (featurep 'xemacs)))) (defvar migemo-search-pattern-alist nil) (defvar migemo-do-isearch nil) (defvar migemo-register-isearch-keybinding-function nil) @@ -182,59 +174,59 @@ (unless pattern (setq pattern (migemo-get-pattern string)) (setq migemo-search-pattern-alist - (cons (cons string pattern) - migemo-search-pattern-alist))) + (cons (cons string pattern) + migemo-search-pattern-alist))) pattern)) (defun migemo-toggle-isearch-enable () (interactive) (setq migemo-isearch-enable-p (not migemo-isearch-enable-p)) (message (if migemo-isearch-enable-p - "t" - "nil"))) + "t" + "nil"))) (defun migemo-start-process (name buffer program args) (let* ((process-connection-type nil) (proc (apply 'start-process name buffer program args))) (if (fboundp 'set-process-coding-system) - (set-process-coding-system proc - migemo-coding-system - migemo-coding-system) + (set-process-coding-system proc + migemo-coding-system + migemo-coding-system) (set-process-input-coding-system proc migemo-coding-system) (set-process-output-coding-system proc migemo-coding-system)) proc)) (defun migemo-init () (when (and migemo-use-frequent-pattern-alist - migemo-frequent-pattern-alist-file - (null migemo-frequent-pattern-alist)) + migemo-frequent-pattern-alist-file + (null migemo-frequent-pattern-alist)) (setq migemo-frequent-pattern-alist - (migemo-pattern-alist-load migemo-frequent-pattern-alist-file))) + (migemo-pattern-alist-load migemo-frequent-pattern-alist-file))) (when (and migemo-use-pattern-alist - migemo-pattern-alist-file - (null migemo-pattern-alist)) + migemo-pattern-alist-file + (null migemo-pattern-alist)) (setq migemo-pattern-alist - (migemo-pattern-alist-load migemo-pattern-alist-file))) + (migemo-pattern-alist-load migemo-pattern-alist-file))) (when (and migemo-use-default-isearch-keybinding migemo-register-isearch-keybinding-function) (funcall migemo-register-isearch-keybinding-function)) (or (and migemo-process - (eq (process-status migemo-process) 'run)) + (eq (process-status migemo-process) 'run)) (let ((options - (delq nil - (append migemo-options - (when (and migemo-user-dictionary - (file-exists-p migemo-user-dictionary)) - (list "-u" migemo-user-dictionary)) - (when (and migemo-regex-dictionary - (file-exists-p migemo-regex-dictionary)) - (list "-r" migemo-regex-dictionary)) - (list "-d" migemo-dictionary))))) - (setq migemo-buffer (get-buffer-create " *migemo*")) - (setq migemo-process (migemo-start-process - "migemo" migemo-buffer migemo-command options)) - (set-process-query-on-exit-flag migemo-process nil) - t))) + (delq nil + (append migemo-options + (when (and migemo-user-dictionary + (file-exists-p migemo-user-dictionary)) + (list "-u" migemo-user-dictionary)) + (when (and migemo-regex-dictionary + (file-exists-p migemo-regex-dictionary)) + (list "-r" migemo-regex-dictionary)) + (list "-d" migemo-dictionary))))) + (setq migemo-buffer (get-buffer-create " *migemo*")) + (setq migemo-process (migemo-start-process + "migemo" migemo-buffer migemo-command options)) + (set-process-query-on-exit-flag migemo-process nil) + t))) (defun migemo-replace-in-string (string from to) (with-temp-buffer @@ -254,43 +246,43 @@ (set-text-properties 0 (length word) nil word) (migemo-init) (when (and migemo-pre-conv-function - (functionp migemo-pre-conv-function)) - (setq word (funcall migemo-pre-conv-function word))) + (functionp migemo-pre-conv-function)) + (setq word (funcall migemo-pre-conv-function word))) (setq pattern - (cond - ((setq freq (and migemo-use-frequent-pattern-alist - (assoc word migemo-frequent-pattern-alist))) - (cdr freq)) - ((setq alst (and migemo-use-pattern-alist - (assoc word migemo-pattern-alist))) - (setq migemo-pattern-alist (cons alst (delq alst migemo-pattern-alist))) - (cdr alst)) - (t - (with-current-buffer (process-buffer migemo-process) - (delete-region (point-min) (point-max)) - (process-send-string migemo-process (concat word "\n")) - (while (not (and (> (point-max) 1) - (eq (char-after (1- (point-max))) ?\n))) - (accept-process-output migemo-process - 0 migemo-accept-process-output-timeout-msec)) - (setq pattern (buffer-substring (point-min) (1- (point-max))))) - (when (and (memq system-type '(windows-nt OS/2 emx)) - (> (length pattern) 1) - (eq ?\r (aref pattern (1- (length pattern))))) - (setq pattern (substring pattern 0 -1))) - (when migemo-use-pattern-alist - (setq migemo-pattern-alist - (cons (cons word pattern) migemo-pattern-alist)) - (when (and migemo-pattern-alist-length - (> (length migemo-pattern-alist) - (* migemo-pattern-alist-length 2))) - (setcdr (nthcdr (1- (* migemo-pattern-alist-length 2)) - migemo-pattern-alist) nil))) - pattern))) + (cond + ((setq freq (and migemo-use-frequent-pattern-alist + (assoc word migemo-frequent-pattern-alist))) + (cdr freq)) + ((setq alst (and migemo-use-pattern-alist + (assoc word migemo-pattern-alist))) + (setq migemo-pattern-alist (cons alst (delq alst migemo-pattern-alist))) + (cdr alst)) + (t + (with-current-buffer (process-buffer migemo-process) + (delete-region (point-min) (point-max)) + (process-send-string migemo-process (concat word "\n")) + (while (not (and (> (point-max) 1) + (eq (char-after (1- (point-max))) ?\n))) + (accept-process-output migemo-process + 0 migemo-accept-process-output-timeout-msec)) + (setq pattern (buffer-substring (point-min) (1- (point-max))))) + (when (and (memq system-type '(windows-nt OS/2 emx)) + (> (length pattern) 1) + (eq ?\r (aref pattern (1- (length pattern))))) + (setq pattern (substring pattern 0 -1))) + (when migemo-use-pattern-alist + (setq migemo-pattern-alist + (cons (cons word pattern) migemo-pattern-alist)) + (when (and migemo-pattern-alist-length + (> (length migemo-pattern-alist) + (* migemo-pattern-alist-length 2))) + (setcdr (nthcdr (1- (* migemo-pattern-alist-length 2)) + migemo-pattern-alist) nil))) + pattern))) (if (and migemo-after-conv-function - (functionp migemo-after-conv-function)) - (funcall migemo-after-conv-function word pattern) - (migemo-replace-in-string pattern "\a" migemo-white-space-regexp)))))) + (functionp migemo-after-conv-function)) + (funcall migemo-after-conv-function word pattern) + (migemo-replace-in-string pattern "\a" migemo-white-space-regexp)))))) (defun migemo-pattern-alist-load (file) "Load migemo alist file." @@ -313,24 +305,24 @@ "Save migemo alist file." (interactive) (when (and migemo-use-pattern-alist - migemo-pattern-alist-file - (or migemo-pattern-alist clear)) + migemo-pattern-alist-file + (or migemo-pattern-alist clear)) (let ((file (expand-file-name migemo-pattern-alist-file))) (when (file-writable-p file) - (when clear - (setq migemo-pattern-alist nil)) - (when (and migemo-pattern-alist-length - (> (length migemo-pattern-alist) migemo-pattern-alist-length)) - (setcdr (nthcdr (1- migemo-pattern-alist-length) - migemo-pattern-alist) nil)) - (with-temp-buffer - (let ((coding-system-for-write migemo-coding-system) + (when clear + (setq migemo-pattern-alist nil)) + (when (and migemo-pattern-alist-length + (> (length migemo-pattern-alist) migemo-pattern-alist-length)) + (setcdr (nthcdr (1- migemo-pattern-alist-length) + migemo-pattern-alist) nil)) + (with-temp-buffer + (let ((coding-system-for-write migemo-coding-system) (buffer-file-coding-system migemo-coding-system)) (if (fboundp 'pp) (pp migemo-pattern-alist (current-buffer)) (prin1 migemo-pattern-alist (current-buffer))) (write-region (point-min) (point-max) file nil 'nomsg))) - (setq migemo-pattern-alist nil))))) + (setq migemo-pattern-alist nil))))) (defun migemo-kill () "Kill migemo process" @@ -356,33 +348,33 @@ (migemo-kill) (migemo-init) (let ((file (expand-file-name migemo-frequent-pattern-alist-file)) - (migemo-use-pattern-alist nil) - (migemo-use-frequent-pattern-alist nil) - (migemo-after-conv-function (lambda (_x y) y)) - word) + (migemo-use-pattern-alist nil) + (migemo-use-frequent-pattern-alist nil) + (migemo-after-conv-function (lambda (_x y) y)) + word) (setq migemo-frequent-pattern-alist nil) (with-temp-buffer (let ((coding-system-for-write migemo-coding-system) (buffer-file-coding-system migemo-coding-system))) - (insert-file-contents fcfile) - (goto-char (point-min)) - (message "Make frequently pattern...") - (while (not (eobp)) - (when (looking-at "^[a-z]+$") - (setq word (match-string 0)) - (message "Make frequently pattern...%s" word) - (setq migemo-frequent-pattern-alist - (cons (cons word (migemo-get-pattern word)) - migemo-frequent-pattern-alist))) - (forward-line 1)) - (when (file-writable-p file) - (setq migemo-frequent-pattern-alist - (nreverse migemo-frequent-pattern-alist)) - (erase-buffer) - (if (fboundp 'pp) - (pp migemo-frequent-pattern-alist (current-buffer)) - (prin1 migemo-frequent-pattern-alist (current-buffer))) - (write-region (point-min) (point-max) file nil 'nomsg))) + (insert-file-contents fcfile) + (goto-char (point-min)) + (message "Make frequently pattern...") + (while (not (eobp)) + (when (looking-at "^[a-z]+$") + (setq word (match-string 0)) + (message "Make frequently pattern...%s" word) + (setq migemo-frequent-pattern-alist + (cons (cons word (migemo-get-pattern word)) + migemo-frequent-pattern-alist))) + (forward-line 1)) + (when (file-writable-p file) + (setq migemo-frequent-pattern-alist + (nreverse migemo-frequent-pattern-alist)) + (erase-buffer) + (if (fboundp 'pp) + (pp migemo-frequent-pattern-alist (current-buffer)) + (prin1 migemo-frequent-pattern-alist (current-buffer))) + (write-region (point-min) (point-max) file nil 'nomsg))) (migemo-kill) (migemo-init) (message "Make frequently pattern...done")))) @@ -390,16 +382,16 @@ (defun migemo-expand-pattern () "\ Expand the Romaji sequences on the left side of the cursor into the migemo's regexp pattern." - (interactive) - (let ((pos (point))) - (goto-char (- pos 1)) - (if (re-search-backward "[^-a-zA-Z]" (line-beginning-position) t) - (forward-char 1) - (beginning-of-line)) - (let* ((str (buffer-substring-no-properties (point) pos)) - (jrpat (migemo-get-pattern str))) - (delete-region (point) pos) - (insert jrpat)))) + (interactive) + (let ((pos (point))) + (goto-char (- pos 1)) + (if (re-search-backward "[^-a-zA-Z]" (line-beginning-position) t) + (forward-char 1) + (beginning-of-line)) + (let* ((str (buffer-substring-no-properties (point) pos)) + (jrpat (migemo-get-pattern str))) + (delete-region (point) pos) + (insert jrpat)))) (defun migemo-forward (word &optional bound noerror count) (interactive "sSearch: \nP\nP") @@ -416,14 +408,14 @@ into the migemo's regexp pattern." (if (null migemo-do-isearch) (search-backward-regexp migemo-search-pattern bound noerror count) (or (and (not (eq this-command 'isearch-repeat-backward)) - (not (get-char-property (point) 'invisible (current-buffer))) - (or (and (looking-at migemo-search-pattern) - (match-beginning 0)) - (and (not (eq (point) (point-min))) - (progn (forward-char -1) - (and (looking-at migemo-search-pattern) - (match-beginning 0)))))) - (search-backward-regexp migemo-search-pattern bound noerror count)))) + (not (get-char-property (point) 'invisible (current-buffer))) + (or (and (looking-at migemo-search-pattern) + (match-beginning 0)) + (and (not (eq (point) (point-min))) + (progn (forward-char -1) + (and (looking-at migemo-search-pattern) + (match-beginning 0)))))) + (search-backward-regexp migemo-search-pattern bound noerror count)))) ;; experimental ;; (define-key global-map "\M-;" 'migemo-dabbrev-expand) @@ -445,83 +437,80 @@ into the migemo's regexp pattern." (defun migemo-dabbrev-expand-done () (remove-hook 'pre-command-hook 'migemo-dabbrev-expand-done) (unless (eq last-command this-command) - (setq migemo-search-pattern-alist nil) - (setq migemo-dabbrev-pre-patterns nil)) + (setq migemo-search-pattern-alist nil) + (setq migemo-dabbrev-pre-patterns nil)) (when migemo-dabbrev-ol (delete-overlay migemo-dabbrev-ol))) (defun migemo-dabbrev-expand () (interactive) (let ((end-pos (point)) - matched-start matched-string) + matched-start matched-string) (if (eq last-command this-command) - (goto-char migemo-dabbrev-search-point) + (goto-char migemo-dabbrev-search-point) (goto-char (- end-pos 1)) (if (re-search-backward "[^a-z-]" (line-beginning-position) t) - (forward-char 1) - (beginning-of-line)) + (forward-char 1) + (beginning-of-line)) (setq migemo-search-pattern-alist nil) (setq migemo-dabbrev-start-point (point)) (setq migemo-dabbrev-search-point (point)) (setq migemo-dabbrev-pattern - (buffer-substring-no-properties (point) end-pos)) + (buffer-substring-no-properties (point) end-pos)) (setq migemo-dabbrev-pre-patterns nil)) (if (catch 'found - (while (if (> migemo-dabbrev-search-point migemo-dabbrev-start-point) - (and (migemo-forward migemo-dabbrev-pattern (point-max) t) - (setq migemo-dabbrev-search-point (match-end 0))) - (if (migemo-backward migemo-dabbrev-pattern (point-min) t) - (setq migemo-dabbrev-search-point (match-beginning 0)) - (goto-char migemo-dabbrev-start-point) - (forward-word 1) - (message (format "Trun back for `%s'" migemo-dabbrev-pattern)) - (and (migemo-forward migemo-dabbrev-pattern (point-max) t) - (setq migemo-dabbrev-search-point (match-end 0))))) - (setq matched-start (match-beginning 0)) - (unless (re-search-forward ".\\>" (line-end-position) t) - (end-of-line)) - (setq matched-string (buffer-substring-no-properties matched-start (point))) - (unless (member matched-string migemo-dabbrev-pre-patterns) - (let ((matched-end (point)) - (str (copy-sequence matched-string)) - lstart lend) - (if (and (pos-visible-in-window-p matched-start) - (pos-visible-in-window-p matched-end)) - (progn - (if migemo-dabbrev-ol - (move-overlay migemo-dabbrev-ol matched-start (point)) - (setq migemo-dabbrev-ol (make-overlay matched-start (point)))) - (overlay-put migemo-dabbrev-ol 'evaporate t) - (overlay-put migemo-dabbrev-ol 'face migemo-dabbrev-ol-face)) - (when migemo-dabbrev-ol - (delete-overlay migemo-dabbrev-ol)) - (when migemo-dabbrev-display-message - (save-excursion - (save-restriction - (goto-char matched-start) - (setq lstart (progn (beginning-of-line) (point))) - (setq lend (progn (end-of-line) (point))) - (if migemo-emacs21p - (put-text-property 0 (length str) - 'face migemo-dabbrev-ol-face str) - (setq str (concat "¡Ú" str "¡Û"))) - (message "(%d): %s%s%s" - (count-lines (point-min) matched-start) - (buffer-substring-no-properties lstart matched-start) - str - (buffer-substring-no-properties matched-end lend))))))) - (throw 'found t)) - (goto-char migemo-dabbrev-search-point))) - (progn - (setq migemo-dabbrev-pre-patterns - (cons matched-string migemo-dabbrev-pre-patterns)) - (delete-region migemo-dabbrev-start-point end-pos) - (forward-char 1) - (goto-char migemo-dabbrev-start-point) - (insert matched-string)) + (while (if (> migemo-dabbrev-search-point migemo-dabbrev-start-point) + (and (migemo-forward migemo-dabbrev-pattern (point-max) t) + (setq migemo-dabbrev-search-point (match-end 0))) + (if (migemo-backward migemo-dabbrev-pattern (point-min) t) + (setq migemo-dabbrev-search-point (match-beginning 0)) + (goto-char migemo-dabbrev-start-point) + (forward-word 1) + (message (format "Trun back for `%s'" migemo-dabbrev-pattern)) + (and (migemo-forward migemo-dabbrev-pattern (point-max) t) + (setq migemo-dabbrev-search-point (match-end 0))))) + (setq matched-start (match-beginning 0)) + (unless (re-search-forward ".\\>" (line-end-position) t) + (end-of-line)) + (setq matched-string (buffer-substring-no-properties matched-start (point))) + (unless (member matched-string migemo-dabbrev-pre-patterns) + (let ((matched-end (point)) + (str (copy-sequence matched-string)) + lstart lend) + (if (and (pos-visible-in-window-p matched-start) + (pos-visible-in-window-p matched-end)) + (progn + (if migemo-dabbrev-ol + (move-overlay migemo-dabbrev-ol matched-start (point)) + (setq migemo-dabbrev-ol (make-overlay matched-start (point)))) + (overlay-put migemo-dabbrev-ol 'evaporate t) + (overlay-put migemo-dabbrev-ol 'face migemo-dabbrev-ol-face)) + (when migemo-dabbrev-ol + (delete-overlay migemo-dabbrev-ol)) + (when migemo-dabbrev-display-message + (save-excursion + (save-restriction + (goto-char matched-start) + (setq lstart (progn (beginning-of-line) (point))) + (setq lend (progn (end-of-line) (point))) + (setq str (concat "ã€" str "】")) + (message "(%d): %s%s%s" + (count-lines (point-min) matched-start) + (buffer-substring-no-properties lstart matched-start) + str + (buffer-substring-no-properties matched-end lend))))))) + (throw 'found t)) + (goto-char migemo-dabbrev-search-point))) + (progn + (setq migemo-dabbrev-pre-patterns + (cons matched-string migemo-dabbrev-pre-patterns)) + (delete-region migemo-dabbrev-start-point end-pos) + (forward-char 1) + (goto-char migemo-dabbrev-start-point) + (insert matched-string)) (goto-char end-pos) (message (format "No dynamic expansion for `%s' found" - migemo-dabbrev-pattern))) + migemo-dabbrev-pattern))) (add-hook 'pre-command-hook 'migemo-dabbrev-expand-done))) (defsubst migemo--isearch-regexp-function () @@ -541,7 +530,7 @@ into the migemo's regexp pattern." "adviced by migemo." (let ((isearch-adjusted isearch-adjusted)) (when (and migemo-isearch-enable-p - (not isearch-forward) (not isearch-regexp) (not (migemo--isearch-regexp-function))) + (not isearch-forward) (not isearch-regexp) (not (migemo--isearch-regexp-function))) ;; don't use 'looking-at' (setq isearch-adjusted t)) ad-do-it)) @@ -550,19 +539,19 @@ into the migemo's regexp pattern." "adviced by migemo." (if migemo-do-isearch (setq ad-return-value - (migemo-forward (ad-get-arg 0) (ad-get-arg 1) (ad-get-arg 2) (ad-get-arg 3))) + (migemo-forward (ad-get-arg 0) (ad-get-arg 1) (ad-get-arg 2) (ad-get-arg 3))) ad-do-it)) (defadvice search-backward (around migemo-search-ad activate) "adviced by migemo." (if migemo-do-isearch (setq ad-return-value - (migemo-backward (ad-get-arg 0) (ad-get-arg 1) (ad-get-arg 2) (ad-get-arg 3))) + (migemo-backward (ad-get-arg 0) (ad-get-arg 1) (ad-get-arg 2) (ad-get-arg 3))) ad-do-it)) (when (and (boundp 'isearch-regexp-lax-whitespace) - (fboundp 're-search-forward-lax-whitespace) - (fboundp 'search-forward-lax-whitespace)) + (fboundp 're-search-forward-lax-whitespace) + (fboundp 'search-forward-lax-whitespace)) (setq isearch-search-fun-function 'isearch-search-fun-migemo) (when (fboundp 'isearch-search-fun-default) @@ -574,43 +563,43 @@ into the migemo's regexp pattern." (funcall ,ad-return-value string bound noerror)))))) (defun isearch-search-fun-migemo () - "Return default functions to use for the search with migemo." - (cond - ((migemo--isearch-regexp-function) - (lambda (string &optional bound noerror count) - ;; Use lax versions to not fail at the end of the word while - ;; the user adds and removes characters in the search string - ;; (or when using nonincremental word isearch) - (let* ((state-string-func (if (fboundp 'isearch--state-string) - 'isearch--state-string - 'isearch-string-state)) + "Return default functions to use for the search with migemo." + (cond + ((migemo--isearch-regexp-function) + (lambda (string &optional bound noerror count) + ;; Use lax versions to not fail at the end of the word while + ;; the user adds and removes characters in the search string + ;; (or when using nonincremental word isearch) + (let* ((state-string-func (if (fboundp 'isearch--state-string) + 'isearch--state-string + 'isearch-string-state)) (lax (not (or isearch-nonincremental - (eq (length isearch-string) - (length (funcall state-string-func (car isearch-cmds)))))))) - (funcall - (if isearch-forward #'re-search-forward #'re-search-backward) - (if (functionp (migemo--isearch-regexp-function)) - (funcall (migemo--isearch-regexp-function) string lax) - (word-search-regexp string lax)) - bound noerror count)))) - ((and isearch-regexp isearch-regexp-lax-whitespace - search-whitespace-regexp) - (if isearch-forward - 're-search-forward-lax-whitespace - 're-search-backward-lax-whitespace)) - (isearch-regexp - (if isearch-forward 're-search-forward 're-search-backward)) - ((and (if (boundp 'isearch-lax-whitespace) isearch-lax-whitespace t) - search-whitespace-regexp migemo-do-isearch) - (if isearch-forward 'migemo-forward 'migemo-backward)) - ((and (if (boundp 'isearch-lax-whitespace) isearch-lax-whitespace t) - search-whitespace-regexp) - (if isearch-forward 'search-forward-lax-whitespace - 'search-backward-lax-whitespace)) - (migemo-do-isearch - (if isearch-forward 'migemo-forward 'migemo-backward)) - (t - (if isearch-forward 'search-forward 'search-backward)))) + (eq (length isearch-string) + (length (funcall state-string-func (car isearch-cmds)))))))) + (funcall + (if isearch-forward #'re-search-forward #'re-search-backward) + (if (functionp (migemo--isearch-regexp-function)) + (funcall (migemo--isearch-regexp-function) string lax) + (word-search-regexp string lax)) + bound noerror count)))) + ((and isearch-regexp isearch-regexp-lax-whitespace + search-whitespace-regexp) + (if isearch-forward + 're-search-forward-lax-whitespace + 're-search-backward-lax-whitespace)) + (isearch-regexp + (if isearch-forward 're-search-forward 're-search-backward)) + ((and (if (boundp 'isearch-lax-whitespace) isearch-lax-whitespace t) + search-whitespace-regexp migemo-do-isearch) + (if isearch-forward 'migemo-forward 'migemo-backward)) + ((and (if (boundp 'isearch-lax-whitespace) isearch-lax-whitespace t) + search-whitespace-regexp) + (if isearch-forward 'search-forward-lax-whitespace + 'search-backward-lax-whitespace)) + (migemo-do-isearch + (if isearch-forward 'migemo-forward 'migemo-backward)) + (t + (if isearch-forward 'search-forward 'search-backward)))) ) ;; Turn off input-method automatically when C-s or C-r are typed. @@ -619,14 +608,10 @@ into the migemo's regexp pattern." (setq migemo-search-pattern nil) (setq migemo-search-pattern-alist nil) (when (and migemo-isearch-enable-p - (boundp 'current-input-method)) + (boundp 'current-input-method)) (setq migemo-current-input-method current-input-method) (setq migemo-current-input-method-title current-input-method-title) (setq migemo-input-method-function input-method-function) - (when (and migemo-mw32-input-method - (stringp migemo-current-input-method) - (string= migemo-current-input-method migemo-mw32-input-method)) - (set-input-method nil)) (setq current-input-method nil) (setq current-input-method-title nil) (setq input-method-function nil) @@ -642,11 +627,7 @@ into the migemo's regexp pattern." (setq migemo-search-pattern nil) (setq migemo-search-pattern-alist nil) (when (and migemo-isearch-enable-p - (boundp 'current-input-method)) - (when (and migemo-mw32-input-method - (stringp migemo-current-input-method) - (string= migemo-current-input-method migemo-mw32-input-method)) - (set-input-method migemo-current-input-method)) + (boundp 'current-input-method)) (let ((state-changed-p (not (equal current-input-method migemo-current-input-method)))) (setq current-input-method migemo-current-input-method) (setq current-input-method-title migemo-current-input-method-title) @@ -667,11 +648,9 @@ into the migemo's regexp pattern." (defadvice isearch-message-prefix (after migemo-status activate) "adviced by migemo." (let ((ret ad-return-value) - (str "[MIGEMO]")) - (when migemo-emacs21p - (put-text-property 0 (length str) 'face migemo-message-prefix-face str)) + (str "[MIGEMO]")) (when (and migemo-isearch-enable-p - (not (or isearch-regexp (migemo--isearch-regexp-function)))) + (not (or isearch-regexp (migemo--isearch-regexp-function)))) (setq ad-return-value (concat str " " ret))))) ;;;; for isearch-lazy-highlight (Emacs 21) @@ -701,17 +680,17 @@ into the migemo's regexp pattern." ;;;; for isearch-highlightify-region (XEmacs 21) (when (fboundp 'isearch-highlightify-region) (defadvice isearch-highlightify-region (around migemo-highlightify-region - activate) + activate) "adviced by migemo." (if migemo-isearch-enable-p - (let ((isearch-string (migemo-search-pattern-get isearch-string)) - (isearch-regexp t)) - ad-do-it) + (let ((isearch-string (migemo-search-pattern-get isearch-string)) + (isearch-regexp t)) + ad-do-it) ad-do-it))) ;; supports C-w C-d for GNU emacs only [migemo:00171] (when (and (not (featurep 'xemacs)) - (fboundp 'isearch-yank-line)) + (fboundp 'isearch-yank-line)) (defun migemo-register-isearch-keybinding () (define-key isearch-mode-map "\C-d" 'migemo-isearch-yank-char) (define-key isearch-mode-map "\C-w" 'migemo-isearch-yank-word) @@ -728,10 +707,10 @@ into the migemo's regexp pattern." (setq migemo-isearch-enable-p (not migemo-isearch-enable-p))) (when (fboundp 'isearch-lazy-highlight-new-loop) (let ((isearch-lazy-highlight-last-string nil)) - (condition-case nil - (isearch-lazy-highlight-new-loop) - (error - (isearch-lazy-highlight-new-loop nil nil))))) + (condition-case nil + (isearch-lazy-highlight-new-loop) + (error + (isearch-lazy-highlight-new-loop nil nil))))) (isearch-message)) (defun migemo-isearch-yank-char () @@ -743,13 +722,13 @@ into the migemo's regexp pattern." isearch-other-end (point))) (setq isearch-message isearch-string)) (let ((search-upper-case (unless migemo-isearch-enable-p - search-upper-case))) + search-upper-case))) (isearch-yank-string (save-excursion - (and (not isearch-forward) isearch-other-end - (goto-char isearch-other-end)) - (buffer-substring-no-properties (point) - (progn (forward-char 1) (point))))))) + (and (not isearch-forward) isearch-other-end + (goto-char isearch-other-end)) + (buffer-substring-no-properties (point) + (progn (forward-char 1) (point))))))) (defun migemo-isearch-yank-word () "Pull next character from buffer into search string with migemo." @@ -760,13 +739,13 @@ into the migemo's regexp pattern." isearch-other-end (point))) (setq isearch-message isearch-string)) (let ((search-upper-case (unless migemo-isearch-enable-p - search-upper-case))) + search-upper-case))) (isearch-yank-string (save-excursion - (and (not isearch-forward) isearch-other-end - (goto-char isearch-other-end)) - (buffer-substring-no-properties (point) - (progn (forward-word 1) (point))))))) + (and (not isearch-forward) isearch-other-end + (goto-char isearch-other-end)) + (buffer-substring-no-properties (point) + (progn (forward-word 1) (point))))))) (defun migemo-isearch-yank-line () "Pull next character from buffer into search string with migemo." @@ -777,24 +756,24 @@ into the migemo's regexp pattern." isearch-other-end (point))) (setq isearch-message isearch-string)) (let ((search-upper-case (unless migemo-isearch-enable-p - search-upper-case))) + search-upper-case))) (isearch-yank-string (save-excursion - (and (not isearch-forward) isearch-other-end - (goto-char isearch-other-end)) - (buffer-substring-no-properties (point) - (line-end-position)))))) -) + (and (not isearch-forward) isearch-other-end + (goto-char isearch-other-end)) + (buffer-substring-no-properties (point) + (line-end-position)))))) + ) (add-hook 'kill-emacs-hook 'migemo-pattern-alist-save) (provide 'migemo) ;; sample -;; 0123 abcd ABCD ¤Ò¤é¤¬¤Ê ¥«¥¿¥«¥Ê ´Á»ú !"[#\$]%^&_':`(;)<*=+>,?-@./{|}~ +;; 0123 abcd ABCD ã²ã‚‰ãŒãª カタカナ 漢字 !"[#\$]%^&_':`(;)<*=+>,?-@./{|}~ ;; Local Variables: -;; coding: euc-japan-unix +;; coding: utf-8 ;; indent-tabs-mode: nil ;; End: diff --git a/packages/minimal-theme-20160608.1022.tar b/packages/minimal-theme-20190113.2132.tar similarity index 63% rename from packages/minimal-theme-20160608.1022.tar rename to packages/minimal-theme-20190113.2132.tar index 89fefa7..1aae5be 100644 Binary files a/packages/minimal-theme-20160608.1022.tar and b/packages/minimal-theme-20190113.2132.tar differ diff --git a/packages/minitest-20160628.1820.tar b/packages/minitest-20160628.1820.tar index 4757062..1390eb7 100644 Binary files a/packages/minitest-20160628.1820.tar and b/packages/minitest-20160628.1820.tar differ diff --git a/packages/mmt-20180101.619.el b/packages/mmt-20190713.1347.el similarity index 97% rename from packages/mmt-20180101.619.el rename to packages/mmt-20190713.1347.el index 48d8de3..e8bca27 100644 --- a/packages/mmt-20180101.619.el +++ b/packages/mmt-20190713.1347.el @@ -1,10 +1,10 @@ ;;; mmt.el --- Missing macro tools for Emacs Lisp -*- lexical-binding: t; -*- ;; -;; Copyright © 2015–2018 Mark Karpov +;; Copyright © 2015–present Mark Karpov ;; ;; Author: Mark Karpov ;; URL: https://github.com/mrkkrp/mmt -;; Package-Version: 20180101.619 +;; Package-Version: 20190713.1347 ;; Version: 0.2.0 ;; Package-Requires: ((emacs "24.1") (cl-lib "0.3")) ;; Keywords: macro, emacs-lisp diff --git a/packages/moe-theme-20180617.200.tar b/packages/moe-theme-20180617.200.tar index 99f5141..a27fc7f 100644 Binary files a/packages/moe-theme-20180617.200.tar and b/packages/moe-theme-20180617.200.tar differ diff --git a/packages/monochrome-theme-20140326.1050.tar b/packages/monochrome-theme-20140326.1050.tar index bb100a3..0c3fcd1 100644 Binary files a/packages/monochrome-theme-20140326.1050.tar and b/packages/monochrome-theme-20140326.1050.tar differ diff --git a/packages/monokai-theme-20180730.1329.el b/packages/monokai-theme-20190801.1701.el similarity index 99% rename from packages/monokai-theme-20180730.1329.el rename to packages/monokai-theme-20190801.1701.el index 4ab030c..d6e5faf 100644 --- a/packages/monokai-theme-20180730.1329.el +++ b/packages/monokai-theme-20190801.1701.el @@ -4,7 +4,7 @@ ;; Author: Kelvin Smith ;; URL: http://github.com/oneKelvinSmith/monokai-emacs -;; Package-Version: 20180730.1329 +;; Package-Version: 20190801.1701 ;; Version: 3.5.3 ;; This program is free software; you can redistribute it and/or modify @@ -3301,6 +3301,15 @@ Also affects 'linum-mode' background." :background ,monokai-256-highlight-line :underline nil)))) + ;; lsp-mode + `(lsp-ui-doc-header + ((,monokai-class (:inherit org-document-title)) + (,monokai-256-class (:inherit org-document-title)))) + + `(lsp-ui-doc-background + ((,monokai-class (:background ,monokai-highlight-line)) + (,monokai-256-class (:background ,monokai-highlight-line)))) + ;; lusty-explorer `(lusty-directory-face ((,monokai-class (:inherit dimonokai-red-directory)) diff --git a/packages/mu4e-alert-20180305.646.el b/packages/mu4e-alert-20190418.558.el similarity index 98% rename from packages/mu4e-alert-20180305.646.el rename to packages/mu4e-alert-20190418.558.el index 1bcc175..84d7c11 100644 --- a/packages/mu4e-alert-20180305.646.el +++ b/packages/mu4e-alert-20190418.558.el @@ -4,7 +4,7 @@ ;; Author: Iqbal Ansari ;; URL: https://github.com/iqbalansari/mu4e-alert -;; Package-Version: 20180305.646 +;; Package-Version: 20190418.558 ;; Keywords: mail, convenience ;; Version: 1.0 ;; Package-Requires: ((alert "1.2") (s "1.10.0") (ht "2.0") (emacs "24.3")) @@ -153,6 +153,13 @@ wish to be notified of all emails at each check irrespective of whether you have been notified of the an email earlier or no." :type 'boolean) +(defcustom mu4e-alert-icon nil + "Full path to icon to show in notification. + +Note that not all 'alert' notification backends support this." + :type 'string + :group 'mu4e-alert) + ;;;###autoload (defun mu4e-alert-set-default-style (value) "Set the default style for unread email notifications. @@ -486,7 +493,8 @@ ALL-MAILS are the all the unread emails" (dolist (notification (cl-subseq notifications 0 (min 5 (length notifications)))) (alert (plist-get notification :body) :title (plist-get notification :title) - :category "mu4e-alert")) + :category "mu4e-alert" + :icon mu4e-alert-icon)) (when notifications (mu4e-alert-set-window-urgency-maybe)))) @@ -496,7 +504,8 @@ ALL-MAILS are the all the unread emails" (alert (funcall mu4e-alert-email-count-notification-formatter mail-count) :title mu4e-alert-email-count-title - :category "mu4e-alert"))) + :category "mu4e-alert" + :icon mu4e-alert-icon))) (defun mu4e-alert-notify-unread-mail-async () "Send a desktop notification about currently unread email." diff --git a/packages/multi-term-20160619.933.el b/packages/multi-term-20190624.1147.el similarity index 98% rename from packages/multi-term-20160619.933.el rename to packages/multi-term-20190624.1147.el index ac9184b..b9c9db2 100644 --- a/packages/multi-term-20160619.933.el +++ b/packages/multi-term-20190624.1147.el @@ -5,9 +5,9 @@ ;; Copyright (C) 2008 ~ 2016 Andy Stewart, all rights reserved. ;; Copyright (C) 2010, ahei, all rights reserved. ;; Created: <2008-09-19 23:02:42> -;; Version: 1.3 -;; Package-Version: 20160619.933 -;; Last-Updated: 2016-06-19 17:30:20 +;; Version: 1.4 +;; Package-Version: 20190624.1147 +;; Last-Updated: 2017-03-03 13:48:38 ;; URL: http://www.emacswiki.org/emacs/download/multi-term.el ;; Keywords: term, terminal, multiple buffer ;; Compatibility: GNU Emacs 23.2.1, GNU Emacs 24.4 (and prereleases) @@ -29,7 +29,7 @@ ;; Features that might be required by this library: ;; -;; `term' `cl' `advice' +;; `term' `cl-lib' `advice' ;; ;;; Commentary: @@ -128,6 +128,9 @@ ;;; Change log: ;; +;; 2017/03/03 +;; * Switch to cl-lib +;; ;; 2016/06/19 ;; * Add Hogren's patch: `term-send-delete-word' and binding to key 'M-d'. ;; @@ -269,7 +272,7 @@ ;;; Require: (require 'term) -(require 'cl) +(require 'cl-lib) (require 'advice) ;;; Code: @@ -698,7 +701,7 @@ If DIRECTION `PREVIOUS', switch to the previous term. Option OFFSET for skip OFFSET number term buffer." (if multi-term-buffer-list (let ((buffer-list-len (length multi-term-buffer-list)) - (my-index (position (current-buffer) multi-term-buffer-list))) + (my-index (cl-position (current-buffer) multi-term-buffer-list))) (if my-index (let ((target-index (if (eq direction 'NEXT) (mod (+ my-index offset) buffer-list-len) @@ -715,7 +718,7 @@ So this function unbinds some keys with `term-raw-map', and binds some keystroke with `term-raw-map'." (let (bind-key bind-command) ;; Unbind base key that conflict with user's keys-tokes. - (dolist (unbind-key term-unbind-key-list) + (cl-dolist (unbind-key term-unbind-key-list) (cond ((stringp unbind-key) (setq unbind-key (read-kbd-macro unbind-key))) ((vectorp unbind-key) nil) @@ -724,7 +727,7 @@ and binds some keystroke with `term-raw-map'." ;; Add some i use keys. ;; If you don't like my keystroke, ;; just modified `term-bind-key-alist' - (dolist (element term-bind-key-alist) + (cl-dolist (element term-bind-key-alist) (setq bind-key (car element)) (setq bind-command (cdr element)) (cond @@ -789,9 +792,9 @@ Otherwise return nil." (walk-windows (lambda (w) (with-selected-window w - (incf window-number) + (cl-incf window-number) (if (window-dedicated-p w) - (incf dedicated-window-number))))) + (cl-incf dedicated-window-number))))) (if (and (> dedicated-window-number 0) (= (- window-number dedicated-window-number) 1)) t nil))) @@ -803,7 +806,7 @@ Dedicated window can't deleted by command `delete-other-windows'." (let ((multi-term-dedicated-active-p (multi-term-window-exist-p multi-term-dedicated-window))) (if multi-term-dedicated-active-p (let ((current-window (selected-window))) - (dolist (win (window-list)) + (cl-dolist (win (window-list)) (when (and (window-live-p win) (not (eq current-window win)) (not (window-dedicated-p win))) @@ -832,7 +835,7 @@ to display buffer, even when the option `pop-up-windows' is enabled. And the example function that can induce the problem is `pop-to-buffer'. This advice will fix this problem when current frame just have one `non-dedicated' window." - (when (and pop-up-windows ;`pop-up-windows' is enable + (when (and pop-up-windows ;`pop-up-windows' is enable (multi-term-window-dedicated-only-one-p) ;just have one `non-dedicated' window. (multi-term-window-exist-p multi-term-dedicated-window) (not (multi-term-dedicated-window-p))) ;not in `sr-speedbar' window diff --git a/packages/multiple-cursors-20180913.1237.tar b/packages/multiple-cursors-20190820.749.tar similarity index 87% rename from packages/multiple-cursors-20180913.1237.tar rename to packages/multiple-cursors-20190820.749.tar index c811ece..0c5ce0e 100644 Binary files a/packages/multiple-cursors-20180913.1237.tar and b/packages/multiple-cursors-20190820.749.tar differ diff --git a/packages/nameless-20180215.2221.el b/packages/nameless-20190429.1202.el similarity index 98% rename from packages/nameless-20180215.2221.el rename to packages/nameless-20190429.1202.el index 695d753..0a549c8 100644 --- a/packages/nameless-20180215.2221.el +++ b/packages/nameless-20190429.1202.el @@ -4,7 +4,7 @@ ;; Author: Artur Malabarba ;; URL: https://github.com/Malabarba/nameless -;; Package-Version: 20180215.2221 +;; Package-Version: 20190429.1202 ;; Keywords: convenience, lisp ;; Version: 1.0.2 ;; Package-Requires: ((emacs "24.4")) @@ -166,7 +166,9 @@ Value can also be nil, in which case the separator is never hidden." (defun nameless--ensure () (save-excursion - (font-lock-fontify-region (point-min) (point-max)))) + (if (fboundp 'font-lock-flush) + (font-lock-flush) + (font-lock-fontify-region (point-min) (point-max))))) (defun nameless--remove-keywords () "Remove font-lock keywords set by `nameless--add-keywords'." diff --git a/packages/names-20180321.1155.tar b/packages/names-20180321.1155.tar index 0b9920a..6568ec1 100644 Binary files a/packages/names-20180321.1155.tar and b/packages/names-20180321.1155.tar differ diff --git a/packages/naquadah-theme-20180212.1240.el b/packages/naquadah-theme-20190225.1427.el similarity index 97% rename from packages/naquadah-theme-20180212.1240.el rename to packages/naquadah-theme-20190225.1427.el index 76dcac7..c3f5e57 100644 --- a/packages/naquadah-theme-20180212.1240.el +++ b/packages/naquadah-theme-20190225.1427.el @@ -1,5 +1,5 @@ ;;; naquadah-theme.el --- A theme based on Tango color set -;; Package-Version: 20180212.1240 +;; Package-Version: 20190225.1427 ;; Copyright (C) 2011-2012 Free Software Foundation, Inc @@ -294,6 +294,7 @@ '(font-lock-comment-face (:inherit shadow :italic t)) '(font-lock-comment-delimiter-face (:inherit font-lock-comment-face)) '(font-lock-constant-face (:foreground chameleon-2)) + '(font-lock-negation-char-face (:foreground chameleon-2)) '(font-lock-type-face (:foreground butter-1 :weight bold)) '(font-lock-doc-face (:inherit shadow :italic t)) '(font-lock-string-face (:foreground plum-1)) @@ -618,10 +619,26 @@ '(flycheck-warning (:underline (:style wave :color orange-2))) '(flycheck-info (:underline (:style wave :color chameleon-1))) + ;; flycheck-color-mode-line-error-face + '(flycheck-color-mode-line-error-face (:inherit error :italic nil)) + '(flycheck-color-mode-line-warning-face (:inherit warning :italic nil)) + ;; flyspell '(flyspell-incorrect (:underline (:style wave :color scarlet-red-1))) '(flyspell-duplicate (:underline (:style wave :color orange-2))) + ;; company + '(company-tooltip (:background aluminium-4)) + '(company-tooltip-selection (:background orange-2)) + '(company-tooltip-common (:foreground scarlet-red-3)) + '(company-tooltip-annotation (:background scarlet-red-3)) + '(company-scrollbar-fg (:background scarlet-red-3)) + '(company-scrollbar-bg (:background black)) + '(company-preview (:background sky-blue-1)) + '(company-preview-common (:inherit company-preview :foreground scarlet-red-3)) + '(company-preview-search (:inherit company-preview :background sky-blue-1)) + '(company-echo-common (:background scarlet-red-3)) + ;; git-gutter '(git-gutter:modified (:foreground orange-1)) '(git-gutter:added (:foreground chameleon-1)) diff --git a/packages/nasm-mode-20180711.1909.el b/packages/nasm-mode-20190410.342.el similarity index 99% rename from packages/nasm-mode-20180711.1909.el rename to packages/nasm-mode-20190410.342.el index b696008..698f237 100644 --- a/packages/nasm-mode-20180711.1909.el +++ b/packages/nasm-mode-20190410.342.el @@ -4,7 +4,7 @@ ;; Author: Christopher Wellons ;; URL: https://github.com/skeeto/nasm-mode -;; Package-Version: 20180711.1909 +;; Package-Version: 20190410.342 ;; Version: 1.1.1 ;; Package-Requires: ((emacs "24.3")) @@ -747,6 +747,8 @@ With a prefix arg, kill the comment on the current line with :group 'nasm-mode (make-local-variable 'indent-line-function) (make-local-variable 'comment-start) + (make-local-variable 'comment-insert-comment-function) + (make-local-variable 'comment-indent-function) (setf font-lock-defaults '(nasm-font-lock-keywords nil :case-fold) indent-line-function #'nasm-indent-line comment-start ";" diff --git a/packages/neotree-20181113.2125.tar b/packages/neotree-20181121.2026.tar similarity index 98% rename from packages/neotree-20181113.2125.tar rename to packages/neotree-20181121.2026.tar index c7c5c44..1d493de 100644 Binary files a/packages/neotree-20181113.2125.tar and b/packages/neotree-20181121.2026.tar differ diff --git a/packages/nim-mode-20181028.1713.tar b/packages/nim-mode-20190710.2254.tar similarity index 96% rename from packages/nim-mode-20181028.1713.tar rename to packages/nim-mode-20190710.2254.tar index 6f183b5..16e873a 100644 Binary files a/packages/nim-mode-20181028.1713.tar and b/packages/nim-mode-20190710.2254.tar differ diff --git a/packages/nix-mode-20181030.346.tar b/packages/nix-mode-20190703.526.tar similarity index 71% rename from packages/nix-mode-20181030.346.tar rename to packages/nix-mode-20190703.526.tar index 0d4297f..546bbe2 100644 Binary files a/packages/nix-mode-20181030.346.tar and b/packages/nix-mode-20190703.526.tar differ diff --git a/packages/nodejs-repl-20190616.1753.el b/packages/nodejs-repl-20190616.1753.el new file mode 100644 index 0000000..098e2a9 --- /dev/null +++ b/packages/nodejs-repl-20190616.1753.el @@ -0,0 +1,545 @@ +;;; nodejs-repl.el --- Run Node.js REPL + +;; Copyright (C) 2012-2019 Takeshi Arabiki + +;; Author: Takeshi Arabiki +;; Version: 0.2.2 +;; Package-Version: 20190616.1753 + +;; 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 . + +;;; Commentary: +;; +;; This program is derived from comint-mode and provides the following features. +;; +;; * TAB completion same as Node.js REPL +;; * file name completion in string +;; * incremental history search +;; +;; +;; Put this file in your Emacs lisp path (e.g. ~/.emacs.d/site-lisp) +;; and add the following line to your .emacs: +;; +;; (require 'nodejs-repl) +;; +;; Type M-x nodejs-repl to run Node.js REPL. +;; See also `comint-mode' to check key bindings. +;; +;; You can define key bindings to send JavaScript codes to REPL like below: +;; +;; (add-hook 'js-mode-hook +;; (lambda () +;; (define-key js-mode-map (kbd "C-x C-e") 'nodejs-repl-send-last-expression) +;; (define-key js-mode-map (kbd "C-c C-r") 'nodejs-repl-send-region) +;; (define-key js-mode-map (kbd "C-c C-l") 'nodejs-repl-load-file) +;; (define-key js-mode-map (kbd "C-c C-z") 'nodejs-repl-switch-to-repl))) +;; +;; When a version manager such as nvm is used to run different versions +;; of Node.js, it is often desirable to start the REPL of the version +;; specified in the .nvmrc file per project. In such case, customize the +;; `nodejs-repl-command` variable with a function symbol. That function +;; should query nvm for the Node.js command to run. For example: +;; +;; (require 'nodejs-repl) +;; (defun nvm-which () +;; (let* ((shell (concat (getenv "SHELL") " -l -c 'nvm which'")) +;; (output (shell-command-to-string shell))) +;; (cadr (split-string output "[\n]+" t)))) +;; (setq nodejs-repl-command #'nvm-which) +;; +;; The `nvm-which` function can be simpler, and perhaps can run faster, +;; too, if using Bash: +;; +;; (defun nvm-which () +;; (let ((output (shell-command-to-string "source ~/.nvm/nvm.sh; nvm which"))) +;; (cadr (split-string output "[\n]+" t)))) +;; + +(require 'cc-mode) +(require 'comint) +(require 'ansi-color) + +(defgroup nodejs-repl nil + "Run Node.js REPL and communicate the process." + :group 'processes) + +(defconst nodejs-repl-version "0.2.2" + "Node.js mode Version.") + +(defcustom nodejs-repl-command "node" + "Node.js command used in `nodejs-repl-mode'. If it is a symbol +of a function, the function is called for the path of the Node.js +command. This allows to integrate with a Node.js version manager +such as nvm." + :group 'nodejs-repl + :type 'string) + +(defcustom nodejs-repl-arguments '() + "Command line parameters forwarded to `nodejs-repl-command'." + :group 'nodejs-repl + :type '(repeat string)) + +(defcustom nodejs-repl-prompt "> " + "Node.js prompt used in `nodejs-repl-mode'." + :group 'nodejs-repl + :type 'string) + +(defcustom nodejs-repl-use-global "false" + "useGlobal option of Node.js REPL method repl.start" + :group 'nodejs-repl + :type 'string) + +(defcustom nodejs-repl-input-ignoredups t + "If non-nil, don't add input matching the last on the input ring. + +See also `comint-input-ignoredups'" + :group 'nodejs-repl + :type 'boolean) + +(defcustom nodejs-repl-process-echoes t + "If non-nil, Node.js does not echo any input. + +See also `comint-process-echoes'" + :group 'nodejs-repl + :type 'boolean) + +(defvar nodejs-repl-nodejs-version) +(defvar nodejs-repl--nodejs-version-re + "^v\\([0-9]+\\(?:\\.[0-9]+\\)*\\)\\(?:\\.x\\)*\\(?:-\\w+\\)?[\r\n]*$") + +(defvar nodejs-repl-mode-hook nil + "Functions runafter `nodejs-repl' is started.") + +(defvar nodejs-repl-process-name "nodejs" + "process name of Node.js REPL.") + +(defvar nodejs-repl-temp-buffer-name "*nodejs-repl-command-output*") + +(defvar nodejs-repl-mode-syntax-table + (let ((st (make-syntax-table))) + (c-populate-syntax-table st) + (modify-syntax-entry ?$ "_" st) + st)) + +(defvar nodejs-repl-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "TAB") 'completion-at-point) + (define-key map (kbd "C-c C-c") 'nodejs-repl-quit-or-cancel) + map)) + +(defvar nodejs-repl-code-format + (concat + "require('repl').start({prompt: '%s', useGlobal: %s, replMode: " + "require('repl')['REPL_MODE_' + '%s'.toUpperCase()] })")) + +(defvar nodejs-repl-extra-espace-sequence-re "\\(\x1b\\[[0-9]+[GJK]\\)") + +(defvar nodejs-repl-ansi-color-sequence-re "\\(\x1b\\[[0-9]+m\\)") + +;;; if send string like "a; Ma\t", return a; Math\x1b[1G> a; Math\x1b[0K\x1b[10G +(defvar nodejs-repl-prompt-re-format + "\x1b\\[1G\x1b\\[0J%s.*\x1b\\[[0-9]+G.*$") +(defvar nodejs-repl-prompt-re + (format nodejs-repl-prompt-re-format nodejs-repl-prompt nodejs-repl-prompt)) +;;; not support Unicode characters +(defvar nodejs-repl-require-re + (concat + "\\(?:^\\|\\s-\\|[-+*/%&|> '("encodeURI" "encodeURIComponent") + (setq completions (split-string + (replace-regexp-in-string " *$" "" (mapconcat 'identity completions " ")) + "[ \t\r\n]+")) + ) + (setq ret (replace-regexp-in-string nodejs-repl-extra-espace-sequence-re "" ret)) + (let ((candidate-token (nodejs-repl--get-last-token ret))) + (setq completions (if (or (null candidate-token) (equal candidate-token token)) + nil + (list candidate-token)))))) + completions)) + +(defun nodejs-repl--get-or-create-process () + (let ((proc (get-process nodejs-repl-process-name))) + (unless (processp proc) + (save-excursion (nodejs-repl)) + (setq proc (get-process nodejs-repl-process-name))) + proc)) + +(defun nodejs-repl--filter-escape-sequnces (string) + "Filter extra escape sequences from output." + (let ((beg (or comint-last-output-start + (point-min-marker))) + (end (process-mark (get-buffer-process (current-buffer))))) + (save-excursion + (goto-char beg) + ;; Remove ansi escape sequences used in readline.js + (while (re-search-forward nodejs-repl-extra-espace-sequence-re end t) + (replace-match ""))))) + +(defun nodejs-repl--clear-cache (string) + "Clear caches when outputting the result." + (setq nodejs-repl-cache-token "") + (setq nodejs-repl-cache-completions ())) + +(defun nodejs-repl--set-prompt-deletion-required-p () + (setq nodejs-repl-prompt-deletion-required-p t)) + +(defun nodejs-repl--remove-duplicated-prompt (string) + ;; `.load` command of Node.js repl outputs a duplicated prompt + (let ((beg (or comint-last-output-start + (point-min-marker))) + (end (process-mark (get-buffer-process (current-buffer))))) + (save-excursion + (goto-char beg) + (when (re-search-forward (concat nodejs-repl-prompt nodejs-repl-prompt) end t) + (replace-match nodejs-repl-prompt))))) + +(defun nodejs-repl--delete-prompt (string) + ;; Redundant prompts are included in outputs from Node.js REPL + (when nodejs-repl-prompt-deletion-required-p + (setq nodejs-repl-prompt-deletion-required-p nil) + (let ((beg (or comint-last-output-start + (point-min-marker))) + (end (process-mark (get-buffer-process (current-buffer))))) + (save-excursion + (goto-char beg) + (forward-line 0) ; Use forward-line instead of beginning-of-line to ignore prompts + (forward-char (length nodejs-repl-prompt)) + (while (re-search-forward nodejs-repl-prompt end t) + (replace-match "")))))) + +;; cf. https://www.ecma-international.org/ecma-262/#sec-ecmascript-language-expressions +(defun nodejs-repl--beginning-of-expression () + (search-backward-regexp "[[:graph:]]" nil t) + (unless (eq (char-after) ?\;) + (forward-char)) + (cond + ;; Allow function + ((and (eq (char-before) ?}) + (save-excursion + (backward-list) + (search-backward-regexp "[[:graph:]]" nil t) + (and (eq (char-before) ?=) (eq (char-after) ?>)))) + (backward-list) + (search-backward-regexp "\\(\\w\\|)\\)\\s-*=>" nil t) + (forward-char) + (nodejs-repl--backward-expression)) + (t + (nodejs-repl--backward-expression) + (while (and (not (bobp)) + (or + (and (eq (char-syntax (char-after)) ?\() + (save-excursion + (search-backward-regexp "[[:graph:]]" nil t) + (and (not (eq (char-after) ?\;)) ; e.g. otherExp; (exp) + (not (eq (sexp-at-point) 'return))))) ; e.g. return (exp) + (save-excursion + (search-backward-regexp "[[:graph:]]" nil t) + (eq (char-after) ?.)) + (save-excursion + (backward-char) + (eq (sexp-at-point) 'function)))) + (search-backward-regexp "[[:graph:]]" nil t) + (when (eq (char-after) ?.) + (search-backward-regexp "[[:graph:]]" nil t)) + (forward-char) + (nodejs-repl--backward-expression)) + + ;; e.g. !function() {}() + (let ((exp (save-excursion + (search-backward-regexp "[[:graph:]]" nil t) + (or (sexp-at-point) (intern (char-to-string (char-after))))))) + (when (member exp nodejs-repl-unary-operators) + (search-backward (symbol-name exp) nil))))) + (point)) + +(defun nodejs-repl--backward-expression () + (cond + ((eq (char-syntax (char-before)) ?\)) + (backward-list)) + ((save-excursion + (search-backward-regexp "[[:graph:]]" nil t) + (eq (char-syntax (char-after)) ?w)) + (backward-sexp)) + (t + (error "No proper expression is found backward")))) + +(defun nodejs-repl--completion-at-point-function () + (setq nodejs-repl-prompt-deletion-required-p t) + (when (comint-after-pmark-p) + (let* ((input (buffer-substring (comint-line-beginning-position) (point))) + require-arg + token-length + file-completion-p) + (setq nodejs-repl-get-completions-for-require-p nil) ;; reset + (if (not (nodejs-repl--in-string-p)) + (setq token-length (length (nodejs-repl--get-last-token input))) + (setq require-arg (nodejs-repl--extract-require-argument input) + nodejs-repl-get-completions-for-require-p t) + (if (and require-arg + (or (= (length require-arg) 1) ; only quote or double quote + (not (string-match-p "[./]" (substring require-arg 1 2))))) ; not file path + (setq token-length (1- (length require-arg))) + (let ((quote-pos (save-excursion + (search-backward-regexp "['\"]" (point-at-bol) t) + (forward-char) + (point)))) + (when quote-pos + (setq file-completion-p t + token-length (- (point) quote-pos)))))) + (when token-length + (list + (save-excursion (backward-char token-length) (point)) + (point) + (if file-completion-p + #'completion-file-name-table + (completion-table-dynamic #'nodejs-repl--get-completions))))))) + +(defun nodejs-repl--get-completions (token) + (let (completions) + (when nodejs-repl-get-completions-for-require-p + (setq token (concat "require('" token))) + (if (and (not (equal nodejs-repl-cache-token "")) + (string-prefix-p nodejs-repl-cache-token token) + (not (string-match-p (concat "^" nodejs-repl-cache-token ".*?[.(/'\"]") token))) + (setq completions nodejs-repl-cache-completions) + (setq completions (nodejs-repl--get-completions-from-process token) + nodejs-repl-cache-token token + nodejs-repl-cache-completions completions)) + completions)) + + +;;;-------------------------- +;;; Public functions +;;;-------------------------- +(defun nodejs-repl-quit-or-cancel () + "Send ^C to Node.js process." + (interactive) + (process-send-string (get-process nodejs-repl-process-name) "\x03")) + +(defun nodejs-repl-clear-line () + "Send ^U to Node.js process." + (nodejs-repl--send-string "\x15")) + +;;;###autoload +(defun nodejs-repl-send-line () + "Send the current line to the `nodejs-repl-process'" + (interactive) + (save-excursion + (let ((proc (nodejs-repl--get-or-create-process)) + (start)) + (beginning-of-line) + (setq start (point)) + (end-of-line) + (comint-send-region proc start (point)) + (comint-send-string proc "\n")))) + +;;;###autoload +(defun nodejs-repl-send-region (start end) + "Send the current region to the `nodejs-repl-process'" + (interactive "r") + (let ((proc (nodejs-repl--get-or-create-process))) + ;; Enclose the region in .editor ... EOF as this is more robust. + ;; See: https://github.com/abicky/nodejs-repl.el/issues/17 + (comint-send-string proc ".editor\n") + (comint-send-region proc start end) + (comint-send-string proc "\n") + (with-current-buffer (process-buffer proc) + (comint-send-eof)))) + +;;;###autoload +(defun nodejs-repl-send-buffer () + "Send the current buffer to the `nodejs-repl-process'" + (interactive) + (nodejs-repl-send-region (point-min) (point-max))) + +;;;###autoload +(defun nodejs-repl-load-file (file) + "Load the file to the `nodejs-repl-process'" + (interactive (list (expand-file-name (read-file-name "Load file: " nil nil 'lambda)))) + (let ((proc (nodejs-repl--get-or-create-process))) + (comint-send-string proc (format ".load %s\n" file)))) + +;;;###autoload +(defun nodejs-repl-send-last-expression () + "Send the expression before point to the `nodejs-repl-process'" + (interactive) + (nodejs-repl-send-region (save-excursion (nodejs-repl--beginning-of-expression)) + (point))) + +;;;###autoload +(defun nodejs-repl-switch-to-repl () + "If there is a `nodejs-repl-process' running switch to it, +otherwise spawn one." + (interactive) + (pop-to-buffer + (process-buffer (nodejs-repl--get-or-create-process)))) + +(defun nodejs-repl-execute (command &optional buf) + "Execute a command and output the result to the temporary buffer." + (let ((ret (nodejs-repl--send-string (concat command "\n")))) + (with-current-buffer (get-buffer-create nodejs-repl-temp-buffer-name) + (erase-buffer) + (setq ret (replace-regexp-in-string nodejs-repl-ansi-color-sequence-re "" ret)) + ;; delete inputs + (setq ret (replace-regexp-in-string "\\(\\w\\|\\W\\)+\r\r\n" "" ret)) + (setq ret (replace-regexp-in-string "\r" "" ret)) + (insert ret) + ;; delete last line (prompt) + (goto-char (point-max)) + (delete-region (point-at-bol) (point))))) + +(define-derived-mode nodejs-repl-mode comint-mode "Node.js REPL" + "Major mode for Node.js REPL" + :syntax-table nodejs-repl-mode-syntax-table + (set (make-local-variable 'font-lock-defaults) '(nil nil t)) + (add-hook 'comint-output-filter-functions 'nodejs-repl--delete-prompt nil t) + (add-hook 'comint-output-filter-functions 'nodejs-repl--remove-duplicated-prompt nil t) + (add-hook 'comint-output-filter-functions 'nodejs-repl--filter-escape-sequnces nil t) + (add-hook 'comint-output-filter-functions 'nodejs-repl--clear-cache nil t) + (setq comint-input-ignoredups nodejs-repl-input-ignoredups) + (setq comint-process-echoes nodejs-repl-process-echoes) + (add-hook 'completion-at-point-functions 'nodejs-repl--completion-at-point-function nil t) + (make-local-variable 'window-configuration-change-hook) + (add-hook 'window-configuration-change-hook 'nodejs-repl--set-prompt-deletion-required-p) + (ansi-color-for-comint-mode-on)) + +;;;###autoload +(defun nodejs-repl () + "Run Node.js REPL." + (interactive) + (let ((node-command (if (and (symbolp nodejs-repl-command) + (functionp nodejs-repl-command)) + (funcall nodejs-repl-command) + nodejs-repl-command))) + (setq nodejs-repl-prompt-re + (format nodejs-repl-prompt-re-format nodejs-repl-prompt nodejs-repl-prompt)) + (setq nodejs-repl-nodejs-version + ;; "v7.3.0" => "7.3.0", "v7.x-dev" => "7" + (replace-regexp-in-string nodejs-repl--nodejs-version-re "\\1" + (shell-command-to-string (concat node-command " --version")))) + (let* ((repl-mode (or (getenv "NODE_REPL_MODE") "magic")) + (nodejs-repl-code (format nodejs-repl-code-format + nodejs-repl-prompt nodejs-repl-use-global repl-mode))) + (pop-to-buffer + ;; Node.js 12 ignores almost all keys if TERM is "dumb" + ;; cf. https://github.com/nodejs/node/commit/d3a62fe7fc683bf74b3e9c743f73471f0167bd15 + (apply 'make-comint nodejs-repl-process-name "env" nil + `("TERM=xterm" ,node-command ,@nodejs-repl-arguments "-e" ,nodejs-repl-code))) + (nodejs-repl-mode)))) + +(provide 'nodejs-repl) +;;; nodejs-repl.el ends here diff --git a/packages/notmuch-20181021.1330.tar b/packages/notmuch-20190525.1602.tar similarity index 95% rename from packages/notmuch-20181021.1330.tar rename to packages/notmuch-20190525.1602.tar index 03e1cc1..14ebdd6 100644 Binary files a/packages/notmuch-20181021.1330.tar and b/packages/notmuch-20190525.1602.tar differ diff --git a/packages/nov-20181118.750.el b/packages/nov-20190818.2002.el similarity index 93% rename from packages/nov-20181118.750.el rename to packages/nov-20190818.2002.el index 9ea1eb2..c2e0091 100644 --- a/packages/nov-20181118.750.el +++ b/packages/nov-20190818.2002.el @@ -1,11 +1,11 @@ ;;; nov.el --- Featureful EPUB reader mode -;; Copyright (C) 2017-2018 Vasilij Schneidermann +;; Copyright (C) 2017-2019 Vasilij Schneidermann ;; Author: Vasilij Schneidermann ;; URL: https://github.com/wasamasa/nov.el -;; Package-Version: 20181118.750 -;; Version: 0.2.7 +;; Package-Version: 20190818.2002 +;; Version: 0.2.9 ;; Package-Requires: ((dash "2.12.0") (esxml "0.3.3") (emacs "24.4")) ;; Keywords: hypermedia, multimedia, epub @@ -81,7 +81,9 @@ effect in Emacs 25.1 or greater." (defcustom nov-render-html-function 'nov-render-html "Function used to render HTML. It's called without arguments with a buffer containing HTML and -should change it to contain the rendered version of it.") +should change it to contain the rendered version of it." + :type 'function + :group 'nov) (defcustom nov-pre-html-render-hook nil "Hook run before `nov-render-html'." @@ -372,6 +374,7 @@ Each alist item consists of the identifier and full path." (define-key map (kbd "g") 'nov-render-document) (define-key map (kbd "v") 'nov-view-source) (define-key map (kbd "V") 'nov-view-content-source) + (define-key map (kbd "a") 'nov-reopen-as-archive) (define-key map (kbd "m") 'nov-display-metadata) (define-key map (kbd "n") 'nov-next-document) (define-key map (kbd "]") 'nov-next-document) @@ -418,23 +421,31 @@ Each alist item consists of the identifier and full path." (setq url (url-generic-parse-url url)) (mapcar 'nov-urldecode (list (url-filename url) (url-target url)))) -(defun nov-insert-image (path) - "Insert an image for PATH at point. +(defun nov-insert-image (path alt) + "Insert an image for PATH at point, falling back to ALT. This function honors `shr-max-image-proportion' if possible." - ;; adapted from `shr-rescale-image' - (if (fboundp 'imagemagick-types) - (let ((edges (window-inside-pixel-edges - (get-buffer-window (current-buffer))))) - (insert-image - (create-image path 'imagemagick nil - :ascent 100 - :max-width (truncate (* shr-max-image-proportion - (- (nth 2 edges) - (nth 0 edges)))) - :max-height (truncate (* shr-max-image-proportion - (- (nth 3 edges) - (nth 1 edges))))))) - (insert-image (create-image path nil nil :ascent 100)))) + (cond + ((not (display-graphic-p)) + (insert alt)) + ((fboundp 'imagemagick-types) + ;; adapted from `shr-rescale-image' + (let ((edges (window-inside-pixel-edges + (get-buffer-window (current-buffer))))) + (insert-image + (create-image path 'imagemagick nil + :ascent 100 + :max-width (truncate (* shr-max-image-proportion + (- (nth 2 edges) + (nth 0 edges)))) + :max-height (truncate (* shr-max-image-proportion + (- (nth 3 edges) + (nth 1 edges)))))))) + (t + ;; `create-image' errors out for unsupported image types + (let ((image (ignore-errors (create-image path nil nil :ascent 100)))) + (if image + (insert-image image) + (insert alt)))))) (defvar nov-original-shr-tag-img-function (symbol-function 'shr-tag-img)) @@ -443,14 +454,15 @@ This function honors `shr-max-image-proportion' if possible." "Custom rendering function for DOM. Uses `shr-tag-img' for external paths and `nov-insert-image' for internal ones." - (let ((url (or url (cdr (assq 'src (cadr dom)))))) + (let ((url (or url (cdr (assq 'src (cadr dom))))) + (alt (or (cdr (assq 'alt (cadr dom))) ""))) (if (nov-external-url-p url) ;; HACK: avoid hanging in an infinite loop when using ;; `cl-letf' to override `shr-tag-img' with a function that ;; might call `shr-tag-img' again (funcall nov-original-shr-tag-img-function dom url) (setq url (expand-file-name (nov-urldecode url))) - (nov-insert-image url)))) + (nov-insert-image url alt)))) (defun nov-render-title (dom) "Custom rendering function for DOM. @@ -505,7 +517,7 @@ the HTML is rendered with `nov-render-html-function'." (cond (imagep - (nov-insert-image path)) + (nov-insert-image path "")) ((and (version< nov-epub-version "3.0") (eq id nov-toc-id)) (insert (nov-ncx-to-html path))) @@ -547,6 +559,12 @@ the HTML is rendered with `nov-render-html-function'." (interactive) (find-file nov-content-file)) +(defun nov-reopen-as-archive () + "Reopen the EPUB document using `archive-mode'." + (interactive) + (with-current-buffer (find-file-literally nov-file-name) + (archive-mode))) + (defun nov-display-metadata () "View the metadata of the EPUB document in a new buffer." (interactive) @@ -719,6 +737,7 @@ Saving is only done if `nov-save-place-file' is set." (recentf-add-file nov-file-name))) (add-hook 'nov-mode-hook 'nov-add-to-recentf) +(add-hook 'nov-mode-hook 'hack-dir-local-variables-non-file-buffer) (provide 'nov) ;;; nov.el ends here diff --git a/packages/nyan-mode-20170423.740.tar b/packages/nyan-mode-20170423.740.tar index 506382e..d4ce8e2 100644 Binary files a/packages/nyan-mode-20170423.740.tar and b/packages/nyan-mode-20170423.740.tar differ diff --git a/packages/ob-cfengine3-20180102.1812.el b/packages/ob-cfengine3-20180102.1812.el deleted file mode 100644 index 34c60af..0000000 --- a/packages/ob-cfengine3-20180102.1812.el +++ /dev/null @@ -1,105 +0,0 @@ -;;; ob-cfengine3.el --- Org Babel functions for CFEngine 3 - -;; Copyright (C) 2017 Nick Anderson - -;; Permission is hereby granted, free of charge, to any person obtaining a copy -;; of this software and associated documentation files (the "Software"), to deal -;; in the Software without restriction, including without limitation the rights -;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;; copies of the Software, and to permit persons to whom the Software is -;; furnished to do so, subject to the following conditions: -;; The above copyright notice and this permission notice shall be included in -;; all copies or substantial portions of the Software. - -;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;; THE SOFTWARE. - -;; Author: Nick Anderson <nick@cmdln.org> -;; Keywords: tools, convenience -;; Package-Version: 20180102.1812 -;; URL: https://github.com/nickanderson/ob-cfengine3 -;; Version: 0.0.2 - -;;; Commentary: -;; Execute CFEngine 3 policy inside org-mode src blocks. - -;;; Code: - -(defvar ob-cfengine3-command "cf-agent" - "Name of command to use for executing cfengine policy.") - -(defvar ob-cfengine3-command-options "" - "Option string that should be passed to the agent. -Note that --file will be appended to the options.") - -(defvar ob-cfengine3-file-control-stdlib "body file control{ inputs => { '$(sys.libdir)/stdlib.cf' };}\n" - "File control body to include the standard libriary from $(sys.libdir). -It is useful to inject into an example source block before execution.") - -(defconst ob-cfengine3-header-args-cfengine3 - '( - (no-lock . :any) - (debug . :any) - (verbose . :any) - (info . :any) - (include-stdlib . :any) - (define . :any) - (bundlesequence . :any)) - "CFEngine specific header arguments.") - -(defun org-babel-execute:cfengine3 (body params) - "Actuate a block of CFEngine 3 policy. -This function is called by `org-babel-execute-src-block'. - - A temporary file is constructed containing - `ob-cfengine3-file-control-stdlib and the BODY of the src - block. `ob-cfengine3-command' is used to execute the - temporary file." - - (let* ((temporary-file-directory ".") - (debug (cdr (assoc :debug params))) - (verbose (cdr (assoc :verbose params))) - (info (cdr (assoc :info params))) - (use-locks (cdr (assoc :use-locks params))) - (include-stdlib (not (string= "no" (cdr (assoc :include-stdlib params))))) - (define (cdr (assoc :define params))) - (bundlesequence (cdr (assoc :bundlesequence params))) - (tempfile (make-temp-file "cfengine3-"))) - (with-temp-file tempfile - (when include-stdlib (insert ob-cfengine3-file-control-stdlib)) - (insert body)) - (unwind-protect - (shell-command-to-string - (concat - ob-cfengine3-command - " " - (when bundlesequence (concat "--bundlesequence " bundlesequence )) - " " - (when define (concat "--define " define )) - " " - (unless use-locks "--no-lock ") - - ;; When info header arg is yes add --info to the command string and throw away the args - (when info (concat "--info ")) - " " - ;; When verbose header arg is yes add --verbose to the command string and throw away the args - (when verbose (concat "--verbose ")) - " " - ;; When debug header arg is yes add --debug with all log modules enabled to the command string and throw away the args - (when debug (concat "--debug --log-modules=all ")) - " " - ob-cfengine3-command-options - " " - (format " --file %s" (shell-quote-argument tempfile)))) - (delete-file tempfile)))) - -(add-to-list 'org-src-lang-modes '("cfengine3" . cfengine3)) -(add-to-list 'org-babel-tangle-lang-exts '("cfengine3" . "cf")) - -(provide 'ob-cfengine3) -;;; ob-cfengine3.el ends here diff --git a/packages/ob-cfengine3-20190520.1929.el b/packages/ob-cfengine3-20190520.1929.el new file mode 100644 index 0000000..0cafa47 --- /dev/null +++ b/packages/ob-cfengine3-20190520.1929.el @@ -0,0 +1,191 @@ +;;; ob-cfengine3.el --- Org Babel functions for CFEngine 3 + +;; Copyright (C) 2017 Nick Anderson + +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the "Software"), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. + +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +;; THE SOFTWARE. + +;; Author: Nick Anderson <nick@cmdln.org> +;; Keywords: tools, convenience +;; Package-Version: 20190520.1929 +;; URL: https://github.com/nickanderson/ob-cfengine3 +;; Version: 0.0.6 + +;;; Commentary: +;; Execute CFEngine 3 policy inside org-mode src blocks. + +;;; Code: + +(defvar ob-cfengine3-command "cf-agent" + "Name of command to use for executing cfengine policy.") + +(defvar ob-cfengine3-command-options nil + "Option string that should be passed to the agent. +Note that --file will be appended to the options.") + +(defvar ob-cfengine3-file-control-stdlib "body file control{ inputs => { '$(sys.libdir)/stdlib.cf' };}\n" + "File control body to include the standard libriary from $(sys.libdir). +It is useful to inject into an example source block before execution.") + +(defvar ob-cfengine3-wrap-with-main-template "bundle agent __main__\n{\n%s\n}\n" + "Template to use to wrap the contents of the source block in a + 'main' bundle. Must contain exactly one '%s', where the body + will be inserted.") + +(defconst ob-cfengine3-header-args-cfengine3 + '( + (debug . :any) + (info . :any) + (verbose . :any) + (use-locks . :any) + (include-stdlib . :any) + (define . :any) + (bundlesequence . :any) + (log-level . :any) + (command . :any) + (command-in-result . :any) + (command-in-result-command . :any) + (command-in-result-prompt . :any) + (command-in-result-filename . :any) + (run-with-main . :any)) + "CFEngine specific header arguments.") + +(defun ob-cfengine3-header-arg (pname params) + "Returns the value of header argument PNAME, extracted from PARAMS." + (cdr (assoc pname params))) + +(defun ob-cfengine3-bool (str) + "Convert string to boolean. Strings `yes', `YES', `true', +`TRUE' and `t' are considered true, anything else is false." + (or (string-equal str "yes") + (string-equal str "true") + (string-equal str "t") + (string-equal str "YES") + (string-equal str "TRUE"))) + +(defun ob-cfengine3-bool-arg (pname params) + "Returns the boolean value of header argument PNAME, extracted from PARAMS." + (ob-cfengine3-bool (ob-cfengine3-header-arg pname params))) + +(defun ob-cfengine3-tangle-file (&optional tangle-value) + "Return the filename to use for tangling a CFEngine code block. + +TANGLE-VALUE must be the value of the `:tangle' header +argument. If `\"yes\"', returns the basename of the current +buffer with the `.cf' extension. If `\"no\"' or `nil', returns +`nil'. If any other string, it is returned as-is." + (cond + ((string= "yes" tangle-value) + (concat (file-name-sans-extension (buffer-file-name)) "." + (cdr (assoc "cfengine3" org-babel-tangle-lang-exts)))) + ((or (null tangle-value) (string= "no" tangle-value)) nil) + ((> (length tangle-value) 0) tangle-value))) + +(defun org-babel-execute:cfengine3 (body params) + "Actuate a block of CFEngine 3 policy. +This function is called by `org-babel-execute-src-block'. + + A temporary file is constructed containing + `ob-cfengine3-file-control-stdlib and the BODY of the src + block. `ob-cfengine3-command' is used to execute the + temporary file." + (let* ((temporary-file-directory ".") + (debug (ob-cfengine3-bool-arg :debug params)) + (info (ob-cfengine3-bool-arg :info params)) + (verbose (ob-cfengine3-bool-arg :verbose params)) + (use-locks (ob-cfengine3-bool-arg :use-locks params)) + (include-stdlib (ob-cfengine3-bool (or (ob-cfengine3-header-arg :include-stdlib params) "yes"))) + (define (ob-cfengine3-header-arg :define params)) + (bundlesequence (ob-cfengine3-header-arg :bundlesequence params)) + (log-level (ob-cfengine3-header-arg :log-level params)) + (command (or (ob-cfengine3-header-arg :command params) ob-cfengine3-command)) + (command-in-result (ob-cfengine3-bool-arg :command-in-result params)) + (command-in-result-command (or (ob-cfengine3-header-arg :command-in-result-command params) command)) + (command-in-result-prompt (or (ob-cfengine3-header-arg :command-in-result-prompt params) "# ")) + (tempfile-dir (or (ob-cfengine3-header-arg :tmpdir params) ".")) + (tempfile (make-temp-file (concat tempfile-dir "/cfengine3-"))) + (command-in-result-filename (or (ob-cfengine3-header-arg :command-in-result-filename params) (ob-cfengine3-tangle-file (ob-cfengine3-header-arg :tangle params)) tempfile)) + (auto-main (ob-cfengine3-bool-arg :auto-main params)) + (run-with-main (or (ob-cfengine3-bool-arg :run-with-main params) auto-main))) + (with-temp-file tempfile + (when include-stdlib (insert ob-cfengine3-file-control-stdlib)) + (if run-with-main + (insert (format ob-cfengine3-wrap-with-main-template body)) + (insert body))) + (unwind-protect + (let ((command-args + (concat + (when bundlesequence (concat "--bundlesequence " bundlesequence " ")) + (when define (concat "--define " define " ")) + (unless use-locks "--no-lock ") + (when info "--inform ") + (when verbose "--verbose ") + ;; When debug header arg is given, add --debug with + ;; all log modules enabled to the command string and + ;; throw away the args + (when debug (concat "--debug --log-modules=all ")) + (when log-level (concat "--log-level " log-level " ")) + (when ob-cfengine3-command-options (concat ob-cfengine3-command-options " "))))) + (concat + ;; When the :command-in-result header arg is specified, + ;; include the command line in the output. The prompt, + ;; command and filename to use (instead of the real ones) + ;; can be specified with the :command-in-result-prompt, + ;; :command-in-result-command and + ;; :command-in-result-filename args. + (when command-in-result + (concat command-in-result-prompt + command-in-result-command " " + command-args + (format "--file %s" (shell-quote-argument command-in-result-filename)) + "\n")) + ;; Execute command and return output + (shell-command-to-string + (concat command " " + command-args + (format "--file %s" (shell-quote-argument tempfile)))))) + (delete-file tempfile)))) + +(add-to-list 'org-src-lang-modes '("cfengine3" . cfengine3)) +(add-to-list 'org-babel-tangle-lang-exts '("cfengine3" . "cf")) + +(setq org-babel-default-header-args:cfengine3 + '((:exports . "both") + ;; I don't know how to make it use the identity format directly + ;;(:tangle-mode . 384) ;; (identity #o600) The standard default + (:tangle-mode . 448) ;; (identity #o700) Since we write the shebang, lets see how useful execution bit is + (:shebang . "#!/var/cfengine/bin/cf-agent -f-") + ;; By default, includ the standard library for exported files. To disable this set the :prologue header arg + (:prologue . "body file control\n{\n inputs => { '$(sys.libdir)/stdlib.cf' };\n}\n") + (:results . "output"))) + +(defun org-babel-expand-body:cfengine3 (body params) + "Expand a block of CFEngine 3 policy before tangling. +This function is called by `org-babel-tangle-single-block'. + + If the `:tangle-with-main'' or `:auto-main' header arguments + are `yes', `true' or `t', the BODY is formatted according to + the template in `ob-cfengine3-wrap-with-main-template`, + otherwise it is returned as-is." + (let* ((auto-main (ob-cfengine3-bool-arg :auto-main params)) + (tangle-with-main (or (ob-cfengine3-bool-arg :tangle-with-main params) auto-main))) + (if tangle-with-main + (format ob-cfengine3-wrap-with-main-template body) + body))) + +(provide 'ob-cfengine3) +;;; ob-cfengine3.el ends here diff --git a/packages/ob-crystal-20180126.718.tar b/packages/ob-crystal-20180126.718.tar index eedff7f..2248196 100644 Binary files a/packages/ob-crystal-20180126.718.tar and b/packages/ob-crystal-20180126.718.tar differ diff --git a/packages/ob-http-20180707.1448.tar b/packages/ob-http-20180707.1448.tar index 2075614..ef27932 100644 Binary files a/packages/ob-http-20180707.1448.tar and b/packages/ob-http-20180707.1448.tar differ diff --git a/packages/ob-hy-20180702.540.tar b/packages/ob-hy-20180702.540.tar index 74cb40e..8b6b100 100644 Binary files a/packages/ob-hy-20180702.540.tar and b/packages/ob-hy-20180702.540.tar differ diff --git a/packages/ob-ipython-20180224.953.tar b/packages/ob-ipython-20180224.953.tar index d9ac4b4..88dc7c9 100644 Binary files a/packages/ob-ipython-20180224.953.tar and b/packages/ob-ipython-20180224.953.tar differ diff --git a/packages/ob-restclient-20180904.709.el b/packages/ob-restclient-20190626.1824.el similarity index 78% rename from packages/ob-restclient-20180904.709.el rename to packages/ob-restclient-20190626.1824.el index 7894cde..6da01eb 100644 --- a/packages/ob-restclient-20180904.709.el +++ b/packages/ob-restclient-20190626.1824.el @@ -4,8 +4,8 @@ ;; Author: Alf LervÃ¥g ;; Keywords: literate programming, reproducible research -;; Package-Version: 20180904.709 -;; Homepage: http://orgmode.org +;; Package-Version: 20190626.1824 +;; Homepage: https://github.com/alf/ob-restclient.el ;; Version: 0.02 ;; Package-Requires: ((restclient "0")) @@ -78,7 +78,9 @@ This function is called by `org-babel-execute-src-block'" (when (search-forward (buffer-name) nil t) (error "Restclient encountered an error")) - (org-babel-restclient-wrap-result)))) + (if (org-babel-restclient-return-pure-payload-result-p params) + (org-babel-restclient-pure-payload-result) + (org-babel-restclient-wrap-result))))) (defun org-babel-restclient-wrap-result () "Wrap the contents of the buffer in an `org-mode' src block." @@ -88,5 +90,20 @@ This function is called by `org-babel-execute-src-block'" (insert "#+END_SRC\n") (buffer-string))) +(defun org-babel-restclient-pure-payload-result () + "Just return the payload." + (let ((comments-start + (save-excursion + (while (not (looking-at "//")) + (forward-line)) + (point)))) + (buffer-substring (point-min) comments-start))) + +(defun org-babel-restclient-return-pure-payload-result-p (params) + "Return `t' if the `:results' key in PARAMS contains `value' or `table'." + (let ((result-type (cdr (assoc :results params)))) + (when result-type + (string-match "value\\|table" result-type)))) + (provide 'ob-restclient) ;;; ob-restclient.el ends here diff --git a/packages/ocp-indent-20180417.1549.el b/packages/ocp-indent-20190726.1452.el similarity index 97% rename from packages/ocp-indent-20180417.1549.el rename to packages/ocp-indent-20190726.1452.el index 1b80ed6..58ce5b3 100644 --- a/packages/ocp-indent-20180417.1549.el +++ b/packages/ocp-indent-20190726.1452.el @@ -3,7 +3,7 @@ ;; Copyright 2012-2013 OCamlPro ;; Keywords: ocaml languages -;; Package-Version: 20180417.1549 +;; Package-Version: 20190726.1452 ;; URL: http://www.typerex.org/ocp-indent.html ;; All rights reserved.This file is distributed under the terms of the @@ -111,8 +111,7 @@ buffer." (let* ((start-line (line-number-at-pos start)) (end-line (line-number-at-pos end)) - (errfile (expand-file-name (make-temp-name "ocp-indent-error") - temporary-file-directory)) + (errfile (make-temp-name (concat temporary-file-directory "ocp-indent-error"))) (indents-str (with-output-to-string (ocp-indent--with-untabify diff --git a/packages/omnisharp-20181023.505.tar b/packages/omnisharp-20190809.341.tar similarity index 90% rename from packages/omnisharp-20181023.505.tar rename to packages/omnisharp-20190809.341.tar index c1f67c7..2724cb3 100644 Binary files a/packages/omnisharp-20181023.505.tar and b/packages/omnisharp-20190809.341.tar differ diff --git a/packages/omtose-phellack-theme-20161111.2120.tar b/packages/omtose-phellack-theme-20161111.2120.tar index 7521dae..e9cd2dd 100644 Binary files a/packages/omtose-phellack-theme-20161111.2120.tar and b/packages/omtose-phellack-theme-20161111.2120.tar differ diff --git a/packages/opencl-mode-20170816.1249.el b/packages/opencl-mode-20190615.1957.el similarity index 97% rename from packages/opencl-mode-20170816.1249.el rename to packages/opencl-mode-20190615.1957.el index 775d7f4..90dcf2b 100644 --- a/packages/opencl-mode-20170816.1249.el +++ b/packages/opencl-mode-20190615.1957.el @@ -4,7 +4,7 @@ ;; ;; Author: Salmane Bah <salmane.bah@u-bordeaux.fr> ;; Keywords: c, opencl -;; Package-Version: 20170816.1249 +;; Package-Version: 20190615.1957 ;; URL: https://github.com/salmanebah/opencl-mode ;; Version: 1.0 @@ -108,7 +108,7 @@ (region-end)) (thing-at-point 'symbol))) (doc-url (concat - "http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/" + "http://www.khronos.org/registry/cl/sdk/2.1/docs/man/xhtml/" api-function ".html"))) (browse-url doc-url))) diff --git a/packages/org-20181112.tar b/packages/org-20190819.tar similarity index 85% rename from packages/org-20181112.tar rename to packages/org-20190819.tar index 43c70cd..d5f240a 100644 Binary files a/packages/org-20181112.tar and b/packages/org-20190819.tar differ diff --git a/packages/org-brain-20181114.2246.el b/packages/org-brain-20190813.1155.el similarity index 57% rename from packages/org-brain-20181114.2246.el rename to packages/org-brain-20190813.1155.el index 75c5bd8..56c8a0e 100644 --- a/packages/org-brain-20181114.2246.el +++ b/packages/org-brain-20190813.1155.el @@ -1,14 +1,14 @@ ;;; org-brain.el --- Org-mode concept mapping -*- lexical-binding: t; -*- -;; Copyright (C) 2017--2018 Erik Sjöstrand +;; Copyright (C) 2017--2019 Erik Sjöstrand ;; MIT License ;; Author: Erik Sjöstrand <sjostrand.erik@gmail.com> ;; URL: http://github.com/Kungsgeten/org-brain -;; Package-Version: 20181114.2246 +;; Package-Version: 20190813.1155 ;; Keywords: outlines hypermedia -;; Package-Requires: ((emacs "25") (org "9")) -;; Version: 0.5 +;; Package-Requires: ((emacs "25") (org "9.2")) +;; Version: 0.7 ;;; Commentary: @@ -41,6 +41,8 @@ :prefix "org-brain-" :group 'org) +;;;; Custom vars + (defcustom org-brain-path (expand-file-name "brain" org-directory) "The root directory of your org-brain. @@ -49,6 +51,11 @@ will be considered org-brain entries." :group 'org-brain :type '(directory)) +(defcustom org-brain-scan-directories-recursively t + "If subdirectories inside `org-brain-path' are considered part of the brain or not." + :group 'org-brain + :type '(boolean)) + (defcustom org-brain-files-extension "org" "The extension for entry files in `org-brain-path'." :group 'org-brain @@ -59,6 +66,10 @@ will be considered org-brain entries." :group 'org-brain :type '(repeat string)) +(make-obsolete-variable 'org-brain-suggest-stored-link-as-resource + "org-brain-suggest-stored-link-as-resource isn't needed because of `org-insert-link-global'." + "0.6") + (defcustom org-brain-data-file (expand-file-name ".org-brain-data.el" org-brain-path) "Where org-brain data is saved." :group 'org-brain @@ -87,6 +98,16 @@ If 'root, only choose from file entries in `org-brain-path' (non-recursive)." :group 'org-brain :type '(boolean)) +(defcustom org-brain-show-history t + "Should the navigation history be shown in `org-brain-visualize'?" + :group 'org-brain + :type '(boolean)) + +(defcustom org-brain-quit-after-goto nil + "Should the *org-brain* buffer window close itself after executing a goto command?" + :group 'org-brain + :type '(boolean)) + (defcustom org-brain-headline-links-only-show-visible t "Only show visible parts (descriptions) of headline links. @@ -102,38 +123,12 @@ filenames will be shown instead, which is faster." :group 'org-brain :type '(boolean)) -(defface org-brain-title - '((t . (:inherit 'org-level-1))) - "Face for the currently selected entry.") - -(defface org-brain-wires - `((t . (:inherit 'font-lock-comment-face :italic nil))) - "Face for the wires connecting entries.") - -(defface org-brain-button - '((t . (:inherit button))) - "Face for buttons in the org-brain visualize buffer.") - -(defface org-brain-parent - '((t . (:inherit (font-lock-builtin-face org-brain-button)))) - "Face for the entries' parent nodes.") - -(defface org-brain-child - '((t . (:inherit org-brain-button))) - "Face for the entries' child nodes.") - -(defface org-brain-sibling - '((t . (:inherit org-brain-child))) - "Face for the entries' sibling nodes.") - -(defface org-brain-friend - '((t . (:inherit org-brain-button))) - "Face for the entries' friend nodes.") - -(defface org-brain-pinned - '((t . (:inherit org-brain-button))) - "Face for pinned entries.") - +(defcustom org-brain-headline-entry-name-format-string "%s::%s" + "How headline entries are represented when choosing entries. +This `format' string is used in `org-brain-entry-name' for headline entries. +`format' gets two objects: the file and the headline." + :group 'org-brain + :type '(string)) (defcustom org-brain-visualize-text-hook nil "Hook runs after inserting `org-brain-text' in `org-brain-visualize'. @@ -188,6 +183,11 @@ Only applies to headline entries." :group 'org-brain :type '(string)) +(defcustom org-brain-exclude-siblings-tag "nosiblings" + "`org-mode' tag which prevents the siblings of children of this node from being displayed." + :group 'org-brain + :type '(string)) + (defcustom org-brain-wander-interval 3 "Seconds between randomized entries, when using `org-brain-visualize-wander'." :group 'org-brain @@ -200,7 +200,7 @@ If 0 or a negative value, the title won't be capped." :type 'integer) (defcustom org-brain-cap-mind-map-titles nil - "Whether to cap entries longer than org-brain-title-max-length in mind map visualization mode" + "Whether to cap entries longer than org-brain-title-max-length in mind map visualization mode." :group 'org-brain :type '(boolean)) @@ -210,11 +210,21 @@ Doing so allows for adding multiple entries at once." :group 'org-brain :type '(string)) -(defcustom org-brain-visualize-one-child-per-line nil - "If non-nil, each child of the visualized entry is listed on its own line. -If nil (default), children are filled up to the `fill-column'." +(make-obsolete-variable + 'org-brain-visualize-one-child-per-line + "Setting `org-brain-child-linebreak-sexp' to 0 visualizes one child per line." + "0.7") + +(defcustom org-brain-child-linebreak-sexp 'fill-column + "Where to break lines when visualizing children? +Reasonable values include: + +'0: every child will be on its own line +'fill-column: lines will break at `fill-column' +'(window-width): lines will break at the width of the window +'most-positive-fixnum: All children will be on one line" :group 'org-brain - :type '(boolean)) + :type '(sexp)) (defcustom org-brain-refile-max-level 1 "The default max-level used by `org-brain-refile'." @@ -242,24 +252,118 @@ Insert links using `org-insert-link'." :group 'org-brain :type '(string)) -;;;###autoload -(defun org-brain-update-id-locations () - "Scan `org-brain-files' using `org-id-update-id-locations'." - (interactive) - (org-id-update-id-locations (org-brain-files))) +;;;;; Faces and face helper functions -;;;###autoload -(defun org-brain-switch-brain (directory) - "Choose another DIRECTORY to be your `org-brain-path'." - (interactive "D") - (setq org-brain-path directory) - (setq org-brain-data-file (expand-file-name ".org-brain-data.el" org-brain-path)) - (setq org-brain-pins nil) - (load org-brain-data-file t) - (org-brain-update-id-locations) - (message "Switched org-brain to %s" directory)) +(defface org-brain-title + '((t . (:inherit 'org-level-1))) + "Face for the currently selected entry.") -;;* API +(defface org-brain-wires + `((t . (:inherit 'font-lock-comment-face :italic nil))) + "Face for the wires connecting entries.") + +(defface org-brain-button + '((t . (:inherit button))) + "Face for header-entry buttons in the org-brain visualize buffer. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-parent + '((t . (:inherit (font-lock-builtin-face org-brain-button)))) + "Face for the entries' linked header-entry parent nodes. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-local-parent + '((t . (:inherit org-brain-parent :weight bold))) + "Face for the entries' local header-entry parent nodes. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-child + '((t . (:inherit org-brain-button))) + "Face for the entries' linked header-entry child nodes. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-local-child + '((t . (:inherit org-brain-child :weight bold))) + "Face for the entries' local header-entry child nodes. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-sibling + '((t . (:inherit org-brain-child))) + "Face for the entries' header-entry sibling nodes. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-local-sibling + '((t . (:inherit org-brain-sibling :weight bold))) + "Face for the entries' local header-entry sibling nodes. +An entry is a local sibling of another entry if they share a local parent. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-friend + '((t . (:inherit org-brain-button))) + "Face for the entries' header-entry friend nodes. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-pinned + '((t . (:inherit org-brain-button))) + + "Face for pinned header entries. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-selected-list + '((t . (:inherit org-brain-pinned))) + "Face for header entries in the selection list. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-history-list + '((t . (:inherit org-brain-pinned))) + "Face for header entries in the history list. +File entries also use this, but also applies `org-brain-file-face-template'.") + +(defface org-brain-file-face-template + '((t . (:slant italic))) + "Attributes of this face are added to file-entry faces.") + +(defface org-brain-edge-annotation-face-template + '((t . (:box t))) + "Attributes of this face are added to links which have an edge annotation +to the visualized entry.") + +;; This needs to be here or defface complains that it is undefined. +(defun org-brain-specified-face-attrs (face &optional frame) + "Return a plist of all face attributes of FACE that are not `unspecified'. +If FRAME is not specified, `selected-frame' is used." + (cl-labels ((alist->plist (alist) + (pcase alist + ('nil nil) + (`((,h1 . ,h2) . ,tail) `(,h1 . (,h2 . ,(alist->plist tail))))))) + (alist->plist (seq-filter + (lambda (f) (not (equal (cdr f) 'unspecified))) + (face-all-attributes face (or frame (selected-frame))))))) + +(defun org-brain-display-face (entry &optional face edge) + "Return the final display face for ENTRY. +Takes FACE as a starting face, or `org-brain-button' if FACE is not specified. +Applies the attributes in `org-brain-edge-annotation-face-template', +`org-brain-selected-face-template', and `org-brain-file-face-template' +as appropriate. +EDGE determines if `org-brain-edge-annotation-face-template' should be used." + (let ((selected-face-attrs + (when (member entry org-brain-selected) + (org-brain-specified-face-attrs 'org-brain-selected-face-template))) + (file-face-attrs + (when (org-brain-filep entry) + (org-brain-specified-face-attrs 'org-brain-file-face-template)))) + (append (list :inherit (or face 'org-brain-button)) + selected-face-attrs + file-face-attrs + (when edge + (org-brain-specified-face-attrs 'org-brain-edge-annotation-face-template))))) + +(defface org-brain-selected-face-template + `((t . ,(org-brain-specified-face-attrs 'highlight))) + "Attributes of this face are added to the faces of selected entries.") + +;;;; API ;; An entry is either a string or a list of three strings. ;; If a string, then the entry is a file. @@ -269,6 +373,9 @@ Insert links using `org-insert-link'." (defvar org-brain--vis-entry nil "The last entry argument to `org-brain-visualize'.") +(defvar org-brain--vis-entry-keywords nil + "The `org-brain-keywords' of `org-brain--vis-entry'.") + (defvar org-brain--vis-history nil "History previously visualized entries. Newest first.") @@ -277,6 +384,36 @@ Insert links using `org-insert-link'." (defvar org-brain-pins nil "List of pinned org-brain entries.") +(defvar org-brain-selected nil "List of selected org-brain entries.") + +;;;###autoload +(defun org-brain-update-id-locations () + "Scan `org-brain-files' using `org-id-update-id-locations'." + (interactive) + (org-id-update-id-locations (org-brain-files))) + +;;;###autoload +(defun org-brain-switch-brain (directory) + "Choose another DIRECTORY to be your `org-brain-path'." + (interactive "D") + (if (file-equal-p directory org-brain-path) + (message "Current brain already is %s, no switch" directory) + (setq org-brain-path directory) + (setq org-brain-data-file (expand-file-name ".org-brain-data.el" org-brain-path)) + (unless (file-exists-p org-brain-data-file) + (org-brain-save-data)) + (setq org-brain-pins nil) + (setq org-brain--vis-history nil) + (load org-brain-data-file t) + (org-brain-update-id-locations) + (message "Switched org-brain to %s" directory))) + +(defun org-brain-maybe-switch-brain () + "Switch brain to `default-directory' if a file named \".org-brain-data.el\" exists there." + (when (and (not (file-equal-p default-directory org-brain-path)) + (file-exists-p (expand-file-name ".org-brain-data.el" default-directory))) + (org-brain-switch-brain default-directory))) + (defun org-brain-filep (entry) "Return t if the ENTRY is a (potential) brain file." (stringp entry)) @@ -288,11 +425,11 @@ Insert links using `org-insert-link'." (defun org-brain-entry-at-point-excludedp () "Return t if the entry at point is tagged as being excluded from org-brain." - (let ((tags (org-get-tags-at))) + (let ((tags (org-get-tags))) (or (member org-brain-exclude-tree-tag tags) (and (member org-brain-exclude-children-tag tags) (not (member org-brain-exclude-children-tag - (org-get-tags-at nil t))))))) + (org-get-tags nil t))))))) (defun org-brain-save-data () "Save data to `org-brain-data-file'." @@ -341,8 +478,11 @@ Ignores \"dotfiles\"." (make-directory org-brain-path t) (if relative (mapcar #'org-brain-path-entry-name (org-brain-files)) - (directory-files-recursively - org-brain-path (format "^[^.].*\\.%s$" org-brain-files-extension)))) + (if org-brain-scan-directories-recursively + (directory-files-recursively + org-brain-path (format "^[^.].*\\.%s$" org-brain-files-extension)) + (directory-files + org-brain-path t (format "^[^.].*\\.%s$" org-brain-files-extension))))) (defun org-brain-replace-links-with-visible-parts (raw-str) "Get RAW-STR with its links replaced by their descriptions." @@ -379,19 +519,28 @@ visibility rendering/formatting in-buffer." (org-brain-replace-links-with-visible-parts (org-entry-get pom "ITEM")) (org-entry-get pom "ITEM")))) -(defun org-brain--headline-entry-at-point () - "Get headline entry at point." +(defun org-brain--name-and-id-at-point () + "Get name and id of headline entry at point. +Respect excluded entries." (unless (org-brain-entry-at-point-excludedp) (when-let ((id (org-entry-get (point) "ID"))) - (list - (org-brain-path-entry-name (buffer-file-name)) - (org-brain-headline-at (point)) - id)))) + (list (org-brain-headline-at (point)) id)))) (defun org-brain-headline-entries () "Get all org-brain headline entries." - (remove nil (org-map-entries #'org-brain--headline-entry-at-point - nil (org-brain-files)))) + (with-temp-buffer + (delay-mode-hooks + (org-mode) + (remove nil + (mapcan + (lambda (file) + (insert-file-contents file nil nil nil 'replace) + (let ((file-entry (org-brain-path-entry-name file))) + (mapcar (lambda (entry) + (cons file-entry entry)) + (remove nil (org-map-entries + #'org-brain--name-and-id-at-point))))) + (org-brain-files)))))) (defun org-brain-entry-from-id (id) "Get entry from ID." @@ -429,13 +578,12 @@ In `org-brain-visualize' just return `org-brain--vis-entry'." (defun org-brain-entry-name (entry) "Get name string of ENTRY." - (if org-brain-file-entries-use-title - (if (org-brain-filep entry) + (if (org-brain-filep entry) + (if org-brain-file-entries-use-title (concat (file-name-directory entry) (org-brain-title entry)) - (concat (org-brain-entry-name (car entry)) "::" (cadr entry))) - (if (org-brain-filep entry) - entry - (concat (car entry) "::" (cadr entry))))) + entry) + (format org-brain-headline-entry-name-format-string + (org-brain-entry-name (car entry)) (cadr entry)))) (defun org-brain-entry-data (entry) "Run `org-element-parse-buffer' on ENTRY text. @@ -444,32 +592,39 @@ Isn't recursive, so do not parse local children." (insert (org-brain-text entry t)) (org-element-parse-buffer))) -(defun org-brain-description (entry) - "Get description of ENTRY. -Descriptions are written like this: - -#+BEGIN_description -This is a description. -#+END_description" - (org-element-map (org-brain-entry-data entry) 'special-block - (lambda (s-block) - (when (string-equal (org-element-property :type s-block) "description") - (org-element-interpret-data (org-element-contents s-block)))) - nil t t)) +(defun org-brain--file-targets (file) + "Return alist of (name . entry-id) for all entries (including the file) in FILE." + (let* ((file-relative (org-brain-path-entry-name file)) + (file-entry-name (org-brain-entry-name file-relative))) + (append (list (cons file-entry-name file-relative)) + (with-temp-buffer + (insert-file-contents file) + (delay-mode-hooks + (org-mode) + (mapcar (lambda (entry) + (cons (format org-brain-headline-entry-name-format-string + file-entry-name (car entry)) + (cadr entry))) + (remove nil (org-map-entries + #'org-brain--name-and-id-at-point)))))))) (defun org-brain-choose-entries (prompt entries &optional predicate require-match initial-input) "PROMPT for one or more ENTRIES, separated by `org-brain-entry-separator'. +ENTRIES can be a list, or 'all which lists all headline and file entries. Return the prompted entries in a list. Very similar to `org-brain-choose-entry', but can return several entries. For PREDICATE, REQUIRE-MATCH and INITIAL-INPUT, see `completing-read'." (unless org-id-locations (org-id-locations-load)) - (let* ((targets (mapcar (lambda (x) - (cons (org-brain-entry-name x) - (if (org-brain-filep x) - x - (nth 2 x)))) - entries)) + (let* ((targets (if (eq entries 'all) + (mapcan #'org-brain--file-targets + (org-brain-files)) + (mapcar (lambda (x) + (cons (org-brain-entry-name x) + (if (org-brain-filep x) + x + (nth 2 x)))) + entries))) (choices (completing-read prompt targets predicate require-match initial-input))) (mapcar (lambda (title) @@ -488,11 +643,12 @@ For PREDICATE, REQUIRE-MATCH and INITIAL-INPUT, see `completing-read'." (write-region "" nil entry-path)) (if (equal (length id) 2) ;; Create new headline entry in file - (with-current-buffer (find-file-noselect entry-path) + (org-with-point-at (org-brain-entry-marker entry-file) (goto-char (point-max)) (insert (concat "\n* " (cadr id))) (let ((new-id (org-id-get-create))) (run-hooks 'org-brain-new-entry-hook) + (save-buffer) (list entry-file (cadr id) new-id))) entry-file)))))) (if org-brain-entry-separator @@ -501,6 +657,7 @@ For PREDICATE, REQUIRE-MATCH and INITIAL-INPUT, see `completing-read'." (defun org-brain-choose-entry (prompt entries &optional predicate require-match initial-input) "PROMPT for an entry from ENTRIES and return it. +ENTRIES can be 'all, which lists all headline and file entries. For PREDICATE, REQUIRE-MATCH and INITIAL-INPUT, see `completing-read'." (let ((org-brain-entry-separator nil)) (car (org-brain-choose-entries prompt entries predicate require-match initial-input)))) @@ -516,15 +673,30 @@ For PREDICATE, REQUIRE-MATCH and INITIAL-INPUT, see `completing-read'." (org-element-property :value kw))))) (error "Only file entries have keywords"))) +(defun org-brain--file-tags (file-entry) + "Get tags of FILE-ENTRY." + (ignore-errors + (split-string + (cdr (assoc "FILETAGS" (org-brain-keywords file-entry))) ":" t))) + +(defun org-brain--missing-id-error (entry) + "Error message to be shown if id of ENTRY isn't found by `org-id-find'." + (error "Couldn't find entry %s, try running org-brain-update-id-locations. " + (org-brain-entry-name entry))) + (defun org-brain-entry-marker (entry) "Get marker to ENTRY." (if (org-brain-filep entry) (let ((path (org-brain-entry-path entry))) (if (file-exists-p path) - (set-marker (make-marker) 0 (find-file-noselect path)) + (set-marker (make-marker) 0 + (or (org-find-base-buffer-visiting path) + (find-file-noselect path))) ;; If file doesn't exists, it is probably an id - (org-id-find entry t))) - (org-id-find (nth 2 entry) t))) + (or (org-id-find entry t) + (org-brain--missing-id-error entry)))) + (or (org-id-find (nth 2 entry) t) + (org-brain--missing-id-error entry)))) (defun org-brain-title (entry &optional capped) "Get title of ENTRY. If CAPPED is t, max length is `org-brain-title-max-length'." @@ -546,39 +718,37 @@ ignore `org-brain-exclude-children-tag' and ((entry-text (if (org-brain-filep entry) ;; File entry - (with-temp-buffer - (ignore-errors (insert-file-contents (org-brain-entry-path entry))) - (if (and (not all-data) - (let ((filetags (ignore-errors - (split-string - (cdr (assoc "FILETAGS" - (org-brain-keywords entry))) - ":" t)))) - (or (member org-brain-show-children-tag filetags) - (member org-brain-exclude-children-tag filetags)))) - ;; Get entire buffer + (let ((keyword-regex "^#\\+[a-zA-Z_]+:")) + (with-temp-buffer + (ignore-errors (insert-file-contents (org-brain-entry-path entry))) + (if (and (not all-data) + (let ((filetags (org-brain--file-tags entry))) + (or (member org-brain-show-children-tag filetags) + (member org-brain-exclude-children-tag filetags)))) + ;; Get entire buffer + (buffer-substring-no-properties + (or (save-excursion + (when (re-search-backward keyword-regex nil t) + (end-of-line) + (point))) + (point-min)) + (point-max)) + ;; Get text up to first heading + (goto-char (point-min)) + (or (looking-at-p org-heading-regexp) + (outline-next-heading) + (goto-char (point-max))) (buffer-substring-no-properties - (or (save-excursion - (when (re-search-backward "^[#:*]" nil t) - (end-of-line) - (point))) + (or (unless all-data + (save-excursion + (when (re-search-backward keyword-regex nil t) + (end-of-line) + (point)))) (point-min)) - (point-max)) - ;; Get text up to first heading - (goto-char (point-min)) - (or (outline-next-heading) - (goto-char (point-max))) - (buffer-substring-no-properties - (or (unless all-data - (save-excursion - (when (re-search-backward "^[#:*]" nil t) - (end-of-line) - (point)))) - (point-min)) - (point)))) + (point))))) ;; Headline entry (org-with-point-at (org-brain-entry-marker entry) - (let ((tags (org-get-tags-at nil t))) + (let ((tags (org-get-tags nil t))) (unless (and (member org-brain-exclude-text-tag tags) (not all-data)) (unless all-data @@ -613,6 +783,19 @@ Often you want the siblings too, then use `org-brain-siblings' instead." (append (org-brain--linked-property-entries entry "BRAIN_CHILDREN") (org-brain--local-children entry)))) +(defun org-brain-descendants (entry) + "Get all entries which descend from ENTRY. +In other words get all the children, grand children, grand-grand children, etc. +The ENTRY itself is also included in the returned list." + (let ((checked nil)) + (cl-labels ((collect-descendants + (e) + (unless (member e checked) + (push e checked) + (mapc #'collect-descendants (org-brain-children e))))) + (collect-descendants entry) + checked))) + (defun org-brain-siblings (entry) "Get siblings of ENTRY. Return an alist where key = parent, value = siblings from that parent." @@ -644,7 +827,7 @@ The car is the raw-link and the cdr is the description." links ;; Headline entry (org-with-point-at (org-brain-entry-marker entry) - (unless (member org-brain-exclude-resouces-tag (org-get-tags-at nil t)) + (unless (member org-brain-exclude-resouces-tag (org-get-tags nil t)) (append links ;; Attachments (when-let ((attach-dir (org-attach-dir))) @@ -655,6 +838,30 @@ The car is the raw-link and the cdr is the description." attachment)) (org-attach-file-list attach-dir))))))))) +(defun org-brain--choose-resource (entries) + "Use `completing-read' to get link to a resource from ENTRIES." + (let ((resources (mapcan + (lambda (entry) + (mapcar (lambda (x) + (cons (or (cdr x) (car x)) (car x))) + (org-brain-resources entry))) + entries))) + (if (equal (length resources) 1) + (cdar resources) + (cdr (assoc (completing-read "Resource: " resources nil t) resources))))) + +;;;###autoload +(defun org-brain-open-resource (entry) + "Choose and open a resource from ENTRY. +If run with `\\[universal-argument]' then also choose from descendants of ENTRY. +Uses `org-brain-entry-at-pt' for ENTRY, or asks for it if none at point." + (interactive (list (or (ignore-errors (org-brain-entry-at-pt)) + (org-brain-choose-entry "Resource from: " 'all)))) + (org-open-link-from-string (org-brain--choose-resource + (if current-prefix-arg + (org-brain-descendants entry) + (list entry))))) + (defun org-brain--local-parent (entry) "Get file local parent of ENTRY, as a list." (if-let ((parent @@ -726,28 +933,26 @@ PROPERTY could for instance be BRAIN_CHILDREN." (org-save-all-org-buffers) (if (org-brain-filep parent) ;; Parent = File - (with-current-buffer (find-file-noselect (org-brain-entry-path parent)) + (org-with-point-at (org-brain-entry-marker parent) (goto-char (point-min)) (if (re-search-forward "^#\\+BRAIN_CHILDREN:.*$" nil t) (insert (concat " " (org-brain-entry-identifier child))) (insert (concat "#+BRAIN_CHILDREN: " (org-brain-entry-identifier child) - "\n\n"))) - (save-buffer)) + "\n\n")))) ;; Parent = Headline (org-entry-add-to-multivalued-property (org-brain-entry-marker parent) "BRAIN_CHILDREN" (org-brain-entry-identifier child))) (if (org-brain-filep child) ;; Child = File - (with-current-buffer (find-file-noselect (org-brain-entry-path child)) + (org-with-point-at (org-brain-entry-marker child) (goto-char (point-min)) (if (re-search-forward "^#\\+BRAIN_PARENTS:.*$" nil t) (insert (concat " " (org-brain-entry-identifier parent))) (insert (concat "#+BRAIN_PARENTS: " (org-brain-entry-identifier parent) - "\n\n"))) - (save-buffer)) + "\n\n")))) ;; Child = Headline (org-entry-add-to-multivalued-property (org-brain-entry-marker child) "BRAIN_PARENTS" @@ -758,7 +963,7 @@ PROPERTY could for instance be BRAIN_CHILDREN." "Delete current line, if matching REGEX." (when (string-match regex (buffer-substring (line-beginning-position) (line-end-position))) - (kill-whole-line))) + (ignore-errors (kill-whole-line)))) (defun org-brain-remove-relationship (parent child) "Remove external relationship between PARENT and CHILD." @@ -767,13 +972,14 @@ PROPERTY could for instance be BRAIN_CHILDREN." (org-save-all-org-buffers) (if (org-brain-filep parent) ;; Parent = File - (with-current-buffer (find-file-noselect (org-brain-entry-path parent)) + (org-with-point-at (org-brain-entry-marker parent) (goto-char (point-min)) (re-search-forward "^#\\+BRAIN_CHILDREN:.*$") (beginning-of-line) (re-search-forward (concat " " (org-brain-entry-identifier child))) (replace-match "") (org-brain-remove-line-if-matching "^#\\+BRAIN_CHILDREN:[[:space:]]*$") + (org-brain-remove-line-if-matching "^[[:space:]]*$") (save-buffer)) ;; Parent = Headline (org-entry-remove-from-multivalued-property (org-brain-entry-marker parent) @@ -781,13 +987,14 @@ PROPERTY could for instance be BRAIN_CHILDREN." (org-brain-entry-identifier child))) (if (org-brain-filep child) ;; Child = File - (with-current-buffer (find-file-noselect (org-brain-entry-path child)) + (org-with-point-at (org-brain-entry-marker child) (goto-char (point-min)) (re-search-forward "^#\\+BRAIN_PARENTS:.*$") (beginning-of-line) (re-search-forward (concat " " (org-brain-entry-identifier parent))) (replace-match "") (org-brain-remove-line-if-matching "^#\\+BRAIN_PARENTS:[[:space:]]*$") + (org-brain-remove-line-if-matching "^[[:space:]]*$") (save-buffer)) ;; Child = Headline (org-entry-remove-from-multivalued-property (org-brain-entry-marker child) @@ -795,92 +1002,93 @@ PROPERTY could for instance be BRAIN_CHILDREN." (org-brain-entry-identifier parent))) (org-save-all-org-buffers)) -;;* Buffer commands +;;;; Buffer commands ;;;###autoload -(defun org-brain-add-child () - "Add external child to entry at point. -If chosen child entry doesn't exist, create it as a new file. +(defun org-brain-add-child (entry children) + "Add external CHILDREN (a list of entries) to ENTRY. +If called interactively use `org-brain-entry-at-pt' and let user choose entry. +If chosen CHILD entry doesn't exist, create it as a new file. Several children can be added, by using `org-brain-entry-separator'." - (interactive) - (dolist (child-entry (org-brain-choose-entries - "Child: " (append (org-brain-files t) - (org-brain-headline-entries)))) - (org-brain-add-relationship (org-brain-entry-at-pt) child-entry)) + (interactive (list (org-brain-entry-at-pt) + (org-brain-choose-entries "Add child: " 'all))) + (dolist (child-entry children) + (org-brain-add-relationship entry child-entry)) (org-brain--revert-if-visualizing)) ;;;###autoload -(defun org-brain-new-child () - "Create a new internal child headline to entry at point. -Several children can be created, by using `org-brain-entry-separator'." - (interactive) - (let ((entry (org-brain-entry-at-pt)) - (child-name-string (read-string "Child name: "))) - (dolist (child-name (split-string child-name-string org-brain-entry-separator)) - (when (equal (length child-name) 0) - (error "Child name must be at least 1 character")) - (if (org-brain-filep entry) - ;; File entry - (with-current-buffer (find-file-noselect (org-brain-entry-path entry)) - (goto-char (point-min)) - (if (re-search-forward (concat "^\\(" org-outline-regexp "\\)") nil t) - (progn - (beginning-of-line) - (open-line 1)) - (goto-char (point-max))) - (insert (concat "* " child-name)) - (org-id-get-create) - (run-hooks 'org-brain-new-entry-hook) - (save-buffer)) - ;; Headline entry +(defun org-brain-add-child-headline (entry child-names) + "Create new internal child headline(s) to ENTRY named CHILD-NAMES. +Several children can be created, by using `org-brain-entry-separator'. +If called interactively use `org-brain-entry-at-pt' and prompt for children." + (interactive (list (org-brain-entry-at-pt) + (read-string "Add child headline: "))) + (dolist (child-name (split-string child-names org-brain-entry-separator)) + (when (equal (length child-name) 0) + (error "Child name must be at least 1 character")) + (if (org-brain-filep entry) + ;; File entry (org-with-point-at (org-brain-entry-marker entry) - (if (org-goto-first-child) - (open-line 1) - (org-end-of-subtree t)) - (org-insert-heading) - (org-do-demote) - (insert child-name) + (goto-char (point-min)) + (if (re-search-forward (concat "^\\(" org-outline-regexp "\\)") nil t) + (progn + (beginning-of-line) + (open-line 1)) + (goto-char (point-max))) + (insert (concat "* " child-name)) (org-id-get-create) (run-hooks 'org-brain-new-entry-hook) - (save-buffer))))) + (save-buffer)) + ;; Headline entry + (org-with-point-at (org-brain-entry-marker entry) + (if (org-goto-first-child) + (open-line 1) + (org-end-of-subtree t)) + (org-insert-heading nil t) + (org-do-demote) + (insert child-name) + (org-id-get-create) + (run-hooks 'org-brain-new-entry-hook) + (save-buffer)))) (org-brain--revert-if-visualizing)) +(define-obsolete-function-alias 'org-brain-new-child 'org-brain-add-child-headline "0.5") + ;;;###autoload -(defun org-brain-remove-child () - "Remove child from entry at point." - (interactive) - (let* ((entry (org-brain-entry-at-pt)) - (child (org-brain-choose-entry "Child: " - (org-brain-children entry) - nil t))) - (if (member child (org-brain--local-children entry)) - (org-brain-delete-entry child) - (org-brain-remove-relationship entry child))) +(defun org-brain-remove-child (entry child) + "Remove CHILD from ENTRY. +If called interactively use `org-brain-entry-at-point' and prompt for CHILD." + (interactive (let ((e (org-brain-entry-at-pt))) + (list e (org-brain-choose-entry "Remove child: " + (org-brain-children e) + nil t)))) + (if (member child (org-brain--local-children entry)) + (org-brain-delete-entry child) + (org-brain-remove-relationship entry child)) (org-brain--revert-if-visualizing)) ;;;###autoload -(defun org-brain-add-parent () - "Add external parent to entry at point. +(defun org-brain-add-parent (entry parents) + "Add external PARENTS (a list of entries) to ENTRY. +If called interactively use `org-brain-entry-at-pt' and prompt for PARENT. If chosen parent entry doesn't exist, create it as a new file. Several parents can be added, by using `org-brain-entry-separator'." - (interactive) - (dolist (parent-entry (org-brain-choose-entries - "Parent: " (append (org-brain-files t) - (org-brain-headline-entries)))) - (org-brain-add-relationship parent-entry (org-brain-entry-at-pt))) + (interactive (list (org-brain-entry-at-pt) + (org-brain-choose-entries "Add parent: " 'all))) + (dolist (parent parents) + (org-brain-add-relationship parent entry)) (org-brain--revert-if-visualizing)) ;;;###autoload -(defun org-brain-remove-parent () - "Remove external parent from entry at point." - (interactive) - (let ((entry (org-brain-entry-at-pt))) - (org-brain-remove-relationship - (org-brain-choose-entry "Parent: " - (org-brain--linked-property-entries - entry "BRAIN_PARENTS") - nil t) - entry)) +(defun org-brain-remove-parent (entry parent) + "Remove external PARENT from ENTRY. +If called interactively use `org-brain-entry-at-pt' and prompt for PARENT." + (interactive (let ((e (org-brain-entry-at-pt))) + (list e (org-brain-choose-entry "Remove parent: " + (org-brain--linked-property-entries + e "BRAIN_PARENTS") + nil t)))) + (org-brain-remove-relationship parent entry) (org-brain--revert-if-visualizing)) (defun org-brain--internal-add-friendship (entry1 entry2 &optional oneway) @@ -891,7 +1099,7 @@ If ONEWAY is t, add ENTRY2 as friend of ENTRY1, but not the other way around." (unless (member entry2 (org-brain-friends entry1)) (if (org-brain-filep entry1) ;; Entry1 = File - (with-current-buffer (find-file-noselect (org-brain-entry-path entry1)) + (org-with-point-at (org-brain-entry-marker entry1) (goto-char (point-min)) (if (re-search-forward "^#\\+BRAIN_FRIENDS:.*$" nil t) (insert (concat " " (org-brain-entry-identifier entry2))) @@ -907,15 +1115,15 @@ If ONEWAY is t, add ENTRY2 as friend of ENTRY1, but not the other way around." (org-save-all-org-buffers)) ;;;###autoload -(defun org-brain-add-friendship () - "Add a new friend to entry at point. +(defun org-brain-add-friendship (entry friends) + "Add a new FRIENDS (a list of entries) to ENTRY. +If called interactively use `org-brain-entry-at-pt' and prompt for FRIENDS. If chosen friend entry doesn't exist, create it as a new file. Several friends can be added, by using `org-brain-entry-separator'." - (interactive) - (dolist (friend-entry (org-brain-choose-entries - "Friend: " (append (org-brain-files t) - (org-brain-headline-entries)))) - (org-brain--internal-add-friendship (org-brain-entry-at-pt) friend-entry)) + (interactive (list (org-brain-entry-at-pt) + (org-brain-choose-entries "Add friend: " 'all))) + (dolist (friend-entry friends) + (org-brain--internal-add-friendship entry friend-entry)) (org-brain--revert-if-visualizing)) ;;;###autoload @@ -927,17 +1135,18 @@ If run interactively, use `org-brain-entry-at-pt' as ENTRY1 and prompt for ENTRY (interactive (let ((entry-at-pt (org-brain-entry-at-pt))) (list entry-at-pt - (org-brain-choose-entry "Remove: " (org-brain-friends entry-at-pt) nil t)))) + (org-brain-choose-entry "Remove friend: " (org-brain-friends entry-at-pt) nil t)))) (when (member entry2 (org-brain-friends entry1)) (if (org-brain-filep entry1) ;; Entry1 = File - (with-current-buffer (find-file-noselect (org-brain-entry-path entry1)) + (org-with-point-at (org-brain-entry-marker entry1) (goto-char (point-min)) (re-search-forward "^#\\+BRAIN_FRIENDS:.*$") (beginning-of-line) (re-search-forward (concat " " (org-brain-entry-identifier entry2))) (replace-match "") (org-brain-remove-line-if-matching "^#\\+BRAIN_FRIENDS:[[:space:]]*$") + (org-brain-remove-line-if-matching "^[[:space:]]*$") (save-buffer)) ;; Entry2 = Headline (org-entry-remove-from-multivalued-property (org-brain-entry-marker entry1) @@ -955,17 +1164,16 @@ If ENTRY isn't specified, ask for the ENTRY. Unless GOTO-FILE-FUNC is nil, use `pop-to-buffer-same-window' for opening the entry." (interactive) (org-brain-stop-wandering) - (unless entry (setq entry (org-brain-choose-entry - "Entry: " - (append (org-brain-files t) - (org-brain-headline-entries)) - nil t))) + (unless entry (setq entry (org-brain-choose-entry "Goto entry: " 'all nil t))) + (when org-brain-quit-after-goto + (org-brain-visualize-quit)) (let ((marker (org-brain-entry-marker entry))) (apply (or goto-file-func #'pop-to-buffer-same-window) (list (marker-buffer marker))) (widen) (goto-char (marker-position marker)) - (org-show-entry)) + (when (org-at-heading-p) + (org-show-subtree))) entry) (define-obsolete-function-alias 'org-brain-open 'org-brain-goto "0.4") @@ -985,7 +1193,7 @@ If ENTRY isn't specified, ask for the ENTRY." (if (org-brain-filep (org-brain-goto entry)) (or (outline-next-heading) (goto-char (point-max))) - (let ((tags (org-get-tags-at nil t))) + (let ((tags (org-get-tags nil t))) (or (and (not (member org-brain-exclude-children-tag tags)) (not (member org-brain-show-children-tag tags)) (org-goto-first-child)) @@ -1007,7 +1215,7 @@ If run interactively, get ENTRY from context. If ALL is nil, choose only between externally linked children." (interactive (list (org-brain-entry-at-pt))) (org-brain-goto (org-brain-choose-entry - "Child: " + "Goto child: " (if all (org-brain-children entry) (org-brain--linked-property-entries @@ -1021,20 +1229,30 @@ If run interactively, get ENTRY from context. If ALL is nil, choose only between externally linked parents." (interactive (list (org-brain-entry-at-pt))) (org-brain-goto (org-brain-choose-entry - "Parent: " + "Goto parent: " (if all (org-brain-parents entry) (org-brain--linked-property-entries entry "BRAIN_PARENTS")) nil t))) +;;;###autoload +(defun org-brain-visualize-parent (entry) + "Visualize a parent of ENTRY, preferring local parents. +This allows the user to quickly jump up the hierarchy." + (interactive (list (org-brain-entry-at-pt))) + (if-let ((parent (car (or (org-brain--local-parent entry) + (org-brain-parents entry))))) + (org-brain-visualize parent) + (error "This entry has no parent"))) + ;;;###autoload (defun org-brain-goto-friend (entry) "Goto a friend of ENTRY. If run interactively, get ENTRY from context." (interactive (list (org-brain-entry-at-pt))) (org-brain-goto (org-brain-choose-entry - "Friend: " + "Goto friend: " (org-brain--linked-property-entries entry "BRAIN_FRIENDS") nil t))) @@ -1055,7 +1273,7 @@ After refiling, all headlines will be given an id." (defun org-brain--remove-relationships (entry &optional recursive) "Remove all external relationships from ENTRY. -Also unpin the entry. +Also unpin and unselect the entry. If RECURSIVE is t, remove local children's relationships." (dolist (child (org-brain--linked-property-entries @@ -1066,7 +1284,8 @@ If RECURSIVE is t, remove local children's relationships." (org-brain-remove-relationship parent entry)) (dolist (friend (org-brain-friends entry)) (org-brain-remove-friendship entry friend)) - (ignore-errors (org-brain-pin entry -1)) + (ignore-errors (org-brain-pin entry -1) + (org-brain-select entry -1)) (when recursive (dolist (child (org-brain--local-children entry)) (org-brain--remove-relationships child t)))) @@ -1077,28 +1296,46 @@ If RECURSIVE is t, remove local children's relationships." Both arguments should be relative to `org-brain-path' and should not contain `org-brain-files-extension'." (interactive (let ((entry (org-brain-choose-entry - "File entry: " (org-brain-files t) nil t))) + "Rename file: " (org-brain-files t) nil t))) (list entry (read-string "New filename: " entry)))) (let ((newpath (org-brain-entry-path new-name)) (oldpath (org-brain-entry-path file-entry))) - (if (file-exists-p newpath) - (error "There's already a file %s" newpath) - (let ((children (org-brain--linked-property-entries file-entry "BRAIN_CHILDREN")) - (parents (org-brain--linked-property-entries file-entry "BRAIN_PARENTS")) - (friends (org-brain-friends file-entry))) - (org-brain--remove-relationships file-entry) - (org-save-all-org-buffers) - (make-directory (file-name-directory newpath) t) - (with-temp-file newpath (insert-file-contents oldpath)) - (org-brain-delete-entry file-entry t) - (org-brain-update-id-locations) - (dolist (child children) - (org-brain-add-relationship new-name child)) - (dolist (parent parents) - (org-brain-add-relationship parent new-name)) - (dolist (friend friends) - (org-brain--internal-add-friendship new-name friend)) - (message "Renamed %s to %s" file-entry new-name))))) + (when (file-exists-p newpath) + (error "There's already a file %s" newpath)) + (when (member newpath (mapcar #'buffer-file-name (buffer-list))) + (error "There's an active buffer associated with file %s" newpath)) + (let ((children (org-brain--linked-property-entries file-entry "BRAIN_CHILDREN")) + (parents (org-brain--linked-property-entries file-entry "BRAIN_PARENTS")) + (friends (org-brain-friends file-entry)) + (is-pinned (member file-entry org-brain-pins)) + (is-selected (member file-entry org-brain-selected))) + (org-brain--remove-relationships file-entry) + (org-save-all-org-buffers) + (make-directory (file-name-directory newpath) t) + (if (vc-backend oldpath) + (vc-rename-file oldpath newpath) + (rename-file oldpath newpath)) + (org-brain-update-id-locations) + (when is-pinned (org-brain-pin new-name 1)) + (when is-selected (org-brain-select new-name 1)) + (cl-flet ((replace-entry (e) (if (org-brain-filep e) + (if (equal e file-entry) new-name e) + (when (equal (car e) file-entry) + (cons new-name (cdr e)) e)))) + (setq org-brain-pins (mapcar #'replace-entry org-brain-pins)) + (setq org-brain-selected (mapcar #'replace-entry org-brain-selected)) + (setq org-brain--vis-history (mapcar #'replace-entry org-brain--vis-history)) + (setq org-brain--vis-entry (replace-entry org-brain--vis-entry))) + (dolist (child children) + (org-brain-add-relationship new-name child)) + (dolist (parent parents) + (org-brain-add-relationship parent new-name)) + (dolist (friend friends) + (org-brain--internal-add-friendship new-name friend)) + (when (equal file-entry org-brain--vis-entry) + (setq org-brain--vis-entry new-name)) + (org-brain--revert-if-visualizing) + (message "Renamed %s to %s" file-entry new-name)))) ;;;###autoload (defun org-brain-delete-entry (entry &optional noconfirm) @@ -1106,10 +1343,7 @@ not contain `org-brain-files-extension'." If run interactively, ask for the ENTRY. If NOCONFIRM is nil, ask if we really want to delete." (interactive - (list (org-brain-choose-entry - "Entry: " (append (org-brain-files t) - (org-brain-headline-entries)) - nil t) + (list (org-brain-choose-entry "Delete entry: " 'all nil t) nil)) (let ((local-children (org-brain--local-children entry))) (when (or noconfirm @@ -1215,6 +1449,104 @@ If STATUS is omitted, toggle between pinned / not pinned." (error "Entry isn't pinned")))) (org-brain--revert-if-visualizing)) +;;;###autoload +(defun org-brain-select (entry &optional status) + "Toggle selection of ENTRY. +If run interactively, get ENTRY from context. + +If STATUS is positive, select ENTRY. If negative, unselect it. +If STATUS is omitted, toggle between selected / not selected." + (interactive (list (org-brain-entry-at-pt))) + (when (null entry) (error "Cannot select null entry")) + (cond ((eq status nil) + (if (member entry org-brain-selected) + (org-brain-select entry -1) + (org-brain-select entry 1))) + ((>= status 1) + (if (member entry org-brain-selected) + (error "Entry is already selected") + (push entry org-brain-selected) + (org-brain-save-data) + (message "Entry selected."))) + ((< status 1) + (if (member entry org-brain-selected) + (progn + (setq org-brain-selected (delete entry org-brain-selected)) + (org-brain-save-data) + (message "Entry unselected.")) + (error "Entry isn't selected")))) + (org-brain--revert-if-visualizing)) + +;;;###autoload +(defun org-brain-clear-selected () + "Clear the selected list." + (interactive) + (setq org-brain-selected nil) + (org-brain--revert-if-visualizing)) + +(defun org-brain-add-selected-children (entry) + "Add selected entries as children of ENTRY. +If run interactively, get ENTRY from context. + +When ENTRY is in the selected list, it is ignored." + (interactive (list (org-brain-entry-at-pt))) + ;; org-brain-add-child takes a list of children, + ;; but we call it one at a time + ;; so that errors don't interrupt the bulk operation. + (dolist (child org-brain-selected) + (ignore-errors (org-brain-add-child entry (list child))))) + +(defun org-brain-remove-selected-children (entry) + "Remove selected entries from the list of ENTRY's children. +If run interactively, get ENTRY from context. + +Ignores selected entries that are not children of ENTRY." + (interactive (list (org-brain-entry-at-pt))) + (dolist (child org-brain-selected) + (ignore-errors (org-brain-remove-child entry child)))) + +(defun org-brain-add-selected-parents (entry) + "Add selected entries as parents of ENTRY. +If run interactively, get ENTRY from context. + +When ENTRY is in the selected list, it is ignored." + (interactive (list (org-brain-entry-at-pt))) + ;; org-brain-add-parent takes a list of parents, + ;; but we call it one at a time + ;; so that errors don't interrupt the bulk operation. + (dolist (parent org-brain-selected) + (ignore-errors (org-brain-add-parent entry (list parent))))) + +(defun org-brain-remove-selected-parents (entry) + "Remove selected entries from the list of ENTRY's parents. +If run interactively, get ENTRY from context. + +Ignores selected entries that are not parents of ENTRY." + (interactive (list (org-brain-entry-at-pt))) + (dolist (parent org-brain-selected) + (ignore-errors (org-brain-remove-parent entry parent)))) + +(defun org-brain-add-selected-friendships (entry) + "Add selected entries as friends of ENTRY. +If run interactively, get ENTRY from context. + +When ENTRY is in the selected list, it is ignored." + (interactive (list (org-brain-entry-at-pt))) + ;; org-brain-add-friendship takes a list of friends, + ;; but we call it one at a time + ;; so that errors don't interrupt the bulk operation. + (dolist (friend org-brain-selected) + (ignore-errors (org-brain-add-friendship entry (list friend))))) + +(defun org-brain-remove-selected-friendships (entry) + "Remove selected entries from the list of ENTRY's friends. +If run interactively, get ENTRY from context. + +Ignores selected entries that are not friends of ENTRY." + (interactive (list (org-brain-entry-at-pt))) + (dolist (selected org-brain-selected) + (ignore-errors (org-brain-remove-friendship entry selected)))) + ;;;###autoload (defun org-brain-set-title (entry title) "Set the name of ENTRY to TITLE. @@ -1227,29 +1559,29 @@ If run interactively, get ENTRY from context and prompt for TITLE." (list entry-at-pt (read-string "Title: " new-title)))) (if (org-brain-filep entry) ;; File entry - (let ((entry-path (org-brain-entry-path entry))) - (with-current-buffer (find-file-noselect entry-path) - (goto-char (point-min)) - (when (assoc "TITLE" (org-brain-keywords entry)) - (re-search-forward "^#\\+TITLE:") - (kill-whole-line)) - (insert (format "#+TITLE: %s\n" title)) - (save-buffer))) + (org-with-point-at (org-brain-entry-marker entry) + (goto-char (point-min)) + (when (assoc "TITLE" (org-brain-keywords entry)) + (re-search-forward "^#\\+TITLE:") + (kill-whole-line)) + (insert (format "#+TITLE: %s\n" title)) + (save-buffer)) ;; Headline entry (org-with-point-at (org-brain-entry-marker entry) (org-edit-headline title) - (save-buffer))) + (save-buffer) + (setf (nth 1 org-brain--vis-entry) title))) (org-brain--revert-if-visualizing)) ;;;###autoload (defun org-brain-set-tags (entry) "Modify the ENTRY tags. -Use `org-set-tags' on headline ENTRY. +Use `org-set-tags-command' on headline ENTRY. Instead sets #+FILETAGS on file ENTRY. If run interactively, get ENTRY from context." (interactive (list (org-brain-entry-at-pt))) (if (org-brain-filep entry) - (with-current-buffer (find-file-noselect (org-brain-entry-path entry)) + (org-with-point-at (org-brain-entry-marker entry) (let ((tag-str (read-string "FILETAGS: " (mapconcat #'identity org-file-tags ":")))) (goto-char (point-min)) @@ -1266,7 +1598,7 @@ If run interactively, get ENTRY from context." (org-save-outline-visibility 'use-markers (org-mode-restart))) (save-buffer)) (org-with-point-at (org-brain-entry-marker entry) - (org-set-tags) + (org-set-tags-command) (save-buffer))) (org-brain--revert-if-visualizing)) @@ -1275,7 +1607,7 @@ If run interactively, get ENTRY from context." "Convert headline ENTRY to a file entry. Prompt for name of the new file. If interactive, also prompt for ENTRY." - (interactive (list (org-brain-choose-entry "Entry: " + (interactive (list (org-brain-choose-entry "Convert entry: " (org-brain-headline-entries) nil t))) (let* (level @@ -1321,7 +1653,12 @@ If interactive, also prompt for ENTRY." (dolist (child children) (org-brain-add-relationship new-entry child)) (dolist (friend friends) - (org-brain--internal-add-friendship new-entry friend))))) + (org-brain--internal-add-friendship new-entry friend)) + (when (equal entry org-brain--vis-entry) + (setq org-brain--vis-entry new-entry)) + (when (member entry org-brain-pins) + (org-brain-pin entry -1) + (org-brain-pin new-entry 1))))) ;;;###autoload (defun org-brain-agenda () @@ -1351,7 +1688,7 @@ function." (org-brain-path-entry-name file) (car (split-string (org-element-property :path link) "::")))))))))) -;;* Sorting +;;;; Sorting (defun org-brain-title< (entry1 entry2) "Return non-nil if title of ENTRY1 is less than ENTRY2 in lexicographic order. @@ -1365,7 +1702,8 @@ The function returns t if the first entry is smaller than the second. If you don't want to sort the relationships, set this to `ignore'.") -;;* Visualize +;;;; Visualize + ;;;###autoload (defun org-brain-visualize (entry &optional nofocus nohistory wander) "View a concept map with ENTRY at the center. @@ -1386,49 +1724,63 @@ Unless NOHISTORY is non-nil, add the entry to `org-brain--vis-history'. Setting NOFOCUS to t implies also having NOHISTORY as t. Unless WANDER is t, `org-brain-stop-wandering' will be run." (interactive - (let ((choices (cond ((equal current-prefix-arg '(4)) 'all) - ((equal current-prefix-arg '(16)) 'files) - ((equal current-prefix-arg '(64)) 'root) - (t org-brain-visualize-default-choices))) - (def-choice (unless (eq major-mode 'org-brain-visualize-mode) - (ignore-errors (org-brain-entry-name (org-brain-entry-at-pt)))))) - (org-brain-stop-wandering) - (list - (org-brain-choose-entry - "Entry: " - (cond ((equal choices 'all) - (append (org-brain-files t) (org-brain-headline-entries))) - ((equal choices 'files) - (org-brain-files t)) - ((equal choices 'root) - (make-directory org-brain-path t) - (mapcar #'org-brain-path-entry-name - (directory-files org-brain-path t (format "\\.%s$" org-brain-files-extension))))) - nil nil def-choice)))) + (progn + (org-brain-maybe-switch-brain) + (let ((choices (cond ((equal current-prefix-arg '(4)) 'all) + ((equal current-prefix-arg '(16)) 'files) + ((equal current-prefix-arg '(64)) 'root) + (t org-brain-visualize-default-choices))) + (def-choice (unless (eq major-mode 'org-brain-visualize-mode) + (ignore-errors (org-brain-entry-name (org-brain-entry-at-pt)))))) + (org-brain-stop-wandering) + (list + (org-brain-choose-entry + "Entry: " + (cond ((equal choices 'all) + 'all) + ((equal choices 'files) + (org-brain-files t)) + ((equal choices 'root) + (make-directory org-brain-path t) + (mapcar #'org-brain-path-entry-name + (directory-files org-brain-path t (format "\\.%s$" org-brain-files-extension))))) + nil nil def-choice))))) (unless wander (org-brain-stop-wandering)) (with-current-buffer (get-buffer-create "*org-brain*") + (setq-local indent-tabs-mode nil) (read-only-mode 1) + (setq-local default-directory (file-name-directory (org-brain-entry-path entry))) + (org-brain-maybe-switch-brain) (unless (eq org-brain--vis-entry entry) (setq org-brain--vis-entry entry) (setq org-brain-mind-map-parent-level (default-value 'org-brain-mind-map-parent-level)) (setq org-brain-mind-map-child-level (default-value 'org-brain-mind-map-child-level))) + (setq org-brain--vis-entry-keywords (when (org-brain-filep entry) + (org-brain-keywords entry))) (let ((inhibit-read-only t) (entry-pos)) (delete-region (point-min) (point-max)) (org-brain--vis-pinned) + (org-brain--vis-selected) + (when (not nohistory) + (setq org-brain--vis-history + (seq-filter (lambda (elt) (not (equal elt entry))) org-brain--vis-history)) + (setq org-brain--vis-history (seq-take org-brain--vis-history 15)) + (push entry org-brain--vis-history)) + (when org-brain-show-history (org-brain--vis-history)) (if org-brain-visualizing-mind-map (setq entry-pos (org-brain-mind-map org-brain--vis-entry org-brain-mind-map-parent-level org-brain-mind-map-child-level)) (insert "\n\n") (org-brain--vis-parents-siblings entry) ;; Insert entry title (let ((title (org-brain-title entry))) - (let ((half-title-length (/ (length title) 2))) + (let ((half-title-length (/ (string-width title) 2))) (if (>= half-title-length (current-column)) (delete-char (- (current-column))) (ignore-errors (delete-char (- half-title-length))))) (setq entry-pos (point)) (insert (propertize title - 'face 'org-brain-title + 'face (org-brain-display-face entry 'org-brain-title) 'aa2u-text t)) (org-brain--vis-friends entry) (org-brain--vis-children entry))) @@ -1441,18 +1793,27 @@ Unless WANDER is t, `org-brain-stop-wandering' will be run." (org-brain-visualize-mode)) (goto-char entry-pos)) (unless nofocus - (pop-to-buffer "*org-brain*") - (when (and (not nohistory) - (not (equal entry (car org-brain--vis-history))) - (< (length org-brain--vis-history) 15)) - (push entry org-brain--vis-history))))) + (pop-to-buffer "*org-brain*")))) ;;;###autoload -(defun org-brain-visualize-random () - "Run `org-brain-visualize' on a random org-brain entry." +(defun org-brain-visualize-entry-at-pt () + "Use `org-brain-visualize' on the `org-brain-entry-at-pt'. +Useful if wanting to visualize the current `org-mode' entry." (interactive) - (let ((entries (append (org-brain-files t) - (org-brain-headline-entries)))) + (org-brain-visualize (org-brain-entry-at-pt))) + +;;;###autoload +(defun org-brain-visualize-random (&optional restrict-to) + "Run `org-brain-visualize' on a random org-brain entry. +If RESTRICT-TO is given, then only choose among those entries. + +If called interactively with `\\[universal-argument]' then +restrict to descendants of the visualized entry." + (interactive (when (equal current-prefix-arg '(4)) + (list (org-brain-descendants org-brain--vis-entry)))) + (let ((entries (or restrict-to + (append (org-brain-files t) + (org-brain-headline-entries))))) (org-brain-visualize (nth (random (length entries)) entries) nil nil t))) (defvar org-brain-wander-timer nil @@ -1460,46 +1821,56 @@ Unless WANDER is t, `org-brain-stop-wandering' will be run." Can be (de)activated by `org-brain-visualize-wander'.") -(defun org-brain-visualize-wander () +(defun org-brain-stop-wandering () + "Cancels `org-brain-wander-timer', if it is active." + (when (member org-brain-wander-timer timer-list) + (cancel-timer org-brain-wander-timer) + t)) + +(defun org-brain-visualize-wander (&optional restrict-to) "Run `org-brain-visualize-random' every `org-brain-wander-interval'. +If RESTRICT-TO is given, then only wander among those entries. -Will be cancelled by many org-brain commands, but can also be +If called interactively with `\\[universal-argument]' then +restrict to descendants of the visualized entry starting the wandering session. + +Wandering is cancelled by many org-brain commands, but can also be cancelled manually with `org-brain-stop-wandering'." - (interactive) - (if (member org-brain-wander-timer timer-list) - (progn - (cancel-timer org-brain-wander-timer) - (message "Wandering stopped.")) - (setq org-brain-wander-timer (run-at-time nil org-brain-wander-interval #'org-brain-visualize-random)) + (interactive (when (equal current-prefix-arg '(4)) + (list (org-brain-descendants org-brain--vis-entry)))) + (if (org-brain-stop-wandering) + (message "Wandering stopped.") + (setq org-brain-wander-timer (run-at-time nil org-brain-wander-interval #'org-brain-visualize-random restrict-to)) (message "Wandering started."))) -(defun org-brain-stop-wandering () - "Cancels `org-brain-wander-timer', if it is active." - (when (member org-brain-wander-timer timer-list) - (cancel-timer org-brain-wander-timer))) - (defun org-brain-visualize-quit () "Like `quit-window', but also stops `org-brain-visualize-wander'." (interactive) (org-brain-stop-wandering) (quit-window)) +(defun org-brain-title-as-button (entry) + "The title of ENTRY when displayed as a button." + (org-brain-title entry (or (not org-brain-visualizing-mind-map) + org-brain-cap-mind-map-titles))) (defun org-brain-insert-visualize-button (entry &optional face) "Insert a button, running `org-brain-visualize' on ENTRY when clicked." - (insert-text-button - (org-brain-title entry (or (not org-brain-visualizing-mind-map) - org-brain-cap-mind-map-titles)) - 'action (lambda (_x) (org-brain-visualize entry)) - 'follow-link t - 'help-echo (org-brain-description entry) - 'aa2u-text t - 'face (or face 'org-brain-button) - )) + (let ((annotation (org-brain-get-edge-annotation org-brain--vis-entry + entry + org-brain--vis-entry-keywords))) + (insert-text-button + (org-brain-title-as-button entry) + 'action (lambda (_x) (org-brain-visualize entry)) + 'id (org-brain-entry-identifier entry) + 'follow-link t + 'help-echo annotation + 'aa2u-text t + 'face (org-brain-display-face entry face annotation)))) (defun org-brain-insert-resource-button (resource &optional indent) "Insert a new line with a RESOURCE button, indented by INDENT spaces." - (insert (make-string (or indent 0) ?\ ) "\n• ") + (insert (make-string (or indent 0) ?\ ) "\n- ") (run-hook-with-args 'org-brain-after-resource-button-functions (car resource)) (insert-text-button (or (cdr resource) (car resource)) @@ -1508,31 +1879,46 @@ cancelled manually with `org-brain-stop-wandering'." 'follow-link t 'aa2u-text t)) -(defun org-brain-add-resource (link &optional description prompt entry) - "Insert LINK with DESCRIPTION in an entry. -If PROMPT is non nil, use `org-insert-link' even if not being run interactively. -If ENTRY is omitted, try to get it from context or prompt for it." - (interactive "i") +(defun org-brain-button-at-point () + "If there's an entry link button at `point' return (entry . button)." + (if-let* ((button (button-at (point))) + (id (button-get button 'id)) + (entry (or (org-brain-entry-from-id id) + (org-entry-restore-space id)))) + (cons entry button) + (user-error "No entry button at point"))) + +(defun org-brain-add-resource (&optional link description prompt entry) + "Insert LINK with DESCRIPTION in ENTRY. +If ENTRY is nil, try to get it from context or prompt for it. +If LINK is nil then use `org-insert-link-global'. Otherwise: +If PROMPT is non nil, let user edit the resource even if run non-interactively." + (interactive) (unless entry (setq entry (or (ignore-errors (org-brain-entry-at-pt)) - (org-brain-choose-entry "Entry: " (append (org-brain-files t) - (org-brain-headline-entries)))))) + (org-brain-choose-entry "Insert link in entry: " 'all)))) (cl-flet ((insert-resource-link () - (unless (and link (not prompt)) - (setq link (read-string "Link: " link)) - (when (string-match org-bracket-link-regexp link) - (let ((linkdesc (match-string 3 link))) - (when (and (not description) linkdesc) - (setq description linkdesc)) - (setq link (match-string 1 link)))) - (setq description (read-string "Description: " description))) - (newline-and-indent) - (insert (format "- %s" (org-make-link-string link description))) - (save-buffer))) + (if link + (progn + (when prompt + (setq link (read-string "Insert link: " link)) + (when (string-match org-bracket-link-regexp link) + (let ((linkdesc (match-string 3 link))) + (when (and (not description) linkdesc) + (setq description linkdesc)) + (setq link (match-string 1 link)))) + (setq description (read-string "Link description: " description))) + (newline-and-indent) + (insert "- " (org-make-link-string link description))) + (when-let ((l (with-temp-buffer + (org-insert-link-global) + (buffer-string)))) + (newline-and-indent) + (insert "- " l))))) (if (org-brain-filep entry) ;; File entry - (with-current-buffer (find-file-noselect (org-brain-entry-path entry)) + (org-with-point-at (org-brain-entry-marker entry) (goto-char (point-min)) (or (re-search-forward (concat "^\\(" org-outline-regexp "\\)") nil t) (goto-char (point-max))) @@ -1542,7 +1928,8 @@ If ENTRY is omitted, try to get it from context or prompt for it." (insert ":RESOURCES:\n:END:\n") (re-search-backward org-brain-resources-start-re nil t) (end-of-line)) - (insert-resource-link)) + (insert-resource-link) + (save-buffer)) ;; Headline entry (org-with-point-at (org-brain-entry-marker entry) (goto-char (cdr (org-get-property-block))) @@ -1556,11 +1943,43 @@ If ENTRY is omitted, try to get it from context or prompt for it." (insert ":END:") (re-search-backward org-brain-resources-start-re nil t) (end-of-line)) - (insert-resource-link)))) + (insert-resource-link) + (save-buffer)))) (org-brain--revert-if-visualizing)) (defalias 'org-brain-visualize-add-resource #'org-brain-add-resource) +(defun org-brain-add-file-line-as-resource (file line &optional entry) + "Add a link to a FILE LINE as a resource in ENTRY. +If called interactively use current FILE and LINE +and prompt for ENTRY, unless called with `\\[universal-argument]' +in which case use the current/last visualized entry." + (interactive (list (buffer-file-name) + (number-to-string (line-number-at-pos)))) + (org-brain-add-resource (concat "file:" file "::" line) + nil nil + (or entry (when current-prefix-arg + org-brain--vis-entry))) + (ignore-errors + (with-current-buffer "*org-brain*" + (org-brain--revert-if-visualizing))) + (message "A new resource has been added.")) + +(defun org-brain-add-file-as-resource (file &optional entry) + "Add a link to a FILE as a resource in ENTRY. +If called interactively use current FILE +and prompt for ENTRY, unless called with `\\[universal-argument]' +in which case use the current/last visualized entry." + (interactive (list (buffer-file-name))) + (org-brain-add-resource (concat "file:" file) + nil nil + (or entry (when current-prefix-arg + org-brain--vis-entry))) + (ignore-errors + (with-current-buffer "*org-brain*" + (org-brain--revert-if-visualizing))) + (message "A new resource has been added.")) + (defun org-brain-visualize-attach () "Use `org-attach' on `org-brain--vis-entry'." (interactive) @@ -1568,16 +1987,11 @@ If ENTRY is omitted, try to get it from context or prompt for it." (error "Not in org-brain-visualize-mode")) (when (org-brain-filep org-brain--vis-entry) (error "Can only attach to headline entries")) - (let* ((entry-path (org-brain-entry-path org-brain--vis-entry)) - (existing-buffer (find-buffer-visiting entry-path))) - (with-current-buffer (find-file entry-path) - (goto-char (cdr (org-id-find (nth 2 org-brain--vis-entry)))) - (call-interactively #'org-attach) - (save-buffer) - (if existing-buffer - (switch-to-buffer "*org-brain*") - (kill-this-buffer)) - (revert-buffer)))) + (org-with-point-at (org-brain-entry-marker org-brain--vis-entry) + (goto-char (cdr (org-id-find (nth 2 org-brain--vis-entry)))) + (call-interactively #'org-attach) + (save-buffer)) + (org-brain--revert-if-visualizing)) (defun org-brain-paste-resource () "Add `current-kill' as a resource link. @@ -1587,12 +2001,76 @@ See `org-brain-add-resource'." (defalias 'org-brain-visualize-paste-resource #'org-brain-paste-resource) +;;;###autoload +(defun org-brain-select-button () + "Toggle selection of the entry linked to by the button at point." + (interactive) + (org-brain-select (car (org-brain-button-at-point))) + t) + +;;;###autoload +(defun org-brain-select-dwim (arg) + "Use `org-brain-select-button' or `org-brain-select' depending on context. +If run with `\\[universal-argument\\]' (ARG is non nil) +then always use `org-brain-select'." + (interactive "P") + (when (or arg (not (ignore-errors (org-brain-select-button)))) + (org-brain-select (org-brain-entry-at-pt)))) + +(defun org-brain-edge-prop-name (entry) + "Retrun edge annotation property name of ENTRY." + (concat "BRAIN_EDGE_" (org-brain-entry-identifier entry))) + +(defun org-brain-get-edge-annotation (from to &optional keywords) + "Get edge annotation FROM an entry TO another entry. +If KEYWORDS is given, use it instead of `org-brain-keywords' (optimization)." + (if (org-brain-filep from) + (cdr (assoc (upcase (org-brain-edge-prop-name to)) + (or keywords (org-brain-keywords from)))) + (org-entry-get (org-brain-entry-marker from) (org-brain-edge-prop-name to)))) + +(defun org-brain-annotate-edge (entry target annotation two-way) + "When visualizing ENTRY, links to TARGET will have an ANNOTATION. +You can think of it as edges with comments in a graph. +If TWO-WAY is non-nil, then also add the ANNOTATION from TARGET to ENTRY. + +When called interactively use the visualized ENTRY, +`org-brain-button-at-point' as TARGET, and prompt for ANNOTATION. +TWO-WAY will be t unless called with `\\[universal-argument\\]'." + (interactive + (let ((target (car (org-brain-button-at-point)))) + (list org-brain--vis-entry + target + (read-string (concat (org-brain-title target) " edge: ")) + (not current-prefix-arg)))) + (if (org-brain-filep entry) + ;; File entry + (let ((edge-regex (format "^#\\+%s:" + (org-brain-edge-prop-name target)))) + (org-with-point-at (org-brain-entry-marker entry) + (if (re-search-forward edge-regex nil t) + (org-brain-remove-line-if-matching edge-regex) + (goto-char (point-min))) + (when (> (length annotation) 0) + (insert "#+" (org-brain-edge-prop-name target) ": " annotation "\n")) + (save-buffer))) + ;; Headline entry + (org-with-point-at (org-brain-entry-marker entry) + (if (> (length annotation) 0) + (org-set-property (org-brain-edge-prop-name target) annotation) + (org-delete-property (org-brain-edge-prop-name target))) + (save-buffer))) + (when two-way + (run-with-idle-timer 0.2 nil 'org-brain-annotate-edge + target entry annotation nil)) + (org-brain--revert-if-visualizing)) + (defun org-brain-visualize-back () "Go back to the previously visualized entry." (interactive) - (pop org-brain--vis-history) - (if org-brain--vis-history - (org-brain-visualize (car org-brain--vis-history) nil t) + (if (cadr org-brain--vis-history) + (progn (pop org-brain--vis-history) + (org-brain-visualize (car org-brain--vis-history) nil t)) (error "No further history"))) (defun org-brain-visualize-revert (_ignore-auto _noconfirm) @@ -1605,32 +2083,25 @@ See `org-brain-add-resource'." (org-brain-stop-wandering) (revert-buffer))) -(defun org-brain-visualize-eldoc-function () - "Return description of org-brain entry button at point." - (ignore-errors - (plist-get (text-properties-at (button-at (point))) - 'help-echo))) - (define-derived-mode org-brain-visualize-mode special-mode "Org-brain Visualize" "Major mode for `org-brain-visualize'. \\{org-brain-visualize-mode-map}" - (setq-local revert-buffer-function #'org-brain-visualize-revert) - (add-function :before-until (local 'eldoc-documentation-function) - #'org-brain-visualize-eldoc-function)) + (setq-local revert-buffer-function #'org-brain-visualize-revert)) -;;** Keybindings +;;;;; Keybindings (define-key org-brain-visualize-mode-map "p" 'org-brain-add-parent) (define-key org-brain-visualize-mode-map "P" 'org-brain-remove-parent) (define-key org-brain-visualize-mode-map "c" 'org-brain-add-child) (define-key org-brain-visualize-mode-map "C" 'org-brain-remove-child) -(define-key org-brain-visualize-mode-map "*" 'org-brain-new-child) -(define-key org-brain-visualize-mode-map "h" 'org-brain-new-child) +(define-key org-brain-visualize-mode-map "*" 'org-brain-add-child-headline) +(define-key org-brain-visualize-mode-map "h" 'org-brain-add-child-headline) (define-key org-brain-visualize-mode-map "n" 'org-brain-pin) (define-key org-brain-visualize-mode-map "t" 'org-brain-set-title) (define-key org-brain-visualize-mode-map "j" 'forward-button) (define-key org-brain-visualize-mode-map "k" 'backward-button) +(define-key org-brain-visualize-mode-map "u" 'org-brain-visualize-parent) (define-key org-brain-visualize-mode-map [?\t] 'forward-button) (define-key org-brain-visualize-mode-map [backtab] 'backward-button) (define-key org-brain-visualize-mode-map "o" 'org-brain-goto-current) @@ -1640,21 +2111,37 @@ See `org-brain-add-resource'." (define-key org-brain-visualize-mode-map "F" 'org-brain-remove-friendship) (define-key org-brain-visualize-mode-map "d" 'org-brain-delete-entry) (define-key org-brain-visualize-mode-map "l" 'org-brain-add-resource) +(define-key org-brain-visualize-mode-map "r" 'org-brain-open-resource) (define-key org-brain-visualize-mode-map "a" 'org-brain-visualize-attach) (define-key org-brain-visualize-mode-map "A" 'org-brain-archive) (define-key org-brain-visualize-mode-map "b" 'org-brain-visualize-back) (define-key org-brain-visualize-mode-map "\C-y" 'org-brain-visualize-paste-resource) (define-key org-brain-visualize-mode-map "T" 'org-brain-set-tags) (define-key org-brain-visualize-mode-map "q" 'org-brain-visualize-quit) -(define-key org-brain-visualize-mode-map "r" 'org-brain-visualize-random) -(define-key org-brain-visualize-mode-map "R" 'org-brain-visualize-wander) +(define-key org-brain-visualize-mode-map "w" 'org-brain-visualize-random) +(define-key org-brain-visualize-mode-map "W" 'org-brain-visualize-wander) (define-key org-brain-visualize-mode-map "m" 'org-brain-visualize-mind-map) -(define-key org-brain-visualize-mode-map "+" 'org-brain-visualize-add-grandchild) -(define-key org-brain-visualize-mode-map "-" 'org-brain-visualize-remove-grandchild) -(define-key org-brain-visualize-mode-map "z" 'org-brain-visualize-add-grandparent) -(define-key org-brain-visualize-mode-map "Z" 'org-brain-visualize-remove-grandparent) - -;;** Drawing helpers +(define-key org-brain-visualize-mode-map "+" 'org-brain-show-descendant-level) +(define-key org-brain-visualize-mode-map "-" 'org-brain-hide-descendant-level) +(define-key org-brain-visualize-mode-map "z" 'org-brain-show-ancestor-level) +(define-key org-brain-visualize-mode-map "Z" 'org-brain-hide-ancestor-level) +(define-key org-brain-visualize-mode-map "e" 'org-brain-annotate-edge) + +(define-prefix-command 'org-brain-select-map) +(define-key org-brain-select-map "s" 'org-brain-clear-selected) +(define-key org-brain-select-map "c" 'org-brain-add-selected-children) +(define-key org-brain-select-map "C" 'org-brain-remove-selected-children) +(define-key org-brain-select-map "p" 'org-brain-add-selected-parents) +(define-key org-brain-select-map "P" 'org-brain-remove-selected-parents) +(define-key org-brain-select-map "f" 'org-brain-add-selected-friendships) +(define-key org-brain-select-map "F" 'org-brain-remove-selected-friendships) +(define-key org-brain-select-map "s" 'org-brain-clear-selected) +(define-key org-brain-select-map "S" 'org-brain-clear-selected) + +(define-key org-brain-visualize-mode-map "s" 'org-brain-select-dwim) +(define-key org-brain-visualize-mode-map "S" 'org-brain-select-map) + +;;;;; Drawing helpers (defun org-brain--vis-pinned () "Insert pinned entries. @@ -1665,6 +2152,41 @@ Helper function for `org-brain-visualize'." (org-brain-insert-visualize-button pin 'org-brain-pinned)) (insert "\n")) +(defun org-brain--vis-selected () + "Insert selected entries. +Helper function for `org-brain-visualize'." + (unless (null org-brain-selected) + (insert "SELECTED:") + (dolist (selection (sort (copy-sequence org-brain-selected) org-brain-visualize-sort-function)) + (insert " ") + (org-brain-insert-visualize-button selection 'org-brain-selected-list)) + (insert "\n"))) + +(defun org-brain--hist-entries-to-draw (max-width hist width to-draw) + "Determines the entries in HIST that can fit on a line of MAX-WIDTH. +Returns those entries in reversed order. +WIDTH and TO-DRAW are state parameters. +WIDTH represents the width of the line comprising the elements in TO-DRAW. +Assumes elements will be drawn with a two-character padding between them. +Helper function for `org-brain--vis-history'." + (if (null hist) + to-draw + (let* ((entry-title-width (string-width (org-brain-title-as-button (car hist)))) + (new-line-width (+ width 2 entry-title-width))) + (if (and (<= max-width new-line-width) + (not (null to-draw))) ; Always display at least one entry + to-draw + (org-brain--hist-entries-to-draw max-width (cdr hist) new-line-width (cons (car hist) to-draw)))))) + +(defun org-brain--vis-history () + "Show as many of the most recently visited entries as fit on one line. +Helper function for `org-brain-visualize'." + (insert "HISTORY:") + (dolist (entry (org-brain--hist-entries-to-draw (window-width) org-brain--vis-history (string-width "HISTORY:") nil)) + (insert " ") + (org-brain-insert-visualize-button entry 'org-brain-history-list)) + (insert "\n")) + (defun org-brain--insert-wire (&rest strings) "Helper function for drawing fontified wires in the org-brain visualization buffer." (insert (propertize (apply 'concat strings) 'face 'org-brain-wires))) @@ -1678,29 +2200,46 @@ Helper function for `org-brain-visualize'." (dolist (parent (sort siblings (lambda (x y) (funcall org-brain-visualize-sort-function (car x) (car y))))) - (let ((children-links (cdr parent)) - (col-start (+ 3 max-width)) - (parent-title (org-brain-title (car parent)))) - (org-goto-line 4) + (let* ((parent-tags (if (org-brain-filep (car parent)) + (org-brain--file-tags (car parent)) + (org-with-point-at + (org-brain-entry-marker (car parent)) + (org-get-tags nil t)))) + (children-links (unless (member org-brain-exclude-siblings-tag parent-tags) + (cdr parent))) + (sibling-middle (ceiling (/ (length children-links) 2.0))) + (base-line (if org-brain-show-history 5 4)) + (col-start (+ 3 max-width)) + (parent-title (org-brain-title (car parent)))) + (org-goto-line base-line) (mapc (lambda (child) (picture-forward-column col-start) - (org-brain--insert-wire (make-string (1+ (length parent-title)) ?\ ) "+-") - (org-brain-insert-visualize-button child 'org-brain-sibling) + (org-brain--insert-wire (make-string (1+ (string-width parent-title)) ?\ ) "+-") + (org-brain-insert-visualize-button + child + (if (and (member (car parent) (org-brain--local-parent child)) + (member (car parent) (org-brain--local-parent entry))) + 'org-brain-local-sibling + 'org-brain-sibling)) (setq max-width (max max-width (current-column))) (newline (forward-line 1))) (sort children-links org-brain-visualize-sort-function)) - (org-goto-line 4) - (forward-line (1- (length children-links))) + (org-goto-line base-line) + (forward-line (1- sibling-middle)) (picture-forward-column col-start) (push (cons (picture-current-line) - (+ (current-column) (/ (length parent-title) 2))) + (+ (current-column) (/ (string-width parent-title) 2))) parent-positions) - (org-brain-insert-visualize-button (car parent) 'org-brain-parent) + (org-brain-insert-visualize-button + (car parent) + (if (member (car parent) (org-brain--local-parent entry)) + 'org-brain-local-parent + 'org-brain-parent)) (setq max-width (max max-width (current-column))) (when children-links (org-brain--insert-wire "-") - (delete-char (+ 1 (length parent-title)))))) + (delete-char (+ 1 (string-width parent-title)))))) ;; Draw lines (when parent-positions (let ((maxline (line-number-at-pos (point-max)))) @@ -1727,7 +2266,8 @@ Helper function for `org-brain-visualize'." ;; Line to main entry (move-to-column (/ (+ (cdar (last parent-positions)) (cdar parent-positions)) - 2)) + 2) + t) (delete-char 1) (when (> (length parent-positions) 1) (org-brain--insert-wire "+") @@ -1735,28 +2275,30 @@ Helper function for `org-brain-visualize'." (picture-move-down 1) (org-brain--insert-wire "|") (picture-move-down 1)) - (org-brain--insert-wire "â–½")))) + (org-brain--insert-wire "V")))) (picture-move-down 1))) (defun org-brain--vis-children (entry) "Insert children of ENTRY. Helper function for `org-brain-visualize'." - (when-let ((children (org-brain-children entry))) + (when-let ((children (org-brain-children entry)) + (fill-col (eval org-brain-child-linebreak-sexp))) (insert "\n\n") (dolist (child (sort children org-brain-visualize-sort-function)) - (let ((child-title (org-brain-title child))) - (when (or org-brain-visualize-one-child-per-line - (> (+ (current-column) (length child-title)) - fill-column)) + (let ((child-title (org-brain-title child)) + (face (if (member entry (org-brain--local-parent child)) + 'org-brain-local-child + 'org-brain-child))) + (when (> (+ (current-column) (length child-title)) fill-col) (insert "\n")) - (org-brain-insert-visualize-button child 'org-brain-child) + (org-brain-insert-visualize-button child face) (insert " "))))) (defun org-brain--vis-friends (entry) "Insert friends of ENTRY. Helper function for `org-brain-visualize'." (when-let ((friends (org-brain-friends entry))) - (org-brain--insert-wire " â†â†’ ") + (org-brain--insert-wire " <-> ") (dolist (friend (sort friends org-brain-visualize-sort-function)) (let ((column (current-column))) (org-brain-insert-visualize-button friend 'org-brain-friend) @@ -1792,7 +2334,7 @@ Helper function for `org-brain-visualize'." (run-hooks 'org-brain-after-visualize-hook))) (run-hooks 'org-brain-after-visualize-hook))) -;;* Mind-map +;;;;; Mind-map (defun org-brain-map-create-indentation (level) "Return a string of spaces, length determined by indentation LEVEL." @@ -1849,10 +2391,17 @@ Return the position of ENTRY in the buffer." (funcall org-brain-visualize-sort-function (car x) (car y))))) (org-brain-insert-recursive-parent-buttons (car parent) (1- parent-max-level) (1- indent)) - (dolist (sibling (sort (cdr parent) org-brain-visualize-sort-function)) - (insert (org-brain-map-create-indentation indent)) - (org-brain-insert-visualize-button sibling 'org-brain-sibling) - (insert "\n"))) + (let* ((parent-tags (if (org-brain-filep (car parent)) + (org-brain--file-tags (car parent)) + (org-with-point-at + (org-brain-entry-marker (car parent)) + (org-get-tags nil t))) ) + (children-links (unless (member org-brain-exclude-siblings-tag parent-tags) + (cdr parent)))) + (dolist (sibling (sort children-links org-brain-visualize-sort-function)) + (insert (org-brain-map-create-indentation indent)) + (org-brain-insert-visualize-button sibling 'org-brain-sibling) + (insert "\n")))) (insert (org-brain-map-create-indentation indent)) (setq entry-pos (point)) (insert (propertize (org-brain-title entry) @@ -1873,44 +2422,54 @@ Return the position of ENTRY in the buffer." (setq org-brain-visualizing-mind-map (not org-brain-visualizing-mind-map)) (org-brain-visualize org-brain--vis-entry))) -(defun org-brain-visualize-add-grandchild () - "Add another grandchild level to the visualized buffer." +;;;;; Show/hide nested levels +(defun org-brain-show-descendant-level () + "Show one more level of descendant entries to the right in the mind-map visualization buffer." (interactive) (setq org-brain-visualizing-mind-map t) (cl-incf org-brain-mind-map-child-level) (org-brain--revert-if-visualizing)) -(defun org-brain-visualize-remove-grandchild () - "Remove a grandchild level from the visualized buffer." +(defun org-brain-hide-descendant-level () + "Hide the rightmost level of descendant entries in the mind-map visualization buffer." (interactive) (setq org-brain-visualizing-mind-map t) (when (> org-brain-mind-map-child-level 1) (cl-decf org-brain-mind-map-child-level)) (org-brain--revert-if-visualizing)) -(defun org-brain-visualize-add-grandparent () - "Add another grandparent level to the visualized buffer." +(defun org-brain-show-ancestor-level () + "Show one more level of ancestor entries to the left in the mind-map visualization buffer." (interactive) (setq org-brain-visualizing-mind-map t) (cl-incf org-brain-mind-map-parent-level) (org-brain--revert-if-visualizing)) -(defun org-brain-visualize-remove-grandparent () - "Remove a grandparent level from the visualized buffer." +(defun org-brain-hide-ancestor-level () + "Hide the leftmost level of ancestor entries in the mind-map visualization buffer." (interactive) (setq org-brain-visualizing-mind-map t) (when (> org-brain-mind-map-parent-level 1) (cl-decf org-brain-mind-map-parent-level)) (org-brain--revert-if-visualizing)) -;;* Brain link +(define-obsolete-function-alias + 'org-brain-visualize-add-grandchild 'org-brain-show-descendant-level "0.5") +(define-obsolete-function-alias + 'org-brain-visualize-remove-grandchild 'org-brain-hide-descendant-level "0.5") +(define-obsolete-function-alias + 'org-brain-visualize-add-grandparent 'org-brain-show-ancestor-level "0.5") +(define-obsolete-function-alias + 'org-brain-visualize-remove-grandparent 'org-brain-hide-ancestor-level "0.5") + +;;;; Brain link + (defun org-brain-link-complete (&optional link-type) "Create an org-link target string to a file in `org-brain-path'. LINK-TYPE will be \"brain\" by default." (setq link-type (or link-type "brain")) (let ((entry (ignore-errors (org-brain-entry-at-pt))) - (choice (org-brain-choose-entry "Entry: " (append (org-brain-files t) - (org-brain-headline-entries))))) + (choice (org-brain-choose-entry "Entry: " 'all))) (cond ((string-equal link-type org-brain-child-link-name) (org-brain-add-relationship entry choice)) ((string-equal link-type org-brain-parent-link-name) @@ -1944,5 +2503,156 @@ LINK-TYPE will be \"brain\" by default." :complete (lambda () (org-brain-link-complete org-brain-friend-link-name)) :follow 'org-brain-goto) +;;;; Brain switch link + +(defun org-brain--switch-link-complete () + "Create an org-link target string to an org-brain and one of its entries." + (let* ((org-brain-path (read-directory-name "Brain dir: " org-brain-path)) + (entry (org-brain-choose-entry "Entry: " (append (org-brain-files t) + (org-brain-headline-entries))))) + (concat "brainswitch:" org-brain-path + "::" + (if (org-brain-filep entry) + entry + (nth 2 entry))))) + +(defun org-brain--switch-and-visualize (directory entry) + "Switch brain to DIRECTORY and visualize ENTRY. +ENTRY should be a string; an id in the case of an headline entry." + (org-brain-switch-brain directory) + (org-brain-visualize (or (org-brain-entry-from-id entry) entry))) + +(defun org-brain--switch-link-follow (link) + "Follow function for brainswitch links." + (let ((link-parts (split-string link "::"))) + (org-brain--switch-and-visualize (car link-parts) + (cadr link-parts)))) + +(org-link-set-parameters "brainswitch" + :complete 'org-brain--switch-link-complete + :follow 'org-brain--switch-link-follow) + +;;;; Helm integration + +(with-eval-after-load "helm" + (defun helm-brain--add-children (_c) + (dolist (candidate (helm-marked-candidates)) + (org-brain-add-relationship + (org-brain-entry-at-pt) (or (org-brain-entry-from-id candidate) candidate))) + (org-brain--revert-if-visualizing)) + + (defun helm-brain--add-parents (_c) + (dolist (candidate (helm-marked-candidates)) + (org-brain-add-relationship + (or (org-brain-entry-from-id candidate) candidate) (org-brain-entry-at-pt))) + (org-brain--revert-if-visualizing)) + + (defun helm-brain--add-friends (_c) + (dolist (candidate (helm-marked-candidates)) + (org-brain--internal-add-friendship + (org-brain-entry-at-pt) (or (org-brain-entry-from-id candidate) candidate))) + (org-brain--revert-if-visualizing)) + + (defun helm-brain--delete-entries (_c) + (dolist (candidate (helm-marked-candidates)) + (org-brain-delete-entry (or (org-brain-entry-from-id candidate) candidate)))) + + (defun helm-brain--archive (_c) + (dolist (candidate (helm-marked-candidates)) + (org-brain-archive (or (org-brain-entry-from-id candidate) candidate)))) + + (defun helm-brain--select (_c) + (dolist (candidate (helm-marked-candidates)) + (org-brain-select (or (org-brain-entry-from-id candidate) candidate) 1))) + + (defun helm-brain--unselect (_c) + (dolist (candidate (helm-marked-candidates)) + (org-brain-select (or (org-brain-entry-from-id candidate) candidate) -1))) + + (defvar helm-brain--actions + (helm-make-actions + "Visualize" (lambda (x) + (org-brain-visualize (or (org-brain-entry-from-id x) x))) + "Add children" 'helm-brain--add-children + "Add parents" 'helm-brain--add-parents + "Add friends" 'helm-brain--add-friends + "Delete" 'helm-brain--delete-entries + "Archive" 'helm-brain--archive + "Select" 'helm-brain--select + "Unselect" 'helm-brain--unselect)) + + (defun helm-brain--source () + (helm-build-sync-source "Brain" + :candidates (mapcan #'org-brain--file-targets + (org-brain-files)) + :action 'helm-brain--actions)) + + (defun helm-brain () + "Use `helm' to choose among your org-brain entries. +Provides actions for visualizing, adding/removing relations, etc. +Supports selecting multiple entries at once." + (interactive) + (helm :sources (helm-brain--source)))) + +;;;; Ivy integration + +(with-eval-after-load "ivy" + (defun counsel-brain () + "Use Ivy to choose among your org-brain entries. +Provides actions for visualizing, adding/removing relations, etc." + (interactive) + (let ((targets (mapcan #'org-brain--file-targets + (org-brain-files)))) + (ivy-read "Org-brain: " + targets + :require-match t + :action (lambda (x) + (org-brain-visualize (or (org-brain-entry-from-id (cdr x)) + (cdr x)))) + :preselect (ignore-errors + (org-brain-entry-name + (org-brain-entry-at-pt))) + :caller 'counsel-brain))) + + (defun counsel-brain--add-child (child) + (org-brain-add-relationship (org-brain-entry-at-pt) + (or (org-brain-entry-from-id (cdr child)) + (cdr child))) + (org-brain--revert-if-visualizing)) + + (defun counsel-brain--add-parent (parent) + (org-brain-add-relationship (or (org-brain-entry-from-id (cdr parent)) + (cdr parent)) + (org-brain-entry-at-pt)) + (org-brain--revert-if-visualizing)) + + (defun counsel-brain--add-friend (friend) + (org-brain--internal-add-friendship (org-brain-entry-at-pt) + (or (org-brain-entry-from-id (cdr friend)) + (cdr friend))) + (org-brain--revert-if-visualizing)) + + (defun counsel-brain--delete (x) + (org-brain-delete-entry (or (org-brain-entry-from-id (cdr x)) (cdr x)))) + + (defun counsel-brain--archive (x) + (org-brain-archive (or (org-brain-entry-from-id (cdr x)) (cdr x)))) + + (defun counsel-brain--select (x) + (org-brain-select (or (org-brain-entry-from-id (cdr x)) (cdr x)) 1)) + + (defun counsel-brain--unselect (x) + (org-brain-select (or (org-brain-entry-from-id (cdr x)) (cdr x)) -1)) + + (ivy-set-actions + 'counsel-brain + '(("c" counsel-brain--add-child "add as child") + ("p" counsel-brain--add-parent "add as parent") + ("f" counsel-brain--add-friend "add as friend") + ("d" counsel-brain--delete "delete") + ("a" counsel-brain--archive "archive") + ("s" counsel-brain--select "select") + ("S" counsel-brain--unselect "unselect")))) + (provide 'org-brain) ;;; org-brain.el ends here diff --git a/packages/org-bullets-20180208.2343.el b/packages/org-bullets-20190802.927.el similarity index 97% rename from packages/org-bullets-20180208.2343.el rename to packages/org-bullets-20190802.927.el index fe7ffee..8576ace 100644 --- a/packages/org-bullets-20180208.2343.el +++ b/packages/org-bullets-20190802.927.el @@ -1,7 +1,7 @@ ;;; org-bullets.el --- Show bullets in org-mode as UTF-8 characters ;; Version: 0.2.4 -;; Package-Version: 20180208.2343 +;; Package-Version: 20190802.927 ;; Author: sabof ;; Maintainer: Jonas Bernoulli <jonas@bernoul.li> ;; Homepage: https://github.com/emacsorphanage/org-bullets @@ -62,7 +62,7 @@ Otherwise the face of the heading level is used." (defun org-bullets-level-char (level) (string-to-char - (nth (mod (1- level) + (nth (mod (/ (1- level) (if org-odd-levels-only 2 1)) (length org-bullets-bullet-list)) org-bullets-bullet-list))) diff --git a/packages/org-cliplink-20190608.2134.tar b/packages/org-cliplink-20190608.2134.tar new file mode 100644 index 0000000..715cf53 Binary files /dev/null and b/packages/org-cliplink-20190608.2134.tar differ diff --git a/packages/org-download-20180925.1528.el b/packages/org-download-20190821.501.el similarity index 80% rename from packages/org-download-20180925.1528.el rename to packages/org-download-20190821.501.el index ed5051b..976cdf7 100644 --- a/packages/org-download-20180925.1528.el +++ b/packages/org-download-20190821.501.el @@ -4,7 +4,7 @@ ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/org-download -;; Package-Version: 20180925.1528 +;; Package-Version: 20190821.501 ;; Version: 0.1.0 ;; Package-Requires: ((async "1.2")) ;; Keywords: images, screenshots, download @@ -87,16 +87,14 @@ :type '(choice (const :tag "Directory" directory) (const :tag "Attachment" attach) - (function :tag "Custom function")) - :group 'org-download) + (function :tag "Custom function"))) (defcustom org-download-image-dir nil "If set, images will be stored in this directory instead of \".\". See `org-download--dir-1' for more info." :type '(choice (const :tag "Default" nil) - (string :tag "Directory")) - :group 'org-download) + (string :tag "Directory"))) (make-variable-buffer-local 'org-download-image-dir) (defcustom org-download-heading-lvl 0 @@ -113,14 +111,12 @@ See `org-download-rename-last-file'.") :type '(choice (const :tag "wget" "wget \"%s\" -O \"%s\"") (const :tag "curl" "curl \"%s\" -o \"%s\"") - (const :tag "url-retrieve" t)) - :group 'org-download) + (const :tag "url-retrieve" t))) (defcustom org-download-timestamp "_%Y-%m-%d_%H-%M-%S" "This `format-time-string'-style string will be appended to the file name. Set this to \"\" if you don't want time stamps." - :type 'string - :group 'org-download) + :type 'string) (defcustom org-download-img-regex-list '("<img +src=\"" "<img +\\(class=\"[^\"]+\"\\)? *src=\"") @@ -128,8 +124,7 @@ Set this to \"\" if you don't want time stamps." The html to which the links points will be searched for these regexes, one by one, until one succeeds. The found image address will be used." - :type '(repeat string) - :group 'org-download) + :type '(repeat string)) (defcustom org-download-screenshot-method "gnome-screenshot -a -f %s" "The tool to capture screenshots." @@ -146,29 +141,74 @@ will be used." (const :tag "screencapture" "screencapture -i %s") ;; take an image that is already on the clipboard, for Linux (const :tag "xclip" - "xclip -selection clipboard -t image/png -o > %s") + "xclip -selection clipboard -t image/png -o > %s") ;; take an image that is already on the clipboard, for Windows - (const :tag "imagemagick/convert" "convert clipboard: %s")) - :group 'org-download) + (const :tag "imagemagick/convert" "convert clipboard: %s") + (function :tag "Custom function"))) -(defcustom org-download-screenshot-file "/tmp/screenshot.png" +(defcustom org-download-screenshot-file (expand-file-name "screenshot.png" temporary-file-directory) "The file to capture screenshots." :type 'string) (defcustom org-download-image-html-width 0 "When non-zero add #+attr_html: :width tag to the image." - :type 'integer - :group 'org-download) + :type 'integer) (defcustom org-download-image-latex-width 0 "When non-zero add #+attr_latex: :width tag to the image." - :type 'integer - :group 'org-download) + :type 'integer) (defcustom org-download-image-org-width 0 "When non-zero add #+attr_org: :width tag to the image." - :type 'integer - :group 'org-download) + :type 'integer) + +(defcustom org-download-image-attr-list nil + "Add attr info to the image. +For example: + + (\"#+attr_html: :width 80% :align center\" + \"#+attr_org: :width 100px\")" + :type '(repeat string)) + +(defcustom org-download-delete-image-after-download nil + "When non-nil delete local image after download." + :type 'boolean) + +(defcustom org-download-display-inline-images t + "When non-nil display inline images in org buffer after download." + :type + '(choice + (const :tag "On" t) + (const :tag "Off" nil) + (const :tag "Posframe" posframe))) + +(defvar org-download-posframe-show-params + '(;; Please do not remove :timeout or set it to large. + :timeout 1 + :internal-border-width 1 + :internal-border-color "red" + :min-width 40 + :min-height 10 + :poshandler posframe-poshandler-window-center) + "List of parameters passed to `posframe-show'.") + +(declare-function posframe-workable-p "ext:posframe") +(declare-function posframe-show "ext:posframe") + +(defun org-download--display-inline-images () + (cond + ((eq org-download-display-inline-images t) + (org-display-inline-images)) + ((eq org-download-display-inline-images 'posframe) + (require 'posframe) + (when (posframe-workable-p) + (let ((buffer (get-buffer-create " *org-download-image"))) + (with-current-buffer buffer + (erase-buffer) + (insert-image-file org-download-path-last-file)) + (apply #'posframe-show + buffer + org-download-posframe-show-params)))))) (defun org-download-get-heading (lvl) "Return the heading of the current entry's LVL level parent." @@ -178,7 +218,9 @@ will be used." (progn (unless (= cur-lvl 1) (org-up-heading-all (- (1- (org-current-level)) lvl))) - (nth 4 (org-heading-components))) + (replace-regexp-in-string + " " "_" + (nth 4 (org-heading-components)))) "")))) (defun org-download--dir-1 () @@ -190,9 +232,9 @@ It's `org-download-image-dir', unless it's nil. Then it's \".\"." "Return the second part of the directory path for `org-download--dir'. Unless `org-download-heading-lvl' is nil, it's the name of the current `org-download-heading-lvl'-leveled heading. Otherwise it's \"\"." - (and org-download-heading-lvl - (org-download-get-heading - org-download-heading-lvl))) + (when org-download-heading-lvl + (org-download-get-heading + org-download-heading-lvl))) (defun org-download--dir () "Return the directory path for image storage. @@ -255,7 +297,7 @@ COMMAND is a format-style string with two slots for LINK and FILENAME." (lexical-let ((cur-buf (current-buffer))) (lambda (x) (with-current-buffer cur-buf - (org-display-inline-images)))))) + (org-download--display-inline-images)))))) (defun org-download--write-image (status filename) ;; Write current buffer to FILENAME @@ -279,7 +321,7 @@ COMMAND is a format-style string with two slots for LINK and FILENAME." (lambda (status filename buffer) (org-download--write-image status filename) (with-current-buffer buffer - (org-display-inline-images))) + (org-download--display-inline-images))) (list (expand-file-name filename) (current-buffer)) @@ -288,14 +330,20 @@ COMMAND is a format-style string with two slots for LINK and FILENAME." (defun org-download-yank () "Call `org-download-image' with current kill." (interactive) - (org-download-image (current-kill 0))) + (org-download-image + (replace-regexp-in-string "\n+$" "" (current-kill 0)))) (defun org-download-screenshot () "Capture screenshot and insert the resulting file. The screenshot tool is determined by `org-download-screenshot-method'." (interactive) - (shell-command (format org-download-screenshot-method - org-download-screenshot-file)) + (let ((default-directory "~")) + (make-directory (file-name-directory org-download-screenshot-file) t) + (if (functionp org-download-screenshot-method) + (funcall org-download-screenshot-method + org-download-screenshot-file) + (shell-command (format org-download-screenshot-method + org-download-screenshot-file)))) (org-download-image org-download-screenshot-file)) (declare-function org-attach-dir "org-attach") @@ -314,7 +362,7 @@ The screenshot tool is determined by `org-download-screenshot-method'." It's inserted before the image link and is used to annotate it.") (defvar org-download-link-format - "[[file:%s]]" + "[[file:%s]]\n" "Format of the file link to insert.") (defun org-download-image (link) @@ -353,6 +401,9 @@ It's inserted before the image link and is used to annotate it.") (org-download--image link filename) (when (eq org-download-method 'attach) (org-attach-attach filename nil 'none)) + (when (and (eq org-download-delete-image-after-download t) + (not (url-handler-file-remote-p (current-kill 0)))) + (delete-file link delete-by-moving-to-trash)) (org-download-insert-link link filename))))) (defun org-download-rename-at-point () @@ -382,7 +433,7 @@ It's inserted before the image link and is used to annotate it.") (file-name-nondirectory org-download-path-last-file) (concat newname "." ext)) (setq org-download-path-last-file newpath) - (org-display-inline-images)))) + (org-download--display-inline-images)))) (defun org-download-replace-all (oldpath newpath) "Function to search for the OLDPATH inside the buffer and replace it by the NEWPATH." @@ -391,27 +442,43 @@ It's inserted before the image link and is used to annotate it.") (while (re-search-forward oldpath nil t) (replace-match newpath)))) +(defcustom org-download-abbreviate-filename-function #'file-relative-name + "Function that takes FILENAME and returns an abbreviated file name." + :type '(choice + (const :tag "relative" file-relative-name) + (const :tag "absolute" expand-file-name))) + (defun org-download-insert-link (link filename) - (if (looking-back "^[ \t]+" (line-beginning-position)) - (delete-region (match-beginning 0) (match-end 0)) - (newline)) - (insert - (concat - (funcall org-download-annotate-function link) - "\n" - (if (= org-download-image-html-width 0) - "" - (format "#+attr_html: :width %dpx\n" org-download-image-html-width)) - (if (= org-download-image-latex-width 0) - "" - (format "#+attr_latex: :width %dcm\n" org-download-image-latex-width)) - (if (= org-download-image-org-width 0) - "" - (format "#+attr_org: :width %dpx\n" org-download-image-org-width)) - (format org-download-link-format - (org-link-escape - (file-relative-name filename (file-name-directory (buffer-name))))))) - (org-display-inline-images)) + (let* ((beg (point)) + (line-beg (line-beginning-position)) + (indent (- beg line-beg)) + (in-item-p (org-in-item-p)) + str) + (if (looking-back "^[ \t]+" line-beg) + (delete-region (match-beginning 0) (match-end 0)) + (newline)) + (insert (funcall org-download-annotate-function link)) + (insert "\n") + (dolist (attr org-download-image-attr-list) + (insert attr "\n")) + (insert (if (= org-download-image-html-width 0) + "" + (format "#+attr_html: :width %dpx\n" org-download-image-html-width))) + (insert (if (= org-download-image-latex-width 0) + "" + (format "#+attr_latex: :width %dcm\n" org-download-image-latex-width))) + (insert (if (= org-download-image-org-width 0) + "" + (format "#+attr_org: :width %dpx\n" org-download-image-org-width))) + (insert + (format org-download-link-format + (org-link-escape + (funcall org-download-abbreviate-filename-function filename)))) + (org-download--display-inline-images) + (setq str (buffer-substring-no-properties line-beg (point))) + (when in-item-p + (indent-region line-beg (point) indent)) + str)) (defun org-download--at-comment-p () "Check if current line begins with #+DOWLOADED:." diff --git a/packages/org-jira-20190712.443.tar b/packages/org-jira-20190712.443.tar new file mode 100644 index 0000000..0a795fd Binary files /dev/null and b/packages/org-jira-20190712.443.tar differ diff --git a/packages/org-journal-20181115.714.el b/packages/org-journal-20181115.714.el deleted file mode 100644 index ed8aad9..0000000 --- a/packages/org-journal-20181115.714.el +++ /dev/null @@ -1,957 +0,0 @@ -;;; org-journal.el --- a simple org-mode based journaling mode - -;; Author: Bastian Bechtold -;; URL: http://github.com/bastibe/org-journal -;; Package-Version: 20181115.714 -;; Version: 1.15.0 -;; Package-Requires: ((emacs "25.1")) - -;;; Commentary: - -;; Adapted from http://www.emacswiki.org/PersonalDiary - -;; Functions to maintain a simple personal diary / journal in Emacs. -;; Feel free to use, modify and improve the code! - mtvoid, bastibe - -;; This file is also available from marmalade as -;; http://marmalade-repo.org/packages/journal. After installing, add -;; the line (require 'org-journal) to your .emacs or init.el to activate -;; it. You also need to specify the directory where your journal files -;; will be saved. You can do this by setting the variable journal-dir -;; (remember to add a trailing slash). journal-dir is also a -;; customizable variable. The default value for journal-dir is -;; ~/Documents/journal/. -;; -;; Inside the journal directory, a separate file is created for each -;; day with a journal entry, with a file name in the format YYYYMMDD -;; (this is customizable). Each journal entry is an org-mode file that -;; begins with a date entry on the top, followed by entries for a -;; different times. Any subsequent entries on the same day are written -;; in the same file, with their own timestamp. You can customize the -;; date and time formats (or remove them entirely). To start writing a -;; journal entry, press "C-c C-j". You can also open the current day's -;; entry without adding a new entry with "C-u C-c C-j". -;; -;; You can browse through existing journal entries on disk via the -;; calendar. All dates for which an entry is present are highlighted. -;; Pressing "j" will open it up for viewing. Pressing "C-j" will open -;; it for viewing, but not switch to it. Pressing "[" or "]" will -;; select the date with the previous or next journal entry, -;; respectively. Pressing "i j" will create a new entry for the chosen -;; date. -;; -;; TODO items from the previous day will carry over to the current -;; day. This is customizable through org-journal-carryover-items. -;; -;; Quick summary: -;; To create a new journal entry for the current time and day: C-c C-j -;; To open today's journal without creating a new entry: C-u C-c C-j -;; In calendar view: j to view an entry in a new buffer -;; C-j to view an entry but not switch to it -;; i j to add a new entry -;; f w to search all entries of the current week -;; f m to search all entries of the current month -;; f y to search all entries of the current year -;; f f to search all entries of all time -;; f F to search all entries in the future -;; [ to go to previous entry -;; ] to go to next entry -;; When viewing a journal entry: C-c C-b to view previous entry -;; C-c C-f to view next entry - -;;; Code: - -(defvar org-journal-file-pattern - (expand-file-name "~/Documents/journal/\\(?1:[0-9]\\{4\\}\\)\\(?2:[0-9][0-9]\\)\\(?3:[0-9][0-9]\\)\\'") - "This matches journal files in your journal directory. -This variable is created and updated automatically by -org-journal. Use org-journal-file-format instead.") - -;; use this function to update auto-mode-alist whenever -;; org-journal-dir or org-journal-file-pattern change. -;;;###autoload -(defun org-journal-update-auto-mode-alist () - "Update auto-mode-alist to open journal files in - org-journal-mode" - (add-to-list 'auto-mode-alist - (cons org-journal-file-pattern 'org-journal-mode))) - -;;;###autoload -(add-hook 'org-mode-hook 'org-journal-update-auto-mode-alist) -(add-hook 'org-agenda-mode-hook 'org-journal-update-org-agenda-files) - -;;;###autoload -(defun org-journal-dir-and-format->regex (dir format) - "Update org-journal-file-pattern with the current - org-journal-file-format" - (concat - (file-truename (expand-file-name (file-name-as-directory dir))) - (replace-regexp-in-string - "%d" "\\\\(?3:[0-9][0-9]\\\\)" - (replace-regexp-in-string - "%m" "\\\\(?2:[0-9][0-9]\\\\)" - (replace-regexp-in-string - "%Y" "\\\\(?1:[0-9]\\\\{4\\\\}\\\\)" format))) - "\\'")) - -; Customizable variables -(defgroup org-journal nil - "Settings for the personal journal" - :version "1.15.0" - :group 'applications) - -(defface org-journal-highlight - '((t (:foreground "#ff1493"))) - "Face for highlighting org-journal buffers." - :group 'org-journal) - -(defun org-journal-highlight (str) - "Highlight STR in current-buffer" - (goto-char (point-min)) - (while (search-forward str nil t) - (put-text-property (match-beginning 0) (match-end 0) 'font-lock-face 'org-journal-highlight))) - -(defface org-journal-calendar-entry-face - '((t (:foreground "#aa0000" :slant italic))) - "Face for highlighting org-journal entries in M-x calendar." - :group 'org-journal) - -(defface org-journal-calendar-scheduled-face - '((t (:foreground "#600000" :slant italic))) - "Face for highlighting future org-journal entries in M-x calendar." - :group 'org-journal) - -(defcustom org-journal-dir "~/Documents/journal/" - "Directory containing journal entries. Setting this will update the - internal `org-journal-file-pattern` to a regex that matches the - directory, using `org-journal-dir-and-format->regex`, and update - `auto-mode-alist` using `(org-journal-update-auto-mode-alist)`." - :type 'string :group 'org-journal - :set (lambda (symbol value) - (set-default symbol value) - ;; if org-journal-file-format is not yet bound, we’ll need a default value - (let ((format (if (boundp 'org-journal-file-format) - org-journal-file-format - "%Y%m%d"))) - (setq org-journal-file-pattern - (org-journal-dir-and-format->regex value format))) - (org-journal-update-auto-mode-alist))) - -(defcustom org-journal-file-format "%Y%m%d" - "Format string for journal file names, by default \"YYYYMMDD\". - This pattern must include `%Y`, `%m` and `%d`. Setting this - will update the internal `org-journal-file-pattern` to a regex - that matches the format string, using - `org-journal-dir-and-format->regex`, and update - `auto-mode-alist` using - `(org-journal-update-auto-mode-alist)`." - :type 'string :group 'org-journal - :set (lambda (symbol value) - (set-default symbol value) - ;; If org-journal-dir is not yet bound, we’ll need a default value - (let ((dir (if (boundp 'org-journal-dir) - org-journal-dir - "~/Documents/journal/"))) - (setq org-journal-file-pattern - (org-journal-dir-and-format->regex dir value))) - (org-journal-update-auto-mode-alist))) - -(defcustom org-journal-date-format "%A, %x" - "Format string for date, by default \"WEEKDAY, DATE\", where - DATE is what Emacs thinks is an appropriate way to format days - in your language. If you define it as a function, it is evaluated - and inserted." - :type 'string :group 'org-journal) - -(defcustom org-journal-date-prefix "* " - "String that is put before every date at the top of a journal - file. By default, this is a org-mode heading. Another good idea - would be \"#+TITLE: \" for org titles." - :type 'string :group 'org-journal) - -(defcustom org-journal-time-format "%R " - "Format string for time, by default HH:MM. Set it to a blank -string if you want to disable timestamps." - :type 'string :group 'org-journal) - -(defcustom org-journal-time-format-post-midnight "" - "When non-blank, a separate time format string for after midnight, -when the current time is before the hour set by `org-extend-today-until`." - :type 'string :group 'org-journal) - -(defcustom org-journal-time-prefix "** " - "String that is put before every time entry in a journal file. - By default, this is an org-mode sub-heading." - :type 'string :group 'org-journal) - -(defcustom org-journal-hide-entries-p t - "If true, org-journal-mode will hide all but the current entry - when creating a new one." - :type 'boolean :group 'org-journal) - -(require 'org-crypt nil 'noerror) - -(defcustom org-journal-enable-encryption nil - "If non-nil, New journal entries will have a -`org-crypt-tag-matcher' tag for encrypting. Whenever a user -saves/opens these journal entries, emacs asks a user passphrase -to encrypt/decrypt it." - :type 'boolean :group 'org-journal) - -(defcustom org-journal-encrypt-on 'before-save-hook - "Hook on which to encrypt entries. It can be set to other hooks - like kill-buffer-hook. " - :type 'function :group 'org-journal) - -(defcustom org-journal-enable-agenda-integration nil - "If non-nil, automatically adds current and future org-journal - files to org-agenda-files." - :type 'boolean :group 'org-journal) - -(defcustom org-journal-find-file 'find-file-other-window - "The function to use when opening an entry. Set this to `find-file` if you don't want org-journal to split your window." - :type 'function :group 'org-journal) - -(defcustom org-journal-carryover-items "TODO=\"TODO\"" - "Carry over items that match these criteria from the previous entry to new entries. -See agenda tags view match description for the format of this." - :type 'string :group 'org-journal) - -(defcustom org-journal-search-results-order-by :asc - "When :desc, make search results ordered by date descending - -Otherwise, date ascending." - :type 'symbol :group 'org-journal) - -(defvar org-journal-after-entry-create-hook nil - "Hook called after journal entry creation") - -;; Automatically switch to journal mode when opening a journal entry file -(setq org-journal-file-pattern - (org-journal-dir-and-format->regex org-journal-dir org-journal-file-format)) -(org-journal-update-auto-mode-alist) - -(require 'calendar) -;;;###autoload -(add-hook 'calendar-today-visible-hook 'org-journal-mark-entries) -;;;###autoload -(add-hook 'calendar-today-invisible-hook 'org-journal-mark-entries) - -;; Journal mode definition -;;;###autoload -(define-derived-mode org-journal-mode org-mode "Journal" - "Mode for writing or viewing entries written in the journal" - (turn-on-visual-line-mode) - (add-hook 'after-save-hook 'org-journal-redraw-calendar nil t) - (add-hook 'after-save-hook 'org-journal-update-org-agenda-files nil t) - (add-hook 'after-revert-hook 'org-journal-redraw-calendar nil t) - (run-mode-hooks)) - -;; Key bindings -(define-key org-journal-mode-map (kbd "C-c C-f") 'org-journal-open-next-entry) -(define-key org-journal-mode-map (kbd "C-c C-b") 'org-journal-open-previous-entry) -(define-key org-journal-mode-map (kbd "C-c C-j") 'org-journal-new-entry) -(define-key org-journal-mode-map (kbd "C-c C-s") 'org-journal-search) - -;;;###autoload -(eval-after-load "calendar" - '(progn - (define-key calendar-mode-map "j" 'org-journal-read-entry) - (define-key calendar-mode-map (kbd "C-j") 'org-journal-display-entry) - (define-key calendar-mode-map "]" 'org-journal-next-entry) - (define-key calendar-mode-map "[" 'org-journal-previous-entry) - (define-key calendar-mode-map (kbd "i j") 'org-journal-new-date-entry) - (define-key calendar-mode-map (kbd "f f") 'org-journal-search-forever) - (define-key calendar-mode-map (kbd "f F") 'org-journal-search-future) - (define-key calendar-mode-map (kbd "f w") 'org-journal-search-calendar-week) - (define-key calendar-mode-map (kbd "f m") 'org-journal-search-calendar-month) - (define-key calendar-mode-map (kbd "f y") 'org-journal-search-calendar-year))) - -;;;###autoload -(global-set-key (kbd "C-c C-j") 'org-journal-new-entry) - -(defun org-journal-get-entry-path (&optional time) - "Return the path to an entry given a TIME. -If no TIME is given, uses the current time." - (file-truename - (expand-file-name - (format-time-string org-journal-file-format time) - (file-name-as-directory org-journal-dir)))) - -(defun org-journal-dir-check-or-create () - "Check existence of `org-journal-dir'. If it doesn't exist, try to make directory." - (unless (file-exists-p org-journal-dir) - (if (yes-or-no-p (format "Journal directory %s not found. Create one? " org-journal-dir)) - (make-directory org-journal-dir t) - (error "Journal directory is necessary to use org-journal."))) - t) - -;;;###autoload -(defun org-journal-new-entry (prefix &optional time) - "Open today's journal file and start a new entry. -Giving the command a PREFIX arg will just open a today's file, -without adding an entry. If given a TIME, create an entry for the -time's day. If no TIME was given, use the current time (which is -interpreted as belonging to yesterday if smaller than -`org-extend-today-until`). - -Whenever a journal entry is created the -`org-journal-after-entry-create-hook' hook is run" - (interactive "P") - (org-journal-dir-check-or-create) - - ;; if time is before org-extend-today-until, interpret it as - ;; part of the previous day: - (let ((oetu-active-p nil)) - (let ((now (decode-time nil))) - (if (and (not time) ; time was not given - (< (nth 2 now) - org-extend-today-until)) - (setq oetu-active-p t - time (encode-time (nth 0 now) ; second - (nth 1 now) ; minute - (nth 2 now) ; hour - (1- (nth 3 now)) ; day - (nth 4 now) ; month - (nth 5 now) ; year - (nth 8 now))))) ; timezone - - (let* ((entry-path (org-journal-get-entry-path time)) - (should-add-entry-p (not prefix))) - - ;; open journal file - (unless (string= entry-path (buffer-file-name)) - (funcall org-journal-find-file entry-path)) - (org-journal-decrypt) - (goto-char (point-max)) - (let ((new-file-p (equal (point-max) 1))) - - ;; empty file? Add a date timestamp - (when new-file-p - (if (functionp org-journal-date-format) - (insert (funcall org-journal-date-format time)) - (insert org-journal-date-prefix - (format-time-string org-journal-date-format time)))) - - ;; add crypt tag if encryption is enabled and tag is not present - (when org-journal-enable-encryption - (goto-char (point-min)) - (unless (member org-crypt-tag-matcher (org-get-tags)) - (org-set-tags-to org-crypt-tag-matcher)) - (goto-char (point-max))) - - ;; move TODOs from previous day here - (when (and org-journal-carryover-items - (string= entry-path (org-journal-get-entry-path (current-time)))) - (save-excursion (org-journal-carryover))) - - ;; insert the header of the entry - (when should-add-entry-p - (unless (eq (current-column) 0) (insert "\n")) - (let* ((day-discrepancy (- (time-to-days (current-time)) (time-to-days time))) - (timestamp (cond - ;; “time†is today, use normal timestamp format - ((= day-discrepancy 0) - (format-time-string org-journal-time-format)) - ;; “time†is yesterday with org-extend-today-until, - ;; use different timestamp format if available - ((and (= day-discrepancy 1) oetu-active-p) - (if (not (string-equal org-journal-time-format-post-midnight "")) - (format-time-string org-journal-time-format-post-midnight) - (format-time-string org-journal-time-format))) - ;; “time†is on some other day, use blank timestamp - (t "")))) - (insert "\n" org-journal-time-prefix timestamp)) - (run-hooks 'org-journal-after-entry-create-hook)) - - ;; switch to the outline, hide subtrees - (org-journal-mode) - (if (and org-journal-hide-entries-p (org-journal-time-entry-level)) - (outline-hide-sublevels (org-journal-time-entry-level)) - (outline-show-all)) - - ;; open the recent entry when the prefix is given - (when should-add-entry-p - (outline-show-entry)))))) - -(defun org-journal-carryover () - "Moves all items matching org-journal-carryover-items from the -previous day's file to the current file." - (interactive) - (let ((current-buffer-name (buffer-name)) - (all-todos)) - (save-excursion - (let ((org-journal-find-file 'find-file) - (delete-mapper - (lambda () - (let ((subtree (org-journal-extract-current-subtree t))) - ;; since the next subtree now starts at point, - ;; continue mapping from before that, to include it - ;; in the search - (backward-char) - (setq org-map-continue-from (point)) - subtree)))) - (org-journal-open-previous-entry) - (setq all-todos (org-map-entries delete-mapper - org-journal-carryover-items)) - (save-buffer))) - (switch-to-buffer current-buffer-name) - (when all-todos - (unless (eq (current-column) 0) (insert "\n")) - (insert "\n") - (insert (mapconcat 'identity all-todos ""))))) - -(defun org-journal-extract-current-subtree (delete-p) - "Get the string content of the entire current subtree." - (let* ((start (progn (beginning-of-line) - (point))) - (end (progn (org-end-of-subtree) - (outline-next-heading) - (point))) - (subtree (buffer-substring-no-properties start end))) - (when delete-p - (delete-region start end)) - subtree)) - -(defun org-journal-time-entry-level () - "Return the headline level of time entries based on the number -of leading asterisks in 'org-journal-time-prefix. - -Return nil when it's impossible to figure out the level." - (if (string-match "\\(^\*+\\)" org-journal-time-prefix) - (length (match-string 1 org-journal-time-prefix)))) - -(defun org-journal-calendar-date->time (calendar-date) - "Convert a date as returned from the calendar to a time" - (encode-time 0 0 0 ; second, minute, hour - (nth 1 calendar-date) ; day - (nth 0 calendar-date) ; month - (nth 2 calendar-date))) ; year - -(defun org-journal-file-name->calendar-date (file-name) - "Convert an org-journal file name to a calendar date. - If org-journal-file-pattern does not contain capture groups, - fall back to the old behavior of taking substrings." - (if (and (integerp (string-match "\(\?1:" org-journal-file-pattern)) - (integerp (string-match "\(\?2:" org-journal-file-pattern)) - (integerp (string-match "\(\?3:" org-journal-file-pattern))) - (list (string-to-number (replace-regexp-in-string - org-journal-file-pattern "\\2" - file-name)) - (string-to-number (replace-regexp-in-string - org-journal-file-pattern "\\3" - file-name)) - (string-to-number (replace-regexp-in-string - org-journal-file-pattern "\\1" - file-name))) - (list (string-to-number (substring file-name 4 6)) - (string-to-number (substring file-name 6 8)) - (string-to-number (substring file-name 0 4))))) - -;;;###autoload -(defun org-journal-new-date-entry (prefix &optional event) - "Open the journal for the date indicated by point and start a new entry. -If the date is not today, it won't be given a time heading. If a -prefix is given, don't add a new heading. -If the date is in the future, create a schedule entry." - (interactive - (list current-prefix-arg last-nonmenu-event)) - (let* ((time (org-journal-calendar-date->time - (calendar-cursor-to-date t event)))) - (if (time-less-p time (current-time)) - (org-journal-new-entry prefix time) - (org-journal-new-scheduled-entry prefix (format-time-string "%Y-%m-%d" time))))) - -;;;###autoload -(defun org-journal-new-scheduled-entry (prefix &optional scheduled-time) - "Create a new entry in the future." - (interactive "P") - (let ((scheduled-time (or scheduled-time (org-read-date nil nil nil "Date:")))) - (org-journal-new-entry nil (org-time-string-to-time scheduled-time)) - (if (not prefix) - (insert "TODO ")) - (save-excursion - (insert "\n<" scheduled-time ">")))) - -(defun org-journal-open-next-entry () - "Open the next journal entry starting from a currently displayed one" - (interactive) - (let ((calendar-date (org-journal-file-name->calendar-date - (buffer-file-name))) - (view-mode-p view-mode) - (dates (org-journal-list-dates))) - ;; insert current buffer in list if not present - (unless (file-exists-p (buffer-file-name)) - (setq dates (cons calendar-date dates)) - (sort dates (lambda (a b) (calendar-date-compare (list a) (list b))))) - (calendar-basic-setup nil t) - (while (and dates (not (calendar-date-compare (list calendar-date) dates))) - (setq dates (cdr dates))) - (calendar-exit) - (if dates - (let* ((time (org-journal-calendar-date->time (car dates))) - (filename (org-journal-get-entry-path time))) - (find-file filename) - (org-journal-decrypt) - (view-mode (if view-mode-p 1 -1)) - (if (org-at-heading-p) (org-show-subtree))) - (message "No next journal entry after this one")))) - -(defun org-journal-open-previous-entry () - "Open the previous journal entry starting from a currently displayed one" - (interactive) - (let ((calendar-date (org-journal-file-name->calendar-date - (buffer-file-name))) - (view-mode-p view-mode) - (dates (reverse (org-journal-list-dates)))) - ;; insert current buffer in list if not present - (unless (file-exists-p (buffer-file-name)) - (setq dates (cons calendar-date dates)) - ;; reverse-sort! - (sort dates (lambda (a b) (calendar-date-compare (list b) (list a))))) - (calendar-basic-setup nil t) - (while (and dates (calendar-date-compare (list calendar-date) dates)) - (setq dates (cdr dates))) - (calendar-exit) - (if (and dates (cadr dates)) - (let* ((time (org-journal-calendar-date->time (cadr dates))) - (filename (org-journal-get-entry-path time))) - (find-file filename) - (org-journal-decrypt) - (view-mode (if view-mode-p 1 -1)) - (if (org-at-heading-p) (org-show-subtree))) - (message "No previous journal entry before this one")))) - -;; -;; Functions to browse existing journal entries using the calendar -;; - -;;;###autoload -(defun org-journal-list-files () - "Returns a list of all files in the journal directory" - (org-journal-dir-check-or-create) - ;; grab the file list. We can’t use directory-files-recursively’s - ;; regexp facility to filter it, because that only checks the - ;; regexp against the base filenames, and we need to check it - ;; against filenames relative to org-journal-dir. - (let ((file-list (directory-files-recursively - (file-truename (expand-file-name (file-name-as-directory org-journal-dir))) "\.*")) - (predicate (lambda (file-path) - (string-match-p org-journal-file-pattern (file-truename file-path))))) - (seq-filter predicate file-list))) - -(defun org-journal-list-dates () - "Loads the list of files in the journal directory, and converts - it into a list of calendar DATE elements" - (mapcar #'org-journal-file-name->calendar-date - (org-journal-list-files))) - -;;;###autoload -(defun org-journal-mark-entries () - "Mark days in the calendar for which a diary entry is present" - (dolist (journal-entry (org-journal-list-dates)) - (if (calendar-date-is-visible-p journal-entry) - (if (time-less-p (org-journal-calendar-date->time journal-entry) - (current-time)) - (calendar-mark-visible-date journal-entry 'org-journal-calendar-entry-face) - (calendar-mark-visible-date journal-entry 'org-journal-calendar-scheduled-face))))) - -;;;###autoload -(defun org-journal-read-entry (arg &optional event) - "Open journal entry for selected date for viewing" - (interactive - (list current-prefix-arg last-nonmenu-event)) - - (let* ((time (org-journal-calendar-date->time - (calendar-cursor-to-date t event)))) - (org-journal-read-or-display-entry time nil))) - -;;;###autoload -(defun org-journal-display-entry (arg &optional event) - "Display journal entry for selected date in another - window (without switÑhing to it)" - (interactive - (list current-prefix-arg last-nonmenu-event)) - (let* ((time (org-journal-calendar-date->time - (calendar-cursor-to-date t event)))) - (org-journal-read-or-display-entry time t))) - -;; silence compiler warning. -(defvar view-exit-action) - -;;;###autoload -(defun org-journal-read-or-display-entry (time &optional noselect) - "Read an entry for the TIME and either select the new - window (NOSELECT is nil) or avoid switching (NOSELECT is - non-nil." - (let ((org-journal-file (org-journal-get-entry-path time))) - (if (file-exists-p org-journal-file) - (progn - ;; open file in view-mode if not opened already - (let ((had-a-buf (get-file-buffer org-journal-file)) - ;; use find-file... instead of view-file... since - ;; view-file does not respect auto-mode-alist - (buf (find-file-noselect org-journal-file))) - (with-current-buffer buf - (when (not had-a-buf) - (view-mode) - (setq view-exit-action 'kill-buffer)) - (set (make-local-variable 'org-hide-emphasis-markers) t) - (org-journal-decrypt) - (if (org-at-heading-p) (org-show-subtree))) - (if (not noselect) - (funcall org-journal-find-file org-journal-file) - (display-buffer buf t)))) - (message "No journal entry for this date.")))) - -;;;###autoload -(defun org-journal-next-entry () - "Go to the next date with a journal entry" - (interactive) - (let ((dates (org-journal-list-dates))) - (while (and dates (not (calendar-date-compare - (list (calendar-cursor-to-date)) dates))) - (setq dates (cdr dates))) - (if dates (calendar-goto-date (car dates))))) - -;;;###autoload -(defun org-journal-previous-entry () - "Go to the previous date with a journal entry" - (interactive) - (let ((dates (reverse (org-journal-list-dates)))) - (while (and dates - (not (calendar-date-compare dates (list (calendar-cursor-to-date))))) - (setq dates (cdr dates))) - (if dates (calendar-goto-date (car dates))))) - -(defun org-journal-redraw-calendar () - "Redraw the calendar with all current journal entries" - (save-window-excursion - (calendar-basic-setup nil t) - (org-journal-mark-entries) - (calendar-exit))) - -;;; Journal search facilities -;; - -;;;###autoload -(defun org-journal-search (str &optional period-name) - "Search for a string in the journal within a given interval. -See `org-read-date` for information on ways to specify dates. -If a prefix argument is given, search all dates." - (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) - (let* ((period-pair (org-journal-read-period (if current-prefix-arg 'forever period-name))) - (start (org-journal-calendar-date->time (car period-pair))) - (end (org-journal-calendar-date->time (cdr period-pair)))) - (org-journal-search-by-string str start end))) - -(defvar org-journal-search-history nil) - -(defun org-journal-search-calendar-week (str) - "Search for a string within a current calendar-mode week entries" - (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) - (org-journal-search str 'week)) - -(defun org-journal-search-calendar-month (str) - "Search for a string within a current calendar-mode month entries" - (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) - (org-journal-search str 'month)) - -(defun org-journal-search-calendar-year (str) - "Search for a string within a current calendar-mode year entries" - (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) - (org-journal-search str 'year)) - -(defun org-journal-search-forever (str) - "Search for a string within all entries" - (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) - (org-journal-search str 'forever)) - -(defun org-journal-search-future (str) - "Search for a string within all future entries" - (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) - (org-journal-search str 'future)) - -(defun org-journal-search-future-scheduled () - "Search for TODOs within all future entries" - (interactive) - (org-journal-search "TODO" 'future)) - -;; This macro is needed for many of the following functions. -(defmacro org-journal-with-find-file (file &rest body) - "Executes BODY in FILE. Use this to insert text into FILE. -The buffer is disposed after the macro exits (unless it already -existed before)." - `(save-excursion - (let ((current-buffer (current-buffer)) - (buffer-exists (get-buffer (file-name-nondirectory ,file))) - (result nil)) - (if buffer-exists - (switch-to-buffer buffer-exists) - (find-file ,file)) - (setq result (progn ,@body)) - (basic-save-buffer) - (unless buffer-exists - (kill-buffer)) - (switch-to-buffer current-buffer) - result))) - -(require 'seq) -(defun org-journal-update-org-agenda-files () - "Adds the current and future journal files to org-agenda-files. -And cleans out past org-journal files." - (when org-journal-enable-agenda-integration - (let ((agenda-files-without-org-journal - (seq-filter - (lambda (fname) - (not (string-match org-journal-file-pattern fname))) - (org-agenda-files))) - (org-journal-agenda-files - (seq-filter - ;; skip files that are older than today - (lambda (fname) - (not (time-less-p - (org-journal-calendar-date->time - (org-journal-file-name->calendar-date fname)) - (time-subtract (current-time) (days-to-time 1))))) - (org-journal-list-files)))) - (setq org-agenda-files (append agenda-files-without-org-journal - org-journal-agenda-files))))) - -(defun org-journal-schedule-view () - "Opens a new window with all scheduled journal entries. -Think of this as a faster, less fancy version of your org-agenda." - (interactive) - (find-file-other-window "*Org-journal schedule*") - (view-mode -1) - (erase-buffer) - (org-mode) - (insert "#+TITLE: Org-Journal Schedule\n\n") - (let* ((schedule-buffer (current-buffer)) - (period-pair (org-journal-read-period 'future)) - (start (org-journal-calendar-date->time (car period-pair))) - (end (org-journal-calendar-date->time (cdr period-pair))) - (file-list (org-journal-search-build-file-list start end)) - (search-results nil)) - (dolist (filename (sort file-list - (lambda (x y) - (time-less-p - (org-journal-calendar-date->time - (org-journal-file-name->calendar-date x)) - (org-journal-calendar-date->time - (org-journal-file-name->calendar-date y)))))) - (let ((time (org-journal-calendar-date->time - (org-journal-file-name->calendar-date filename))) - (copy-mapper (lambda () (let ((subtree (org-journal-extract-current-subtree nil))) - ;; since the next subtree now starts at point, - ;; continue mapping from before that, to include it - ;; in the search - (backward-char) - (setq org-map-continue-from (point)) - subtree))) - (content-to-copy nil)) - (if (functionp org-journal-date-format) - (insert (funcall org-journal-date-format time)) - (insert org-journal-date-prefix - (format-time-string org-journal-date-format time) - "\n")) - (org-journal-with-find-file - filename - (setq content-to-copy (org-map-entries copy-mapper - "+TIMESTAMP>=\"<now>\"|+SCHEDULED>=\"<now>\""))) - (if content-to-copy - (insert (mapconcat 'identity content-to-copy "") "\n") - (insert "N/A\n")))) - (set-buffer-modified-p nil) - (view-mode t) - (goto-char (point-min)))) - -(defun org-journal-read-period (period-name) - "If the PERIOD-NAME is nil, then ask the user for period -start/end; if PERIOD-NAME is 'forever, set the period from the -beginning of time to eternity; if PERIOD-NAME is a symbol equal -to 'week/'month/'year then use current week/month/year from the -calendar accordingly." - (cond - ;; no period-name? ask the user for input - ((not period-name) - (let* ((org-read-date-prefer-future nil) - (absolute-start (time-to-days (org-read-date nil t nil "Enter a period start"))) - (absolute-end (time-to-days (org-read-date nil t nil "Enter a period end"))) - (start (calendar-gregorian-from-absolute absolute-start)) - (end (calendar-gregorian-from-absolute absolute-end))) - (cons start end))) - - ;; eternity start/end - ((eq period-name 'forever) - (cons (list 1 1 1971) - (list 12 31 2030))) - - ;; future start/end - ((eq period-name 'future) - (let ((date (decode-time (current-time)))) - (cons (list (nth 4 date) (nth 3 date) (nth 5 date)) - (list 12 31 2030)))) - - ;; extract a year start/end using the calendar curson - ((and (eq period-name 'year) (eq major-mode 'calendar-mode)) - (calendar-cursor-to-nearest-date) - (let* ((date (calendar-cursor-to-date)) - (year (calendar-extract-year date)) - (jan-first (list 1 1 year)) - (dec-31 (list 12 31 year))) - (cons jan-first - dec-31))) - - ;; month start/end - ((and (eq period-name 'month) (eq major-mode 'calendar-mode)) - (calendar-cursor-to-nearest-date) - (let* ((date (calendar-cursor-to-date)) - (year (calendar-extract-year date)) - (month (calendar-extract-month date)) - (last-day (calendar-last-day-of-month month year))) - (cons (list month 1 year) - (list month last-day year)))) - - ;; week start/end - ((and (eq period-name 'week) (eq major-mode 'calendar-mode)) - (calendar-cursor-to-nearest-date) - (let* ((date (calendar-cursor-to-date)) - (absoluteday (calendar-absolute-from-gregorian date)) - (weekday (calendar-day-of-week date)) - (zerobased-weekday (- weekday calendar-week-start-day)) - (absolute-start (- absoluteday zerobased-weekday)) - (absolute-end (+ absoluteday (- 7 zerobased-weekday))) - (start (calendar-gregorian-from-absolute absolute-start)) - (end (calendar-gregorian-from-absolute absolute-end))) - (cons start end))) - - (t (error "Wrong period-name given or not in the calendar mode")))) - -(defun org-journal-search-by-string (str &optional period-start period-end) - "Search for a string within a given time interval. -if no string is given, search for all entries using -org-journal-time-prefix." - (when (time-less-p period-end period-start) - (error "Period end cannot be before the start")) - (let* ((search-str (if (string= "" str) org-journal-time-prefix str)) - (files (org-journal-search-build-file-list period-start period-end)) - (results (org-journal-search-do-search search-str files))) - (with-current-buffer-window - "*Org-journal search*" nil nil - (org-journal-search-print-results str results period-start period-end)))) - -(defun org-journal-search-build-file-list (&optional period-start period-end) - "Build a list of journal files within a given time interval" - (let ((files (org-journal-list-files)) - result) - (dolist (file files) - (let ((filetime (org-journal-calendar-date->time - (org-journal-file-name->calendar-date file)))) - (cond ((not (and period-start period-end)) - (push file result)) - - ((and period-start period-end - (time-less-p period-start filetime) - (time-less-p filetime period-end)) - (push file result)) - - ((and period-start - (not period-end) - (time-less-p period-start filetime)) - (push file result)) - - ((and period-end - (not period-start) - (time-less-p filetime period-end)) - (push file result))))) - result)) - -(defun org-journal-search-do-search (str files) - "Search for a string within a list of files, return match pairs (PATH . LINENUM)" - (let (results) - (dolist (fname (reverse files)) - (with-temp-buffer - (insert-file-contents fname) - (while (search-forward str nil t) - (let* ((fullstr (buffer-substring-no-properties - (line-beginning-position) - (line-end-position))) - (res (list fname (line-number-at-pos) fullstr))) - (push res results))))) - (cond - ((eql org-journal-search-results-order-by :desc) results) - (t (reverse results))))) - -(defun org-journal-format-date (time) - "Format TIME according to `org-journal-date-format`" - (if (functionp org-journal-date-format) - (funcall org-journal-date-format time) - (format-time-string org-journal-date-format time))) - -(defun org-journal-search-print-results (str results period-start period-end) - "Print search results using text buttons" - (let ((label-start (org-journal-format-date period-start)) - (label-end (org-journal-format-date period-end))) - (princ (concat "Search results for \"" str "\" between " - label-start " and " label-end - ": \n\n"))) - (dolist (res results) - (let* ((fname (nth 0 res)) - (lnum (nth 1 res)) - (fullstr (nth 2 res)) - (time (org-journal-calendar-date->time - (org-journal-file-name->calendar-date fname))) - (label (org-journal-format-date time)) - - (label-end (org-journal-format-date period-start))) - - (insert-text-button label - 'action 'org-journal-search-follow-link-action - 'org-journal-link (cons fname lnum)) - (princ "\t") - (princ fullstr) - (princ "\n"))) - (org-journal-highlight str) - (local-set-key (kbd "q") 'kill-this-buffer) - (local-set-key (kbd "<tab>") 'forward-button) - (local-set-key (kbd "<backtab>") 'backward-button) - (local-set-key (kbd "n") 'forward-button) - (local-set-key (kbd "p") 'backward-button)) - -(defun org-journal-search-follow-link-action (button) - "Follow the link using info saved in button properties" - (let* ((target (button-get button 'org-journal-link)) - (fname (car target)) - (lnum (cdr target))) - (org-journal-read-or-display-entry - (org-journal-calendar-date->time - (org-journal-file-name->calendar-date fname))) - (outline-show-all) ; TODO: could not find out a proper way to go to a hidden line - (goto-char (point-min)) - (forward-line (1- lnum)))) - -(defun org-journal-decrypt () - (when (fboundp 'org-decrypt-entries) - (let ((buffer-read-only nil)) - (org-decrypt-entries)))) - -(defun org-journal-encryption-hook () - "The function added to the hook specified by - `org-journal-encrypt-on'." - (when org-journal-enable-encryption - (org-encrypt-entries) - (unless (equal org-journal-encrypt-on - 'before-save-hook) - (save-buffer)))) - -;; Setup encryption by default -;;;###autoload -(add-hook 'org-journal-mode-hook - (lambda () (org-add-hook org-journal-encrypt-on - 'org-journal-encryption-hook - nil t))) - -(provide 'org-journal) - -;;; org-journal.el ends here diff --git a/packages/org-journal-20190816.2036.el b/packages/org-journal-20190816.2036.el new file mode 100644 index 0000000..1f7b54d --- /dev/null +++ b/packages/org-journal-20190816.2036.el @@ -0,0 +1,1316 @@ +;;; org-journal.el --- a simple org-mode based journaling mode -*- lexical-binding: t; -*- + +;; Author: Bastian Bechtold +;; URL: http://github.com/bastibe/org-journal +;; Package-Version: 20190816.2036 +;; Version: 1.15.1 +;; Package-Requires: ((emacs "25.1")) + +;;; Commentary: + +;; Adapted from http://www.emacswiki.org/PersonalDiary + +;; Functions to maintain a simple personal diary / journal in Emacs. +;; Feel free to use, modify and improve the code! - mtvoid, bastibe + +;; This file is also available from marmalade as +;; http://marmalade-repo.org/packages/journal. After installing, add +;; the line (require 'org-journal) to your .emacs or init.el to activate +;; it. You also need to specify the directory where your journal files +;; will be saved. You can do this by setting the variable journal-dir +;; (remember to add a trailing slash). journal-dir is also a +;; customizable variable. The default value for journal-dir is +;; ~/Documents/journal/. +;; +;; Inside the journal directory, a separate file is created for each +;; day with a journal entry, with a file name in the format YYYYMMDD +;; (this is customizable). Each journal entry is an org-mode file that +;; begins with a date entry on the top, followed by entries for a +;; different times. Any subsequent entries on the same day are written +;; in the same file, with their own timestamp. You can customize the +;; date and time formats (or remove them entirely). To start writing a +;; journal entry, press "C-c C-j". You can also open the current day's +;; entry without adding a new entry with "C-u C-c C-j". +;; +;; You can browse through existing journal entries on disk via the +;; calendar. All dates for which an entry is present are highlighted. +;; Pressing "j" will open it up for viewing. Pressing "C-j" will open +;; it for viewing, but not switch to it. Pressing "[" or "]" will +;; select the date with the previous or next journal entry, +;; respectively. Pressing "i j" will create a new entry for the chosen +;; date. +;; +;; TODO items from the previous day will carry over to the current +;; day. This is customizable through org-journal-carryover-items. +;; +;; Quick summary: +;; To create a new journal entry for the current time and day: C-c C-j +;; To open today's journal without creating a new entry: C-u C-c C-j +;; In calendar view: j to view an entry in a new buffer +;; C-j to view an entry but not switch to it +;; i j to add a new entry +;; f w to search all entries of the current week +;; f m to search all entries of the current month +;; f y to search all entries of the current year +;; f f to search all entries of all time +;; f F to search all entries in the future +;; [ to go to previous entry +;; ] to go to next entry +;; When viewing a journal entry: C-c C-b to view previous entry +;; C-c C-f to view next entry + + +;;; Code: +(require 'org) +(require 'cal-iso) +(require 'org-crypt nil 'noerror) +(require 'seq) + +(when (version< org-version "9.2") + (defalias 'org-set-tags-to 'org-set-tags)) + +(defvar org-journal-file-pattern + (expand-file-name "~/Documents/journal/\\(?1:[0-9]\\{4\\}\\)\\(?2:[0-9][0-9]\\)\\(?3:[0-9][0-9]\\)\\'") + "This matches journal files in your journal directory. + +This variable is created and updated automatically by +org-journal. Use `org-journal-file-format' instead.") + +;; use this function to update auto-mode-alist whenever +;; org-journal-dir or org-journal-file-pattern change. +;;;###autoload +(defun org-journal-update-auto-mode-alist () + "Update `auto-mode-alist' to open journal files in `org-journal-mode'." + (add-to-list 'auto-mode-alist + (cons org-journal-file-pattern 'org-journal-mode))) + +;;;###autoload +(add-hook 'org-mode-hook 'org-journal-update-auto-mode-alist) +(add-hook 'org-agenda-mode-hook 'org-journal-update-org-agenda-files) + +;;;###autoload +(defun org-journal-dir-and-format->regex (dir format) + "Update `org-journal-file-pattern' with the current `org-journal-file-format'." + (concat + (file-truename (expand-file-name (file-name-as-directory dir))) + (replace-regexp-in-string + "%d" "\\\\(?3:[0-9][0-9]\\\\)" + (replace-regexp-in-string + "%m" "\\\\(?2:[0-9][0-9]\\\\)" + (replace-regexp-in-string + "%Y" "\\\\(?1:[0-9]\\\\{4\\\\}\\\\)" format))) + "\\(\\.gpg\\)?\\'")) + +; Customizable variables +(defgroup org-journal nil + "Settings for the personal journal" + :version "1.15.1" + :group 'applications) + +(defface org-journal-highlight + '((t (:foreground "#ff1493"))) + "Face for highlighting org-journal buffers.") + +(defun org-journal-highlight (str) + "Highlight STR in current-buffer" + (goto-char (point-min)) + (while (search-forward str nil t) + (put-text-property (match-beginning 0) (match-end 0) 'font-lock-face 'org-journal-highlight))) + +(defface org-journal-calendar-entry-face + '((t (:foreground "#aa0000" :slant italic))) + "Face for highlighting org-journal entries in M-x calendar.") + +(defface org-journal-calendar-scheduled-face + '((t (:foreground "#600000" :slant italic))) + "Face for highlighting future org-journal entries in M-x calendar.") + +(defcustom org-journal-file-type 'daily + "What type of journal file to create." + :type '(choice + (const :tag "Daily" daily) + (const :tag "Weekly" weekly) + (const :tag "Monthly" monthly) + (const :tag "Yearly" yearly))) + +(defcustom org-journal-dir "~/Documents/journal/" + "Directory containing journal entries. + +Setting this will update the internal `org-journal-file-pattern' to a regex +that matches the directory, using `org-journal-dir-and-format->regex', and +update `auto-mode-alist' using `org-journal-update-auto-mode-alist'." + :type 'string + :set (lambda (symbol value) + (set-default symbol value) + ;; if org-journal-file-format is not yet bound, we’ll need a default value + (let ((format (if (boundp 'org-journal-file-format) + org-journal-file-format + "%Y%m%d"))) + (setq org-journal-file-pattern + (org-journal-dir-and-format->regex value format))) + (org-journal-update-auto-mode-alist))) + +(defcustom org-journal-file-format "%Y%m%d" + "Format string for journal file names (Default \"YYYYMMDD\"). + +This pattern must include `%Y', `%m' and `%d'. Setting this will update the internal +`org-journal-file-pattern' to a regex that matches the format string, using +`org-journal-dir-and-format->regex', and update `auto-mode-alist' using +`org-journal-update-auto-mode-alist'." + :type 'string + :set (lambda (symbol value) + (set-default symbol value) + ;; If org-journal-dir is not yet bound, we’ll need a default value + (let ((dir (if (boundp 'org-journal-dir) + org-journal-dir + "~/Documents/journal/"))) + (setq org-journal-file-pattern + (org-journal-dir-and-format->regex dir value))) + (org-journal-update-auto-mode-alist))) + +(defcustom org-journal-date-format "%A, %x" + "Format string for date entries. + +By default \"WEEKDAY, DATE\", where DATE is what Emacs thinks is an +appropriate way to format days in your language. If you define it as +a function, it is evaluated and inserted." + :type 'string) + +(defcustom org-journal-date-prefix "* " + "String that is put before every date at the top of a journal file. + +By default, this is a org-mode heading. Another good idea would be +\"#+TITLE: \" for org titles. + +Setting `org-journal-date-prefix' to something other than \"* \" +for weekly/monthly/yearly journal files won't work correctly." + :type 'string) + +(defcustom org-journal-time-format "%R " + "Format string for time entries. + +By default HH:MM. Set it to a blank string if you want to disable timestamps." + :type 'string) + +(defcustom org-journal-time-format-post-midnight "" + "When non-blank, a separate time format string for after midnight. + +When the current time is before the hour set by `org-extend-today-until'." + :type 'string) + +(defcustom org-journal-time-prefix "** " + "String that is put before every time entry in a journal file. + +By default, this is an org-mode sub-heading." + :type 'string) + +(defcustom org-journal-hide-entries-p t + "If true, `org-journal-mode' will hide all but the current entry when creating a new one." + :type 'boolean) + +(defcustom org-journal-enable-encryption nil + "If non-nil, new journal entries will have a `org-crypt-tag-matcher' tag for encrypting. + +Whenever a user saves/opens these journal entries, emacs asks a user passphrase +to encrypt/decrypt it." + :type 'boolean) + +(defcustom org-journal-encrypt-journal nil + "If non-nil, encrypt journal files using gpg. + +The journal files will have the file extension \".gpg\"." + :type 'boolean) + +(defcustom org-journal-encrypt-on 'before-save-hook + "Hook on which to encrypt entries. + +It can be set to other hooks like `kill-buffer-hook'." + :type 'function) + +(defcustom org-journal-enable-agenda-integration nil + "If non-nil, automatically adds current and future org-journal files to `org-agenda-files'." + :type 'boolean) + +(defcustom org-journal-find-file 'find-file-other-window + "The function to use when opening an entry. + +Set this to `find-file' if you don't want org-journal to split your window." + :type 'function) + +(defcustom org-journal-carryover-items "TODO=\"TODO\"" + "Carry over items that match these criteria from the previous entry to new entries. + +See agenda tags view match description for the format of this." + :type 'string) + +(defcustom org-journal-search-results-order-by :asc + "When :desc, make search results ordered by date descending, otherwise date ascending." + :type 'symbol) + +(defcustom org-journal-tag-alist nil + "Default tags for use in Org-Journal mode. +This is analogous to `org-tag-alist', and uses the same format. +If nil, the default, then `org-tag-alist' is used instead. +This can also be overridden on a file-local level by using a “#+TAGS:†+keyword." + :type (get 'org-tag-alist 'custom-type)) + +(defcustom org-journal-tag-persistent-alist nil + "Persistent tags for use in Org-Journal mode. +This is analogous to `org-tag-persistent-alist', and uses the same +format. If nil, the default, then `org-tag-persistent-alist' is used +instead. These tags cannot be overridden with a “#+TAGS:†keyword, but +they can be disabled per-file by adding the line “#+STARTUP: noptag†+anywhere in your file." + :type (get 'org-tag-persistent-alist 'custom-type)) + +(defcustom org-journal-search-forward-fn 'search-forward + "The function used by `org-journal-search` to look for the string +forward in a buffer. +Defaults to search-forward. +You can, for example, set it to `search-forward-regexp` so the +search works with regexps." + :type 'function) + +(defvar org-journal-after-entry-create-hook nil + "Hook called after journal entry creation.") + +(defvar org-journal-search-buffer "*Org-journal search*") + + +;; Automatically switch to journal mode when opening a journal entry file +(setq org-journal-file-pattern + (org-journal-dir-and-format->regex org-journal-dir org-journal-file-format)) +(org-journal-update-auto-mode-alist) + +(add-hook 'calendar-today-visible-hook 'org-journal-mark-entries) +(add-hook 'calendar-today-invisible-hook 'org-journal-mark-entries) + +;; Journal mode definition +;;;###autoload +(define-derived-mode org-journal-mode org-mode + "Journal" + "Mode for writing or viewing entries written in the journal." + (turn-on-visual-line-mode) + (add-hook 'after-save-hook 'org-journal-update-org-agenda-files nil t) + (when (or org-journal-tag-alist org-journal-tag-persistent-alist) + (org-journal-set-current-tag-alist)) + (run-mode-hooks)) + +;; Key bindings +(define-key org-journal-mode-map (kbd "C-c C-f") 'org-journal-open-next-entry) +(define-key org-journal-mode-map (kbd "C-c C-b") 'org-journal-open-previous-entry) +(define-key org-journal-mode-map (kbd "C-c C-j") 'org-journal-new-entry) +(define-key org-journal-mode-map (kbd "C-c C-s") 'org-journal-search) + +;;;###autoload +(eval-after-load "calendar" + '(progn + (define-key calendar-mode-map "m" 'org-journal-mark-entries) + (define-key calendar-mode-map "j" 'org-journal-read-entry) + (define-key calendar-mode-map (kbd "C-j") 'org-journal-display-entry) + (define-key calendar-mode-map "]" 'org-journal-next-entry) + (define-key calendar-mode-map "[" 'org-journal-previous-entry) + (define-key calendar-mode-map (kbd "i j") 'org-journal-new-date-entry) + (define-key calendar-mode-map (kbd "f f") 'org-journal-search-forever) + (define-key calendar-mode-map (kbd "f F") 'org-journal-search-future) + (define-key calendar-mode-map (kbd "f w") 'org-journal-search-calendar-week) + (define-key calendar-mode-map (kbd "f m") 'org-journal-search-calendar-month) + (define-key calendar-mode-map (kbd "f y") 'org-journal-search-calendar-year))) + +(global-set-key (kbd "C-c C-j") 'org-journal-new-entry) + +(defmacro org-journal-with-journal (journal-file &rest body) + "Opens JOURNAL-FILE in fundamental mode, or switches to the buffer which is visiting JOURNAL-FILE. + +Returns the last value from BODY. If the buffer didn't exist before it will be deposed." + ;; Use find-file... instead of view-file... since + ;; view-file does not respect auto-mode-alist + `(let* ((buffer-exists (get-buffer (file-name-nondirectory ,journal-file))) + (buf (if buffer-exists buffer-exists + (generate-new-buffer (file-name-nondirectory ,journal-file)))) + result) + (with-current-buffer buf + (unless buffer-exists + (insert-file-contents ,journal-file)) + (setq result (progn ,@body))) + (unless buffer-exists + (kill-buffer buf)) + result)) + +(defvar org-journal-created-re " *:CREATED: *[0-9]\\{8\\}" + "Regex to find created property.") + +(defsubst org-journal-search-forward-created (date) + "Search for CREATED tag with date. + +DATE should be a calendar date list (MONTH DAY YEAR)." + (re-search-forward + (format " *:CREATED: *%.4d%.2d%.2d" (nth 2 date) (car date) (cadr date)))) + +(defun org-journal-daily-p () + "Returns t if `org-journal-file-type' is set to `'daily'." + (eq org-journal-file-type 'daily)) + +(defun org-journal-org-heading-p () + "Returns t if `org-journal-date-prefix' starts with \"* \"." + (string-match "^\* " org-journal-date-prefix)) + +(defun org-journal-convert-time-to-file-type-time (&optional time) + "Converts TIME to the file type format date. + +If `org-journal-file-type' is 'weekly the TIME will be rounded to +the first date of the week. + +If `org-journal-file-type' is 'monthly the TIME will be rounded to +the first date of the month. + +If `org-journal-file-type' is 'yearly the TIME will be rounded to +the first date of the year." + (or time (setq time (current-time))) + (pcase org-journal-file-type + ;; Do nothing for daily + (`daily time) + ;; Round to the monday of the current week, e.g. 20181231 is the first week of 2019 + (`weekly + (let ((date + (calendar-gregorian-from-absolute + (calendar-iso-to-absolute + (mapcar 'string-to-number + (split-string (format-time-string "%V 1 %G" time) " ")))))) + (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))) + ;; Round to the first day of the month, e.g. 20190301 + (`monthly + (apply 'encode-time + `(0 0 0 ,@(mapcar 'string-to-number + (split-string (format-time-string "1 %m %Y" time) " "))))) + ;; Round to the first day of the year, e.g. 20190101 + (`yearly + (apply 'encode-time + `(0 0 0 ,@(mapcar 'string-to-number + (split-string (format-time-string "1 1 %Y" time) " "))))))) + +(defun org-journal-get-entry-path (&optional time) + "Return the path to an entry matching TIME, if no TIME is given, uses the current time." + (let ((file (file-truename + (expand-file-name + (format-time-string org-journal-file-format + (org-journal-convert-time-to-file-type-time time)) + (file-name-as-directory org-journal-dir))))) + (when (and org-journal-encrypt-journal (not (file-exists-p file))) + (setq file (concat file ".gpg"))) + file)) + +(defun org-journal-dir-check-or-create () + "Check existence of `org-journal-dir'. If it doesn't exist, try to make directory." + (unless (file-exists-p org-journal-dir) + (if (yes-or-no-p (format "Journal directory %s not found. Create one? " org-journal-dir)) + (make-directory org-journal-dir t) + (error "Journal directory is necessary to use org-journal."))) + t) + +(defun org-journal-set-current-tag-alist () + "Set `org-current-tag-alist' for the current journal file. +This allows the use of `org-journal-tag-alist' and +`org-journal-tag-persistent-alist', which when non-nil override +`org-tag-alist' and `org-journal-tag-persistent-alist' respectively." + (setq org-current-tag-alist ; this var is always buffer-local + (org--tag-add-to-alist + (or org-journal-tag-persistent-alist org-tag-persistent-alist) + (let* ((alist (org--setup-collect-keywords + (org-make-options-regexp + '("FILETAGS" "TAGS" "SETUPFILE")))) + (tags (cdr (assq 'tags alist)))) + (if (and alist tags) + (org-tag-string-to-alist tags) + (or org-journal-tag-alist org-tag-alist)))))) + +;;;###autoload +(defun org-journal-new-entry (prefix &optional time) + "Open today's journal file and start a new entry. + +With a PREFIX arg, open the today's file, create a heading if it doesn't exist yet, +but do not create a new entry. + +If given a TIME, create an entry for the time's day. If no TIME was given, +use the current time (which is interpreted as belonging to yesterday if +smaller than `org-extend-today-until`). + +Whenever a journal entry is created the `org-journal-after-entry-create-hook' +hook is run." + (interactive "P") + (org-journal-dir-check-or-create) + + ;; if time is before org-extend-today-until, interpret it as + ;; part of the previous day: + (let (oetu-active-p) ;; org-extend-today-until-active-p + (let ((now (decode-time nil))) + (if (and (not time) ; time was not given + (< (nth 2 now) + org-extend-today-until)) + (setq oetu-active-p t + time (encode-time (nth 0 now) ; second + (nth 1 now) ; minute + (nth 2 now) ; hour + (1- (nth 3 now)) ; day + (nth 4 now) ; month + (nth 5 now) ; year + (nth 8 now))))) ; timezone + + (let* ((entry-path (org-journal-get-entry-path time)) + (should-add-entry-p (not prefix)) + match) + + ;; Open journal file + (unless (string= entry-path (buffer-file-name)) + (funcall org-journal-find-file entry-path)) + + ;; Create new journal entry if there isn't one. + (let ((entry-header + (if (functionp org-journal-date-format) + (funcall org-journal-date-format time) + (concat org-journal-date-prefix + (format-time-string org-journal-date-format time))))) + (goto-char (point-min)) + (unless (search-forward entry-header nil t) + ;; Insure we insert the new journal header at the correct location + (unless (org-journal-daily-p) + (let ((date (decode-time time)) + (dates (sort (org-journal-file->calendar-dates (buffer-file-name)) + (lambda (a b) + (calendar-date-compare (list b) (list a)))))) + (setq date (list (nth 4 date) (nth 3 date) (nth 5 date))) + (while dates + (when (calendar-date-compare dates (list date)) + (org-journal-search-forward-created (car dates)) + (outline-end-of-subtree) + (insert "\n") + (setq match t + dates nil)) + (setq dates (cdr dates))))) + ;; True if entry must be inserted at the end of the journal file. + (unless match + (goto-char (point-max)) + (forward-line)) + (when (looking-back "[^\t ]" (point-at-bol)) + (insert "\n")) + (beginning-of-line) + (insert entry-header) + ;; For 'weekly, 'monthly and 'yearly journal entries + ;; create a "CREATED" property with the current date. + (unless (org-journal-daily-p) + (org-set-property "CREATED" (format-time-string "%Y%m%d" time))) + (when org-journal-enable-encryption + (unless (member org-crypt-tag-matcher (org-get-tags)) + (org-set-tags org-crypt-tag-matcher))))) + (org-journal-decrypt) + + ;; move TODOs from previous day here + (when (and org-journal-carryover-items + (string= entry-path (org-journal-get-entry-path (current-time)))) + (org-journal-carryover)) + + (if (org-journal-org-heading-p) + (outline-end-of-subtree) + (goto-char (point-max))) + + ;; insert the header of the entry + (when should-add-entry-p + (unless (eq (current-column) 0) (insert "\n")) + (let* ((day-discrepancy (- (time-to-days (current-time)) (time-to-days time))) + (timestamp (cond + ;; “time†is today, use normal timestamp format + ((= day-discrepancy 0) + (format-time-string org-journal-time-format)) + ;; “time†is yesterday with org-extend-today-until, + ;; use different timestamp format if available + ((and (= day-discrepancy 1) oetu-active-p) + (if (not (string-equal org-journal-time-format-post-midnight "")) + (format-time-string org-journal-time-format-post-midnight) + (format-time-string org-journal-time-format))) + ;; “time†is on some other day, use blank timestamp + (t "")))) + (insert org-journal-time-prefix timestamp)) + (run-hooks 'org-journal-after-entry-create-hook)) + + (if (and org-journal-hide-entries-p (org-journal-time-entry-level)) + (outline-hide-sublevels (org-journal-time-entry-level)) + (save-excursion (org-journal-finalize-view))) + + (when should-add-entry-p + (outline-show-entry))))) + +(defvar org-journal--kill-buffer nil + "Will be set to the `t' if `org-journal-open-entry' is visiting a +buffer not open already, otherwise `nil'.") + +(defun org-journal-carryover () + "Moves all items matching `org-journal-carryover-items' from the +previous day's file to the current file." + (interactive) + (let* ((org-journal-find-file 'find-file) + ;; Doesn't keep value after org-journal-carryover-item-with-parents + (mapper (lambda () + (let ((headings (org-journal-carryover-item-with-parents))) + ;; since the next subtree now starts at point, + ;; continue mapping from before that, to include it + ;; in the search + (setq org-map-continue-from (point)) + headings))) + carryover-items-with-parents + carryover-items-non-parents + prev-entry-buffer) + (save-excursion + (save-restriction + (when (let ((inhibit-message t)) + (org-journal-open-previous-entry 'no-select)) + (setq prev-entry-buffer (current-buffer)) + (unless (org-journal-daily-p) ;; (org-journal-org-heading-p) should work to + (org-narrow-to-subtree)) + ;; Create a sorted list with duplicates removed from the value returned + ;; from `org-map-entries'. The returned value from `org-map-entries', + ;; is a list where each element is list containing points, which are representing + ;; the headers to carryover -- cddr contains the text. + (mapc (lambda (carryover-path) + (push (car carryover-path) carryover-items-non-parents) + (mapc (lambda (heading) + (unless (member heading carryover-items-with-parents) + (push heading carryover-items-with-parents))) + carryover-path)) + (org-map-entries mapper org-journal-carryover-items)) + (setq carryover-items-with-parents (sort carryover-items-with-parents + (lambda (x y) + (< (car x) (car y)))))))) + (when carryover-items-with-parents + (when (org-journal-org-heading-p) + (outline-end-of-subtree)) + (unless (eq (current-column) 0) (insert "\n")) + (mapc (lambda (x) (insert (cddr x))) + carryover-items-with-parents) + ;; Delete carryover items + (with-current-buffer prev-entry-buffer + (mapc (lambda (x) + (kill-region (car x) (cadr x))) + carryover-items-non-parents) + (save-buffer) + (when org-journal--kill-buffer + (kill-buffer)))))) + +(defun org-journal-carryover-item-with-parents () + "Return carryover item inclusive the parents. + + The carryover item The parents + | /---------\ +;; ((START END . \"TEXT\") ... (START END . \"TEXT\")) +" + (let (start end text carryover-item-with-parents) + (save-excursion + (while (> (org-outline-level) (org-journal-time-entry-level)) + (org-up-heading-safe) + (setq start (point) + end (save-excursion (outline-next-heading) (point)) + text (buffer-substring-no-properties start end)) + (push (cons start (cons end text)) carryover-item-with-parents))) + (setq start (point-at-bol) + end (progn (outline-end-of-subtree) (outline-next-heading) (point)) + text (buffer-substring-no-properties start end)) + (push (cons start (cons end text)) carryover-item-with-parents))) + +(defun org-journal-time-entry-level () + "Return the headline level of time entries based on the number +of leading asterisks in `org-journal-time-prefix'. + +Return nil when it's impossible to figure out the level." + (when (string-match "\\(^\*+\\)" org-journal-time-prefix) + (length (match-string 1 org-journal-time-prefix)))) + +(defun org-journal-calendar-date->time (calendar-date) + "Convert a date as returned from the calendar to a time." + (encode-time 0 0 0 ; second, minute, hour + (nth 1 calendar-date) ; day + (nth 0 calendar-date) ; month + (nth 2 calendar-date))) ; year + +(defun org-journal-file-name->calendar-date (file-name) + "Convert an org-journal file name to a calendar date. + +If `org-journal-file-pattern' does not contain capture groups, +fall back to the old behavior of taking substrings." + (if (and (integerp (string-match "\(\?1:" org-journal-file-pattern)) + (integerp (string-match "\(\?2:" org-journal-file-pattern)) + (integerp (string-match "\(\?3:" org-journal-file-pattern))) + (list (string-to-number (replace-regexp-in-string + org-journal-file-pattern "\\2" + file-name)) + (string-to-number (replace-regexp-in-string + org-journal-file-pattern "\\3" + file-name)) + (string-to-number (replace-regexp-in-string + org-journal-file-pattern "\\1" + file-name))) + (list (string-to-number (substring file-name 4 6)) + (string-to-number (substring file-name 6 8)) + (string-to-number (substring file-name 0 4))))) + +(defun org-journal-entry-date->calendar-date () + "Return journal calendar-date from current buffer. + +This is the counterpart of `org-journal-file-name->calendar-date' for +'weekly, 'monthly and 'yearly journal files." + (let (date) + (setq date (org-entry-get (point) "CREATED")) + (string-match "\\([0-9]\\{4\\}\\)\\([0-9]\\{2\\}\\)\\([0-9]\\{2\\}\\)" date) + (list (string-to-number (match-string 2 date)) + (string-to-number (match-string 3 date)) + (string-to-number (match-string 1 date))))) + +(defun org-journal-file->calendar-dates (file) + "Return journal dates from FILE." + (interactive "P") + (org-journal-with-journal + file (let (dates) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward org-journal-created-re nil t) + (push (org-journal-entry-date->calendar-date) dates)) + dates)))) + +;;;###autoload +(defun org-journal-new-date-entry (prefix &optional event) + "Open the journal for the date indicated by point and start a new entry. + +If the date is not today, it won't be given a time heading. With one prefix (C-u), +don't add a new heading. + +If the date is in the future, create a schedule entry, unless two universal prefix +arguments (C-u C-u) are given. In that case insert just the heading." + (interactive + (list current-prefix-arg last-nonmenu-event)) + (let* ((time (org-journal-calendar-date->time + (calendar-cursor-to-date t event)))) + (if (time-less-p time (current-time)) + (org-journal-new-entry prefix time) + (org-journal-new-scheduled-entry prefix (format-time-string "%Y-%m-%d" time))))) + +;;;###autoload +(defun org-journal-new-scheduled-entry (prefix &optional scheduled-time) + "Create a new entry in the future." + (interactive "P") + (let ((scheduled-time (or scheduled-time (org-read-date nil nil nil "Date:"))) + (raw (prefix-numeric-value prefix))) + (org-journal-new-entry (= raw 16) (org-time-string-to-time scheduled-time)) + (unless (= raw 16) + (if (not prefix) + (insert "TODO ")) + (save-excursion + (insert "\n<" scheduled-time ">"))))) + +(defsubst org-journal-goto-journal-heading () + "Goto to journal heading." + (while (org-up-heading-safe))) + +(defun org-journal-open-entry (msg &optional prev no-select) + "Open journal entry. + +If no next/PREVious entry was found print MSG." + (let ((calendar-date (if (org-journal-daily-p) + (org-journal-file-name->calendar-date (file-truename (buffer-file-name))) + (org-journal-goto-journal-heading) + (org-journal-entry-date->calendar-date))) + (view-mode-p view-mode) + (dates (org-journal-list-dates))) + (unless (member calendar-date dates) + ;; Insert calendar-date into dates list keeping it in order. + (setq dates (cl-loop + for date in dates + while (calendar-date-compare (list date) (list calendar-date)) + collect date into result and count t into cnt + finally return (if result + ;; Front + `(,@result ,calendar-date) + ;; Somewhere enbetween or end of dates + `(,calendar-date ,@result ,@(nthcdr cnt dates)))))) + ;; Reverse list for previous search. + (when prev + (setq dates (reverse dates))) + (while (and dates (car dates) + (or (if prev + (calendar-date-compare (list calendar-date) dates) + (calendar-date-compare dates (list calendar-date))) + (calendar-date-equal (car dates) calendar-date))) + (setq dates (cdr dates))) + (if (and dates (car dates)) + (let* ((date (car dates)) + (time (org-journal-calendar-date->time date)) + (filename (org-journal-get-entry-path time))) + (if (get-file-buffer filename) + (progn + (if (eq 'no-select no-select) + (set-buffer (get-file-buffer filename)) + (switch-to-buffer (get-file-buffer filename))) + (setq org-journal--kill-buffer nil)) + (setq org-journal--kill-buffer (if (eq 'no-select no-select) + (set-buffer (find-file-noselect filename)) + (find-file filename)))) + (goto-char (point-min)) + (if (org-journal-daily-p) + (outline-next-visible-heading 1) + (org-journal-search-forward-created date)) + (org-journal-finalize-view) + (view-mode (if view-mode-p 1 -1)) + t) + (message msg) + nil))) + +(defun org-journal-open-next-entry (&optional no-select) + "Open the next journal entry starting from a currently displayed one." + (interactive) + (org-journal-open-entry "No next journal entry after this one" nil no-select)) + +(defun org-journal-open-previous-entry (&optional no-select) + "Open the previous journal entry starting from a currently displayed one." + (interactive) + (org-journal-open-entry "No previous journal entry before this one" t no-select)) + +;; +;; Functions to browse existing journal entries using the calendar +;; + +;;;###autoload +(defun org-journal-list-files () + "Returns a list of all files in the journal directory." + (org-journal-dir-check-or-create) + ;; grab the file list. We can’t use directory-files-recursively’s + ;; regexp facility to filter it, because that only checks the + ;; regexp against the base filenames, and we need to check it + ;; against filenames relative to org-journal-dir. + (let ((file-list (directory-files-recursively + (file-truename (expand-file-name + (file-name-as-directory org-journal-dir))) "\.*")) + (predicate (lambda (file-path) + (and (string-match-p org-journal-file-pattern (file-truename file-path)) + (or org-journal-encrypt-journal + (not (string-match-p "\.gpg$" (file-truename file-path)))))))) + (seq-filter predicate file-list))) + +(defun org-journal-list-dates () + "Loads the list of files in the journal directory, and converts +it into a list of calendar date elements." + (let ((dates (mapcar (if (org-journal-daily-p) + 'org-journal-file-name->calendar-date + 'org-journal-file->calendar-dates) + (org-journal-list-files)))) + ;; Need to flatten the list and bring dates in correct order. + (unless (org-journal-daily-p) + (let ((flattened-date-l '()) + flattened-date-reverse-l file-dates) + (while dates + (setq file-dates (car dates)) + (setq flattened-date-reverse-l '()) + (while file-dates + (push (car file-dates) flattened-date-reverse-l) + (setq file-dates (cdr file-dates))) + ;; Correct order of journal entries from file by pushing it to a new list. + (mapc (lambda (p) + (push p flattened-date-l)) + flattened-date-reverse-l) + (setq dates (cdr dates))) + (setq dates (reverse flattened-date-l)))) + dates)) + +;;;###autoload +(defun org-journal-mark-entries () + "Mark days in the calendar for which a diary entry is present" + (interactive) + (when (file-exists-p org-journal-dir) + (dolist (journal-entry (org-journal-list-dates)) + (if (calendar-date-is-visible-p journal-entry) + (if (time-less-p (org-journal-calendar-date->time journal-entry) + (current-time)) + (calendar-mark-visible-date journal-entry 'org-journal-calendar-entry-face) + (calendar-mark-visible-date journal-entry 'org-journal-calendar-scheduled-face)))))) + +;;;###autoload +(defun org-journal-read-entry (_arg &optional event) + "Open journal entry for selected date for viewing" + (interactive + (list current-prefix-arg last-nonmenu-event)) + (let* ((time (org-journal-calendar-date->time + (calendar-cursor-to-date t event)))) + (org-journal-read-or-display-entry time nil))) + +;;;###autoload +(defun org-journal-display-entry (_arg &optional event) + "Display journal entry for selected date in another window." + (interactive + (list current-prefix-arg last-nonmenu-event)) + (let* ((time (org-journal-calendar-date->time + (calendar-cursor-to-date t event)))) + (org-journal-read-or-display-entry time t))) + +;; silence compiler warning. +(defvar view-exit-action) + +(defun org-journal-finalize-view () + "Finalize visability of entry." + (org-journal-decrypt) + (if (org-journal-org-heading-p) + (progn + (org-up-heading-safe) + (org-back-to-heading) + (outline-hide-other) + (outline-show-subtree)) + (outline-show-all))) + +;;;###autoload +(defun org-journal-read-or-display-entry (time &optional noselect) + "Read an entry for the TIME and either select the new window when NOSELECT +is nil or avoid switching when NOSELECT is non-nil." + (let* ((org-journal-file (org-journal-get-entry-path time)) + (buf-exists (get-file-buffer org-journal-file)) + buf point) + (if (and (when (file-exists-p org-journal-file) + (setq buf (find-file-noselect org-journal-file))) + ;; If daily continoue with body of if condition + (or (org-journal-daily-p) + ;; Search for journal entry + (with-current-buffer buf + (save-mark-and-excursion + (goto-char (point-min)) + (setq point (re-search-forward + (format-time-string " *:CREATED: *%Y%m%d" time) nil t)))))) + (progn + ;; Use `find-file-noselect' instead of `view-file' as it does not respect `auto-mode-alist' + (with-current-buffer buf + ;; Open file in view-mode if not opened already. + (unless buf-exists + (view-mode) + (setq view-exit-action 'kill-buffer)) + (set (make-local-variable 'org-hide-emphasis-markers) t) + (unless (org-journal-daily-p) + (goto-char point)) + (org-journal-finalize-view) + (setq point (point))) + (if noselect + (display-buffer buf t) + (funcall org-journal-find-file org-journal-file)) + (set-window-point (get-buffer-window (get-file-buffer org-journal-file)) point) + buf) + (message "No journal entry for this date.")))) + +;;;###autoload +(defun org-journal-next-entry () + "Go to the next date with a journal entry." + (interactive) + (let ((dates (org-journal-list-dates))) + (while (and dates (not (calendar-date-compare + (list (calendar-cursor-to-date)) dates))) + (setq dates (cdr dates))) + (when dates + (calendar-goto-date (car dates))))) + +;;;###autoload +(defun org-journal-previous-entry () + "Go to the previous date with a journal entry." + (interactive) + (let ((dates (reverse (org-journal-list-dates)))) + (while (and dates + (not (calendar-date-compare dates (list (calendar-cursor-to-date))))) + (setq dates (cdr dates))) + (when dates + (calendar-goto-date (car dates))))) + +;;; Journal search facilities +;; + +;;;###autoload +(defun org-journal-search (str &optional period-name) + "Search for a string in the journal within a given interval. + +See `org-read-date' for information on ways to specify dates. +If a prefix argument is given, search all dates." + (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) + (let* ((period-pair (org-journal-read-period (if current-prefix-arg 'forever period-name))) + (start (org-journal-calendar-date->time (car period-pair))) + (end (org-journal-calendar-date->time (cdr period-pair)))) + (org-journal-search-by-string str start end))) + +(defvar org-journal-search-history nil) + +(defun org-journal-search-calendar-week (str) + "Search for a string within a current calendar-mode week entries." + (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) + (org-journal-search str 'week)) + +(defun org-journal-search-calendar-month (str) + "Search for a string within a current calendar-mode month entries." + (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) + (org-journal-search str 'month)) + +(defun org-journal-search-calendar-year (str) + "Search for a string within a current calendar-mode year entries." + (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) + (org-journal-search str 'year)) + +(defun org-journal-search-forever (str) + "Search for a string within all entries." + (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) + (org-journal-search str 'forever)) + +(defun org-journal-search-future (str) + "Search for a string within all future entries." + (interactive (list (read-string "Enter a string to search for: " nil 'org-journal-search-history))) + (org-journal-search str 'future)) + +(defun org-journal-search-future-scheduled () + "Search for TODOs within all future entries." + (interactive) + (org-journal-search "TODO" 'future)) + +;; This macro is needed for many of the following functions. +(defmacro org-journal-with-find-file (file &rest body) + "Executes BODY in FILE. Use this to insert text into FILE. + +The buffer is disposed after the macro exits (unless it already +existed before)." + `(save-excursion + (let ((current-buffer (current-buffer)) + (buffer-exists (get-buffer (file-name-nondirectory ,file))) + (result nil)) + (if buffer-exists + (switch-to-buffer buffer-exists) + (find-file ,file)) + (setq result (progn ,@body)) + (basic-save-buffer) + (unless buffer-exists + (kill-buffer)) + (switch-to-buffer current-buffer) + result))) + +(defun org-journal-update-org-agenda-files () + "Adds the current and future journal files to `org-agenda-files', and cleans +out past org-journal files." + (when org-journal-enable-agenda-integration + (let ((not-org-journal-agenda-files + (seq-filter + (lambda (fname) + (not (string-match org-journal-file-pattern fname))) + (org-agenda-files))) + (org-journal-agenda-files + (let* ((future (org-journal-read-period 'future)) + (beg (car future)) + (end (cdr future))) + ;; TODO(cschwarzgruber): Needs to be adopted for weekly, monthly or yearly journal file type. + ;; We actually would need to limit the file scope, if we only want TODO's for today, and future. + (setcar (cdr beg) (1- (cadr beg))) + (org-journal-search-build-file-list + (org-journal-calendar-date->time beg) + (org-journal-calendar-date->time end))))) + (setq org-agenda-files (append not-org-journal-agenda-files + org-journal-agenda-files))))) + +(defun org-journal-schedule-view () + "Opens a new window with all scheduled journal entries. + +Think of this as a faster, less fancy version of your `org-agenda'." + (interactive) + (find-file-other-window "*Org-journal schedule*") + (view-mode -1) + (erase-buffer) + (org-mode) + (insert "#+TITLE: Org-Journal Schedule\n\n") + (let* ((period-pair (org-journal-read-period 'future)) + (start (org-journal-calendar-date->time (car period-pair))) + (end (org-journal-calendar-date->time (cdr period-pair))) + (file-list (org-journal-search-build-file-list start end))) + (dolist (filename (sort file-list + (lambda (x y) + (time-less-p + (org-journal-calendar-date->time + (org-journal-file-name->calendar-date x)) + (org-journal-calendar-date->time + (org-journal-file-name->calendar-date y)))))) + (let ((time (org-journal-calendar-date->time + (org-journal-file-name->calendar-date filename))) + (copy-mapper + (lambda () + (let ((subtree (org-journal-carryover-item-with-parents))) + ;; since the next subtree now starts at point, + ;; continue mapping from before that, to include it + ;; in the search + (backward-char) + (setq org-map-continue-from (point)) + subtree))) + (content-to-copy nil)) + (if (functionp org-journal-date-format) + (insert (funcall org-journal-date-format time)) + (insert org-journal-date-prefix + (format-time-string org-journal-date-format time) + "\n")) + (org-journal-with-find-file + filename + (setq content-to-copy (org-map-entries + copy-mapper + "+TIMESTAMP>=\"<now>\"|+SCHEDULED>=\"<now>\""))) + (if content-to-copy + (insert (mapconcat 'identity content-to-copy "") "\n") + (insert "N/A\n")))) + (set-buffer-modified-p nil) + (view-mode t) + (goto-char (point-min)))) + +(defun org-journal-read-period (period-name) + "Return read period. + +If the PERIOD-NAME is nil, then ask the user for period start/end. +If PERIOD-NAME is 'forever, set the period from the beginning of time +to eternity. If PERIOD-NAME is a symbol equal to 'week, 'month or 'year +then use current week, month or year from the calendar, accordingly." + (cond + ;; no period-name? ask the user for input + ((not period-name) + (let* ((org-read-date-prefer-future nil) + (absolute-start (time-to-days (org-read-date nil t nil "Enter a period start"))) + (absolute-end (time-to-days (org-read-date nil t nil "Enter a period end"))) + (start (calendar-gregorian-from-absolute absolute-start)) + (end (calendar-gregorian-from-absolute absolute-end))) + (cons start end))) + + ;; eternity start/end + ((eq period-name 'forever) + (cons (list 1 1 1971) + (list 12 31 2030))) + + ;; future start/end + ((eq period-name 'future) + (let ((date (decode-time (current-time)))) + (cons (list (nth 4 date) (nth 3 date) (nth 5 date)) + (list 12 31 2030)))) + + ;; extract a year start/end using the calendar curson + ((and (eq period-name 'year) (eq major-mode 'calendar-mode)) + (calendar-cursor-to-nearest-date) + (let* ((date (calendar-cursor-to-date)) + (year (calendar-extract-year date)) + (jan-first (list 1 1 year)) + (dec-31 (list 12 31 year))) + (cons jan-first + dec-31))) + + ;; month start/end + ((and (eq period-name 'month) (eq major-mode 'calendar-mode)) + (calendar-cursor-to-nearest-date) + (let* ((date (calendar-cursor-to-date)) + (year (calendar-extract-year date)) + (month (calendar-extract-month date)) + (last-day (calendar-last-day-of-month month year))) + (cons (list month 1 year) + (list month last-day year)))) + + ;; week start/end + ((and (eq period-name 'week) (eq major-mode 'calendar-mode)) + (calendar-cursor-to-nearest-date) + (let* ((date (calendar-cursor-to-date)) + (absoluteday (calendar-absolute-from-gregorian date)) + (weekday (calendar-day-of-week date)) + (zerobased-weekday (- weekday calendar-week-start-day)) + (absolute-start (- absoluteday zerobased-weekday)) + (absolute-end (+ absoluteday (- 7 zerobased-weekday))) + (start (calendar-gregorian-from-absolute absolute-start)) + (end (calendar-gregorian-from-absolute absolute-end))) + (cons start end))) + + (t (error "Wrong period-name given or not in the calendar mode")))) + +(defun org-journal-search-by-string (str &optional period-start period-end) + "Search for a string within a given time interval. + +If STR is empty, search for all entries using `org-journal-time-prefix'." + (when (time-less-p period-end period-start) + (error "Period end cannot be before the start")) + (let* ((search-str (if (string= "" str) org-journal-time-prefix str)) + (files (org-journal-search-build-file-list period-start period-end)) + (results (org-journal-search-do-search search-str files)) + (buf (get-buffer-create org-journal-search-buffer)) + (inhibit-read-only t)) + (unless (get-buffer-window buf 0) + (switch-to-buffer buf)) + (with-current-buffer buf + (org-journal-search-mode) + (erase-buffer) + (org-journal-search-print-results str results period-start period-end) + (goto-char (point-min)) + (forward-button 1) + (button-activate (button-at (point)))))) + +(defun org-journal-search-build-file-list (period-start period-end) + "Build a list of journal files within a given time interval." + (unless (and period-start period-end ;; Check for null values + (car period-start) (cdr period-start) + (car period-end) (cdr period-end)) + (error "Time `%s' and/or `%s' are not valid" period-start period-end)) + + (let (result filetime) + (dolist (file (org-journal-list-files)) + (setq filetime (org-journal-calendar-date->time + (org-journal-file-name->calendar-date file))) + (when (and + (time-less-p + period-start + ;; Convert to period-start boundary. + (pcase org-journal-file-type + ;; For daily, filetime is period-start boundary. + (`daily filetime) + ;; For weekly, filetime +6 days is period-start boundary. + (`weekly + (let* ((time (decode-time filetime)) + (day (+ 6 (nth 3 time))) ;; End of week + (month (nth 4 time)) + (year (nth 5 time)) + (last-day-of-month (calendar-last-day-of-month month year))) + (when (> day last-day-of-month) + (setq day (- day last-day-of-month)) + (when (= month 12) + (setq month 0) + (setq year (1+ year))) + (setq month (1+ month))) + (encode-time 0 0 0 day month year))) + ;; For monthly, end of month is period-start boundary. + (`monthly + (let* ((time (decode-time filetime)) + (month (nth 4 time)) + (year (nth 5 time))) + (encode-time 0 0 0 (calendar-last-day-of-month month year) month year))) + ;; For yearly, end of year is period-start boundary. + (`yearly + (encode-time 0 0 0 31 12 (nth 5 (decode-time filetime)))))) + (time-less-p filetime period-end)) + (push file result))) + result)) + + + +(defun org-journal-search-do-search (str files) + "Search for a string within a list of files, return match pairs (PATH . LINENUM)." + (let (results result) + (dolist (fname (reverse files)) + (setq result (org-journal-with-journal + fname + (goto-char (point-min)) + (when org-journal-enable-encryption + ;; FIXME(cschwarzgruber): need to iterate over all entries for weekly/monthly/yearly + (org-decrypt-entry)) + (while (funcall org-journal-search-forward-fn str nil t) + (push + (list + (let ((date + (if (org-journal-daily-p) + (org-journal-file-name->calendar-date fname) + (save-excursion + (when (re-search-backward org-journal-created-re nil t) + (org-journal-entry-date->calendar-date)))))) + (when date + (org-journal-calendar-date->time date))) + (- (point) (length str)) + (buffer-substring-no-properties + (line-beginning-position) + (line-end-position))) + result)) + result)) + (when result + (mapc (lambda (res) (push res results)) result))) + (cond + ((eql org-journal-search-results-order-by :desc) results) + (t (reverse results))))) + +(defun org-journal-format-date (time) + "Format TIME according to `org-journal-date-format'." + (format-time-string "%A, %x" time)) + +(defun org-journal-search-next () + (interactive) + (forward-button 1 t) + (button-activate (button-at (point)))) + +(defun org-journal-search-prev () + (interactive) + (backward-button 1 t) + (button-activate (button-at (point)))) + +(defvar org-journal-search-mode-map nil + "Keymap for *Org-journal search* buffers.") +(unless org-journal-search-mode-map + (setq org-journal-search-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "q" 'kill-this-buffer) + (define-key map (kbd "<tab>") 'org-journal-search-next) + (define-key map (kbd "<backtab>") 'org-journal-search-prev) + (define-key map "n" 'org-journal-search-next) + (define-key map "p" 'org-journal-search-prev) + map))) +(fset 'org-journal-search-mode-map org-journal-search-mode-map) + +(define-derived-mode org-journal-search-mode special-mode + "org-journal-search" + "Major mode for displaying org-journal search results. +\\{org-journal-search-mode-map}." + (use-local-map org-journal-search-mode-map) + (setq truncate-lines t + buffer-undo-list t) + (hl-line-mode 1)) + +(defun org-journal-search-print-results (str results period-start period-end) + "Print search results using text buttons." + (let ((label-start (org-journal-format-date period-start)) + (label-end (org-journal-format-date period-end))) + (insert (concat "Search results for \"" str "\" between " + label-start " and " label-end + ": \n\n"))) + (let (point fullstr time label) + (dolist (res results) + (setq time (nth 0 res) + point (nth 1 res) + fullstr (nth 2 res) + label (and time (org-journal-format-date time))) + ;; Filter out entries not within period-start/end for weekly/monthly/yearly journal files. + (when (or(org-journal-daily-p) + (and time + (time-less-p period-start time) + (time-less-p time period-end))) + (insert-text-button label + 'action 'org-journal-search-follow-link-action + 'org-journal-link (cons point time)) + (insert "\t" fullstr "\n")))) + (org-journal-highlight str)) + +(defun org-journal-search-follow-link-action (button) + "Follow the link using info saved in button properties." + (let* ((target (button-get button 'org-journal-link)) + (point (car target)) + (time (cdr target)) + (buf (org-journal-read-or-display-entry time t))) + (set-window-point (get-buffer-window buf) point))) + +(defun org-journal-decrypt () + (when (fboundp 'org-decrypt-entries) + (let ((buffer-read-only nil)) + (org-decrypt-entries)))) + +(defun org-journal-encryption-hook () + "The function added to the hook specified by `org-journal-encrypt-on'." + (when org-journal-enable-encryption + (org-encrypt-entries) + (unless (equal org-journal-encrypt-on + 'before-save-hook) + (save-buffer)))) + +;; Setup encryption by default +;;;###autoload +(add-hook 'org-journal-mode-hook + (lambda () (add-hook org-journal-encrypt-on + 'org-journal-encryption-hook + nil t))) + +(provide 'org-journal) + +;;; org-journal.el ends here diff --git a/packages/org-mime-20181023.2314.el b/packages/org-mime-20190805.57.el similarity index 81% rename from packages/org-mime-20181023.2314.el rename to packages/org-mime-20190805.57.el index b913dcb..68a3af6 100644 --- a/packages/org-mime-20181023.2314.el +++ b/packages/org-mime-20190805.57.el @@ -5,9 +5,9 @@ ;; Author: Eric Schulte ;; Maintainer: Chen Bin (redguardtoo) ;; Keywords: mime, mail, email, html -;; Package-Version: 20181023.2314 +;; Package-Version: 20190805.57 ;; Homepage: http://github.com/org-mime/org-mime -;; Version: 0.1.1 +;; Version: 0.1.6 ;; Package-Requires: ((emacs "24.4") (cl-lib "0.5")) ;; This file is not part of GNU Emacs. @@ -43,17 +43,15 @@ ;; encoding. ;; ;; `org-mime-org-subtree-htmlize' is similar to `org-mime-org-buffer-htmlize' -;; but works on a subtree. It can also read the following subtree properties: -;; MAIL_SUBJECT, MAIL_TO, MAIL_CC, and MAIL_BCC. Note the behavior of this is -;; controlled by `org-mime-up-subtree-heading'. The default is to go up to the -;; heading containing the current subtree. - -;; Here is the sample of a subtree: +;; but works on current subtree. It can read following subtree properties: +;; MAIL_SUBJECT, MAIL_TO, MAIL_FROM, MAIL_CC, and MAIL_BCC. ;; +;; Here is the sample of a subtree: ;; * mail one ;; :PROPERTIES: ;; :MAIL_SUBJECT: mail title ;; :MAIL_TO: person1@gmail.com +;; :MAIL_FROM: sender@gmail.com ;; :MAIL_CC: person2@gmail.com ;; :MAIL_BCC: person3@gmail.com ;; :END: @@ -105,6 +103,7 @@ ;;; Code: (require 'cl-lib) +(require 'outline) (require 'org) (require 'ox-org) @@ -151,7 +150,7 @@ And ensure first line isn't assumed to be a title line." :group 'org-mime :type 'sexp) -(defvar org-mime-export-options nil +(defvar org-mime-export-options '(:with-latex dvipng) "Default export options which may overrides org buffer/subtree options. You avoid exporting section-number/author/toc with the setup below, `(setq org-mime-export-options '(:section-numbers nil :with-author nil :with-toc nil))'") @@ -163,7 +162,7 @@ This could be used for example to post-process html elements.") (defvar org-mime-pre-html-hook nil "Hook to run before html export. Functions should take no arguments and will be run in a -buffer holdin the text to be exported.") +buffer holding the text to be exported.") (defvar org-mime-send-buffer-hook nil "Hook to run in the Org-mode file before export.") @@ -171,11 +170,6 @@ buffer holdin the text to be exported.") (defvar org-mime-debug nil "Enable debug logger.") -(defvar org-mime-up-subtree-heading 'org-up-heading-safe - "Function to call before exporting a subtree. -You could use either `org-up-heading-safe' or `org-back-to-heading'.") - - (defun org-mime-get-export-options (subtreep) "SUBTREEP is t if current node is subtree." (cond @@ -188,31 +182,33 @@ You could use either `org-up-heading-safe' or `org-back-to-heading'.") (if (fboundp 'org-export--get-inbuffer-options) (org-export--get-inbuffer-options)))))) -(defun org-mime-get-exported-content (fmt subtreep) +(defun org-mime-current-line () + "Get current line" + (buffer-substring-no-properties (line-beginning-position) + (line-end-position))) + +(defun org-mime-export-buffer-or-subtree (subtreep) "Similar to `org-html-export-as-html' and `org-org-export-as-org'. -FMT is either 'org or 'html. SUBTREEP is t if current node is subtree." - (let* ((buf (org-export-to-buffer fmt "*Org Mime Export*" + (let* ((plain (buffer-string)) + (buf (org-export-to-buffer 'html "*Org Mime Export*" nil subtreep nil (org-mime-get-export-options subtreep))) (body (prog1 (with-current-buffer buf - (format "#+BEGIN_EXPORT %s\n%s\n#+END_EXPORT" - (symbol-name fmt) - (buffer-string))) + (buffer-string)) (kill-buffer buf)))) - body)) + (cons body plain))) -(defun org-mime--export-string (s fmt &optional opts) - "Export string S using FMT as the backend. +(defun org-mime-export-string (string &optional opts) + "Export STRING into html. OPTS is export options." ;; Emacs 25+ prefer exporting drawer by default ;; obviously not acceptable in exporting to mail body (let* ((org-export-with-drawers nil)) - (when org-mime-debug (message "org-mime--export-string called => %s" opts)) ;; we won't export title from org file anyway (if opts (setq opts (plist-put opts 'title nil))) ;; emacs24.4+ - (org-export-string-as s fmt t (or org-mime-export-options opts)))) + (org-export-string-as string 'html t (or org-mime-export-options opts)))) ;; example hook, for setting a dark background in ;; <pre style="background-color: #EEE;"> elements @@ -284,10 +280,10 @@ HTML is the body of the message." (buffer-substring (point-min) (point-max))))) (defun org-mime-multipart (plain html &optional images) - "Markup a multipart/alternative PLAIN with PLAIN and HTML alternatives. + "Markup a multipart/alternative with HTML alternatives. If html portion of message includes IMAGES they are wrapped in multipart/related part." (cl-case org-mime-library - (mml (concat "<#multipart type=alternative><#part type=text/plain>" + (mml (concat "<#multipart type=alternative>\n<#part type=text/plain>" plain (when images "<#multipart type=related>") "<#part type=text/html>" @@ -363,7 +359,8 @@ CURRENT-FILE is used to calculate full path of images." (message "Warning: org-element-map is not available. File links will not be attached.") nil))) -(defun org-mime-insert-html-content (body file s opts) +(defun org-mime-insert-html-content (plain file html opts) + "Insert HTML content." (let* ((files (org-mime-extract-non-image-files)) ;; dvipng for inline latex because MathJax doesn't work in mail ;; Also @see https://github.com/org-mime/org-mime/issues/16 @@ -372,15 +369,13 @@ CURRENT-FILE is used to calculate full path of images." ;; we don't want to convert org file links to html (org-html-link-org-files-as-html nil) (org-link-file-path-type 'absolute) - ;; makes the replies with ">"s look nicer + ;; prettify reply with ">" (org-export-preserve-breaks org-mime-preserve-breaks) - (plain (org-mime--export-string body 'org)) ;; org 9 (org-html-htmlize-output-type 'inline-css) ;; org 8 (org-export-htmlize-output-type 'inline-css) - (html-and-images (org-mime-replace-images (org-mime--export-string s 'html opts) - file)) + (html-and-images (org-mime-replace-images html file)) (images (cdr html-and-images)) (html (org-mime-apply-html-hook (car html-and-images)))) @@ -397,7 +392,7 @@ CURRENT-FILE is used to calculate full path of images." (insert (org-mime-multipart plain html - (mapconcat 'identity images "\n"))) + (if images (mapconcat 'identity images "\n")))) ;; Attach any residual files (when files @@ -422,22 +417,19 @@ If called with an active region only export that region, otherwise entire body." (html-end (or (and region-p (region-end)) ;; TODO: should catch signature... (point-max))) - (body (buffer-substring - html-start html-end)) - (str (concat org-mime-default-header body)) - (file (make-temp-name (expand-file-name - "mail" temporary-file-directory))) - - - ;; to hold attachments for inline html images + (plain (buffer-substring html-start html-end)) +;; to hold attachments for inline html images (opts (if (fboundp 'org-export--get-inbuffer-options) - (org-export--get-inbuffer-options)))) + (org-export--get-inbuffer-options))) + (html (org-mime-export-string (concat org-mime-default-header plain) opts)) + (file (make-temp-name (expand-file-name + "mail" temporary-file-directory)))) ;; delete current region (delete-region html-start html-end) (goto-char html-start) ;; insert new current - (org-mime-insert-html-content body file str opts))) + (org-mime-insert-html-content plain file html opts))) (defun org-mime-apply-html-hook (html) "Apply HTML hook." @@ -458,28 +450,27 @@ If called with an active region only export that region, otherwise entire body." (set-text-properties 0 (length txt) nil txt) txt)))) -(defun org-mime-compose (body file to subject headers subtreep) - "Create mail BODY in FILE with TO, SUBJECT, HEADERS. +(defun org-mime-compose (exported file to subject headers subtreep) + "Create mail body from EXPORTED in FILE with TO, SUBJECT, HEADERS. If SUBTREEP is t, curret org node is subtree." ;; start composing mail - (unless (featurep 'message) - (require 'message)) - (message-mail to subject headers nil) - (message-goto-body) - - ;; insert text - (let* ((str (with-temp-buffer - (insert body) - (goto-char (point-min)) - (run-hooks 'org-mime-pre-html-hook) - (buffer-string)))) - (org-mime-insert-html-content body - file - str - (org-mime-get-export-options subtreep)))) + (let* ((html (car exported)) + (plain (cdr exported)) + (export-opts (org-mime-get-export-options subtreep)) + patched-html) + (unless (featurep 'message) (require 'message)) + (message-mail to subject headers nil) + (message-goto-body) + (setq patched-html (with-temp-buffer + (insert html) + (goto-char (point-min)) + (run-hooks 'org-mime-pre-html-hook) + (buffer-string))) + ;; insert text + (org-mime-insert-html-content plain file patched-html export-opts))) (defun org-mime-extract-keywords () - "Extract keyword from " + "Extract keywords." (cond ((>= (org-mime-org-major-version) 9) (org-element-map (org-element-parse-buffer) 'keyword @@ -490,18 +481,14 @@ If SUBTREEP is t, curret org node is subtree." (message "Warning: org-element-map is not available. File keywords will not work.") '()))) -(defun org-mime-build-mail-other-headers (cc bcc) - "Build mail header from CC and BCC." - (cond - ((and cc bcc) - (list (cons "Cc" cc) - (cons "Bcc" bcc))) - (cc - (list (cons "Cc" cc))) - (bcc - (list (cons "Bcc" bcc))) - (t - nil))) +(defun org-mime-build-mail-other-headers (cc bcc from) + "Build mail header from CC, BCC, and FROM." + (let* ((arr (list (cons "Cc" cc) (cons "Bcc" bcc) (cons "From" from ))) + rlt) + (dolist (e arr) + (when (cdr e) + (push e rlt))) + rlt)) ;;;###autoload (defun org-mime-org-buffer-htmlize () @@ -514,6 +501,7 @@ The following file keywords can be used to control the headers: #+MAIL_SUBJECT: a subject line #+MAIL_CC: some2@some.place #+MAIL_BCC: some3@some.place +#+MAIL_FROM: sender@some.place The cursor ends in the TO field." (interactive) @@ -527,46 +515,57 @@ The cursor ends in the TO field." (if (not file) (buffer-name (buffer-base-buffer)) (file-name-sans-extension (file-name-nondirectory file))))) - (body (org-mime-get-exported-content 'html nil)) + (exported (org-mime-export-buffer-or-subtree nil)) (to (cdr (assoc "MAIL_TO" keywords))) (cc (cdr (assoc "MAIL_CC" keywords))) (bcc (cdr (assoc "MAIL_BCC" keywords))) - (other-headers (org-mime-build-mail-other-headers cc bcc))) - (org-mime-compose body file to subject other-headers nil) + (from (cdr (assoc "MAIL_FROM" keywords))) + (other-headers (org-mime-build-mail-other-headers cc bcc from))) + (org-mime-compose exported file to subject other-headers nil) (message-goto-to))) (defun org-mime-org-major-version () "Get Org major version." (string-to-number (car (split-string (org-release) "\\.")))) -;; TODO integrating patch +(defun org-mime-attr (p) + (org-entry-get nil p org-mime-use-property-inheritance)) + ;;;###autoload -(defun org-mime-org-subtree-htmlize () - "Create an email buffer of the current subtree. -The buffer will contain both html and in org formats as mime -alternatives. +(defun org-mime-org-subtree-htmlize (&optional htmlize-first-level) + "Create an email buffer of the current subtree. If HTMLIZE-FIRST-LEVEL is +not nil, the first level subtree which containing current subtree is htmlized. -The following headline properties can determine the headers. +Following headline properties can determine the mail headers, * subtree heading - :PROPERTIES: - :MAIL_SUBJECT: mail title - :MAIL_TO: person1@gmail.com - :MAIL_CC: person2@gmail.com - :MAIL_BCC: person3@gmail.com - :END: - -The cursor is left in the TO field." - (interactive) + :PROPERTIES: + :MAIL_SUBJECT: mail title + :MAIL_TO: person1@gmail.com + :MAIL_CC: person2@gmail.com + :MAIL_BCC: person3@gmail.com + :MAIL_FROM: sender@gmail.com + :END: +" + (interactive "P") (save-excursion - (funcall org-mime-up-subtree-heading) - (cl-flet ((mp (p) (org-entry-get nil p org-mime-use-property-inheritance))) + (org-back-to-heading) + + (when (and htmlize-first-level + (not (string-match "^\\* " (org-mime-current-line)))) + ;; go back to the 1st level substree + (re-search-backward "^\\* ") + (org-back-to-heading)) + + (when (outline-on-heading-p nil) (let* ((file (buffer-file-name (current-buffer))) - (subject (or (mp "MAIL_SUBJECT") (nth 4 (org-heading-components)))) - (to (mp "MAIL_TO")) - (cc (mp "MAIL_CC")) - (bcc (mp "MAIL_BCC")) + (subject (or (org-mime-attr "MAIL_SUBJECT") + (nth 4 (org-heading-components)))) + (to (org-mime-attr "MAIL_TO")) + (cc (org-mime-attr "MAIL_CC")) + (bcc (org-mime-attr "MAIL_BCC")) + (from (org-mime-attr "MAIL_FROM")) ;; Thanks to Matt Price improving handling of cc & bcc headers - (other-headers (org-mime-build-mail-other-headers cc bcc)) + (other-headers (org-mime-build-mail-other-headers cc bcc from)) (org-export-show-temporary-export-buffer nil) (subtree-opts (when (fboundp 'org-export--get-subtree-options) (org-export--get-subtree-options))) @@ -575,16 +574,11 @@ The cursor is left in the TO field." ;; I wrap these bodies in export blocks because in org-mime-compose ;; they get exported again. This makes each block conditionally ;; exposed depending on the backend. - (org-body (save-restriction - (org-narrow-to-subtree) - (org-mime-get-exported-content 'org t))) - (html-body (save-restriction - (org-narrow-to-subtree) - (org-mime-get-exported-content 'html t))) - (body (concat org-body "\n" html-body))) + (exported (save-restriction (org-narrow-to-subtree) + (org-mime-export-buffer-or-subtree t)))) (save-restriction (org-narrow-to-subtree) - (org-mime-compose body file to subject other-headers t)) + (org-mime-compose exported file to subject other-headers t)) (message-goto-to))))) (provide 'org-mime) diff --git a/packages/org-plus-contrib-20181112.tar b/packages/org-plus-contrib-20190819.tar similarity index 87% rename from packages/org-plus-contrib-20181112.tar rename to packages/org-plus-contrib-20190819.tar index 66dd47d..cfd0bc6 100644 Binary files a/packages/org-plus-contrib-20181112.tar and b/packages/org-plus-contrib-20190819.tar differ diff --git a/packages/org-pomodoro-20171108.2114.tar b/packages/org-pomodoro-20190530.1445.tar similarity index 96% rename from packages/org-pomodoro-20171108.2114.tar rename to packages/org-pomodoro-20190530.1445.tar index 1bc8ed6..40f2821 100644 Binary files a/packages/org-pomodoro-20171108.2114.tar and b/packages/org-pomodoro-20190530.1445.tar differ diff --git a/packages/org-projectile-20180601.242.el b/packages/org-projectile-20190130.1439.el similarity index 94% rename from packages/org-projectile-20180601.242.el rename to packages/org-projectile-20190130.1439.el index f2b1be5..388ed01 100644 --- a/packages/org-projectile-20180601.242.el +++ b/packages/org-projectile-20190130.1439.el @@ -4,7 +4,7 @@ ;; Author: Ivan Malison <IvanMalison@gmail.com> ;; Keywords: org-mode projectile todo tools outlines -;; Package-Version: 20180601.242 +;; Package-Version: 20190130.1439 ;; URL: https://github.com/IvanMalison/org-projectile ;; Version: 1.1.0 ;; Package-Requires: ((projectile "0.11.0") (dash "2.10.0") (emacs "24") (s "1.9.0") (org-category-capture "0.0.0")) @@ -47,10 +47,18 @@ :type '(string) :group 'org-projectile) +(defcustom org-projectile-projects-directory nil + "Directory to store per-project `org-projectile' TODOs. If non-nil, it +would serve as a root directory for storing project specific TODOs. +Otherwise, `org-projectile-per-project-filepath' would be used to build a +filename related to project root." + :type '(string) + :group 'org-projectile) + (defcustom org-projectile-per-project-filepath "TODO.org" - "The path (relative to the project) where todos will be stored. -Alternatively you may provide a function that will compute this -path." + "The path (relative to the project or `org-projectile-projects-directory') +where todos will be stored. Alternatively you may provide a function that will +compute this path." :type '(choice string function) :group 'org-projectile) @@ -140,12 +148,15 @@ path." ;; One file per project strategy (defun org-projectile-get-project-todo-file (project-path) - (let ((relative-filepath + (let ((project-todos-filepath (if (stringp org-projectile-per-project-filepath) org-projectile-per-project-filepath - (funcall org-projectile-per-project-filepath project-path)))) - (concat - (file-name-as-directory project-path) relative-filepath))) + (funcall org-projectile-per-project-filepath project-path))) + (org-projectile-directory + (if org-projectile-projects-directory + org-projectile-projects-directory + (file-name-as-directory project-path)))) + (concat org-projectile-directory project-todos-filepath))) (defun org-projectile-get-category-from-project-todo-file (project-path) (let ((todo-filepath (org-projectile-get-project-todo-file project-path))) diff --git a/packages/org-re-reveal-20190821.919.tar b/packages/org-re-reveal-20190821.919.tar new file mode 100644 index 0000000..0a4819e Binary files /dev/null and b/packages/org-re-reveal-20190821.919.tar differ diff --git a/packages/org-ref-20181115.51.tar b/packages/org-ref-20190802.1327.tar similarity index 95% rename from packages/org-ref-20181115.51.tar rename to packages/org-ref-20190802.1327.tar index 0b0f5bf..d2bec53 100644 Binary files a/packages/org-ref-20181115.51.tar and b/packages/org-ref-20190802.1327.tar differ diff --git a/packages/org-sticky-header-20190406.2313.el b/packages/org-sticky-header-20190406.2313.el new file mode 100644 index 0000000..856bd81 --- /dev/null +++ b/packages/org-sticky-header-20190406.2313.el @@ -0,0 +1,208 @@ +;;; org-sticky-header.el --- Show off-screen Org heading at top of window -*- lexical-binding: t -*- + +;; Author: Adam Porter <adam@alphapapa.net> +;; Url: http://github.com/alphapapa/org-sticky-header +;; Package-Version: 20190406.2313 +;; Version: 1.0.1 +;; Package-Requires: ((emacs "24.4") (org "8.3.5")) +;; Keywords: hypermedia, outlines, Org + +;;; Commentary: + +;; This package displays in the header-line the Org heading for the +;; node that's at the top of the window. This way, if the heading for +;; the text at the top of the window is beyond the top of the window, +;; you don't forget which heading the text belongs to. + +;; The code is very simple and is based on `semantic-stickyfunc-mode'. + +;;; Installation: + +;; Install from MELPA and run `org-sticky-header-mode'. + +;; To install manually, put this file in your `load-path', require +;; `org-sticky-header' in your init file, and run the same command. + +;; You probably want to add `org-sticky-header-mode' to your `org-mode-hook'. + +;; By default, the line will be indented like a real headline. To +;; change this, configure `org-sticky-header-prefix'. + +;;; License: + +;; 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/>. + +;;; Code: + +;;;; Requirements + +(require 'cl-lib) +(require 'org) + +;;;; Variables + +(defvar org-sticky-header-old-hlf nil + "Value of the header line when entering org-sticky-header mode.") + +(defvar-local org-sticky-header-stickyline nil + "Value of header line") +(put 'org-sticky-header-stickyline 'risky-local-variable t) + +(defconst org-sticky-header-header-line-format + '(:eval (progn + (setq org-sticky-header-stickyline (org-sticky-header--fetch-stickyline)) + (list + (propertize " " 'display '((space :align-to 0))) + 'org-sticky-header-stickyline))) + "The header line format used by stickyfunc mode.") + +(defgroup org-sticky-header nil + "Options for `org-sticky-header-mode'." + :group 'org) + +(defcustom org-sticky-header-full-path nil + "Show the full outline path." + :type '(radio (const :tag "Show only current heading" nil) + (const :tag "Show full outline path to current heading" full) + (const :tag "Show full outline path, but reversed so current heading is first" reversed))) + +(defcustom org-sticky-header-always-show-header t + "Show the header even when the top line of the buffer is a heading. +When this is on, and the top line of the buffer is a heading, +you'll see the heading shown twice: once in the header and once +in the buffer. But since the header can look different than the +heading (i.e. it can show the full path), it shouldn't +necessarily disappear. If you use full-path display, you probably +want this on, but if you only display the current heading, you +might prefer to turn it off. " + :type 'boolean) + +(defcustom org-sticky-header-prefix 'org-sticky-header--indent-prefix + "Prefix to display before heading in header line. +`org-indent-mode' users should use the default function. Custom +functions will be run with point on a heading." + :type '(choice (function-item :tag "Like real headline" org-sticky-header--indent-prefix) + (string :tag "Custom string" :value " ") + (function :tag "Custom function which returns a string") + (const :tag "None" nil))) + +(defcustom org-sticky-header-outline-path-separator "/" + "String displayed between elements of outline paths." + :type 'string) + +(defcustom org-sticky-header-outline-path-reversed-separator "\\" + "String displayed between elements of reversed outline paths." + :type 'string) + +(defcustom org-sticky-header-heading-star "*" + "String to show before heading. +By default, show an asterisk, like in an Org buffer. Changing +this to something else may help distinguish the header line from +headings in the buffer when `org-sticky-header-always-show-header' +is enabled." + :type 'string) + +;;;; Functions + +(defun org-sticky-header--fetch-stickyline () + "Return string of Org heading or outline path for display in header line." + (org-with-wide-buffer + (goto-char (window-start)) + (unless (org-before-first-heading-p) + ;; No non-header lines above top displayed header + (when (or org-sticky-header-always-show-header + (not (org-at-heading-p))) + ;; Header should be shown + (when (fboundp 'org-inlinetask-in-task-p) + ;; Skip inline tasks + (while (and (org-back-to-heading) + (org-inlinetask-in-task-p)) + (forward-line -1))) + (cond + ;; FIXME: Convert cond back to pcase, but one compatible with Emacs 24 + ((null org-sticky-header-full-path) + (concat (org-sticky-header--get-prefix) + (org-get-heading t t))) + ((eq org-sticky-header-full-path 'full) + (concat (org-sticky-header--get-prefix) + (org-format-outline-path (org-get-outline-path t) + (window-width) + nil org-sticky-header-outline-path-separator))) + ((eq org-sticky-header-full-path 'reversed) + (let ((s (concat (org-sticky-header--get-prefix) + (mapconcat 'identity + (nreverse (org-split-string (org-format-outline-path (org-get-outline-path t) + 1000 nil "") + "")) + org-sticky-header-outline-path-reversed-separator)))) + (if (> (length s) (window-width)) + (concat (substring s 0 (- (window-width) 2)) + "..") + s))) + (t nil)))))) + +(defun org-sticky-header--get-prefix () + "Return prefix string depending on value of `org-sticky-header-prefix'." + (cl-typecase org-sticky-header-prefix + (function (funcall org-sticky-header-prefix)) + (string org-sticky-header-prefix) + (nil nil))) + +(defun org-sticky-header--indent-prefix () + "Return indentation prefix for heading at point. +This will do the right thing both with and without `org-indent-mode'." + ;; Modelled after `org-indent-set-line-properties' + (let* ((level (org-current-level)) + (indent-mode (bound-and-true-p org-indent-mode)) + (npre (if (<= level 1) 0 + (+ (if indent-mode + (* (1- org-indent-indentation-per-level) + (1- level)) + 0) + level -1))) + (prefix (concat (make-string npre (if indent-mode ?\ ?*)) org-sticky-header-heading-star " "))) + (org-add-props prefix nil 'face + (if org-cycle-level-faces + (setq org-f (nth (% (1- level) org-n-level-faces) org-level-faces)) + (setq org-f (nth (1- (min level org-n-level-faces)) org-level-faces)))))) + +;;;; Minor mode + +;;;###autoload +(define-minor-mode org-sticky-header-mode + "Minor mode to show the current Org heading in the header line. +With prefix argument ARG, turn on if positive, otherwise off. +Return non-nil if the minor mode is enabled." + :group 'org + (if org-sticky-header-mode + (progn + (when (and (local-variable-p 'header-line-format (current-buffer)) + (not (eq header-line-format org-sticky-header-header-line-format))) + ;; Save previous buffer local value of header line format. + (set (make-local-variable 'org-sticky-header-old-hlf) + header-line-format)) + ;; Enable the mode + (setq header-line-format org-sticky-header-header-line-format)) + ;; Disable mode + (when (eq header-line-format org-sticky-header-header-line-format) + ;; Restore previous buffer local value of header line format if + ;; the current one is the sticky func one. + (kill-local-variable 'header-line-format) + (when (local-variable-p 'org-sticky-header-old-hlf (current-buffer)) + (setq header-line-format org-sticky-header-old-hlf) + (kill-local-variable 'org-sticky-header-old-hlf))))) + +(provide 'org-sticky-header) + +;;; org-sticky-header.el ends here diff --git a/packages/org-trello-20180331.631.tar b/packages/org-trello-20190304.900.tar similarity index 98% rename from packages/org-trello-20180331.631.tar rename to packages/org-trello-20190304.900.tar index 8f7ef2a..d5fb318 100644 Binary files a/packages/org-trello-20180331.631.tar and b/packages/org-trello-20190304.900.tar differ diff --git a/packages/orgit-20180318.2001.el b/packages/orgit-20190717.1526.el similarity index 63% rename from packages/orgit-20180318.2001.el rename to packages/orgit-20190717.1526.el index b68217f..e1b3c6e 100644 --- a/packages/orgit-20180318.2001.el +++ b/packages/orgit-20190717.1526.el @@ -1,12 +1,12 @@ ;;; orgit.el --- support for Org links to Magit buffers -;; Copyright (C) 2014-2018 The Magit Project Developers +;; Copyright (C) 2014-2019 The Magit Project Contributors ;; Author: Jonas Bernoulli <jonas@bernoul.li> ;; Maintainer: Jonas Bernoulli <jonas@bernoul.li> -;; Package-Requires: ((emacs "24.4") (dash "2.13.0") (magit "2.10.0") (org "8.3.3")) -;; Package-Version: 20180318.2001 +;; Package-Requires: ((emacs "25.1") (dash "2.14.1") (magit "2.90.0") (org "9.3")) +;; Package-Version: 20190717.1526 ;; Homepage: https://github.com/magit/orgit ;; This library is free software; you can redistribute it and/or modify @@ -95,6 +95,12 @@ (require 'magit) (require 'org) +(unless (fboundp 'org-link-store-props) + (defalias 'org-link-store-props 'org-store-link-props)) + +(eval-when-compile + (require 'subr-x)) + ;;;###autoload (defun orgit-link-set-parameters (type &rest parameters) (if (fboundp 'org-link-set-parameters) ; since v9.0 @@ -126,14 +132,14 @@ "https://bitbucket.org/%n" "https://bitbucket.org/%n/commits/branch/%r" "https://bitbucket.org/%n/commits/%r") - ("orgmode.org[:/]\\(.+\\)$" - "http://orgmode.org/cgit.cgi/%n" - "http://orgmode.org/cgit.cgi/%n/log/?h=%r" - "http://orgmode.org/cgit.cgi/%n/commit/?id=%r") + ("code.orgmode.org[:/]\\(.+\\)$" + "https://code.orgmode.org/cgit.cgi/%n" + "https://code.orgmode.org/cgit.cgi/%n/commits/%r" + "https://code.orgmode.org/cgit.cgi/%n/commit/%r") ("git.kernel.org/pub/scm[:/]\\(.+\\)$" - "http://git.kernel.org/cgit/%n" - "http://git.kernel.org/cgit/%n/log/?h=%r" - "http://git.kernel.org/cgit/%n/commit/?id=%r")) + "https://git.kernel.org/cgit/%n" + "https://git.kernel.org/cgit/%n/log/?h=%r" + "https://git.kernel.org/cgit/%n/commit/?id=%r")) "Alist used to translate Git urls to web urls when exporting links. Each entry has the form (REMOTE-REGEXP STATUS LOG REVISION). If @@ -175,6 +181,41 @@ If all of the above fails then `orgit-export' raises an error." :group 'orgit :type 'boolean) +(defcustom orgit-store-repository-id nil + "Whether to store only name of repository instead of path. + +If nil, then store the full path to the repository in the link. + +If t, then attempt to store only the name of the repository. +This works by looking up the repository's path in the list of +repositories defined by `magit-repository-directories'. If the +repository cannot be found there, then the path is used instead. +If the repository is checked out multiple times, then the names +of the clones are made unique by adding additional parts of the +path. + +Storing just the name can be useful if you want to share links +with others, but be aware that doing so does not guarantee that +others will be able to open these links. The repository has to +be checked out under the same name that you use and it has to be +configured in `magit-repository-directory'." + :package-version '(orgit . "1.6.0") + :group 'orgit + :type 'boolean) + +(defcustom orgit-store-reference nil + "Whether `orgit-rev-store' attemts to store link to a reference. + +If nil, then store a link to the commit itself, using its full +hash. + +If t, then attempt to store a link to a tag or branch. If that +is not possible because no such reference points at the commit, +then store a link to the commit itself." + :package-version '(orgit . "1.6.0") + :group 'orgit + :type 'boolean) + ;;; Command ;;;###autoload @@ -185,7 +226,7 @@ If all of the above fails then `orgit-export' raises an error." (defun orgit-store-link (arg) "Like `org-store-link' but store links to all selected commits, if any." (interactive "P") - (-if-let (sections (magit-region-sections 'commit)) + (if-let ((sections (magit-region-sections 'commit))) (save-excursion (dolist (section sections) (goto-char (oref section start)) @@ -212,15 +253,15 @@ When the region selects one or more commits, then do nothing. In that case `orgit-rev-store' stores one or more links instead." (when (and (eq major-mode 'magit-status-mode) (not (magit-region-sections 'commit))) - (let ((repo (abbreviate-file-name default-directory))) - (org-store-link-props + (let ((repo (orgit--current-repository))) + (org-link-store-props :type "orgit" :link (format "orgit:%s" repo) :description (format "%s (magit-status)" repo))))) ;;;###autoload -(defun orgit-status-open (path) - (magit-status-internal (file-name-as-directory (expand-file-name path)))) +(defun orgit-status-open (repo) + (magit-status-setup-buffer (orgit--repository-directory repo))) ;;;###autoload (defun orgit-status-export (path desc format) @@ -247,36 +288,32 @@ When the region selects one or more commits, then do nothing. In that case `orgit-rev-store' stores one or more links instead." (when (and (eq major-mode 'magit-log-mode) (not (magit-region-sections 'commit))) - (let ((repo (abbreviate-file-name default-directory))) - (if orgit-log-save-arguments - (let ((args (if (car (last magit-refresh-args)) - magit-refresh-args - (butlast magit-refresh-args)))) - (org-store-link-props - :type "orgit-log" - :link (format "orgit-log:%s::%S" repo args) - :description (format "%s %S" repo (cons 'magit-log args)))) - (let ((args (car magit-refresh-args))) - (org-store-link-props - :type "orgit-log" - :link (concat (format "orgit-log:%s::" repo) - (if (cdr args) - (prin1-to-string args) - (car args))) - :description (format "%s %S" repo (list 'magit-log args)))))))) + (let ((repo (orgit--current-repository)) + (args (if orgit-log-save-arguments + (if magit-buffer-log-files + (list magit-buffer-revisions + magit-buffer-log-args + magit-buffer-log-files) + (list magit-buffer-revisions + magit-buffer-log-args)) + magit-buffer-revisions))) + (org-link-store-props + :type "orgit-log" + :link (format "orgit-log:%s::%S" repo args) + :description (format "%s %S" repo (cons 'magit-log args)))))) ;;;###autoload (defun orgit-log-open (path) - (-let* (((dir args) - (split-string path "::")) - (default-directory (file-name-as-directory (expand-file-name dir)))) - (apply #'magit-log - (cond ((string-prefix-p "((" args) - (read args)) - ((string-prefix-p "(" args) - (cons (read args) (magit-log-arguments))) - (t - (cons (list args) (magit-log-arguments))))))) + (pcase-let* ((`(,repo ,args) (split-string path "::")) + (`(,revs ,args ,files) + (cond ((string-prefix-p "((" args) + (read args)) + ((string-prefix-p "(" args) + (list (read args) (car (magit-log-arguments)))) + (t + (list (list args) (car (magit-log-arguments)))))) + (default-directory (orgit--repository-directory repo))) + (magit-log-setup-buffer revs args files))) ;;;###autoload (defun orgit-log-export (path desc format) @@ -302,35 +339,42 @@ In that case `orgit-rev-store' stores one or more links instead." ;;;###autoload (defun orgit-rev-store () "Store a link to a Magit-Revision mode buffer. -With a prefix argument instead store the name of the branch that -points at the revision, if any. +With a prefix argument instead store the name of a tag or branch +that points at the revision, if any. + +If `orgit-store-reference' is non-nil, then the meaning of the +prefix argument is reversed. When the region selects one or more commits, e.g. in a log, then store links to the Magit-Revision mode buffers for these commits." (cond ((eq major-mode 'magit-revision-mode) - (orgit-rev-store-1 (car magit-refresh-args))) - ((and (derived-mode-p 'magit-mode) - (magit-region-sections 'commit)) - (orgit-rev-store-1 (oref (magit-current-section) value))))) + (orgit-rev-store-1 magit-buffer-revision)) + ((derived-mode-p 'magit-mode) + (when-let ((revs (magit-region-values 'commit))) + (mapc 'orgit-rev-store-1 revs) + t)))) (defun orgit-rev-store-1 (rev) - (let ((repo (abbreviate-file-name default-directory))) - (unless (magit-ref-p rev) - (setq rev (if current-prefix-arg - (magit-get-shortname rev) - (magit-rev-abbrev rev)))) - (org-store-link-props + (let ((repo (orgit--current-repository)) + (ref (and (if orgit-store-reference + (not current-prefix-arg) + current-prefix-arg) + (or (and (magit-ref-p rev) rev) + (magit-name-tag rev) + (magit-name-branch rev))))) + (org-link-store-props :type "orgit-rev" - :link (format "orgit-rev:%s::%s" repo rev) - :description (format "%s (magit-rev %s)" repo rev)))) + :link (format "orgit-rev:%s::%s" repo + (or ref (magit-rev-parse rev))) + :description (format "%s (magit-rev %s)" repo + (or ref (magit-rev-abbrev rev)))))) ;;;###autoload (defun orgit-rev-open (path) - (-let* (((dir rev) - (split-string path "::")) - (default-directory (file-name-as-directory (expand-file-name dir)))) - (apply #'magit-show-commit - (cons rev (magit-diff-arguments))))) + (pcase-let* ((`(,repo ,rev) (split-string path "::")) + (default-directory (orgit--repository-directory repo))) + (magit-revision-setup-buffer + rev (car (magit-diff-arguments 'magit-revision-mode)) nil))) ;;;###autoload (defun orgit-rev-export (path desc format) @@ -346,24 +390,24 @@ store links to the Magit-Revision mode buffers for these commits." ;;; Export (defun orgit-export (path desc format gitvar idx) - (-let* (((dir rev) - (split-string path "::")) - (default-directory (file-name-as-directory (expand-file-name dir))) - (remotes (magit-git-lines "remote")) - (remote (magit-get "orgit.remote")) - (remote (cond ((= (length remotes) 1) (car remotes)) - ((member remote remotes) remote) - ((member orgit-remote remotes) orgit-remote)))) + (pcase-let* + ((`(,dir ,rev) (split-string path "::")) + (default-directory (file-name-as-directory (expand-file-name dir))) + (remotes (magit-git-lines "remote")) + (remote (magit-get "orgit.remote")) + (remote (cond ((= (length remotes) 1) (car remotes)) + ((member remote remotes) remote) + ((member orgit-remote remotes) orgit-remote)))) (if remote - (-if-let - (link (or (-when-let (url (magit-get "orgit" gitvar)) - (format-spec url `((?r . ,rev)))) - (-when-let (url (magit-get "remote" remote "url")) - (--when-let (--first (string-match (car it) url) - orgit-export-alist) - (format-spec (nth idx it) - `((?n . ,(match-string 1 url)) - (?r . ,rev))))))) + (if-let ((link (or (when-let ((url (magit-get "orgit" gitvar))) + (format-spec url `((?r . ,rev)))) + (when-let ((url (magit-get "remote" remote "url")) + (format (--first + (string-match (car it) url) + orgit-export-alist))) + (format-spec (nth idx format) + `((?n . ,(match-string 1 url)) + (?r . ,rev))))))) (pcase format (`html (format "<a href=\"%s\">%s</a>" link desc)) (`latex (format "\\href{%s}{%s}" link desc)) @@ -372,6 +416,23 @@ store links to the Magit-Revision mode buffers for these commits." (error "Cannot determine public url for %s" path)) (error "Cannot determine public remote for %s" default-directory)))) +;;; Utilities + +(defun orgit--current-repository () + (or (and orgit-store-repository-id + (car (rassoc default-directory (magit-repos-alist)))) + (abbreviate-file-name default-directory))) + +(defun orgit--repository-directory (repo) + (if (file-name-absolute-p repo) + (let ((dir (file-name-as-directory (expand-file-name repo)))) + (unless (file-exists-p dir) + (error "Cannot open link; %S does not exist" dir)) + dir) + (or (cdr (assoc repo (magit-repos-alist))) + (error "Cannot open link; no entry for %S in `%s'" + repo 'magit-repository-directories)))) + ;;; _ (provide 'orgit) ;; Local Variables: diff --git a/packages/origami-20180101.1553.tar b/packages/origami-20180101.1553.tar index 1ee6ddd..a2d79e6 100644 Binary files a/packages/origami-20180101.1553.tar and b/packages/origami-20180101.1553.tar differ diff --git a/packages/osx-clipboard-20141012.717.el b/packages/osx-clipboard-20141012.717.el new file mode 100644 index 0000000..24561cb --- /dev/null +++ b/packages/osx-clipboard-20141012.717.el @@ -0,0 +1,128 @@ +;;; osx-clipboard.el --- Use the OS X clipboard from terminal Emacs + +;; Copyright (C) 2014 Jon Oddie <jonxfield@gmail.com> + +;; Author: Jon Oddie <jonxfield at gmail.com> +;; Created: 11 October 2014 +;; Version: 0.1 +;; Package-Version: 20141012.717 +;; Url: https://github.com/joddie/osx-clipboard-mode + +;; This file is NOT part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation, either version 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: + +;; Sometimes it is useful to run Emacs in a plain terminal window, even +;; when a graphical display is available, but it's a nuisance if you need +;; to copy and paste from the text-mode Emacs to another program. This is +;; a tiny minor mode which lets Emacs on Mac OS X use the system clipboard +;; even when running in a text terminal, via the external `pbpaste' and +;; `pbcopy' programs. + +;; To enable it, either customize the variable `osx-clipboard-mode' to `t', +;; or add the following line to your init file: + +;; ,---- +;; | (osx-clipboard-mode +1) +;; `---- + +;; Attempting to enable this mode an a non-OS-X system or in a graphical +;; Emacs will do nothing, so it should be safe to enable it unconditionally +;; even if you share your configuration between multiple machines. + +;;;; Code: + +;;;###autoload +(defgroup osx-clipboard nil + "Enable the OS X clipboard when running in a text terminal." + :group 'environment + :tag "OS X Clipboard" + :link '(url-link "http://github.com/joddie/osx-clipboard-mode")) + +;;;###autoload +(define-minor-mode osx-clipboard-mode + "Kill and yank using the OS X clipboard when running in a text terminal. + +This mode allows Emacs to use the OS X system clipboard when +running in the terminal, making killing and yanking behave +similarly to a graphical Emacs. It is not needed in a graphical +Emacs, where NS clipboard integration is built in. + +It sets the variables `interprogram-cut-function' and +`interprogram-paste-function' to thin wrappers around the +\"pbcopy\" and \"pbpaste\" command-line programs. + +Consider also customizing the variable + `save-interprogram-paste-before-kill' to `t' for best results." + :global t + :lighter " OSX-Clipboard" :tag "OS X Clipboard Mode" + :group 'osx-clipboard + (if (not (and (eq system-type 'darwin) (not window-system))) + (progn + (when (called-interactively-p 'any) + (message "`osx-clipboard-mode' only works in text terminals under OS X")) + (setq osx-clipboard-mode nil)) + (if osx-clipboard-mode + ;; Turn on + (setq interprogram-cut-function #'osx-clipboard-cut-function + interprogram-paste-function #'osx-clipboard-paste-function) + ;; Turn off + (setq interprogram-cut-function nil + interprogram-paste-function nil)))) + +(defun osx-clipboard-cut-function (text &rest ignore) + "Copy TEXT to the OS X clipboard using \"pbpaste\". + +This is set as the value of `interprogram-cut-function' by +`osx-clipboard-mode'. It should only be used when Emacs is running in a +text terminal." + (with-temp-buffer + (insert text) + (with-demoted-errors "Error calling pbcopy: %S" + (call-process-region (point-min) (point-max) "pbcopy")))) + +(defvar osx-clipboard-last-selected-text nil) + +(defun osx-clipboard-paste-function () + "Return the value of the OS X clipboard using \"pbcopy\". + +This is set as the value of `interprogram-paste-function' by +`osx-clipboard-mode'. It should only be used when Emacs is running in a +text terminal." + (with-temp-buffer + (with-demoted-errors "Error calling pbpaste: %S" + (call-process "pbpaste" nil t) + (let ((text (buffer-substring-no-properties (point-min) (point-max)))) + ;; The following logic is adapted from `x-selection-value' + ;; in `ns-win.el.gz' + (cond + ((or + ;; Avoid copying an empty clipboard, or copying the same + ;; text twice + (not text) + (eq text osx-clipboard-last-selected-text) + (string= text "") + (string= text (car kill-ring))) nil) + ((string= text osx-clipboard-last-selected-text) + ;; Record the newer string, so subsequent calls can use the `eq' test. + (setq osx-clipboard-last-selected-text text) + nil) + (t + (setq osx-clipboard-last-selected-text text))))))) + +(provide 'osx-clipboard) + +;;; osx-clipboard.el ends here diff --git a/packages/osx-dictionary-20171026.734.tar b/packages/osx-dictionary-20171026.734.tar index f344ed4..051a5f2 100644 Binary files a/packages/osx-dictionary-20171026.734.tar and b/packages/osx-dictionary-20171026.734.tar differ diff --git a/packages/osx-location-20150613.917.tar b/packages/osx-location-20150613.917.tar index 410fc5e..eaed22e 100644 Binary files a/packages/osx-location-20150613.917.tar and b/packages/osx-location-20150613.917.tar differ diff --git a/packages/osx-trash-20160520.1300.tar b/packages/osx-trash-20160520.1300.tar index 90be9a1..75838d0 100644 Binary files a/packages/osx-trash-20160520.1300.tar and b/packages/osx-trash-20160520.1300.tar differ diff --git a/packages/ox-epub-20181101.1854.el b/packages/ox-epub-20181101.1854.el new file mode 100644 index 0000000..beff323 --- /dev/null +++ b/packages/ox-epub-20181101.1854.el @@ -0,0 +1,688 @@ +;;; ox-epub.el --- Export org mode projects to EPUB -*- lexical-binding: t; -*- + +;; Copyright (c) 2017-2018 - Mark Meyer + +;; Author: Mark Meyer <mark@ofosos.org> +;; Maintainer: Mark Meyer <mark@ofosos.org> + +;; URL: http://github.com/ofosos/org-epub +;; Package-Version: 20181101.1854 +;; Keywords: hypermedia + +;; Version: 0.1.0 + +;; Package-Requires: ((emacs "24.3") (org "9")) + +;; 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: + +;; This is an addition to the standard org-mode exporters. The package +;; extends the (X)HTML exporter to produce EPUB files. It eliminates +;; all inline CSS and JavaScript to accomplish this. This exporter +;; will also tie the XHTML DTD to XHTML 1.1, a concrete DTD specifier +;; that was not supported by ox-html previously. + +;; The main part is the generation of the table of contents in machine +;; readable form, as well as the spine, which defines the order in +;; which files are presented. A lesser part is the inclusion of +;; various metadata properties, among them authorship and rights. + +;;; Code: + +(require 'cl-lib) +(require 'ox-publish) +(require 'ox-html) +(require 'org-element) + +(org-export-define-derived-backend 'epub 'html + :options-alist + '((:epub-uid "UID" nil nil t) + (:epub-subject "Subject" nil nil t) + (:epub-description "Description" nil nil t) + (:epub-publisher "Publisher" nil nil t) + (:epub-rights "License" nil nil t) + (:epub-style "EPUBSTYLE" nil nil t) + (:epub-cover "EPUBCOVER" nil nil t) + (:html-doctype "HTML_DOCTYPE" nil "xhtml" t)) + + :translate-alist + '((template . org-epub-template) + (link . org-epub-link) + (latex-environment . org-epub--latex-environment) + (latex-fragment . org-epub--latex-fragment)) + :menu-entry + '(?E "Export to Epub" + ((?e "As Epub file" org-epub-export-to-epub) + (?O "As Epub file and open" + (lambda (a s v b) + (if a (org-epub-export-to-epub t s v) + (org-open-file (org-epub-export-to-epub nil s v) 'system))))))) + +(defvar org-epub-zip-dir nil + "The temporary directory to export to") + +(defvar org-epub-style-default " + .title { text-align: center; + margin-bottom: .2em; } + .subtitle { text-align: center; + font-size: medium; + font-weight: bold; + margin-top:0; } + .todo { font-family: monospace; color: red; } + .done { font-family: monospace; color: green; } + .priority { font-family: monospace; color: orange; } + .tag { background-color: #eee; font-family: monospace; + padding: 2px; font-size: 80%; font-weight: normal; } + .timestamp { color: #bebebe; } + .timestamp-kwd { color: #5f9ea0; } + .org-right { margin-left: auto; margin-right: 0px; text-align: right; } + .org-left { margin-left: 0px; margin-right: auto; text-align: left; } + .org-center { margin-left: auto; margin-right: auto; text-align: center; } + .underline { text-decoration: underline; } + #postamble p, #preamble p { font-size: 90%; margin: .2em; } + p.verse { margin-left: 3%; } + pre { + border: 1px solid #ccc; + box-shadow: 3px 3px 3px #eee; + padding: 8pt; + font-family: monospace; + overflow: auto; + margin: 1.2em; + } + pre.src { + position: relative; + overflow: visible; + padding-top: 1.2em; + } + + table { border-collapse:collapse; } + caption.t-above { caption-side: top; } + caption.t-bottom { caption-side: bottom; } + td, th { vertical-align:top; } + th.org-right { text-align: center; } + th.org-left { text-align: center; } + th.org-center { text-align: center; } + td.org-right { text-align: right; } + td.org-left { text-align: left; } + td.org-center { text-align: center; } + dt { font-weight: bold; } + .footpara { display: inline; } + .footdef { margin-bottom: 1em; } + .figure { padding: 1em; } + .figure p { text-align: center; } + .inlinetask { + padding: 10px; + border: 2px solid gray; + margin: 10px; + background: #ffffcc; + } + #org-div-home-and-up + { text-align: right; font-size: 70%; white-space: nowrap; } + textarea { overflow-x: auto; } + .linenr { font-size: smaller } + .code-highlighted { background-color: #ffff00; } + .org-info-js_info-navigation { border-style: none; } + #org-info-js_console-label + { font-size: 10px; font-weight: bold; white-space: nowrap; } + .org-info-js_search-highlight + { background-color: #ffff00; color: #000000; font-weight: bold; } + .org-svg { width: 90%; } + +" + "Default style declarations for org epub") + +(defvar org-epub-zip-command "zip" + "Command to call to create zip files.") + +(defvar org-epub-zip-no-compress (list "-Xu0") + "Zip command option list to pass for no compression.") + +(defvar org-epub-zip-compress (list "-Xu9") + "Zip command option list to pass for compression.") + +(defvar org-epub-metadata nil + "EPUB export metadata") + +(defvar org-epub-headlines nil + "EPUB headlines") + +(defvar org-epub-style-counter 0 + "EPUB style counter") + +;; manifest mechanism + +(defvar org-epub-manifest nil + "EPUB export manifest") + +(defun org-epub-manifest-entry (id filename type mimetype &optional source) + "Create a manifest entry with the given ID, FILENAME, TYPE, MIMETYPE and optional SOUCE. + +FILENAME should be the new name in the epub container. TYPE +should be one of `'html', `'stylesheet', `'coverimg', `'cover' or +`'img'. If SOURCE is given the file name by SOUCE will be copied +to FILENAME at the end of the export process. " + (list :id id :filename filename :type type :mimetype mimetype :source source)) + +(defun org-epub-cover-p (manifest-entry) + "Determine if MANIFEST-ENTRY is of type cover." + (eq (plist-get manifest-entry :type) 'cover)) + +(defun org-epub-coverimg-p (manifest-entry) + "Determine if MANIFEST-ENTRY is of type cover image." + (eq (plist-get manifest-entry :type) 'coverimg)) + +(defun org-epub-style-p (manifest-entry) + "Determine if MANIFEST-ENTRY is of type stylesheet." + (eq (plist-get manifest-entry :type) 'stylesheet)) + +(defun org-epub-manifest-needcopy (manifest-entry) + "Determine if MANIFEST-ENTRY needs to be copied. + +If it needs to be copied return a pair (sourcefile . targetfile)." + (if (plist-get manifest-entry :source) + (cons (plist-get manifest-entry :source) + (plist-get manifest-entry :filename)) + nil)) + +(defun org-epub-manifest-all (pred) + "Return all manifest entries for which PRED is true." + (cl-remove-if-not pred org-epub-manifest)) + +(cl-defun org-epub-manifest-first (pred) + "Return the first manifest entry for which PRED is true." + (let ((val)) + (dolist (el org-epub-manifest val) + (when (funcall pred el) + (cl-return-from org-epub-manifest-first el))))) + +;; core + +;;; Latex Environment - stolen from ox-html + +(defun org-epub--latex-environment (latex-environment _contents info) + "Transcode a LATEX-ENVIRONMENT element from Org to HTML. +CONTENTS is nil. INFO is a plist holding contextual information." + (let ((processing-type (plist-get info :with-latex)) + (latex-frag (org-remove-indentation + (org-element-property :value latex-environment))) + (attributes (org-export-read-attribute :attr_html latex-environment))) + (cond + ((assq processing-type org-preview-latex-process-alist) + (let ((formula-link + (org-html-format-latex latex-frag processing-type info))) + (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) + ;; Do not provide a caption or a name to be consistent with + ;; `mathjax' handling. + (org-html--wrap-image + (org-html--format-image + (let* ((path (match-string 1 formula-link)) + (ref (org-export-get-reference latex-environment info)) + (mime (file-name-extension path)) + (name (concat "img-" ref "." mime))) + (message "Formatting Latex environment: %s" name) + (push (org-epub-manifest-entry ref name 'img (concat "image/" mime) path) org-epub-manifest) + name) attributes info) info)))) + (t latex-frag)))) + +;;;; Latex Fragment - stolen from ox-html + +(defun org-epub--latex-fragment (latex-fragment _contents info) + "Transcode a LATEX-FRAGMENT object from Org to HTML. +CONTENTS is nil. INFO is a plist holding contextual information." + (let ((latex-frag (org-element-property :value latex-fragment)) + (processing-type (plist-get info :with-latex))) + (cond + ((assq processing-type org-preview-latex-process-alist) + (let ((formula-link + (org-html-format-latex latex-frag processing-type info))) + (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) + (let* ((path (match-string 1 formula-link)) + (ref (org-export-get-reference latex-fragment info)) + (mime (file-name-extension path)) + (name (concat "img-" ref "." mime))) + (message "Formatting Latex fragement: %s" name) + (push (org-epub-manifest-entry ref name 'img (concat "image/" mime) path) org-epub-manifest) + (org-html--format-image name nil info))))) + (t latex-frag)))) + + +(defun org-epub-link (link desc info) + "Return the HTML required for a link descriped by LINK, DESC, and INFO. + +See org-html-link for more info." + (when (org-export-inline-image-p link (plist-get info :html-inline-image-rules)) + (let* ((path (org-link-unescape (org-element-property :path link))) + (ref (org-export-get-reference link info)) + (mime (file-name-extension path)) + (name (concat "img-" ref "." mime))) + (push (org-epub-manifest-entry ref name 'img (concat "image/" mime) path) org-epub-manifest) + (org-element-put-property link :path name))) + (org-html-link link desc info)) + +(defun org-epub-meta-put (symbols info) + "Put SYMBOLS taken from INFO into the org-epub metadata cache." + (mapc + #'(lambda (sym) + (let ((data (plist-get info sym))) + (setq org-epub-metadata + (plist-put org-epub-metadata sym + (if (listp data) + (org-export-data data info) + data))))) + symbols)) + +(defun org-epub-template (contents info) + "Return complete document string after HTML conversion. +CONTENTS is the transcoded contents string. INFO is a plist +holding export options." + (org-epub-meta-put '(:epub-uid :title :language :epub-subject :epub-description :author + :epub-publisher :date :epub-rights :html-head-include-default-style :epub-cover :epub-style) info) + (setq org-epub-metadata (plist-put org-epub-metadata :epub-toc-depth 2)) + ;; maybe set toc-depth "2" to some dynamic value + (setq org-epub-headlines + (mapcar (lambda (headline) + (list + (org-element-property :raw-value headline) + (org-element-property :level headline) + (org-export-get-reference headline info))) + (org-export-collect-headlines info 2))) + (let ((styles (split-string (or (plist-get org-epub-metadata :epub-style) " ")))) + (mapc #'(lambda (style) + (let* ((stylenum (cl-incf org-epub-style-counter)) + (stylename (concat "style-" (format "%d" stylenum))) + (stylefile (concat stylename ".css"))) + (push (org-epub-manifest-entry stylename stylefile 'stylesheet "text/css" style) org-epub-manifest))) + styles)) + (concat + (when (and (not (org-html-html5-p info)) (org-html-xhtml-p info)) + (let* ((xml-declaration (plist-get info :html-xml-declaration)) + (decl (or (and (stringp xml-declaration) xml-declaration) + (cdr (assoc (plist-get info :html-extension) + xml-declaration)) + (cdr (assoc "html" xml-declaration)) + ""))) + (when (not (or (not decl) (string= "" decl))) + (format "%s\n" + (format decl + (or (and org-html-coding-system + (fboundp 'coding-system-get) + (coding-system-get org-html-coding-system 'mime-charset)) + "iso-8859-1")))))) + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">" + "\n" + (concat "<html" + (format + " xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\"" + (plist-get info :language) (plist-get info :language)) + ">\n") + + "<head>\n" + (org-html--build-meta-info info) + (when (plist-get info :html-head-include-default-style) + "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/>\n") + (when (plist-get info :epub-style) + (mapconcat + #'(lambda (entry) + (concat "<link rel=\"stylesheet\" type=\"text/css\" href=\"" (plist-get entry :filename) "\"/>\n")) + (org-epub-manifest-all #'org-epub-style-p) "\n")) + "</head>\n" + "<body>\n" + ;; Preamble. + (org-html--build-pre/postamble 'preamble info) + ;; Document contents. + ; (let ((div (assq 'content (plist-get info :html-divs)))) + ; (format "<%s id=\"%s\">\n" (nth 1 div) (nth 2 div))) + "<div id=\"content\">" + ;; Document title. + (when (plist-get info :with-title) + (let ((ftitle (plist-get info :title)) + (subtitle (plist-get info :subtitle))) + (when ftitle + (message (org-export-data ftitle info)) + (format + "<h1 class=\"title\">%s</h1>%s\n" + (org-export-data ftitle info) + (if subtitle + (format + "<p class=\"subtitle\">%s</p>\n" + (org-export-data subtitle info)) + ""))))) + contents + "</div>" + ; (format "</%s>\n" (nth 1 (assq 'content (plist-get info :html-divs)))) + ;; Postamble. + (org-html--build-pre/postamble 'postamble info) + ;; Closing document. + "</body>\n</html>")) + +;; see ox-odt + +(defmacro org-epub--export-wrapper (outfile &rest body) + "Export an Epub with BODY generating the main html file and OUTFILE as target file." + `(let* ((outfile ,outfile) + (org-epub-manifest nil) + (org-epub-metadata nil) + (org-epub-style-counter 0) + (out-file-type (file-name-extension outfile)) + (org-epub-zip-dir (file-name-as-directory + (make-temp-file (format "%s-" out-file-type) t))) + (body ,@body)) + (condition-case err + (progn + (when (plist-get org-epub-metadata :html-head-include-default-style) + (with-current-buffer (find-file (concat org-epub-zip-dir "style.css")) + (insert org-epub-style-default) + (save-buffer 0) + (kill-buffer) + (push (org-epub-manifest-entry "default-style" "style.css" 'stylesheet "text/css") org-epub-manifest))) + (when (org-string-nw-p (plist-get org-epub-metadata :epub-cover)) + (let* ((cover-path (plist-get org-epub-metadata :epub-cover)) + (cover-type (file-name-extension cover-path)) + (cover-img (create-image (expand-file-name cover-path))) + (cover-width (car (image-size cover-img t))) + (cover-height (cdr (image-size cover-img t))) + (cover-name (concat "cover." cover-type))) + (with-current-buffer (find-file (concat org-epub-zip-dir "cover.html")) + (erase-buffer) + (insert + (org-epub-template-cover cover-name cover-width cover-height)) + (save-buffer 0) + (kill-buffer) + (let ((men (org-epub-manifest-entry "cover" "cover.html" 'cover "application/xhtml+xml"))) + (push men org-epub-manifest)) + (let ((men (org-epub-manifest-entry "cover-image" cover-name 'coverimg (concat "image/" cover-type) cover-path))) + (push men org-epub-manifest))))) + (unless (file-directory-p (expand-file-name "META-INF" org-epub-zip-dir)) + (make-directory (file-name-as-directory (expand-file-name "META-INF" org-epub-zip-dir)))) + (with-current-buffer (find-file (expand-file-name "META-INF/container.xml" org-epub-zip-dir)) + (erase-buffer) + (insert (org-epub-template-container)) + (save-buffer 0) + (kill-buffer)) + (with-current-buffer (find-file (concat org-epub-zip-dir "mimetype")) + (erase-buffer) + (insert (org-epub-template-mimetype)) + (save-buffer 0) + (kill-buffer)) + (with-current-buffer (find-file (concat org-epub-zip-dir "body.html")) + (erase-buffer) + (insert body) + (save-buffer 0) + (kill-buffer) + (nconc org-epub-manifest (list (org-epub-manifest-entry "body-html" "body.html" 'html "application/xhtml+xml")))) + (with-current-buffer (find-file (concat org-epub-zip-dir "toc.ncx")) + (erase-buffer) + (insert + (org-epub-template-toc-ncx + (plist-get org-epub-metadata :epub-uid) + (plist-get org-epub-metadata :epub-toc-depth) + (plist-get org-epub-metadata :title) + (org-epub-generate-toc-single org-epub-headlines "body.html"))) + (save-buffer 0) + (kill-buffer)) + (with-current-buffer (find-file (concat org-epub-zip-dir "content.opf")) + (erase-buffer) + (insert (org-epub-template-content-opf + org-epub-metadata + (org-epub-gen-manifest org-epub-manifest) + (org-epub-gen-spine '(("body-html" . "body.html"))))) + (save-buffer 0) + (kill-buffer)) + (org-epub-zip-it-up outfile org-epub-manifest org-epub-zip-dir) + (delete-directory org-epub-zip-dir t) + (message (with-output-to-string (print org-epub-manifest))) + (message "Generated %s" outfile) + (expand-file-name outfile)) + (error (delete-directory org-epub-zip-dir t) + (message "ox-epub eport error: %s" err))))) + +;;compare org-export-options-alist +;;;###autoload +(defun org-epub-export-to-epub (&optional async subtreep visible-only ext-plist) + "Export the current buffer to an EPUB file. + +ASYNC defines wether this process should run in the background, +SUBTREEP supports narrowing of the document, VISIBLE-ONLY allows +you to export only visible parts of the document, EXT-PLIST is +the property list for the export process." + (interactive) + (let* ((outfile (org-export-output-file-name ".epub" subtreep))) + (message "Output to:") + (message outfile) + (if async + (org-export-async-start (lambda (f) (org-export-add-to-stack f 'odt)) + (org-epub--export-wrapper + outfile + (org-export-as 'epub subtreep visible-only nil ext-plist))) + (org-epub--export-wrapper + outfile + (org-export-as 'epub subtreep visible-only nil ext-plist))))) + +(defun org-epub-template-toc-ncx (uid toc-depth title toc-nav) + "Create the toc.ncx file. + +UID is the uid/url of the file. TOC-DEPTH is the depth of the toc +that should be shown to the readers. TITLE is the title of the +ebook and TOC-NAV being the raw contents enclosed in navMap." + (concat + "<?xml version=\"1.0\"?> +<!DOCTYPE ncx PUBLIC \"-//NISO//DTD ncx 2005-1//EN\" + \"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd\"> + +<ncx xmlns=\"http://www.daisy.org/z3986/2005/ncx/\" version=\"2005-1\"> + + <head> + <meta name=\"dtb:uid\" content=\"" + uid + "\"/> + <meta name=\"dtb:depth\" content=\"" + (format "%d" toc-depth) + "\"/> + <meta name=\"dtb:totalPageCount\" content=\"0\"/> + <meta name=\"dtb:maxPageNumber\" content=\"0\"/> + </head> + + <docTitle> + <text>" + title + "</text> + </docTitle> + + <navMap>" + toc-nav + "</navMap> +</ncx>")) + +(defun org-epub-template-content-opf (meta manifest spine) + "Create the content.opf file. + +META is a metadata PLIST. + +The following arguments are XML strings: MANIFEST is the content +inside the manifest tags, this should include all user generated +html files but not things like the cover page, SPINE is an XML +string with the list of html files in reading order." + (concat + "<?xml version=\"1.0\"?> + +<package xmlns=\"http://www.idpf.org/2007/opf\" unique-identifier=\"dcidid\" + version=\"2.0\"> + + <metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\" + xmlns:dcterms=\"http://purl.org/dc/terms/\" + xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" + xmlns:opf=\"http://www.idpf.org/2007/opf\"> + <dc:title>" (plist-get meta :title) "</dc:title> + <dc:language xsi:type=\"dcterms:RFC3066\">" (plist-get meta :language) "</dc:language> + <dc:identifier id=\"dcidid\" opf:scheme=\"URI\">" + (plist-get meta :epub-uid) + "</dc:identifier> + <dc:subject>" (plist-get meta :epub-subject) + "</dc:subject> + <dc:description>" (plist-get meta :epub-description) + + "</dc:description> + <dc:creator>" (plist-get meta :author) "</dc:creator> + <dc:publisher>" (plist-get meta :epub-publisher) "</dc:publisher> + <dc:date xsi:type=\"dcterms:W3CDTF\">" (plist-get meta :date) "</dc:date> + <dc:rights>" (plist-get meta :epub-rights) "</dc:rights>" + (let ((cimg (org-epub-manifest-first #'org-epub-coverimg-p))) + (when cimg + (concat "<meta name=\"cover\" content=\"" (plist-get cimg :id) "\"/>"))) + " + </metadata> + + <manifest>\n + <item id=\"ncx\" href=\"toc.ncx\" + media-type=\"application/x-dtbncx+xml\" />" + + manifest + + "</manifest> + + <spine toc=\"ncx\">" + (let ((chtml (org-epub-manifest-first #'org-epub-cover-p))) + (when chtml + (concat "<itemref idref=\"" (plist-get chtml :id) "\" linear=\"no\" />"))) + + spine + + "</spine> + + <guide>" + (let ((chtml (org-epub-manifest-first #'org-epub-cover-p))) + (when chtml + (concat " <reference type=\"cover\" href=\"" (plist-get chtml :filename) "\" />"))) + " + </guide> + +</package>")) + +(defun org-epub-gen-manifest (files) + "Generate the manifest XML string. + +FILES is the list of files to be included in the manifest xml string." + (mapconcat + (lambda (file) + (concat "<item id=\"" (plist-get file :id) "\" href=\"" (plist-get file :filename) "\" + media-type=\"" (plist-get file :mimetype) "\" />\n")) + files "")) + +(defun org-epub-gen-spine (files) + "Generate the spine XML string. + +FILES is the list of files to be included in the spine, these +must be in reading order." + (mapconcat + (lambda (file) + (concat "<itemref idref=\"" (car file) "\" />\n")) + files "")) + +(defun org-epub-template-container () + "Generate the container.xml file, the root of any EPUB." + "<?xml version=\"1.0\"?> +<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\"> + <rootfiles> + <rootfile full-path=\"content.opf\" + media-type=\"application/oebps-package+xml\"/> + </rootfiles> +</container>") + +(defun org-epub-template-cover (cover-file width height) + "Generate a HTML template for the cover page. + +COVER-FILE is the filename of a jpeg file, while WIDTH and HEIGHT are +properties of the image." + (concat "<?xml version=\"1.0\" encoding=\"utf-8\"?> + <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"> + + <html xmlns=\"http://www.w3.org/1999/xhtml\"> + <head> + <title> + + + + + + + + ")) + +(defun org-epub-template-mimetype () + "Generate the mimetype file for the epub." + "application/epub+zip") + +(defun org-epub-zip-it-up (epub-file files target-dir) + "Create the .epub file by zipping up the contents. + +EPUB-FILE is the target filename, FILES is the list of source +files to process, while TARGET-DIR is the directory where +exported HTML files live. This function will copy any files into +their proper place." + (mapc #'(lambda (entry) + (let ((copy (org-epub-manifest-needcopy entry))) + (when copy + (copy-file (car copy) (concat target-dir (cdr copy)) t)))) + files) + (let ((default-directory target-dir) + (meta-files '("META-INF/container.xml" "content.opf" "toc.ncx"))) + (apply 'call-process + (append (list org-epub-zip-command nil '(:file "zip.log") nil) + org-epub-zip-no-compress + (list epub-file + "mimetype"))) + (apply 'call-process org-epub-zip-command nil '(:file "zip.log") nil + (append org-epub-zip-compress + (list epub-file) + (append meta-files (mapcar #'(lambda (el) (plist-get el :filename)) files))))) + (copy-file (concat target-dir epub-file) default-directory t)) + +(defun org-epub-generate-toc-single (headlines filename) + "Generate a single file TOC. + +HEADLINES is a list containing the abbreviated headline +information. The name of the target file is given by FILENAME." + (let ((toc-id 0) + (current-level 0)) + (with-output-to-string + (mapc + (lambda (headline) + (let* ((title (nth 0 headline)) + (level (nth 1 headline)) + (ref (nth 2 headline))) + (cl-incf toc-id) + (cond + ((< current-level level) + (cl-incf current-level)) + ((> current-level level) + (princ "") + (while (> current-level level) + (cl-decf current-level) + (princ ""))) + ((eq current-level level) + (princ ""))) + (princ + (concat (format "\n" current-level filename toc-id) + (format "%s\n" (org-html-encode-plain-text title)) + (format "" filename ref))))) + headlines) + (while (> current-level 0) + (princ "") + (cl-decf current-level))))) + +(provide 'ox-epub) + +;;; ox-epub.el ends here diff --git a/packages/ox-hugo-20181106.2350.tar b/packages/ox-hugo-20190802.1755.tar similarity index 88% rename from packages/ox-hugo-20181106.2350.tar rename to packages/ox-hugo-20190802.1755.tar index 4eef178..547724b 100644 Binary files a/packages/ox-hugo-20181106.2350.tar and b/packages/ox-hugo-20190802.1755.tar differ diff --git a/packages/ox-jira-20171001.916.el b/packages/ox-jira-20171001.916.el new file mode 100644 index 0000000..5784000 --- /dev/null +++ b/packages/ox-jira-20171001.916.el @@ -0,0 +1,566 @@ +;;; ox-jira.el --- JIRA Backend for Org Export Engine + +;; Copyright (C) 2016 Stig Brautaset + +;; Author: Stig Brautaset +;; Version: 0.1-SNAPSHOT +;; Package-Version: 20171001.916 +;; Keywords: outlines, hypermedia, wp +;; Homepage: https://github.com/stig/ox-jira.el +;; Package-Requires: ((org "8.3")) + +;; This file is NOT part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 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 . + +;;; Commentary: + +;; This module plugs into the regular Org Export Engine and transforms Org +;; files to JIRA markup for pasting into JIRA tickets & comments. + +;; In an Org buffer, hit `C-c C-e j j' to bring up *Org Export Dispatcher* +;; and export it as a JIRA buffer. I usually use `C-x h' to mark the whole +;; buffer, then `M-w' to save it to the kill ring (and global pasteboard) for +;; pasting into JIRA issues. + +;;; Code: + +;; This is Cargo-culted from `ox-latex.el'` +(eval-when-compile (require 'cl)) +(require 'ox) +(require 'ox-publish) +(require 'subr-x) + + +;;; User Configurable Options +(defgroup ox-jira-export nil + "Options specific to JIRA export back-end." + :tag "Org Export JIRA" + :group 'org-export + :version "24.4" + :package-version '(ox-jira . "0.1")) + +(defcustom ox-jira-src-collapse-threshold 30 + "Minimum number of lines in a src block to set collapse=true in JIRA/Confluence {code} block." + :group 'ox-export-jira + :type '(integer)) + + + +;;; Defining Backend +(org-export-define-backend 'jira + '((babel-call . (lambda (&rest args) (ox-jira--not-implemented 'babel-call))) + (body . (lambda (&rest args) (ox-jira--not-implemented 'body))) + (bold . ox-jira-bold) + (center-block . (lambda (&rest args) (ox-jira--not-implemented 'center-block))) + (clock . (lambda (&rest args) (ox-jira--not-implemented 'clock))) + (code . ox-jira-code) + (diary-sexpexample-block . (lambda (&rest args) (ox-jira--not-implemented 'diary-sexpexample-block))) + (drawer . (lambda (&rest args) (ox-jira--not-implemented 'drawer))) + (dynamic-block . (lambda (&rest args) (ox-jira--not-implemented 'dynamic-block))) + (entity . (lambda (&rest args) (ox-jira--not-implemented 'entity))) + (example-block . ox-jira-example-block) + (export-block . (lambda (&rest args) (ox-jira--not-implemented 'export-block))) + (export-snippet . (lambda (&rest args) (ox-jira--not-implemented 'export-snippet))) + (final-output . (lambda (&rest args) (ox-jira--not-implemented 'final-output))) + (fixed-width . ox-jira-fixed-width) + (footnote-definition . ox-jira-footnote-definition) + (footnote-reference . ox-jira-footnote-reference) + (headline . ox-jira-headline) + (horizontal-rule . ox-jira-horizontal-rule) + (inline-babel-call . (lambda (&rest args) (ox-jira--not-implemented 'inline-babel-call))) + (inline-src-block . (lambda (&rest args) (ox-jira--not-implemented 'inline-src-block))) + (inlinetask . (lambda (&rest args) (ox-jira--not-implemented 'inlinetask))) + (italic . ox-jira-italic) + (item . ox-jira-item) + (keyword . (lambda (&rest args) "")) + (latex-environment . (lambda (&rest args) (ox-jira--not-implemented 'latex-environment))) + (latex-fragment . (lambda (&rest args) (ox-jira--not-implemented 'latex-fragment))) + (line-break . (lambda (&rest args) (ox-jira--not-implemented 'line-break))) + (link . ox-jira-link) + (node-property . (lambda (&rest args) (ox-jira--not-implemented 'node-property))) + (options . (lambda (&rest args) (ox-jira--not-implemented 'options))) + (paragraph . ox-jira-paragraph) + (parse-tree . (lambda (&rest args) (ox-jira--not-implemented 'parse-tree))) + (plain-list . ox-jira-plain-list) + (plain-text . ox-jira-plain-text) + (planning . (lambda (&rest args) (ox-jira--not-implemented 'planning))) + (property-drawer . (lambda (&rest args) (ox-jira--not-implemented 'property-drawer))) + (quote-block . ox-jira-quote-block) + (radio-target . (lambda (&rest args) (ox-jira--not-implemented 'radio-target))) + (section . ox-jira-section) + (special-block . (lambda (&rest args) (ox-jira--not-implemented 'special-block))) + (src-block . ox-jira-src-block) + (statistics-cookie . ox-jira-statistics-cookie) + (strike-through . ox-jira-strike-through) + (subscript . ox-jira-subscript) + (superscript . ox-jira-superscript) + (table . ox-jira-table) + (table-cell . ox-jira-table-cell) + (table-row . ox-jira-table-row) + (target . (lambda (&rest args) (ox-jira--not-implemented 'target))) + (timestamp . ox-jira-timestamp) + (underline . ox-jira-underline) + (verbatim . ox-jira-verbatim) + (verse-block . (lambda (&rest args) (ox-jira--not-implemented 'verse-block)))) + :filters-alist '((:filter-parse-tree . ox-jira-fix-multi-paragraph-items)) + :options-alist + '((:src-collapse-threshold nil nil ox-jira-src-collapse-threshold)) + :menu-entry + '(?j "Export to JIRA" + ((?j "As JIRA buffer" ox-jira-export-as-jira)))) + +;;; Internal Helpers + +;; Because I'm adding support for things as I find I need it rather than all +;; in one go, let's put a big fat red marker in for things we have not +;; implemented yet, to avoid missing it. +;; +(defun ox-jira--not-implemented (element-type) + "Replace anything we don't handle yet with a big red marker." + (format "{color:red}Element of type '%s' not implemented!{color}" element-type)) + +;; Super^script and sub_script I often want at the end of words, with no +;; whitespace immediately before it. Unfortunately JIRA doesn't support +;; that,so we have to fake it. This function makes simple text transforms +;; "embeddable" by preceding them with an empty anchor. This is admittedly a +;; bit of a hack, but I haven't found anything better. +;; +(defun ox-jira--text-transform-embeddable (transform-char contents) + (concat "{anchor}" transform-char contents transform-char)) + +;;; Filters + +;; Org support a single blank line between items in a list, but if we export +;; like that to JIRA format it will be interpreted as multiple consecutive +;; lists, which is never what I want. We can attempt to fix this by removing +;; the "post-blank" after a items (and paragraphs inside items) using a +;; filter. +;; +(defun ox-jira-fix-multi-paragraph-items (tree backend info) + "Remove extra blank line between paragraphs in plain-list items. + +TREE is the parse tree being exported. BACKEND is the export +back-end used. INFO is a plist used as a communication channel. + +Assume BACKEND is `jira'." + (org-element-map tree '(item paragraph src-block) + (lambda (e) + (org-element-put-property + e :post-blank + (if (or (eq (org-element-type e) 'item) + (eq (org-element-type (org-element-property :parent e)) 'item)) + 0 1)))) + ;; Return updated tree. + tree) + +;;; Transcode functions + +;; These functions do the actual translation to JIRA format. For this section +;; I've used Atlassian's Text Formatting Notation Help page as a reference: +;; https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all + +(defun ox-jira-bold (bold contents info) + "Transcode BOLD from Org to JIRA. +CONTENTS is the text with bold markup. INFO is a plist holding +contextual information." + (format "*%s*" contents)) + +(defun ox-jira-code (code _contents info) + "Transcode a CODE object from Org to JIRA. +CONTENTS is nil. INFO is a plist used as a communication +channel." + (format "{{%s}}" (org-element-property :value code))) + +(defun ox-jira-example-block (example-block contents info) + "Transcode an EXAMPLE-BLOCK element from Org to Jira. +CONTENTS is nil. INFO is a plist holding contextual +information." + (when (org-string-nw-p (org-element-property :value example-block)) + (format "{noformat}\n%s{noformat}" + (org-export-format-code-default example-block info)))) + +(defun ox-jira-fixed-width (fixed-width contents info) + "Transcode an FIXED-WIDTH element from Org to Jira. +CONTENTS is nil. INFO is a plist holding contextual +information." + (format "{noformat}\n%s{noformat}" + (org-remove-indentation + (org-element-property :value fixed-width)))) + +;; Footnotes have two parts: the reference, and the definition. +;; +(defun ox-jira--footnote-anchor (element) + (let ((label (org-element-property :label element))) + (replace-regexp-in-string ":" "" label))) + +(defun ox-jira--footnote-ref (anchor) + (replace-regexp-in-string "fn" "" anchor)) + +(defun ox-jira-footnote-reference (footnote-reference contents info) + "Transcode an FOOTNOTE-REFERENCE element from Org to Jira. +CONTENTS is nil. INFO is a plist holding contextual +information." + (let* ((anchor (ox-jira--footnote-anchor footnote-reference)) + (ref (ox-jira--footnote-ref anchor))) + (format "{anchor:fnr%s}[^%s^|#fn%s]" + anchor ref anchor))) + +(defun ox-jira-footnote-definition (footnote-definition contents info) + "Transcode an FOOTNOTE-DEFINITION element from Org to Jira. +CONTENTS is nil. INFO is a plist holding contextual +information." + (let* ((anchor (ox-jira--footnote-anchor footnote-definition)) + (ref (ox-jira--footnote-ref anchor))) + (format "{anchor:fn%s}[^%s^|#fnr%s] %s" + anchor ref anchor contents))) + +;; Headlines are a little bit more complex. I'm not even attempting to support +;; TODO labels and meta-information, just the straight-up text. It would be +;; nice to support the six standard levels of headlines JIRA offers though. +;; +;; Since the headline level is _relative_ rather than absolute, if the +;; exporter sees a '** second level' heading before it's seen a '* first +;; level' then the '** second level' will think it's a top-level heading. +;; That's a bit weird, but there you go. +;; +(defun ox-jira-headline (headline contents info) + "Transcode a HEADLINE element from Org to JIRA. +CONTENTS is the contents of the headline, as a string. INFO is +the plist used as a communication channel." + (let* ((level (org-export-get-relative-level headline info)) + (title (org-export-data-with-backend + (org-element-property :title headline) + 'jira info)) + (todo (and (plist-get info :with-todo-keywords) + (let ((todo (org-element-property :todo-keyword headline))) + (and todo (org-export-data todo info))))) + (todo-type (and todo (org-element-property :todo-type headline))) + (todo-text (if todo + (format "{color:%s}{{%s}}{color} " + (if (eq todo-type 'done) "lightgreen" "red") + todo) + "")) + (tags (and (plist-get info :with-tags) + (org-export-get-tags headline info))) + (tags-text (if tags + (format " {color:blue}{{:%s:}}{color}" (string-join tags ":")) + ""))) + (concat + (format "h%d. %s%s%s\n" level todo-text title tags-text) + contents))) + +(defun ox-jira-horizontal-rule (horizontal-rule contents info) + "Transcode a HORIZONTAL-RULE element from Org to JIRA." + "----\n") + +(defun ox-jira-italic (italic contents info) + "Transcode ITALIC from Org to JIRA. +CONTENTS is the text with italic markup. INFO is a plist holding +contextual information." + (format "_%s_" contents)) + +;; A list item. The JIRA format for nested lists follows. (You can also mix +;; ordered and unordered lists.) +;; +;; * item +;; ** sub-item +;; ** sub-item 2 +;; * item 2 +;; +;; The item element itself does not know what type it is: that is an attribute +;; of its parent, a plain-list element. We need to walk the path of +;; alternating plain-list and item nodes until there are no more, and extract +;; their type. The type list is used to create a bullet string. +;; +;; JIRA doesn't really have support for definition lists, so we fake it with a +;; bullet list and some bold text for the term. +;; +(defun ox-jira--list-type-path (item) + (when (and item (eq 'item (org-element-type item))) + (let* ((list (org-element-property :parent item)) + (list-type (org-element-property :type list))) + (cons list-type (ox-jira--list-type-path + (org-element-property :parent list)))))) + +(defun ox-jira--bullet-string (list-type-path) + (apply 'string + (mapcar (lambda (x) (if (eq x 'ordered) ?# ?*)) + list-type-path))) + +(defun ox-jira-item (item contents info) + "Transcode ITEM from Org to JIRA. +CONTENTS is the text with item markup. INFO is a plist holding +contextual information." + (let* ((list-type-path (ox-jira--list-type-path item)) + (bullet-string (ox-jira--bullet-string (reverse list-type-path))) + (tag (let ((tag (org-element-property :tag item))) + (when tag + (org-export-data tag info)))) + (checkbox (case (org-element-property :checkbox item) + (on "(/)") + (off "(x)") + (trans "(i)")))) + (concat + bullet-string + " " + (when checkbox + (concat checkbox " ")) + (when tag + (format "*%s*: " tag)) + contents))) + +;; JIRA supports many types of links. I don't expect we support them all, but +;; we must make a token effort. A lot of this code is cribbed from +;; `ox-latex.el'. +;; +(defun ox-jira-link (link desc info) + "Transcode a LINK object from Org to JIRA. + +DESC is the description part of the link, or the empty string. +INFO is a plist holding contextual information. See +`org-export-data'." + (let* ((type (org-element-property :type link)) + (raw-path (org-element-property :path link)) + (desc (and (not (string= desc "")) desc)) + (path (cond + ((member type '("http" "https" "ftp" "mailto" "doi")) + (concat type ":" raw-path)) + ((string= type "file") + (org-export-file-uri raw-path)) + (t raw-path)))) + (cond + ;; Link with description + ((and path desc) (format "[%s|%s]" desc path)) + ;; Link without description + (path (format "[%s]" path)) + ;; Link with only description?! + (t desc)))) + +(defun ox-jira-underline (underline contents info) + "Transcode UNDERLINE from Org to JIRA. +CONTENTS is the text with underline markup. INFO is a plist holding +contextual information." + (format "+%s+" contents)) + +(defun ox-jira-verbatim (verbatim _contents info) + "Transcode a VERBATIM object from Org to Jira. +CONTENTS is nil. INFO is a plist used as a communication +channel." + (format "{{%s}}" (org-element-property :value verbatim))) + +;; One of the most annoying things about JIRA markup is the way it doesn't +;; reflow text properly, so any linebreaks become hard linebreaks in the +;; rendered output. Let's fix that! +;; +;; What we need to do is replace any *internal* newlines (i.e. any not at the +;; end of the string) with a space. Regexes to the rescue! I used the +;; following reference to help me with this function: +;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Regexp-Backslash.html#Regexp-Backslash + + +(defun ox-jira-paragraph (paragraph contents info) + "Transcode a PARAGRAPH element from Org to JIRA. +CONTENTS is the contents of the paragraph, as a string. INFO is +the plist used as a communication channel." + (replace-regexp-in-string "\n\\([^\']\\)" " \\1" contents)) + +;; I make a lot of lists. Let's make sure we handle them! This is very simple, +;; as in the JIRA format all the logic is actually _for each item_ in the +;; list. +;; +(defun ox-jira-plain-list (plain-list contents info) + "Transcode PLAIN-LIST from Org to JIRA. +CONTENTS is the text with plain-list markup. INFO is a plist holding +contextual information." + contents) + +;; This is text with no markup, but we have to escape certain characters to +;; avoid tripping up JIRA. In particular: +;; +;; - ={= :: Introduces macros +;; - =[= :: Introduces links +;; +(defun ox-jira-plain-text (text info) + "Transcode TEXT from Org to JIRA. +TEXT is the string to transcode. INFO is a plist holding +contextual information." + (replace-regexp-in-string "\\([[{]\\)" + '(lambda (p) (format "\\\\%s" p)) + text)) + +;; Paragraphs are grouped into sections. I've not found any mention in the Org +;; documentation, but it appears to be essential for any export to happen. +;; I've essentially cribbed this from `ox-latex.el`. +;; + +(defun ox-jira-section (section contents info) + "Transcode a SECTION element from Org to JIRA. +CONTENTS is the contents of the section, as a string. INFO is +the plist used as a communication channel." + contents) + +;; JIRA supports formatting for these languages: actionscript, html, +;; java, javascript, sql, xhtml, xml. If none of them fits, we can use 'none', +;; or leave out the language altogether, which I imagine will be a bit like +;; ={noformat}=. +;; +(defun ox-jira-src-block (src-block contents info) + "Transcode a SRC-BLOCK element from Org to Jira. +CONTENTS holds the contents of the src-block. INFO is a plist holding +contextual information." + (when (org-string-nw-p (org-element-property :value src-block)) + (let* ((title (apply #'concat (org-export-get-caption src-block))) + (lang (org-element-property :language src-block)) + (lang (if (member lang '("actionscript" "html" "java" "javascript" "sql" "xhtml" "xml")) lang "none")) + (code (org-export-format-code-default src-block info)) + (collapse (if (< (plist-get info :src-collapse-threshold) + (org-count-lines code)) + "true" "false"))) + (concat + (format "{code:title=%s|language=%s|collapse=%s}" title lang collapse) + code + "{code}")))) + +(defun ox-jira-subscript (subscript contents info) + "Transcode SUBSCRIPT from Org to JIRA. +CONTENTS is the text with subscript markup. INFO is a plist holding +contextual information." + (ox-jira--text-transform-embeddable "~" contents)) + +(defun ox-jira-superscript (superscript contents info) + "Transcode SUPERSCRIPT from Org to JIRA. +CONTENTS is the text with superscript markup. INFO is a plist holding +contextual information." + (ox-jira--text-transform-embeddable "^" contents)) + + +;; Org's table editor is one of the many reasons to use Org. It is excellent. +;; Org and JIRA's tables are quite similar. Where Org marks tables up like +;; this: +;; +;; | Name | Score | +;; |--------+-------| +;; | Ashley | 2 | +;; | Alex | 3 | +;; +;; Jira uses the following format: +;; +;; || Name || Score || +;; | Ashley | 2 | +;; | Alex | 3 | +;; +;; Tables are complex beasts. I only hope to support very simple ones. Looks +;; like most of the logic will live in the row and cell transcoding functions. +;; +(defun ox-jira-table (table contents info) + "Transcode a TABLE element from Org to JIRA. +CONTENTS holds the contents of the table. INFO is a plist holding +contextual information." + contents) + +;; We only want to output =standard= rows, not horizontal lines. I'm not sure +;; if detection of header rows belongs here or in the cells. +;; +(defun ox-jira-table-row (table-row contents info) + "Transcode a TABLE-ROW element from Org to JIRA. +CONTENTS holds the contents of the table-row. INFO is a plist holding +contextual information." + (when (eq 'standard (org-element-property :type table-row)) + (format "%s\n" contents))) + +;; The cell itself does not know if it is a header cell or not, so we have to +;; ask its containing row if it is the first row, and the table if it has a +;; header row at all. If those things are true, make the cell a header cell. +;; +(defun ox-jira-table-cell (table-cell contents info) + "Transcode a TABLE-CELL element from Org to JIRA. +CONTENTS holds the contents of the table-cell. INFO is a plist holding +contextual information." + (let* ((row (org-element-property :parent table-cell)) + (table (org-element-property :parent row)) + (has-header (org-export-table-has-header-p table info)) + (group (org-export-table-row-group row info)) + (is-header (and has-header (eq 1 group))) + (sep (if is-header "||" "|"))) + (format "%s %s %s" sep (if contents contents "") + (if (org-export-last-sibling-p table-cell info) sep "")))) + +;; This is updated to show progress of subsequent list of check boxes. +;; +(defun ox-jira-statistics-cookie (statistics-cookie _contents _info) + "Transcode a STATISTICS-COOKIE object from Org to JIRA. +CONTENTS is nil. INFO is a plist holding contextual information." + (format "\\%s" (org-element-property :value statistics-cookie))) + +(defun ox-jira-strike-through (strike-through contents info) + "Transcode STRIKE-THROUGH from Org to JIRA. +CONTENTS is the text with strike-through markup. INFO is a plist holding +contextual information." + (format "-%s-" contents)) + +(defun ox-jira-quote-block (quote-block contents info) + "Transcode a QUOTE-BLOCK element from Org to Jira. +CONTENTS holds the contents of the block. INFO is a plist +holding contextual information." + (format "{quote}\n%s{quote}" contents)) + + +(defun ox-jira-timestamp (timestamp _contents info) + "Transcode a TIMESTAMP object from Org to JIRA. +CONTENTS is nil. INFO is a plist holding contextual information." + (let ((value (org-timestamp-translate timestamp)) + (fmt (cl-case (org-element-property :type timestamp) + ((active active-range) "_%s_") + ((inactive inactive-range) "_\\%s_") + (otherwise "_%s_")))) + (format fmt value))) + +(defun ox-jira-export-as-jira + (&optional async subtreep visible-only body-only ext-plist) + "Export current buffer as a Jira buffer. + +If narrowing is active in the current buffer, only export its +narrowed part. + +If a region is active, export that region. + +A non-nil optional argument ASYNC means the process should happen +asynchronously. The resulting buffer should be accessible +through the `org-export-stack' interface. + +When optional argument SUBTREEP is non-nil, export the sub-tree +at point, extracting information from the headline properties +first. + +When optional argument VISIBLE-ONLY is non-nil, don't export +contents of hidden elements. + +When optional argument BODY-ONLY is non-nil, omit header +stuff. (e.g. AUTHOR and TITLE.) + +EXT-PLIST, when provided, is a property list with external +parameters overriding Org default settings, but still inferior to +file-local settings. + +Export is done in a buffer named \"*Org JIRA Export*\", which +will be displayed when `org-export-show-temporary-export-buffer' +is non-nil." + (interactive) + (org-export-to-buffer 'jira "*Org JIRA Export*" + async subtreep visible-only body-only ext-plist)) + +(provide 'ox-jira) + +;;; ox-jira.el ends here diff --git a/packages/ox-reveal-20161027.926.el b/packages/ox-reveal-20161027.926.el deleted file mode 100644 index 19ff679..0000000 --- a/packages/ox-reveal-20161027.926.el +++ /dev/null @@ -1,1192 +0,0 @@ -;;; ox-reveal.el --- reveal.js Presentation Back-End for Org Export Engine - -;; Copyright (C) 2013 Yujie Wen - -;; Author: Yujie Wen -;; Created: 2013-04-27 -;; Version: 1.0 -;; Package-Version: 20161027.926 -;; Package-Requires: ((org "20150330")) -;; Keywords: outlines, hypermedia, slideshow, presentation - -;; This file is not part of GNU Emacs. - -;;; Copyright Notice: - -;; 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 GNU Emacs. If not, see . - -;; Please see "Readme.org" for detail introductions. - -;; Pull request: Multiplex Support - Stephen Barrett \n%s\n\n" contents) - (org-html-special-block special-block contents info)))) - -;; Copied from org-html-headline and modified to embed org-reveal -;; specific attributes. -(defun org-reveal-headline (headline contents info) - "Transcode a HEADLINE element from Org to HTML. -CONTENTS holds the contents of the headline. INFO is a plist -holding contextual information." - (unless (org-element-property :footnote-section-p headline) - (if (org-export-low-level-p headline info) - ;; This is a deep sub-tree: export it as in ox-html. - (org-html-headline headline contents info) - ;; Standard headline. Export it as a slide - (let* ((level (org-export-get-relative-level headline info)) - (preferred-id (or (org-element-property :CUSTOM_ID headline) - (org-export-get-reference headline info) - (org-element-property :ID headline))) - (hlevel (org-reveal--get-hlevel info)) - (header (plist-get info :reveal-slide-header)) - (header-div (when header (format "

%s
\n" header))) - (footer (plist-get info :reveal-slide-footer)) - (footer-div (when footer (format "
%s
\n" footer))) - (first-sibling (org-export-first-sibling-p headline info)) - (last-sibling (org-export-last-sibling-p headline info)) - (default-slide-background (plist-get info :reveal-default-slide-background)) - (default-slide-background-size (plist-get info :reveal-default-slide-background-size)) - (default-slide-background-position (plist-get info :reveal-default-slide-background-position)) - (default-slide-background-repeat (plist-get info :reveal-default-slide-background-repeat)) - (default-slide-background-transition (plist-get info :reveal-default-slide-background-transition)) - (slide-section-tag (format "
\n" - (org-html--make-attribute-string - `(:id ,(format "slide-%s" preferred-id) - :data-transition ,(org-element-property :REVEAL_DATA_TRANSITION headline) - :data-state ,(org-element-property :REVEAL_DATA_STATE headline) - :data-background ,(or (org-element-property :REVEAL_BACKGROUND headline) - default-slide-background) - :data-background-size ,(or (org-element-property :REVEAL_BACKGROUND_SIZE headline) - default-slide-background-size) - :data-background-position ,(or (org-element-property :REVEAL_BACKGROUND_POSITION headline) - default-slide-background-position) - :data-background-repeat ,(or (org-element-property :REVEAL_BACKGROUND_REPEAT headline) - default-slide-background-repeat) - :data-background-transition ,(or (org-element-property :REVEAL_BACKGROUND_TRANS headline) - default-slide-background-transition))) - (let ((extra-attrs (org-element-property :REVEAL_EXTRA_ATTR headline))) - (if extra-attrs (format " %s" extra-attrs) "")))) - (ret (concat - (if (or (/= level 1) (not first-sibling)) - ;; Not the first heading. Close previou slide. - (concat - ;; Slide footer if any - footer-div - ;; Close previous slide - "
\n" - (if (<= level hlevel) - ;; Close previous vertical slide group. - "\n"))) - (if (<= level hlevel) - ;; Add an extra "
" to group following slides - ;; into vertical slide group. Transition override - ;; attributes are attached at this level, too. - (let ((attrs - (org-html--make-attribute-string - `(:data-transition ,(org-element-property :REVEAL_DATA_TRANSITION headline))))) - (if (string= attrs "") - "
\n" - (format "
\n" attrs)))) - ;; Start a new slide. - (prog1 - slide-section-tag - ;; Cache the current slide's section tag, except the id attr - (setq org-reveal--last-slide-section-tag - (replace-regexp-in-string "id\\s-*=\\s-*[\][\"].*?[\][\"]" - "" slide-section-tag))) - ;; Slide header if any. - header-div - ;; The HTML content of the headline - ;; Strip the
tags, if any - (let ((html (org-html-headline headline contents info))) - (if (string-prefix-p " and the last
tags from html - (concat "<" - (mapconcat 'identity - (butlast (cdr (split-string html "<" t))) - "<")) - ;; Return the HTML content unchanged - html)) - (if (and (= level 1) - (org-export-last-sibling-p headline info)) - ;; Last head 1. Close all slides. - (concat - ;; Slide footer if any - footer-div - "
\n
\n"))))) - ret)))) - -(defgroup org-export-reveal nil - "Options for exporting Orgmode files to reveal.js HTML pressentations." - :tag "Org Export Reveal" - :group 'org-export) - -(defun org-reveal--read-file (file) - "Return the content of file" - (with-temp-buffer - (insert-file-contents-literally file) - (buffer-string))) - -(defun org-reveal--file-url-to-path (url) - "Convert URL that points to local files to file path." - (replace-regexp-in-string - (if (string-equal system-type "windows-nt") "^file:///" "^file://") - "" url)) - -(defun org-reveal--css-label (in-single-file file-name style-id) - "Generate an HTML label for including a CSS file, if - IN-SINGLE-FILE is t, the content of FILE-NAME is embedded, - otherwise, a `' label is generated." - (when (and file-name (not (string= file-name ""))) - (if in-single-file - ;; Single-file - (let ((local-file-name (org-reveal--file-url-to-path file-name))) - (if (file-readable-p local-file-name) - (concat "\n") - ;; But file is not readable. - (error "Cannot read %s" file-name))) - ;; Not in-single-file - (concat "\n")))) - -(defun org-reveal-stylesheets (info) - "Return the HTML contents for declaring reveal stylesheets -using custom variable `org-reveal-root'." - (let* ((root-path (file-name-as-directory (plist-get info :reveal-root))) - (reveal-css (concat root-path "css/reveal.css")) - (theme (plist-get info :reveal-theme)) - (theme-css (concat root-path "css/theme/" theme ".css")) - (extra-css (plist-get info :reveal-extra-css)) - (in-single-file (plist-get info :reveal-single-file))) - (concat - ;; Default embedded style sheets - " -" - ;; stylesheets - (mapconcat (lambda (elem) (org-reveal--css-label in-single-file (car elem) (cdr elem))) - (append (list (cons reveal-css nil) - (cons theme-css "theme")) - (mapcar (lambda (a) (cons a nil)) - (split-string extra-css "\n"))) - "\n") - - ;; Include CSS for highlight.js if necessary - (if (org-reveal--using-highlight.js info) - (format "" - (format-spec (plist-get info :reveal-highlight-css) - `((?r . ,(directory-file-name root-path)))))) - ;; print-pdf - (if in-single-file "" - (format " - - -" - root-path))))) - -(defun org-reveal-mathjax-scripts (info) - "Return the HTML contents for declaring MathJax scripts" - (if (plist-get info :reveal-mathjax) - ;; MathJax enabled. - (format "\n" - (plist-get info :reveal-mathjax-url)))) - -(defun org-reveal-scripts (info) - "Return the necessary scripts for initializing reveal.js using -custom variable `org-reveal-root'." - (let* ((root-path (file-name-as-directory (plist-get info :reveal-root))) - (head-min-js (concat root-path "lib/js/head.min.js")) - (reveal-js (concat root-path "js/reveal.js")) - ;; Local files - (local-root-path (org-reveal--file-url-to-path root-path)) - (local-head-min-js (concat local-root-path "lib/js/head.min.js")) - (local-reveal-js (concat local-root-path "js/reveal.js")) - (in-single-file (plist-get info :reveal-single-file))) - (concat - ;; reveal.js/lib/js/head.min.js - ;; reveal.js/js/reveal.js - (if (and in-single-file - (file-readable-p local-head-min-js) - (file-readable-p local-reveal-js)) - ;; Embed scripts into HTML - (concat "") - ;; Fall-back to extern script links - (if in-single-file - ;; Tried to embed scripts but failed. Print a message about possible errors. - (error (concat "Cannot read " - (mapconcat 'identity - (delq nil (mapcar (lambda (file) (if (not (file-readable-p file)) file)) - (list local-head-min-js local-reveal-js))) - ", ")))) - (concat - "\n" - "\n")) - ;; plugin headings - " -\n"))) - -(defun org-reveal-toc (depth info) - "Build a slide of table of contents." - (let ((toc (org-html-toc depth info))) - (if toc - (format "
\n%s
\n" - (replace-regexp-in-string "\n%s" org-reveal--last-slide-section-tag "")))) - -(defun org-reveal-parse-keyword-value (value) - "According to the value content, return HTML tags to split slides." - (let ((tokens (mapcar - (lambda (x) (split-string x ":")) - (split-string value)))) - (mapconcat - (lambda (x) (apply 'org-reveal-parse-token x)) - tokens - ""))) - -;; Copied from org-html-format-list-item. Overwrite HTML class -;; attribute when there is attr_html attributes. -(defun org-reveal-format-list-item (contents type checkbox attributes info - &optional term-counter-id - headline) - "Format a list item into HTML." - (let ((attr-html (cond (attributes (format " %s" (org-html--make-attribute-string attributes))) - (checkbox (format " class=\"%s\"" (symbol-name checkbox))) - (t ""))) - (checkbox (concat (org-html-checkbox checkbox info) - (and checkbox " "))) - (br (org-html-close-tag "br" nil info))) - (concat - (case type - (ordered - (let* ((counter term-counter-id) - (extra (if counter (format " value=\"%s\"" counter) ""))) - (concat - (format "" attr-html extra) - (when headline (concat headline br))))) - (unordered - (let* ((id term-counter-id) - (extra (if id (format " id=\"%s\"" id) ""))) - (concat - (format "" attr-html extra) - (when headline (concat headline br))))) - (descriptive - (let* ((term term-counter-id)) - (setq term (or term "(no term)")) - ;; Check-boxes in descriptive lists are associated to tag. - (concat (format "%s" - attr-html (concat checkbox term)) - (format "" attr-html))))) - (unless (eq type 'descriptive) checkbox) - (and contents (org-trim contents)) - (case type - (ordered "") - (unordered "") - (descriptive ""))))) - -;; Copied from org-html-item, changed to call -;; org-reveal-format-list-item. -(defun org-reveal-item (item contents info) - "Transcode an ITEM element from Org to Reveal. -CONTENTS holds the contents of the item. INFO is a plist holding -contextual information." - (let* ((plain-list (org-export-get-parent item)) - (type (org-element-property :type plain-list)) - (counter (org-element-property :counter item)) - (attributes (org-export-read-attribute :attr_html item)) - ; (attributes (org-html--make-attribute-string (org-export-read-attribute :attr_html item))) - (checkbox (org-element-property :checkbox item)) - (tag (let ((tag (org-element-property :tag item))) - (and tag (org-export-data tag info))))) - (org-reveal-format-list-item - contents type checkbox attributes info (or tag counter)))) - -(defun org-reveal-keyword (keyword contents info) - "Transcode a KEYWORD element from Org to Reveal, -and may change custom variables as SIDE EFFECT. -CONTENTS is nil. INFO is a plist holding contextual information." - (let ((key (org-element-property :key keyword)) - (value (org-element-property :value keyword))) - (case (intern key) - (REVEAL (org-reveal-parse-keyword-value value)) - (REVEAL_HTML value) - (HTML value)))) -(defun org-reveal-embedded-svg (path) - "Embed the SVG content into Reveal HTML." - (with-temp-buffer - (insert-file-contents-literally path) - (let ((start (re-search-forward "<[ \t\n]*svg[ \t\n]")) - (end (re-search-forward "<[ \t\n]*/svg[ \t\n]*>"))) - (concat "\n%s\n\n" - (if attrs (concat " " (org-html--make-attribute-string attrs)) "") - (org-html-latex-environment latex-env contents info)))) - -(defun org-reveal-plain-list (plain-list contents info) - "Transcode a PLAIN-LIST element from Org to Reveal. - -CONTENTS is the contents of the list. INFO is a plist holding -contextual information. - -Extract and set `attr_html' to plain-list tag attributes." - (let ((tag (case (org-element-property :type plain-list) - (ordered "ol") - (unordered "ul") - (descriptive "dl"))) - (attrs (org-export-read-attribute :attr_html plain-list))) - (format "%s<%s%s>\n%s\n%s" - (if (string= org-html-checkbox-type 'html) "
" "") - tag - (if attrs (concat " " (org-html--make-attribute-string attrs)) "") - contents - tag - (if (string= org-html-checkbox-type 'html) "
" "")))) - -(defun org-reveal--build-pre/postamble (type info) - "Return document preamble or postamble as a string, or nil." - (let ((section (plist-get info (intern (format ":reveal-%s" type)))) - (spec (org-html-format-spec info))) - (when section - (let ((section-contents - (if (functionp (intern section)) (funcall (intern section) info) - ;; else section is a string. - (format-spec section spec)))) - (when (org-string-nw-p section-contents) - (org-element-normalize-string section-contents)))))) - - -(defun org-reveal-section (section contents info) - "Transcode a SECTION element from Org to Reveal. -CONTENTS holds the contents of the section. INFO is a plist -holding contextual information." - ;; Just return the contents. No "
" tags. - contents) - -(defun org-reveal--using-highlight.js (info) - "Check whether highlight.js plugin is enabled." - (let ((reveal-plugins (condition-case e - (car (read-from-string (plist-get info :reveal-plugins))) - (end-of-file nil) - (wrong-type-argument nil)))) - (memq 'highlight (or (and reveal-plugins (listp reveal-plugins) reveal-plugins) - org-reveal-plugins)))) - -(defun org-reveal-src-block (src-block contents info) - "Transcode a SRC-BLOCK element from Org to Reveal. -CONTENTS holds the contents of the item. INFO is a plist holding -contextual information." - (if (org-export-read-attribute :attr_html src-block :textarea) - (org-html--textarea-block src-block) - (let* ((use-highlight (org-reveal--using-highlight.js info)) - (lang (org-element-property :language src-block)) - (caption (org-export-get-caption src-block)) - (code (if (not use-highlight) - (org-html-format-code src-block info) - (cl-letf (((symbol-function 'org-html-htmlize-region-for-paste) - #'buffer-substring)) - (org-html-format-code src-block info)))) - (frag (org-export-read-attribute :attr_reveal src-block :frag)) - (code-attribs (or (org-export-read-attribute - :attr_reveal src-block :code_attribs) "")) - (label (let ((lbl (org-element-property :name src-block))) - (if (not lbl) "" - (format " id=\"%s\"" lbl))))) - (if (not lang) - (format "
\n%s
" - (or (frag-class frag info) " class=\"example\"") - label - code) - (format - "
\n%s%s\n
" - (if (not caption) "" - (format "" - (org-export-data caption info))) - (if use-highlight - (format "\n%s" - (or (frag-class frag info) "") - label lang code-attribs code) - (format "\n
%s
" - (or (frag-class frag info) - (format " class=\"src src-%s\"" lang)) - label code))))))) - -(defun org-reveal-quote-block (quote-block contents info) - "Transcode a QUOTE-BLOCK element from Org to Reveal. -CONTENTS holds the contents of the block INFO is a plist holding -contextual information." - (format "
\n%s
" - (frag-class (org-export-read-attribute :attr_reveal quote-block :frag) info) - contents)) - - -(defun org-reveal--auto-title-slide-template (info) - "Generate the automatic title slide template." - (let* ((spec (org-html-format-spec info)) - (title (org-export-data (plist-get info :title) info)) - (author (cdr (assq ?a spec))) - (email (cdr (assq ?e spec))) - (date (cdr (assq ?d spec)))) - (concat - (when (and (plist-get info :with-title) - (org-string-nw-p title)) - (concat "

" title "

")) - (when (and (plist-get info :with-author) - (org-string-nw-p author)) - (concat "

" author "

")) - (when (and (plist-get info :with-email) - (org-string-nw-p email)) - (concat "

" email "

")) - (when (and (plist-get info :with-date) - (org-string-nw-p date)) - (concat "

" date "

")) - (when (plist-get info :time-stamp-file) - (concat "

" - (org-html--translate "Created" info) - ": " - (format-time-string - (plist-get info :html-metadata-timestamp-format)) - "

"))))) - -(defun org-reveal-template (contents info) - "Return complete document string after HTML conversion. -contents is the transcoded contents string. -info is a plist holding export options." - (concat - (format "\n\n\n" - (if-format " lang=\"%s\"" (plist-get info :language))) - "\n" - (if-format "%s\n" (org-export-data (plist-get info :title) info)) - (if-format "\n" (plist-get info :author)) - (if-format "\n" (plist-get info :description)) - (if-format "\n" (plist-get info :keywords)) - (org-reveal-stylesheets info) - (org-reveal-mathjax-scripts info) - (org-reveal--build-pre/postamble 'head-preamble info) - (org-element-normalize-string (plist-get info :html-head)) - (org-element-normalize-string (plist-get info :html-head-extra)) - " -\n" - (org-reveal--build-pre/postamble 'preamble info) - "
-
\n" - ;; Title slides - (let ((title-slide (plist-get info :reveal-title-slide))) - (when (and title-slide (not (plist-get info :reveal-subtree))) - (let ((title-slide-background (plist-get info :reveal-title-slide-background)) - (title-slide-background-size (plist-get info :reveal-title-slide-background-size)) - (title-slide-background-position (plist-get info :reveal-title-slide-background-position)) - (title-slide-background-repeat (plist-get info :reveal-title-slide-background-repeat)) - (title-slide-background-transition (plist-get info :reveal-title-slide-background-transition))) - (concat "
" - (cond ((eq title-slide nil) nil) - ((stringp title-slide) (format-spec title-slide (org-html-format-spec info))) - ((eq title-slide 'auto) (org-reveal--auto-title-slide-template info))) - "\n
\n")))) - contents - "
-
\n" - (org-reveal--build-pre/postamble 'postamble info) - (org-reveal-scripts info) - " -\n")) - -(defun org-reveal-filter-parse-tree (tree backend info) - "Do filtering before parsing TREE. - -Tree is the parse tree being exported. BACKEND is the export -back-end used. INFO is a plist-used as a communication channel. - -Assuming BACKEND is `reveal'. - -Each `attr_reveal' attribute is mapped to corresponding -`attr_html' attributes." - (let ((default-frag-style (plist-get info :reveal-default-frag-style))) - (org-element-map tree (remq 'item org-element-all-elements) - (lambda (elem) (org-reveal-append-frag elem default-frag-style)))) - ;; Return the updated tree. - tree) - -(defun org-reveal--update-attr-html (elem frag default-style &optional frag-index) - "Update ELEM's attr_html atrribute with reveal's -fragment attributes." - (let ((attr-html (org-element-property :attr_html elem))) - (when (and frag (not (string= frag "none"))) - (push (cond ((string= frag t) - (if default-style (format ":class fragment %s" default-style) - ":class fragment")) - (t (format ":class fragment %s" frag))) - attr-html) - (when frag-index - (push (format ":data-fragment-index %s" frag-index) attr-html))) - (org-element-put-property elem :attr_html attr-html))) - -(defun org-reveal-append-frag (elem default-style) - "Read org-reveal's fragment attribute from ELEM and append -transformed fragment attribute to ELEM's attr_html plist." - (let ((frag (org-export-read-attribute :attr_reveal elem :frag)) - (frag-index (org-export-read-attribute :attr_reveal elem :frag_idx))) - (if frag - (cond ((and (string= (org-element-type elem) 'plain-list) - (char-equal (string-to-char frag) ?\()) - (let* ((frag-list (car (read-from-string frag))) - (frag-list (if default-style - (mapcar (lambda (s) - "Replace t with default-style" - (if (string= s t) default-style - s)) - frag-list) - frag-list)) - (items (org-element-contents elem))) - (if frag-index - (mapcar* 'org-reveal--update-attr-html - items frag-list default-style (car (read-from-string frag-index))) - (let* ((last-frag (car (last frag-list))) - (tail-list (mapcar (lambda (a) last-frag) - (number-sequence (+ (length frag-list) 1) - (length items)))) - (default-style-list - (mapcar (lambda (a) default-style) - (number-sequence 1 (length items))))) - (nconc frag-list tail-list) - (mapcar* 'org-reveal--update-attr-html items frag-list default-style-list))))) - (t (org-reveal--update-attr-html elem frag default-style frag-index))) - elem))) - -(defvar client-multiplex nil - "used to cause generation of client html file for multiplex") - -(defun org-reveal-export-to-html - (&optional async subtreep visible-only body-only ext-plist) - "Export current buffer to a reveal.js HTML file." - (interactive) - (let* ((extension (concat "." org-html-extension)) - (file (org-export-output-file-name extension subtreep)) - (clientfile (org-export-output-file-name (concat "_client" extension) subtreep))) - - ; export filename_client HTML file if multiplexing - (setq client-multiplex nil) - (setq retfile (org-export-to-file 'reveal file - async subtreep visible-only body-only ext-plist)) - - ; export the client HTML file if client-multiplex is set true - ; by previous call to org-export-to-file - (if (eq client-multiplex t) - (org-export-to-file 'reveal clientfile - async subtreep visible-only body-only ext-plist)) - (cond (t retfile)))) - -(defun org-reveal-export-to-html-and-browse - (&optional async subtreep visible-only body-only ext-plist) - "Export current buffer to a reveal.js and browse HTML file." - (interactive) - (browse-url-of-file (expand-file-name (org-reveal-export-to-html async subtreep visible-only body-only ext-plist)))) - -(defun org-reveal-export-current-subtree - (&optional async subtreep visible-only body-only ext-plist) - "Export current subtree to a Reveal.js HTML file." - (interactive) - (org-narrow-to-subtree) - (let ((ret (org-reveal-export-to-html async subtreep visible-only body-only (plist-put ext-plist :reveal-subtree t)))) - (widen) - ret)) - -;;;###autoload -(defun org-reveal-publish-to-reveal - (plist filename pub-dir) - "Publish an org file to Html. - -FILENAME is the filename of the Org file to be published. PLIST -is the property list for the given project. PUB-DIR is the -publishing directory. - -Return output file name." - (org-publish-org-to 'reveal filename ".html" plist pub-dir)) - -;; Register auto-completion for speaker notes. -(when org-reveal-note-key-char - (add-to-list 'org-structure-template-alist - (list org-reveal-note-key-char "#+BEGIN_NOTES\n\?\n#+END_NOTES"))) - -(provide 'ox-reveal) - -;;; ox-reveal.el ends here diff --git a/packages/ox-rfc-20190429.1133.tar b/packages/ox-rfc-20190429.1133.tar new file mode 100644 index 0000000..5cfa4cd Binary files /dev/null and b/packages/ox-rfc-20190429.1133.tar differ diff --git a/packages/package-lint-20190807.1837.el b/packages/package-lint-20190807.1837.el new file mode 100644 index 0000000..0c6e4ed --- /dev/null +++ b/packages/package-lint-20190807.1837.el @@ -0,0 +1,1087 @@ +;;; package-lint.el --- A linting library for elisp package authors -*- lexical-binding: t -*- + +;; Copyright (C) 2014-2017 Steve Purcell, Fanael Linithien + +;; Author: Steve Purcell +;; Fanael Linithien +;; URL: https://github.com/purcell/package-lint +;; Package-Version: 20190807.1837 +;; Keywords: lisp +;; Version: 0 +;; Package-Requires: ((cl-lib "0.5") (emacs "24")) + +;; 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 . + +;;; Commentary: + +;; Provides a list of issues with the package metadata of a file, +;; e.g. the package dependencies it requires. + +;; See function `package-lint-buffer'. + +;; Checks will currently be enabled only if a "Package-Requires:" or +;; "Package-Version:" header is present in the file. + +;;; Code: + +(eval-when-compile (require 'pcase)) ; `pcase-dolist' is not autoloaded +(require 'cl-lib) +(require 'package) +(require 'lisp-mnt) +(require 'finder) +(require 'imenu) + + +;;; Compatibility + +(defalias 'package-lint--package-desc-summary + (if (fboundp 'package-desc-summary) + 'package-desc-summary + 'package-desc-doc)) + +(defalias 'package-lint--package-desc-name + (if (fboundp 'package-desc-name) + 'package-desc-name + (lambda (desc) (intern (elt desc 0))))) + + +;;; Machinery + +(defvar package-lint--errors nil + "List of errors and warnings for the current buffer. +This is bound dynamically while the checks run.") + +(defmacro package-lint--match-symbols (&rest symbols) + "Return a regexp matching the string names of all given SYMBOLS." + (regexp-opt (mapcar #'symbol-name symbols))) + +(defconst package-lint--libraries-added-alist + (list + (cons '(24 4) + (package-lint--match-symbols + nadvice + subr-x)) + (cons '(25 1) + (package-lint--match-symbols + cl-generic + js-jsx-mode + map + pinentry + thunk))) + "An alist of library names and when they were added to Emacs.") + +(defconst package-lint--functions-and-macros-added-alist + (list + (cons '(24) + (package-lint--match-symbols + bidi-string-mark-left-to-right + condition-case-unless-debug + current-bidi-paragraph-direction + file-selinux-context + letrec + make-composed-keymap + pcase + pcase-dolist + pcase-let + pcase-let* + prog-mode + read-char-choice + run-hook-wrapped + server-eval-at + set-file-selinux-context + special-variable-p + string-prefix-p + url-queue-retrieve + window-body-height + window-stage-get + window-stage-put + window-total-width + window-valid-p + with-wrapper-hook)) + (cons '(24 3) + (package-lint--match-symbols + autoload-do-load + autoloadp + buffer-narrowed-p + defvar-local + file-name-base + function-get + posnp + read-only-mode + setq-local + system-groups + system-users + tty-top-frame + url-encode-url + user-error + with-temp-buffer-window)) + (cons '(24 4) + (package-lint--match-symbols + add-face-text-property + add-function + advice-add + advice-remove + cl-tagbody + completion-table-merge + completion-table-with-cache + define-alternative + define-error + display-monitor-attributes-list + eieio-object-class + file-acl + file-extended-attributes + fill-single-char-nobreak-p + frame-monitor-attributes + get-pos-property + group-gid + group-real-gid + hash-table-keys + hash-table-values + line-pixel-height + macrop + process-lines + remove-function + set-file-acl + special-form-p + string-blank-p + string-empty-p + string-join + string-remove-prefix + string-remove-suffix + string-reverse + string-suffix-p + string-trim + string-trim-left + string-trim-right + window-bottom-divider-width + window-header-line-height + window-mode-line-height + window-pixel-height + window-right-divider-width + window-scroll-bar-width + window-text-pixel-size + with-eval-after-load + zlib-decompress-region)) + (cons '(25) + (package-lint--match-symbols + alist-get + backward-word-strictly + bidi-find-overridden-directionality + buffer-substring-with-bidi-context + bufferpos-to-filepos + char-fold-to-regexp + checkdoc-file + cl-digit-char-p + cl-fresh-line + cl-parse-integer + default-font-width + define-advice + define-inline + directory-files-recursively + directory-name-p + file-notify-valid-p + filepos-to-bufferpos + font-lock-ensure + font-lock-flush + format-message + forward-word-strictly + frame-edges + frame-geometry + frame-scroll-bar-height + funcall-interactively + function-put + horizontal-scroll-bars-available-p + if-let + macroexpand-1 + make-process + mouse-absolute-pixel-position + pcase-defmacro + pcase-exhaustive + pcase-lambda + set-binary-mode + set-mouse-absolute-pixel-position + string-collate-equalp + string-collate-lessp + string-greaterp + thread-first + thread-last + toggle-horizontal-scroll-bar + when-let + window-absolute-pixel-position + window-font-height + window-font-width + window-max-chars-per-line + window-preserve-size + window-scroll-bar-height + with-displayed-buffer-window + with-file-modes)) + (cons '(26) + (package-lint--match-symbols + read-answer + list-at-point + list-timers + replace-buffer-contents + apropos-local-variable + apropos-local-value + dired-mouse-find-file + dired-mouse-find-file-other-frame + if-let* + when-let*)) + (cons '(26 2) + (package-lint--match-symbols + read-answer + assoc-delete-all))) + "An alist of function/macro names and when they were added to Emacs.") + +(defconst package-lint--sane-prefixes + (rx + string-start + (or + "org-dblock-write:" + "org-babel-execute:" + "org-babel-prep-session:" + "org-babel-variable-assignments:" + "org-babel-default-header-args:" + "pcomplete/")) + "A regexp matching whitelisted non-standard symbol prefixes.") + +(defun package-lint--check-all () + "Return a list of errors/warnings for the current buffer." + (let ((package-lint--errors '()) + (case-fold-search nil)) + (save-match-data + (save-excursion + (save-restriction + (widen) + (package-lint--check-reserved-keybindings) + (package-lint--check-keywords-list) + (package-lint--check-url-header) + (package-lint--check-package-version-present) + (package-lint--check-lexical-binding-is-on-first-line) + (package-lint--check-objects-by-regexp + "(define-minor-mode\\s-" + #'package-lint--check-minor-mode) + (package-lint--check-objects-by-regexp + "(define-global\\(?:ized\\)?-minor-mode\\s-" + #'package-lint--check-globalized-minor-mode) + (package-lint--check-objects-by-regexp + (concat "(" (regexp-opt '("defalias" "defvaralias")) "\\s-") + #'package-lint--check-defalias) + (package-lint--check-objects-by-regexp + "(defgroup\\s-" #'package-lint--check-defgroup) + (let ((desc (package-lint--check-package-el-can-parse))) + (when desc + (package-lint--check-package-summary desc) + (package-lint--check-provide-form desc))) + (package-lint--check-no-use-of-cl) + (package-lint--check-no-use-of-cl-lib-sublibraries) + (package-lint--check-eval-after-load) + (let ((deps (package-lint--check-dependency-list))) + (package-lint--check-lexical-binding-requires-emacs-24 deps) + (package-lint--check-libraries-available-in-emacs deps) + (package-lint--check-macros-functions-available-in-emacs deps)) + (package-lint--check-for-literal-emacs-path) + (package-lint--check-commentary-existence) + (let ((definitions (package-lint--get-defs))) + (package-lint--check-autoloads-on-private-functions definitions) + (package-lint--check-defs-prefix definitions) + (package-lint--check-symbol-separators definitions))))) + (sort package-lint--errors + (lambda (a b) + (pcase-let ((`(,a-line ,a-column ,_ ,a-message) a) + (`(,b-line ,b-column ,_ ,b-message) b)) + (cond + ((/= a-line b-line) (< a-line b-line)) + ((/= a-column b-column) (< a-column b-column)) + (t + (string-lessp a-message b-message)))))))) + +(defun package-lint--error (line col type message) + "Construct a datum for error at LINE and COL with TYPE and MESSAGE." + (push (list line col type message) package-lint--errors)) + +(defun package-lint--error-at-point (type message) + "Construct a datum for error at the point with TYPE and MESSAGE." + (package-lint--error (line-number-at-pos) (current-column) type message)) + + +;;; Checks + +(defun package-lint--check-reserved-keybindings () + "Warn about reserved keybindings." + (let ((re (rx "(" (*? space) (or "kbd" "global-set-key" "local-set-key" "define-key") symbol-end))) + (goto-char (point-min)) + (while (re-search-forward re nil t) + (unless (nth 8 (save-match-data (syntax-ppss))) + ;; Read form and get key-sequence + (goto-char (match-beginning 0)) + (let ((seq (package-lint--extract-key-sequence + (read (current-buffer))))) + (when seq + (let ((message (package-lint--test-keyseq seq))) + (when message + (package-lint--error-at-point 'warning message))))))))) + +(defun package-lint--check-commentary-existence () + "Warn about nonexistent or empty commentary section." + (let ((start (lm-commentary-start))) + (if (null start) + (package-lint--error + 1 1 'error + "Package should have a ;;; Commentary section.") + ;; Skip over the section header. + (goto-char start) + (forward-line) + (when (package-lint--region-empty-p (point) (lm-commentary-end)) + (goto-char start) + (package-lint--error-at-point + 'error + "Package should have a non-empty ;;; Commentary section."))))) + +(defun package-lint--check-autoloads-on-private-functions (definitions) + "Verify that private functions DEFINITIONS don't have autoload cookies." + (pcase-dolist (`(,symbol . ,position) definitions) + (when (string-match-p (rx "--") symbol) + (goto-char position) + (forward-line -1) + (when (looking-at-p (rx ";;;###autoload")) + (package-lint--error-at-point + 'warning + "Private functions generally should not be autoloaded."))))) + +(defun package-lint--check-for-literal-emacs-path () + "Verify package does not refer to \"\.emacs\.d\" literally. +Instead it should use `user-emacs-directory' or `locate-user-emacs-file'." + (goto-char (point-min)) + ;; \b won't find a word boundary between a symbol and the "." in + ;; ".emacs.d". / is a valid symbol constituent in Emacs Lisp, so + ;; must be explicitly blacklisted. + (while (re-search-forward "\\(?:\\_<\\|/\\)\\.emacs\\.d\\b" nil t) + (unless (nth 4 (syntax-ppss)) + ;; Not in a comment + (package-lint--error-at-point + 'warning + "Use variable `user-emacs-directory' or function `locate-user-emacs-file' instead of a literal path to the Emacs user directory or files.")))) + +(defun package-lint--check-keywords-list () + "Verify that package keywords are listed in `finder-known-keywords'." + (when (package-lint--goto-header "Keywords") + (let ((line-no (line-number-at-pos)) + (keywords (lm-keywords-list))) + (unless (cl-some (lambda (keyword) (assoc (intern keyword) finder-known-keywords)) keywords) + (package-lint--error + line-no 1 'warning + (format "You should include standard keywords: see the variable `finder-known-keywords'.")))))) + +(defun package-lint--check-url-header () + "Verify that the package has an HTTPS or HTTP Homepage/URL header." + (if (package-lint--goto-header "\\(?:URL\\|Homepage\\)") + (let ((url (match-string 3)) + (url-start (match-beginning 3))) + (unless (and (equal (thing-at-point 'url) url) + (string-match-p "^https?://" url)) + (package-lint--error + (line-number-at-pos) + (1+ (- url-start (line-beginning-position))) + 'error + "Package URLs should be a single HTTPS or HTTP URL."))) + (package-lint--error + 1 1 'error + "Package should have a Homepage or URL header."))) + +(defun package-lint--check-dependency-list () + "Check the contents of the \"Package-Requires\" header. +Return a list of well-formed dependencies, same as +`package-lint--check-well-formed-dependencies'." + (when (package-lint--goto-header "Package-Requires") + (let ((position (match-beginning 3)) + (line-no (line-number-at-pos)) + (deps (match-string 3))) + (condition-case err + (pcase-let ((`(,parsed-deps . ,parse-end-pos) (read-from-string deps))) + (unless (= parse-end-pos (length deps)) + (package-lint--error + line-no 1 'error + "More than one expression provided.")) + (let ((deps (package-lint--check-well-formed-dependencies position line-no parsed-deps))) + (package-lint--check-packages-installable deps) + (package-lint--check-deps-use-non-snapshot-version deps) + (package-lint--check-deps-do-not-use-zero-versions deps) + (package-lint--check-do-not-depend-on-cl-lib-1.0 deps) + deps)) + (error + (package-lint--error + line-no 1 'error + (format "Couldn't parse \"Package-Requires\" header: %s" (error-message-string err))) + nil))))) + +(defun package-lint--check-well-formed-dependencies (position line-no parsed-deps) + "Check that dependencies listed at POSITION on LINE-NO are well-formed. +These PARSED-DEPS must have the format (name \"version\"). +Return a list of well-formed dependencies, where each element is of +the form (PACKAGE-NAME PACKAGE-VERSION LINE-NO LINE-BEGINNING-OFFSET)." + (let (valid-deps) + (dolist (entry parsed-deps) + (pcase entry + ((and `(,package-name ,package-version) + (guard (symbolp package-name)) + (guard (stringp package-version))) + ;; Find the column at which the dependency is declared so we can + ;; properly report the position of errors. + (let ((offset + (save-excursion + (goto-char position) + (let ((line-start (line-beginning-position)) + (pattern + (format "( *\\(%s\\)\\(?:)\\|[^[:alnum:]_\\-].*?)\\)" + (regexp-quote (symbol-name package-name))))) + (if (re-search-forward pattern (line-end-position) t) + (- (1+ (match-beginning 1)) line-start) + 1))))) + (if (ignore-errors (version-to-list package-version)) + (push (list package-name + (version-to-list package-version) + line-no + offset) + valid-deps) + (package-lint--error + line-no offset 'error + (format "%S is not a valid version string: see `version-to-list'." + package-version))))) + (_ + (package-lint--error + line-no 1 'error + (format "Expected (package-name \"version-num\"), but found %S." entry))))) + valid-deps)) + +(defun package-lint--check-package-installable (archive-entry package-version line-no offset) + "Check that ARCHIVE-ENTRY is installable from a configured package archive. + +Check that package described by ARCHIVE-ENTRY can be installed at +required version PACKAGE-VERSION. If not, raise an error for +LINE-NO at OFFSET." + (let* ((package-name (car archive-entry)) + (best-version (package-lint--highest-installable-version-of package-name))) + (when (version-list-< best-version package-version) + (package-lint--error + line-no offset 'warning + (format "Version dependency for %s appears too high: try %s" package-name + (package-version-join best-version)))))) + +(defun package-lint--check-packages-installable (valid-deps) + "Check that all VALID-DEPS are available for installation." + (pcase-dolist (`(,package-name ,package-version ,line-no ,offset) valid-deps) + (if (eq 'emacs package-name) + (unless (version-list-<= '(24) package-version) + (package-lint--error + line-no offset 'error + "You can only depend on Emacs version 24 or greater: package.el for Emacs 23 does not support the \"emacs\" pseudopackage.")) + ;; Not 'emacs + (let ((archive-entry (assq package-name package-archive-contents))) + (if archive-entry + (package-lint--check-package-installable archive-entry package-version line-no offset) + (package-lint--error + line-no offset 'error + (format "Package %S is not installable." package-name))))))) + +(defun package-lint--check-deps-use-non-snapshot-version (valid-deps) + "Warn about any VALID-DEPS on snapshot versions of packages." + (pcase-dolist (`(,package-name ,package-version ,line-no ,offset) valid-deps) + (unless (version-list-< package-version '(19001201 1)) + (package-lint--error + line-no offset 'warning + (format "Use a non-snapshot version number for dependency on \"%S\" if possible." + package-name))))) + +(defun package-lint--check-deps-do-not-use-zero-versions (valid-deps) + "Warn about VALID-DEPS on \"0\" versions of packages." + (pcase-dolist (`(,package-name ,package-version ,line-no ,offset) valid-deps) + (when (equal package-version '(0)) + (package-lint--error + line-no offset 'warning + (format "Use a properly versioned dependency on \"%S\" if possible." + package-name))))) + +(defun package-lint--check-lexical-binding-requires-emacs-24 (valid-deps) + "Warn about use of `lexical-binding' when Emacs 24 is not among VALID-DEPS." + (goto-char (point-min)) + (when (package-lint--lexical-binding-declared-in-header-line-p) + (let* ((lexbind-line (line-number-at-pos)) + (lexbind-col (1+ (- (match-beginning 1) (line-beginning-position))))) + (unless (assq 'emacs valid-deps) + (package-lint--error + lexbind-line lexbind-col 'warning + "You should depend on (emacs \"24\") if you need lexical-binding."))))) + +(defun package-lint--inside-comment-or-string-p () + "Return non-nil if point is inside a comment or string." + (let ((ppss (save-match-data (syntax-ppss)))) + (or (nth 3 ppss) (nth 4 ppss)))) + +(defun package-lint--seen-fboundp-check-for (sym) + "Return non-nil if a `fboundp' check for SYM is present before point." + (save-excursion + (save-match-data + (and (re-search-backward + (concat "(fboundp\\s-+'" (regexp-quote sym) "\\_>") (point-min) t) + (not (package-lint--inside-comment-or-string-p)))))) + +(defun package-lint--check-version-regexp-list (valid-deps list rx-start rx-end) + "Warn about any match of REGEXP when VERSION is not in VALID-DEPS. +LIST is an alist of (VERSION . REGEXP*). +REGEXP is (concat RX-START REGEXP* RX-END) for each REGEXP*." + (let ((emacs-version-dep (or (cadr (assq 'emacs valid-deps)) '(0)))) + (pcase-dolist (`(,added-in-version . ,regexp) list) + (when (version-list-< emacs-version-dep added-in-version) + (goto-char (point-min)) + (while (re-search-forward (concat rx-start regexp rx-end) nil t) + (unless (package-lint--inside-comment-or-string-p) + (let ((sym (match-string-no-properties 1))) + (unless (package-lint--seen-fboundp-check-for sym) + (save-excursion + (goto-char (match-beginning 1)) + (package-lint--error-at-point + 'error + (format "You should depend on (emacs \"%s\") if you need `%s'." + (mapconcat #'number-to-string added-in-version ".") + sym))))))))))) + +(defun package-lint--check-eval-after-load () + "Warn about use of `eval-after-load' and co." + (save-excursion + (save-match-data + (goto-char (point-min)) + (when (re-search-forward "(\\s-*?\\(\\(?:with-\\)?eval-after-load\\)\\_>" nil t) + (package-lint--error-at-point + 'warning + (format "`%s' is for use in configurations, and should rarely be used in packages." (match-string 1))))))) + +(defun package-lint--check-no-use-of-cl () + "Warn about use of deprecated `cl' library." + (save-excursion + (save-match-data + (goto-char (point-min)) + (when (re-search-forward "(\\s-*?require\\s-*?'cl\\_>" nil t) + (package-lint--error-at-point + 'warning + "Replace deprecated `cl' with `cl-lib'. The `cl-libify' package can help with this."))))) + +(defun package-lint--check-no-use-of-cl-lib-sublibraries () + "Warn about use of `cl-macs', `cl-seq' etc." + (save-excursion + (save-match-data + (goto-char (point-min)) + (when (re-search-forward "(\\s-*?require\\s-*?'cl-\\(?:macs\\|seq\\)\\_>" nil t) + (package-lint--error-at-point + 'warning + "This file is not in the `cl-lib' ELPA compatibility package: require `cl-lib' instead."))))) + +(defun package-lint--check-libraries-available-in-emacs (valid-deps) + "Warn about use of libraries that are not available in the Emacs version in VALID-DEPS." + (package-lint--check-version-regexp-list + valid-deps + package-lint--libraries-added-alist + "(\\s-*?require\\s-*?'\\(" + ;; Match the ending paren so we can be sure it's a single argument + ;; `require'. If there are additional arguments, we don't want to warn, + ;; because (require 'foo nil t) indicates an optional dependency and + ;; (require 'foo "filename") is very uncommon. + "\\)\\_>\\s-*?)")) + +(defun package-lint--check-macros-functions-available-in-emacs (valid-deps) + "Warn about use of functions/macros that are not available in the Emacs version in VALID-DEPS." + (package-lint--check-version-regexp-list + valid-deps + package-lint--functions-and-macros-added-alist + "(\\s-*?\\(" + "\\)\\_>")) + +(defun package-lint--check-lexical-binding-is-on-first-line () + "Check that any `lexical-binding' declaration is on the first line of the file." + (cl-block return + (let ((original-buffer (current-buffer))) + (with-temp-buffer + (let ((lexical-binding-found-at-end nil)) + (insert-buffer-substring-no-properties original-buffer) + (condition-case err + (cl-letf (((symbol-function #'hack-local-variables-apply) #'ignore) + ((symbol-function #'hack-local-variables-filter) + (lambda (variables _dir-name) + (setq file-local-variables-alist variables))) + ;; Silence any messages Emacs may want to share with the user. + ;; There's no user. + ((symbol-function #'display-warning) #'ignore) + ((symbol-function #'message) #'ignore)) + ;; HACK: this is an internal variable! + ;; Unfortunately, Emacsen that have this variable also have + ;; `hack-local-variables' that doesn't store `lexical-binding' + ;; in `file-local-variables-alist'. + (defvar enable-dir-local-variables) + (defvar hack-local-variables--warned-lexical) + (let ((hack-local-variables--warned-lexical nil) + (enable-dir-local-variables nil) + (enable-local-variables t) + (local-enable-local-variables t)) + (hack-local-variables) + (setq lexical-binding-found-at-end + hack-local-variables--warned-lexical))) + (error + (package-lint--error 1 1 'error (error-message-string err)) + (cl-return-from return nil))) + (when (or lexical-binding-found-at-end + ;; In case this is an Emacs from before `hack-local-variables' + ;; started to warn about `lexical-binding' on a line other + ;; than the first. + (and (cdr (assq 'lexical-binding file-local-variables-alist)) + (not (package-lint--lexical-binding-declared-in-header-line-p)))) + (package-lint--error + 1 1 'error + "`lexical-binding' must be set in the first line."))))))) + +(defun package-lint--check-do-not-depend-on-cl-lib-1.0 (valid-deps) + "Check that any dependency in VALID-DEPS on \"cl-lib\" is on a remotely-installable version." + (let ((cl-lib-dep (assq 'cl-lib valid-deps))) + (when cl-lib-dep + (let ((cl-lib-version (nth 1 cl-lib-dep))) + (when (version-list-<= '(1) cl-lib-version) + (package-lint--error + (nth 2 cl-lib-dep) (nth 3 cl-lib-dep) 'error + (format "Depend on the latest 0.x version of cl-lib rather than on version \"%S\". +Alternatively, depend on (emacs \"24.3\") or greater, in which cl-lib is bundled." + cl-lib-version))))))) + +(defun package-lint--check-package-version-present () + "Check that a valid \"Version\" header is present." + (let ((version (package-lint--goto-header (rx (? "Package-") "Version")))) + (if version + (unless (ignore-errors (version-to-list version)) + (package-lint--error + (line-number-at-pos) + (1+ (- (match-beginning 3) (line-beginning-position))) + 'warning + (format "\"%s\" is not a valid version. MELPA will handle this, but other archives will not." version))) + (package-lint--error + 1 1 'warning + "\"Version:\" or \"Package-Version:\" header is missing. MELPA will handle this, but other archives will not.")))) + +(defun package-lint--check-package-el-can-parse () + "Check that `package-buffer-info' can read metadata from this file. +If it can, return the read metadata." + (condition-case err + (let ((orig-buffer (current-buffer))) + ;; We've reported version header issues separately, so rule them out here + (with-temp-buffer + (insert-buffer-substring-no-properties orig-buffer) + (package-lint--update-or-insert-version "0") + (package-buffer-info))) + (error + (package-lint--error + 1 1 + 'error + (format "package.el cannot parse this buffer: %s" (error-message-string err))) + nil))) + +(defun package-lint--check-package-summary (desc) + "Check the summary for package with descriptor DESC. +DESC is a struct as returned by `package-buffer-info'." + (let ((summary (package-lint--package-desc-summary desc))) + (cond + ((string= summary "") + (package-lint--error + 1 1 + 'warning + "Package should have a non-empty summary.")) + (t + (unless (let ((case-fold-search nil)) + (string-match-p "^[A-Z0-9]" summary)) + (package-lint--error + 1 1 + 'warning + "The package summary should start with an uppercase letter or a digit.")) + (when (> (length summary) 60) + (package-lint--error + 1 1 + 'warning + "The package summary is too long. It should be at most 60 characters.")) + (when (save-match-data + (let ((case-fold-search t)) + (and (string-match "[^.]\\" summary) + (not (string-match-p "[[:space:]]+lisp" + summary (match-end 0)))))) + (package-lint--error + 1 1 + 'warning + "Including \"Emacs\" in the package summary is usually redundant.")))))) + +(defun package-lint--check-provide-form (desc) + "Check the provide form for package with descriptor DESC. +DESC is a struct as returned by `package-buffer-info'." + (let ((name (package-lint--package-desc-name desc)) + (feature (package-lint--provided-feature))) + (unless (string-equal (symbol-name name) feature) + (package-lint--error + 1 1 + 'error + (format "There is no (provide '%s) form." name))))) + +(defun package-lint--check-symbol-separators (definitions) + "Check that symbol DEFINITIONS don't contain non-standard separators." + (pcase-dolist (`(,name . ,position) definitions) + (when (and (string-match "[:/]" name) + (not (string-match-p package-lint--sane-prefixes name))) + (let ((match-pos (match-beginning 0))) + ;; As a special case, allow `/=' when at the end of a symbol. + (when (or (not (string-match (rx "/=" string-end) name)) + (/= match-pos (match-beginning 0))) + (goto-char position) + (package-lint--error + (line-number-at-pos) 1 'error + (format "`%s' contains a non-standard separator `%s', use hyphens instead (see Elisp Coding Conventions)." + name (substring-no-properties name match-pos (1+ match-pos))))))))) + +(defun package-lint--valid-definition-name-p (name prefix &optional position) + "Return non-nil if NAME denotes a valid definition name. + +Valid definition names are: + +- a NAME starting with PREFIX, a string representing the current + package prefix, + +- a NAME matching `package-lint--sane-prefixes', or + +- a NAME whose POSITION in the buffer denotes a global definition." + (or (string-prefix-p prefix name) + (string-match-p package-lint--sane-prefixes name) + (string-match-p (rx-to-string `(seq string-start (or "define" "defun" "defvar") "-" ,prefix)) name) + (string-match-p (rx-to-string `(seq string-start "global-" ,prefix (or "-mode" (seq "-" (* any) "-mode")) string-end)) name) + (when position + (goto-char position) + (looking-at-p (rx (*? space) "(" (*? space) + (or "defadvice" "cl-defmethod") + symbol-end))))) + +(defun package-lint--check-defs-prefix (definitions) + "Verify that symbol DEFINITIONS start with package prefix." + (let ((prefix (package-lint--get-package-prefix))) + (when prefix + (pcase-dolist (`(,name . ,position) definitions) + (unless (package-lint--valid-definition-name-p name prefix position) + (let ((line-no (line-number-at-pos position))) + (package-lint--error + line-no 1 'error + (format "\"%s\" doesn't start with package's prefix \"%s\"." + name prefix)))))))) + +(defun package-lint--check-minor-mode (def) + "Offer up concerns about the minor mode definition DEF." + (when (cl-search '(:global t) def) + (package-lint--check-globalized-minor-mode def))) + +(defun package-lint--check-globalized-minor-mode (def) + "Offer up concerns about the global minor mode definition DEF." + (let ((feature-name (package-lint--provided-feature))) + (when feature-name + (let ((feature (intern feature-name)) + (autoloaded (save-excursion + (forward-line -1) + (beginning-of-line) + (looking-at ";;;###autoload")))) + (unless (or autoloaded + (cl-search `(:require ',feature) def :test #'equal)) + (package-lint--error-at-point + 'error + (format + "Global minor modes should be autoloaded or, rarely, `:require' their defining file (i.e. \":require '%s\"), to support the customization variable of the same name." feature))))))) + +(defun package-lint--check-defgroup (def) + "Offer up concerns about the customization group definition DEF." + (when (symbolp (cadr def)) + (let ((group-name (symbol-name (cadr def)))) + (when (string-match "\\(.*\\)-mode$" group-name) + (let ((parent (intern (match-string 1 group-name)))) + (unless (cl-search `(:group ',parent) def :test #'equal) + (package-lint--error-at-point + 'error + "Customization groups should not end in \"-mode\" unless that name would conflict with their parent group.")))))) + + (unless (memq :group def) + (package-lint--error-at-point + 'error + "Customization groups should specify a parent via `:group'."))) + +(defun package-lint--check-defalias (def) + "Offer up concerns about the customization group definition DEF." + (let ((prefix (package-lint--get-package-prefix))) + (when prefix + (pcase (cadr def) + (`(quote ,alias) + (unless (package-lint--valid-definition-name-p (symbol-name alias) prefix) + (package-lint--error-at-point + 'error + (concat "Aliases should start with the package's prefix \"" prefix "\".")))))))) + + +;;; Helpers + +(defun package-lint--extract-key-sequence (form) + "Extract the key sequence from FORM." + (pcase form + (`(kbd ,seq) + (package-lint--extract-key-sequence seq)) + ((or `(global-set-key ,seq ,_) `(local-set-key ,seq ,_)) + (package-lint--extract-key-sequence seq)) + (`(define-key ,_ ,seq ,_) + (package-lint--extract-key-sequence seq)) + ((pred stringp) + (listify-key-sequence (read-kbd-macro form))) + ((pred vectorp) + (unless (listp (elt form 0)) + (listify-key-sequence form))))) + +(defun package-lint--test-keyseq (lks) + "Return a message if the listified key sequence LKS is invalid, otherwise nil." + (let* ((modifiers (event-modifiers lks)) + (basic-type (event-basic-type lks))) + (when (or (and (> (length lks) 1) (equal (car (last lks)) ?\C-g)) + (and (equal (car (last lks)) ?\e) + (not (equal (nthcdr (- (length lks) 2) lks) + '(?\e ?\e)))) + (equal (car (last lks)) ?\C-h) + (and (equal modifiers '(control)) + (equal ?c basic-type) + (cdr lks) + (let ((v (event-basic-type (cdr lks))) + (m (event-modifiers (cdr lks)))) + (and (numberp v) + (<= v ?z) + (>= v ?a) + (or (null m) (equal '(shift) m))))) + (member basic-type '(f5 f6 f7 f8 f9))) + "This key sequence is reserved (see Key Binding Conventions in the Emacs Lisp manual)"))) + +(defun package-lint--region-empty-p (start end) + "Return t iff the region between START and END has no non-empty lines. + +Lines consisting only of whitespace or empty comments are considered empty." + (save-excursion + (save-restriction + (let ((inhibit-changing-match-data t)) + (narrow-to-region start end) + (goto-char start) + (while (and (looking-at "^[[:space:]]*;*[[:space:]]*$") + (= 0 (forward-line)))) + (eobp))))) + +(defun package-lint--highest-installable-version-of (package) + "Return the highest version of PACKAGE available for installation." + (let ((descriptors (cdr (assq package package-archive-contents)))) + (if (fboundp 'package-desc-version) + (car (sort (mapcar 'package-desc-version descriptors) + (lambda (v1 v2) (not (version-list-< v1 v2))))) + (aref descriptors 0)))) + +(defun package-lint--goto-header (header-name) + "Move to the first occurrence of HEADER-NAME in the file. +If the return value is non-nil, then point will be at the end of +the file, and the second and third match groups will contain the name and +value of the header with any leading or trailing whitespace removed." + (let ((initial-point (point))) + (goto-char (point-min)) + (let ((case-fold-search t)) + (if (re-search-forward (concat (lm-get-header-re header-name) "\\(.*?\\) *$") nil t) + (match-string-no-properties 3) + (goto-char initial-point) + nil)))) + +(defun package-lint--update-or-insert-version (version) + "Ensure current buffer has a \"Version: VERSION\" header." + (if (package-lint--goto-header "Version") + (move-beginning-of-line nil) + (forward-line)) + (insert (format ";; Version: %s" version)) + (newline)) + +(defun package-lint--get-header-line-file-local-variables () + "Return local variables specified in the -*- line. +Returns an alist of elements (VAR . VAL), where VAR is a variable +and VAL is the specified value. + +For details, see `hack-local-variables-prop-line'." + (cl-letf (((symbol-function #'message) #'ignore)) + (hack-local-variables-prop-line))) + +(defun package-lint--lexical-binding-declared-in-header-line-p () + "Test if `lexical-binding' is declared in the -*- line." + ;; Test the `cdr' to see if it's actually true, because + ;; -*- lexical-binding: nil -*- + ;; is legal, if silly. + (cdr (assq 'lexical-binding (package-lint--get-header-line-file-local-variables)))) + +(defvar semantic-imenu-summary-function) + +(defun package-lint--get-defs () + "Return a list of all variables and functions defined in the current buffer. + +The returned list is of the form (SYMBOL-NAME . POSITION)." + ;; We probably could use Semantic instead, but it's a *global* minor mode and + ;; it tends to be quite heavy, so use Imenu instead; if the user has Semantic + ;; enabled, Imenu will use its index anyway. + (let ((result '()) + (index + (save-excursion + ;; Use the default imenu expression list so that we're not confused + ;; by user customizations. + (let ((imenu-generic-expression lisp-imenu-generic-expression) + ;; In case it's actually Semantic, tell it not to decorate + ;; symbol names. + (semantic-imenu-summary-function 'semantic-format-tag-name)) + (funcall imenu-create-index-function))))) + (dolist (entry index) + (pcase entry + ((and `(,submenu-name . ,submenu-elements) + (guard (consp submenu-elements))) + (when (member submenu-name '("Variables" "Defuns")) + (setq result (nconc (reverse submenu-elements) result)))) + (_ + (push entry result)))) + ;; If it's Semantic, then it returns overlays, not positions. Convert + ;; them. + (dolist (entry result) + (when (overlayp (cdr entry)) + (setcdr entry (overlay-start (cdr entry))))) + (nreverse result))) + +(defun package-lint--provided-feature () + "Return the first-provided feature name, as a string, or nil if none." + (save-excursion + (goto-char (point-max)) + (cond ((re-search-backward (rx "(provide '" (group (1+ (or (syntax word) (syntax symbol))))) nil t) + (match-string-no-properties 1)) + ((re-search-backward "(provide-me)" nil t) + (file-name-sans-extension (file-name-nondirectory buffer-file-name)))))) + +(defun package-lint--get-package-prefix () + "Return package prefix string (i.e. the symbol the package `provide's). +Prefix is returned without any `-mode' suffix." + (let ((feature (package-lint--provided-feature))) + (when feature + (replace-regexp-in-string "-mode\\'" "" feature)))) + +(defun package-lint--check-objects-by-regexp (regexp function) + "Check all objects with the literal printed form matching REGEXP. + +The objects are parsed with `read'. The FUNCTION is passed the +read object, with the point at the beginning of the match. + +S-expressions in comments or comments, partial s-expressions, or +otherwise invalid read forms are ignored." + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (save-excursion + (goto-char (match-beginning 0)) + (let ((obj (unless (package-lint--inside-comment-or-string-p) + (save-excursion + (ignore-errors (read (current-buffer))))))) + (when obj (funcall function obj)))))) + + +;;; Public interface + +;;;###autoload +(defun package-lint-buffer (&optional buffer) + "Get linter errors and warnings for BUFFER. + +Returns a list, each element of which is list of + + (LINE COL TYPE MESSAGE) + +where TYPE is either 'warning or 'error. + +Current buffer is used if none is specified." + (with-current-buffer (or buffer (current-buffer)) + (package-lint--check-all))) + +;;;###autoload +(defun package-lint-current-buffer () + "Display lint errors and warnings for the current buffer." + (interactive) + (let ((errs (package-lint-buffer)) + (buf "*Package-Lint*")) + (with-current-buffer (get-buffer-create buf) + (let ((buffer-read-only nil)) + (erase-buffer) + (cond + ((null errs) (insert "No issues found.")) + ((null (cdr errs)) (insert "1 issue found:\n\n")) + (t (insert (format "%d issues found:\n\n" (length errs))))) + (pcase-dolist (`(,line ,col ,type ,message) errs) + (insert (format "%d:%d: %s: %s\n" line col type message)))) + (special-mode) + (view-mode 1)) + (display-buffer buf))) + +(defun package-lint-batch-and-exit-1 (filenames) + "Internal helper function for `package-lint-batch-and-exit'. + +The main loop is this separate function so it's easier to test." + ;; Make sure package.el is initialized so we can query its database. + (package-initialize) + (let ((success t) (last-directory nil) (text-quoting-style 'grave)) + (dolist (file filenames success) + (let* ((file (expand-file-name file)) + (file-directory (file-name-directory file)) + (base (file-name-nondirectory file))) + (with-temp-buffer + (insert-file-contents file t) + (emacs-lisp-mode) + (let ((checking-result (package-lint-buffer))) + (when checking-result + (setq success nil) + (unless (equal last-directory file-directory) + (setq last-directory file-directory) + (message "Entering directory '%s'" file-directory)) + (pcase-dolist (`(,line ,col ,type ,message) checking-result) + (message "%s:%d:%d: %s: %s" + base line col type message))))))))) + +;;;###autoload +(defun package-lint-batch-and-exit () + "Run `package-lint-buffer' on the files remaining on the command line. +Use this only with -batch, it won't work interactively. + +When done, exit Emacs with status 0 if there were no errors nor warnings or 1 +otherwise." + (unless noninteractive + (error "`package-lint-batch-and-exit' is to be used only with -batch")) + (let ((success (package-lint-batch-and-exit-1 command-line-args-left))) + (kill-emacs (if success 0 1)))) + +;;;###autoload +(defun package-lint-looks-like-a-package-p () + "Return non-nil if the current buffer appears to be intended as a package." + (save-match-data + (save-excursion + (save-restriction + (widen) + (goto-char (point-min)) + (re-search-forward + (concat lm-header-prefix + (rx (or "Version" "Package-Version" "Package-Requires"))) + nil t))))) + +(provide 'package-lint) +;; Local Variables: +;; indent-tabs-mode: nil +;; End: +;;; package-lint.el ends here diff --git a/packages/pacmacs-20160131.832.tar b/packages/pacmacs-20160131.832.tar index 645ae70..caef571 100644 Binary files a/packages/pacmacs-20160131.832.tar and b/packages/pacmacs-20160131.832.tar differ diff --git a/packages/pact-mode-20180905.1647.el b/packages/pact-mode-20190710.1817.el similarity index 93% rename from packages/pact-mode-20180905.1647.el rename to packages/pact-mode-20190710.1817.el index db94394..f349cf5 100644 --- a/packages/pact-mode-20180905.1647.el +++ b/packages/pact-mode-20190710.1817.el @@ -1,12 +1,14 @@ ;;; pact-mode.el --- Mode for Pact, a LISPlike smart contract language. -*- lexical-binding: t; -*- -;; Copyright (c) 2016 Stuart Popejoy +;; Copyright (c) 2016 - 2019 Stuart Popejoy ;; Author: Stuart Popejoy ;; Maintainer: Stuart Popejoy +;; Maintainer: Emily Pillmore +;; Maintainer: Colin Woodbury ;; Keywords: pact, lisp, languages, blockchain, smartcontracts, tools, mode -;; Package-Version: 20180905.1647 -;; Version: 0.0.4-git +;; Package-Version: 20190710.1817 +;; Version: 0.0.5-git ;; URL: https://github.com/kadena-io/pact-mode ;; Package-Requires: ((emacs "24.3")) @@ -30,13 +32,15 @@ ;;; Change Log: +;; Version 0.0.5 +;; Enable syntax highlighting for new keywords. + ;;; Code: (require 'semantic) (require 'semantic/bovine/el) (require 'inf-lisp) - (defconst pact-symbols "%#+_&$@<>=^?*!|/-" "Regexp match for non-alphanumerics in pact symbols.") @@ -57,8 +61,9 @@ (,(concat "(" (regexp-opt - '("module" "list" "let" "let*" - "step" "use" "step-with-rollback") t) + '("module" "list" "let*" "let" + "step" "use" "step-with-rollback" + "interface" "implements" "if" "bless") t) "\\>") 1 font-lock-keyword-face) ;; Macros similar to let, when, and while diff --git a/packages/page-break-lines-20171210.831.el b/packages/page-break-lines-20190519.2238.el similarity index 91% rename from packages/page-break-lines-20171210.831.el rename to packages/page-break-lines-20190519.2238.el index b78d6f3..c096a7e 100644 --- a/packages/page-break-lines-20171210.831.el +++ b/packages/page-break-lines-20190519.2238.el @@ -4,7 +4,7 @@ ;; Author: Steve Purcell ;; URL: https://github.com/purcell/page-break-lines -;; Package-Version: 20171210.831 +;; Package-Version: 20190519.2238 ;; Package-X-Original-Version: 0 ;; Package-Requires: ((emacs "24.4")) ;; Keywords: convenience, faces @@ -76,6 +76,13 @@ :type '(choice (const :tag "No lighter" "") string) :group 'page-break-lines) +;;;###autoload +(defcustom page-break-lines-max-width nil + "If non-nil, maximum width (in characters) of page break indicator. +If nil, indicator will span the width of the frame." + :type '(choice integer (const :tag "Full width" nil)) + :group 'page-break-lines) + ;;;###autoload (defcustom page-break-lines-modes '(emacs-lisp-mode lisp-mode scheme-mode compilation-mode outline-mode help-mode) @@ -99,7 +106,7 @@ displayed as a junk character." "Toggle Page Break Lines mode. In Page Break mode, page breaks (^L characters) are displayed as a -horizontal line of `page-break-string-char' characters." +horizontal line of `page-break-lines-char' characters." :lighter page-break-lines-lighter :group 'page-break-lines (page-break-lines--update-display-tables)) @@ -134,11 +141,14 @@ its display table will be modified as necessary." 0))) (width (- (/ wwidth-pix (frame-char-width) cwidth) (if (display-graphic-p) 0 1))) + (width (if page-break-lines-max-width + (min width page-break-lines-max-width) + width)) (glyph (make-glyph-code page-break-lines-char 'page-break-lines)) (new-display-entry (vconcat (make-list width glyph)))) (unless (equal new-display-entry (elt buffer-display-table ?\^L)) (aset buffer-display-table ?\^L new-display-entry))))) - (when (and (member major-mode page-break-lines-modes) + (when (and (apply 'derived-mode-p page-break-lines-modes) buffer-display-table) (aset buffer-display-table ?\^L nil)))))) diff --git a/packages/pandoc-mode-20180917.721.tar b/packages/pandoc-mode-20190711.2122.tar similarity index 94% rename from packages/pandoc-mode-20180917.721.tar rename to packages/pandoc-mode-20190711.2122.tar index 878f5d8..c3f4a21 100644 Binary files a/packages/pandoc-mode-20180917.721.tar and b/packages/pandoc-mode-20190711.2122.tar differ diff --git a/packages/pangu-spacing-20170317.857.el b/packages/pangu-spacing-20190422.514.el similarity index 78% rename from packages/pangu-spacing-20170317.857.el rename to packages/pangu-spacing-20190422.514.el index 83a7f7a..dae5d09 100644 --- a/packages/pangu-spacing-20170317.857.el +++ b/packages/pangu-spacing-20190422.514.el @@ -5,7 +5,7 @@ ;; Author: coldnew ;; Kyewords: converience ;; Version: 0.4 -;; Package-Version: 20170317.857 +;; Package-Version: 20190422.514 ;; X-URL: http://github.com/coldnew/pangu-spacing ;; This file is free software: you can redistribute it and/or modify @@ -177,25 +177,26 @@ When you set t here, the space will be insert when you save file." ;; ;; Url: http://lists.gnu.org/archive/html/emacs-diffs/2014-01/msg00049.html -(defvar pangu-spacing-chinese-before-english-regexp - (rx (group-n 1 (category chinse-two-byte)) - (group-n 2 (in "a-zA-Z0-9"))) - "Regexp to find Chinese character before English character.") - -(defvar pangu-spacing-chinese-after-english-regexp - (rx (group-n 1 (in "a-zA-Z0-9")) - (group-n 2 (category chinse-two-byte))) - "Regexp to find Chinese character after English character.") - -(defvar pangu-spacing-chinese-before-english-regexp-exclude - (rx (group-n 1 (or (in "。,ï¼ï¼Ÿï¼›ï¼šã€Œã€ï¼ˆï¼‰ã€"))) - (group-n 2 (in "a-zA-Z0-9"))) - "Excluded regexp to find Chinese character before English character.") - -(defvar pangu-spacing-chinese-after-english-regexp-exclude - (rx (group-n 1 (in "a-zA-Z0-9")) - (group-n 2 (or (in "。,ï¼ï¼Ÿï¼›ï¼šã€Œã€ï¼ˆï¼‰ã€")))) - "Excluded regexp to find Chinese character after English character.") +(defvar pangu-spacing-include-regexp + (rx (or (and (or (group-n 3 (any "。,ï¼ï¼Ÿï¼›ï¼šã€Œã€ï¼ˆï¼‰ã€")) + (group-n 1 (category chinse-two-byte))) + (group-n 2 (in "a-zA-Z0-9"))) + (and (group-n 1 (in "a-zA-Z0-9")) + (or (group-n 3 (any "。,ï¼ï¼Ÿï¼›ï¼šã€Œã€ï¼ˆï¼‰ã€")) + (group-n 2 (category chinse-two-byte)))))) + "Regexp to find Chinese character before English character. + +Group 1 contains the character before the potential pangu +spacing, and group 2 the character after that. A space is needed +when both group 1 and group 2 are non-nil. Group 3 exists as a +workaround for excluded characters. Since rx does not support +matching text that satisfy two regexp at the same time (we want +to match all Chinese two byte characters, but not punctuations), +we first try to match excluded characters, then the characters +that need pangu-spacing. The excluded characters will be matched +to group 3, and shortcut the matching for Chinese characters. +Thus group 1 and group 2 will both be non nil when a pangu space +is needed.") ;;;; Functions @@ -205,54 +206,45 @@ pangu-spacing-mode." `(let ((start ,start) (end ,end)) (save-excursion (goto-char start) - (while (re-search-forward ,regexp end t) ,func)))) + (while (re-search-forward ,regexp end t) + (when (and (match-beginning 1) + (match-beginning 2)) + ,func))))) -(defmacro pangu-spacing-search-overlay (func regexp) +(defmacro pangu-spacing-search-overlay (beg end func regexp) "Helper macro to search and update overlay according func and regexp for pangu-sapce-mode." - `(pangu-spacing-search-buffer ,regexp (point-min) (point-max) - (,func (match-beginning 1) (match-end 1)))) + `(pangu-spacing-search-buffer ,regexp ,beg ,end + (,func (match-beginning 1) (match-end 1)))) (defun pangu-spacing-search-and-replace (match regexp) "Replace regexp with match in buffer." (pangu-spacing-search-buffer regexp (point-min) (point-max) - (replace-match match nil nil))) + (replace-match match nil nil))) (defun pangu-spacing-overlay-p (ov) "Determine whether overlay OV was created by space-between." (and (overlayp ov) (overlay-get ov 'pangu-spacing-overlay))) -(defun pangu-spacing-check-overlay () - "Insert a space between English words and Chinese charactors in overlay." - (pangu-spacing-delete-all-overlays) - (pangu-spacing-search-overlay pangu-spacing-make-overlay - pangu-spacing-chinese-before-english-regexp) - - (pangu-spacing-search-overlay pangu-spacing-make-overlay - pangu-spacing-chinese-after-english-regexp) - - (pangu-spacing-search-overlay pangu-spacing-delete-overlay - pangu-spacing-chinese-before-english-regexp-exclude) - (pangu-spacing-search-overlay pangu-spacing-delete-overlay - pangu-spacing-chinese-after-english-regexp-exclude)) +(defun pangu-spacing-check-overlay (beg end) + "Insert a space between English words and Chinese charactors in overlay." + (setq beg (if beg + (max (- beg 1) (point-min)) + (point-min)) + end (or end (point-max))) + (pangu-spacing-delete-overlay beg end) + (setq end (min (1+ end) (point-max))) + (pangu-spacing-search-overlay beg end + pangu-spacing-make-overlay + pangu-spacing-include-regexp) + ) (defun pangu-spacing-modify-buffer () "Real insert separator between English words and Chinese charactors in buffer." (when pangu-spacing-real-insert-separtor (pangu-spacing-search-and-replace "\\1 \\2" - pangu-spacing-chinese-before-english-regexp) - - (pangu-spacing-search-and-replace "\\1 \\2" - pangu-spacing-chinese-after-english-regexp) - - (pangu-spacing-search-and-replace "\\1\\2" - (replace-regexp-in-string "\\\\)\\\\(" "\\\\) \\\\(" - pangu-spacing-chinese-before-english-regexp-exclude)) - - (pangu-spacing-search-and-replace "\\1\\2" - (replace-regexp-in-string "\\\\)\\\\(" "\\\\) \\\\(" - pangu-spacing-chinese-after-english-regexp-exclude))) + pangu-spacing-include-regexp)) ;; nil must be returned to allow use in write file hooks nil) @@ -263,7 +255,9 @@ pangu-sapce-mode." (has-pangu-spacing-overlays nil)) (while (consp ov) (when (pangu-spacing-overlay-p (car ov)) - (setq has-pangu-spacing-overlays t)) + (setq has-pangu-spacing-overlays t + ;; break the while loop + ov nil)) (setq ov (cdr ov)) has-pangu-spacing-overlays))) @@ -282,12 +276,12 @@ pangu-sapce-mode." (when (pangu-spacing-overlay-p ov) (delete-overlay ov)))) -(defun pangu-spacing-delete-all-overlays () +(defun pangu-spacing-delete-all-overlays (&optional beg end) "Delete all pangu-spacing-overlays in BUFFER." (pangu-spacing-delete-overlay (point-min) (point-max))) (defun turn-on-pangu-spacing (beg end) - (pangu-spacing-check-overlay)) + (pangu-spacing-check-overlay beg end)) ;;;###autoload (defun pangu-spacing-space-current-buffer () diff --git a/packages/paradox-20181027.2234.tar b/packages/paradox-20190624.41.tar similarity index 94% rename from packages/paradox-20181027.2234.tar rename to packages/paradox-20190624.41.tar index 4eaae11..98749a3 100644 Binary files a/packages/paradox-20181027.2234.tar and b/packages/paradox-20190624.41.tar differ diff --git a/packages/parinfer-20180904.844.tar b/packages/parinfer-20180904.844.tar index 30fc52e..370ee6d 100644 Binary files a/packages/parinfer-20180904.844.tar and b/packages/parinfer-20180904.844.tar differ diff --git a/packages/parsebib-20181031.1021.el b/packages/parsebib-20181219.928.el similarity index 99% rename from packages/parsebib-20181031.1021.el rename to packages/parsebib-20181219.928.el index a995703..aff0dee 100644 --- a/packages/parsebib-20181031.1021.el +++ b/packages/parsebib-20181219.928.el @@ -7,7 +7,7 @@ ;; Maintainer: Joost Kremers ;; Created: 2014 ;; Version: 2.3 -;; Package-Version: 20181031.1021 +;; Package-Version: 20181219.928 ;; Keywords: text bibtex ;; Package-Requires: ((emacs "24.3")) @@ -606,8 +606,8 @@ file. Return nil if no dialect is found." (when (re-search-backward (concat parsebib--entry-start "comment") (- (point-max) 3000) t) (let ((comment (parsebib-read-comment))) (when (and comment - (string-match-p "\\`[ \n\t\r]*Local Variables:" comment) - (string-match-p "End:[ \n\t\r]*\\'" comment) + (string-match-p "\\`{[ \n\t\r]*Local Variables:" comment) + (string-match-p "End:[ \n\t\r]*}\\'" comment) (string-match (concat "bibtex-dialect: " (regexp-opt (mapcar #'symbol-name bibtex-dialect-list) t)) comment)) (intern (match-string 1 comment)))))))) diff --git a/packages/parseclj-20190531.711.tar b/packages/parseclj-20190531.711.tar new file mode 100644 index 0000000..866b9b0 Binary files /dev/null and b/packages/parseclj-20190531.711.tar differ diff --git a/packages/parseedn-20190331.1058.el b/packages/parseedn-20190331.1058.el new file mode 100644 index 0000000..45fd4f9 --- /dev/null +++ b/packages/parseedn-20190331.1058.el @@ -0,0 +1,202 @@ +;;; parseedn.el --- Clojure/EDN parser -*- lexical-binding: t; -*- + +;; Copyright (C) 2017-2018 Arne Brasseur + +;; Author: Arne Brasseur +;; Keywords: lisp clojure edn parser +;; Package-Version: 20190331.1058 +;; Package-Requires: ((emacs "25") (a "0.1.0alpha4") (parseclj "0.1.0")) +;; Version: 0.1.0 + +;; This file is not 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 file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; parseedn is an Emacs Lisp library for parsing EDN (Clojure) data. +;; It uses parseclj's shift-reduce parser internally. + +;; EDN and Emacs Lisp have some important differences that make +;; translation from one to the other not transparent (think +;; representing an EDN map into Elisp, or being able to differentiate +;; between false and nil in Elisp). Because of this, parseedn takes +;; certain decisions when parsing and transforming EDN data into Elisp +;; data types. For more information please refer to parseclj's design +;; documentation. + +;;; Code: + +;; The EDN spec is not clear about whether \u0123 and \o012 are supported in +;; strings. They are described as character literals, but not as string escape +;; codes. In practice all implementations support them (mostly with broken +;; surrogate pair support), so we do the same. Sorry, emoji ðŸ™. +;; +;; Note that this is kind of broken, we don't correctly detect if \u or \o forms +;; don't have the right forms. + +(require 'a) +(require 'cl-lib) +(require 'parseclj-parser) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Reader + +(defvar parseedn-default-tag-readers + (a-list 'inst (lambda (s) + (cl-list* 'edn-inst (date-to-time s))) + 'uuid (lambda (s) + (list 'edn-uuid s))) + "Default reader functions for handling tagged literals in EDN. +These are the ones defined in the EDN spec, #inst and #uuid. It +is not recommended you change this variable, as this globally +changes the behavior of the EDN reader. Instead pass your own +handlers as an optional argument to the reader functions.") + +(defun parseedn-reduce-leaf (stack token _options) + "Put in the STACK an elisp value representing TOKEN. + +OPTIONS is an association list. See `parseclj-parse' for more information +on available options." + (if (member (parseclj-lex-token-type token) (list :whitespace :comment)) + stack + (cons (parseclj-lex--leaf-token-value token) stack))) + +(defun parseedn-reduce-branch (stack opening-token children options) + "Reduce STACK with an sequence containing a collection of other elisp values. +Ignores discard tokens. + +OPENING-TOKEN is a lex token representing an opening paren, bracket or +brace. +CHILDREN is a collection elisp values to be reduced into an elisp +sequence. +OPTIONS is an association list. See `parseclj-parse' for more information +on available options." + (let ((tag-readers (a-merge parseedn-default-tag-readers (a-get options :tag-readers))) + (token-type (parseclj-lex-token-type opening-token))) + (if (eq token-type :discard) + stack + (cons + (cl-case token-type + (:root children) + (:lparen children) + (:lbracket (apply #'vector children)) + (:set (list 'edn-set children)) + (:lbrace (let* ((kvs (seq-partition children 2)) + (hash-map (make-hash-table :test 'equal :size (length kvs)))) + (seq-do (lambda (pair) + (puthash (car pair) (cadr pair) hash-map)) + kvs) + hash-map)) + (:tag (let* ((tag (intern (substring (a-get opening-token :form) 1))) + (reader (a-get tag-readers tag :missing))) + (when (eq :missing reader) + (user-error "No reader for tag #%S in %S" tag (a-keys tag-readers))) + (funcall reader (car children))))) + stack)))) + +(defun parseedn-read (&optional tag-readers) + "Read content from current buffer and parse it as EDN source. +Returns an Emacs Lisp value. + +TAG-READERS is an optional association list where keys are symbols +identifying *tags*, and values are tag handler functions that receive one +argument: *the tagged element*, and specify how to interpret it." + (parseclj-parser #'parseedn-reduce-leaf + #'parseedn-reduce-branch + (a-list :tag-readers tag-readers))) + +(defun parseedn-read-str (s &optional tag-readers) + "Parse string S as EDN. +Returns an Emacs Lisp value. + +TAG-READERS is an optional association list. For more information, see +`parseedn-read'." + (with-temp-buffer + (insert s) + (goto-char 1) + (car (parseedn-read tag-readers)))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Printer + +(defun parseedn-print-seq (coll) + "Insert sequence COLL as EDN into the current buffer." + (parseedn-print (elt coll 0)) + (let ((next (seq-drop coll 1))) + (when (not (seq-empty-p next)) + (insert " ") + (parseedn-print-seq next)))) + +(defun parseedn-print-kvs (map) + "Insert hash table MAP as an EDN map into the current buffer." + (let ((keys (a-keys map))) + (parseedn-print (car keys)) + (insert " ") + (parseedn-print (a-get map (car keys))) + (let ((next (cdr keys))) + (when (not (seq-empty-p next)) + (insert ", ") + (parseedn-print-kvs next))))) + +(defun parseedn-print (datum) + "Insert DATUM as EDN into the current buffer. +DATUM can be any Emacs Lisp value." + (cond + ((or (null datum) (numberp datum)) + (prin1 datum (current-buffer))) + + ((stringp datum) + (insert "\"") + (seq-doseq (char datum) + (insert (cl-case char + (?\t "\\t") + (?\f "\\f") + (?\" "\\\"") + (?\r "\\r") + (?\n"foo\t" "\\n") + (?\\ "\\\\") + (t (char-to-string char))))) + (insert "\"")) + + ((eq t datum) + (insert "true")) + + ((symbolp datum) + (insert (symbol-name datum))) + + ((vectorp datum) (insert "[") (parseedn-print-seq datum) (insert "]")) + + ((consp datum) + (cond + ((eq 'edn-set (car datum)) + (insert "#{") (parseedn-print-seq (cadr datum)) (insert "}")) + (t (insert "(") (parseedn-print-seq datum) (insert ")")))) + + ((hash-table-p datum) + (insert "{") (parseedn-print-kvs datum) (insert "}")))) + +(defun parseedn-print-str (datum) + "Return a string containing DATUM as EDN. +DATUM can be any Emacs Lisp value." + (with-temp-buffer + (parseedn-print datum) + (buffer-substring-no-properties (point-min) (point-max)))) + +(provide 'parseedn) + +;;; parseedn.el ends here diff --git a/packages/password-store-20181031.1440.el b/packages/password-store-20190804.2004.el similarity index 72% rename from packages/password-store-20181031.1440.el rename to packages/password-store-20190804.2004.el index 43ef26d..1b67fca 100644 --- a/packages/password-store-20181031.1440.el +++ b/packages/password-store-20190804.2004.el @@ -1,12 +1,12 @@ -;;; password-store.el --- Password store (pass) support +;;; password-store.el --- Password store (pass) support -*- lexical-binding: t; -*- -;; Copyright (C) 2014-2018 Svend Sorensen +;; Copyright (C) 2014-2019 Svend Sorensen ;; Author: Svend Sorensen -;; Version: 1.0.2 -;; Package-Version: 20181031.1440 +;; Version: 2.0.2 +;; Package-Version: 20190804.2004 ;; URL: https://www.passwordstore.org/ -;; Package-Requires: ((emacs "24") (f "0.11.0") (s "1.9.0") (with-editor "2.5.11")) +;; Package-Requires: ((emacs "25") (f "0.11.0") (s "1.9.0") (with-editor "2.5.11")) ;; Keywords: tools pass password password-store ;; This file is not part of GNU Emacs. @@ -60,30 +60,44 @@ (string-to-number (getenv "PASSWORD_STORE_CLIP_TIME")) 45)) +(defun password-store--run-1 (callback &rest args) + "Run pass with ARGS. + +Nil arguments are ignored. Calls CALLBACK with the output on success, +or outputs error message on failure." + (let ((output "")) + (make-process + :name "password-store-gpg" + :command (cons password-store-executable (delq nil args)) + :connection-type 'pipe + :noquery t + :filter (lambda (process text) + (setq output (concat output text))) + :sentinel (lambda (process state) + (cond + ((string= state "finished\n") + (funcall callback output)) + ((string= state "open\n") (accept-process-output process)) + (t (error (concat "password-store: " state)))))))) + (defun password-store--run (&rest args) "Run pass with ARGS. Nil arguments are ignored. Returns the output on success, or outputs error message on failure." - (with-temp-buffer - (let* ((tempfile (make-temp-file "")) - (exit-code - (apply 'call-process - (append - (list password-store-executable nil (list t tempfile) nil) - (delq nil args))))) - (unless (zerop exit-code) - (erase-buffer) - (insert-file-contents tempfile)) - (delete-file tempfile) - (if (zerop exit-code) - (s-chomp (buffer-string)) - (error (s-chomp (buffer-string))))))) + (let ((output nil) + (slept-for 0)) + (apply #'password-store--run-1 (lambda (password) + (setq output password)) + (delq nil args)) + (while (not output) + (sleep-for .1)) + output)) (defun password-store--run-async (&rest args) "Run pass asynchronously with ARGS. -Nil arguments are ignored." +Nil arguments are ignored. Output is discarded." (let ((args (mapcar #'shell-quote-argument args))) (with-editor-async-shell-command (mapconcat 'identity @@ -104,9 +118,10 @@ Nil arguments are ignored." (defun password-store--run-find (&optional string) (error "Not implemented")) -(defun password-store--run-show (entry) - (password-store--run "show" - entry)) +(defun password-store--run-show (entry &optional callback) + (if callback + (password-store--run-1 callback "show" entry) + (password-store--run "show" entry))) (defun password-store--run-insert (entry password &optional force) (error "Not implemented")) @@ -163,30 +178,39 @@ Nil arguments are ignored." "Return entry name corresponding to FILE." (f-no-ext (f-relative file (password-store-dir)))) -(defun password-store--completing-read () - "Read a password entry in the minibuffer, with completion." - (completing-read "Password entry: " (password-store-list))) +(defun password-store--completing-read (&optional require-match) + "Read a password entry in the minibuffer, with completion. + +Require a matching password if `REQUIRE-MATCH' is 't'." + (completing-read "Password entry: " (password-store-list) nil require-match)) (defun password-store-list (&optional subdir) "List password entries under SUBDIR." (unless subdir (setq subdir "")) (let ((dir (f-join (password-store-dir) subdir))) (if (f-directory? dir) - (mapcar 'password-store--file-to-entry - (f-files dir (lambda (file) (equal (f-ext file) "gpg")) t))))) + (delete-dups + (mapcar 'password-store--file-to-entry + (f-files dir (lambda (file) (equal (f-ext file) "gpg")) t)))))) ;;;###autoload (defun password-store-edit (entry) "Edit password for ENTRY." - (interactive (list (password-store--completing-read))) + (interactive (list (password-store--completing-read t))) (password-store--run-edit entry)) ;;;###autoload -(defun password-store-get (entry) +(defun password-store-get (entry &optional callback) "Return password for ENTRY. -Returns the first line of the password data." - (car (s-lines (password-store--run-show entry)))) +Returns the first line of the password data. +When CALLBACK is non-`NIL', call CALLBACK with the first line instead." + (if callback + (password-store--run-show + entry + (lambda (password) + (funcall callback (car (s-lines password))))) + (car (s-lines (password-store--run-show entry))))) ;;;###autoload (defun password-store-clear () @@ -207,14 +231,16 @@ Returns the first line of the password data." Clear previous password from kill ring. Pointer to kill ring is stored in `password-store-kill-ring-pointer'. Password is cleared after `password-store-timeout' seconds." - (interactive (list (password-store--completing-read))) - (let ((password (password-store-get entry))) - (password-store-clear) - (kill-new password) - (setq password-store-kill-ring-pointer kill-ring-yank-pointer) - (message "Copied %s to the kill ring. Will clear in %s seconds." entry (password-store-timeout)) - (setq password-store-timeout-timer - (run-at-time (password-store-timeout) nil 'password-store-clear)))) + (interactive (list (password-store--completing-read t))) + (password-store-get + entry + (lambda (password) + (password-store-clear) + (kill-new password) + (setq password-store-kill-ring-pointer kill-ring-yank-pointer) + (message "Copied %s to the kill ring. Will clear in %s seconds." entry (password-store-timeout)) + (setq password-store-timeout-timer + (run-at-time (password-store-timeout) nil 'password-store-clear))))) ;;;###autoload (defun password-store-init (gpg-id) @@ -252,13 +278,13 @@ Default PASSWORD-LENGTH is `password-store-password-length'." ;;;###autoload (defun password-store-remove (entry) "Remove existing password for ENTRY." - (interactive (list (password-store--completing-read))) + (interactive (list (password-store--completing-read t))) (message "%s" (password-store--run-remove entry t))) ;;;###autoload (defun password-store-rename (entry new-entry) "Rename ENTRY to NEW-ENTRY." - (interactive (list (password-store--completing-read) + (interactive (list (password-store--completing-read t) (read-string "Rename entry to: "))) (message "%s" (password-store--run-rename entry new-entry t))) @@ -274,7 +300,7 @@ Default PASSWORD-LENGTH is `password-store-password-length'." This will only browse URLs that start with http:// or https:// to avoid sending a password to the browser." - (interactive (list (password-store--completing-read))) + (interactive (list (password-store--completing-read t))) (let ((url (password-store-get entry))) (if (or (string-prefix-p "http://" url) (string-prefix-p "https://" url)) diff --git a/packages/pdf-tools-20181117.1939.tar b/packages/pdf-tools-20190701.202.tar similarity index 96% rename from packages/pdf-tools-20181117.1939.tar rename to packages/pdf-tools-20190701.202.tar index fd74151..18bffc4 100644 Binary files a/packages/pdf-tools-20181117.1939.tar and b/packages/pdf-tools-20190701.202.tar differ diff --git a/packages/perl6-mode-20180619.1159.tar b/packages/perl6-mode-20180619.1159.tar index 7d745c6..d03e69b 100644 Binary files a/packages/perl6-mode-20180619.1159.tar and b/packages/perl6-mode-20180619.1159.tar differ diff --git a/packages/persp-mode-20180930.1720.el b/packages/persp-mode-20190511.1402.el similarity index 98% rename from packages/persp-mode-20180930.1720.el rename to packages/persp-mode-20190511.1402.el index 14cfb38..5e60bfd 100644 --- a/packages/persp-mode-20180930.1720.el +++ b/packages/persp-mode-20190511.1402.el @@ -4,7 +4,7 @@ ;; Author: Constantin Kulikov (Bad_ptr) ;; Version: 2.9.7 -;; Package-Version: 20180930.1720 +;; Package-Version: 20190511.1402 ;; Package-Requires: () ;; Keywords: perspectives, session, workspace, persistence, windows, buffers, convenience ;; URL: https://github.com/Bad-ptr/persp-mode.el @@ -2351,16 +2351,15 @@ Return the created perspective." (setq switchorno (not switchorno))) (unless buffs-or-names (setq buffs-or-names - (if called-interactively-p - (let ((*persp-restrict-buffers-to* 1) - persp-restrict-buffers-to-if-foreign-buffer) - (persp-read-buffer (concat - "Add buffers to the perspective" - (and switchorno - " and switch to first added buffer") - ": ") - (current-buffer) t nil t)) - (current-buffer)))) + (when called-interactively-p + (let ((*persp-restrict-buffers-to* 1) + persp-restrict-buffers-to-if-foreign-buffer) + (persp-read-buffer (concat + "Add buffers to the perspective" + (and switchorno + " and switch to first added buffer") + ": ") + (current-buffer) t nil t))))) (unless (listp buffs-or-names) (setq buffs-or-names (list buffs-or-names))) (mapc #'(lambda (bon) @@ -2585,41 +2584,40 @@ cause it already contain all buffers."))) "[persp-mode] Error: There is already a perspective with that name %s" new-name) nil) - (let* ((current-persp (get-current-persp)) - (choosen-buffers t) - (new-buffers - (if (and current-persp - (not (and called-interactively-p current-prefix-arg))) - (copy-list (persp-buffers current-persp)) - (delete-if-not - (destructuring-bind (char &rest _) - (read-multiple-choice - "What buffers to copy? " - '((?a "all") - (?d "displayed") - (?f "free and displayed") - (?F "free") - (?c "choose") - (?n "none"))) - (case char - (?d #'(lambda (b) (get-buffer-window-list b 'no-minibuf))) - (?f #'(lambda (b) (or (persp-buffer-free-p b t) - (get-buffer-window-list b 'no-minibuf)))) - (?F #'(lambda (b) (persp-buffer-free-p b t))) - (?c #'(lambda (b) - (unless (listp choosen-buffers) - (setq choosen-buffers - (persp-read-buffer - "" (current-buffer) t nil t 'push))) - nil)) - (?n #'not) - (?a nil) - (t nil))) - (if current-persp - (copy-list (persp-buffers current-persp)) - (safe-persp-buffers current-persp))))) - (new-persp (persp-add-new new-name))) + (let* ((new-persp (persp-add-new new-name)) + (current-persp (get-current-persp)) + (new-buffers (when new-persp + (if current-persp + (copy-list (persp-buffers current-persp)) + (safe-persp-buffers current-persp))))) (when new-persp + (when (and called-interactively-p current-prefix-arg) + (setq new-buffers + (let (choosen-buffers) + (delete-if-not + (destructuring-bind (char &rest _) + (read-multiple-choice + "What buffers to copy? " + '((?a "all") + (?d "displayed") + (?f "free and displayed") + (?F "free") + (?c "choose") + (?n "none"))) + (case char + (?d #'(lambda (b) (get-buffer-window-list b 'no-minibuf))) + (?f #'(lambda (b) (or (persp-buffer-free-p b t) + (get-buffer-window-list b 'no-minibuf)))) + (?F #'(lambda (b) (persp-buffer-free-p b t))) + (?c (setq choosen-buffers + (mapcar #'get-buffer + (persp-read-buffer + "" (current-buffer) t nil t 'push))) + #'(lambda (b) (memq b choosen-buffers))) + (?n #'not) + (?a nil) + (t nil))) + new-buffers)))) (persp-save-state current-persp) (setf (persp-window-conf new-persp) (safe-persp-window-conf current-persp) @@ -2627,8 +2625,7 @@ cause it already contain all buffers."))) (copy-list (safe-persp-parameters current-persp)) (persp-weak new-persp) (if current-persp (persp-weak current-persp) nil)) - (when (listp choosen-buffers) - (persp-add-buffer choosen-buffers new-persp nil nil)) + (persp-add-buffer new-buffers new-persp nil nil) (case switch (window (persp-window-switch new-name)) (frame (persp-frame-switch new-name)) diff --git a/packages/pfuture-20180922.1315.el b/packages/pfuture-20190505.1006.el similarity index 56% rename from packages/pfuture-20180922.1315.el rename to packages/pfuture-20190505.1006.el index 32aea83..4aa8367 100644 --- a/packages/pfuture-20180922.1315.el +++ b/packages/pfuture-20190505.1006.el @@ -5,8 +5,8 @@ ;; Author: Alexander Miller ;; Homepage: https://github.com/Alexander-Miller/pfuture ;; Package-Requires: ((emacs "25.2")) -;; Package-Version: 20180922.1315 -;; Version: 1.2.2 +;; Package-Version: 20190505.1006 +;; Version: 1.6 ;; 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 @@ -26,22 +26,73 @@ ;;; Code: (require 'cl-lib) +(require 'inline) + +(defvar pfuture--dummy-buffer nil + "Dummy buffer for stderr pipes.") + +(define-inline pfuture--delete-process (process) + "Delete PROCESS with redisplay inhibited." + (inline-letevals (process) + (inline-quote + (let ((inhibit-redisplay t)) + (delete-process ,process))))) + +(defun pfuture--sentinel (process _) + "Delete the stderr pipe process of PROCESS." + (unless (process-live-p process) + (let* ((stderr-process (process-get process 'stderr-process))) + ;; Set stderr-process to nil so that await-to-finish does not delete + ;; the buffer again. + (process-put process 'stderr-process nil) + ;; delete-process may trigger other sentinels. If there are many pfutures, + ;; this will overflow the stack. + (run-with-idle-timer 0 nil #'pfuture--delete-process stderr-process)))) ;;;###autoload -(defun pfuture-new (cmd &rest cmd-args) - "Create a new future process for command CMD and arguments CMD-ARGS. -This will return a process object with one additional 'result property which -can be read via \(process-get process 'result\) or alternatively with -\(pfuture-result process\). - -Note that CMD-ARGS must be a *sequence* of strings, meaning +(defun pfuture-new (&rest cmd) + "Create a new future process for command CMD. +Any arguments after the command are interpreted as arguments to the command. +This will return a process object with additional 'stderr and 'stdout +properties, which can be read via \(process-get process 'stdout\) and +\(process-get process 'stderr\) or alternatively with +\(pfuture-result process\) or \(pfuture-stderr process\). + +Note that CMD must be a *sequence* of strings, meaning this is wrong: (pfuture-new \"git status\") this is right: (pfuture-new \"git\" \"status\")" - (let* ((process-connection-type nil) - (process (apply #'start-process "Process Future" nil cmd cmd-args))) - (process-put process 'result "") - (set-process-filter process #'pfuture--append-output) - process)) + (let ((stderr (make-pipe-process + :name "Process Future stderr" + :coding 'no-conversion + ;; Use a dummy buffer for the stderr process. make-pipe-process creates a + ;; buffer unless one is specified, even when :filter is specified and the + ;; buffer is not used at all. + :buffer (or pfuture--dummy-buffer + (setq pfuture--dummy-buffer (get-buffer-create " *pfuture stderr dummy*"))) + :noquery t + :filter #'pfuture--append-stderr))) + ;; Make sure that the same buffer is not shared between processes. + ;; This is not a race condition, since the pipe is not yet connected and + ;; cannot receive input. + (set-process-buffer stderr nil) + (condition-case err + (let ((process + (make-process + :name "Process Future" + :stderr stderr + :coding 'no-conversion + :sentinel #'pfuture--sentinel + :filter #'pfuture--append-stdout + :command cmd + :noquery t)) + ;; Make the processes share their plist so that 'stderr is easily accessible. + (plist (list 'stdout "" 'stderr "" 'stderr-process stderr))) + (set-process-plist process plist) + (set-process-plist stderr plist) + process) + (error + (pfuture--delete-process stderr) + (signal (car err) (cdr err)))))) (defmacro pfuture--decompose-fn-form (fn &rest args) "Expands into the correct call form for FN and ARGS. @@ -74,7 +125,8 @@ Internally based on `make-process'. Requires lexical scope. The first - and only required - argument is COMMAND. It is an (unquoted) list of the command and the arguments for the process that should be started. A vector -is likewise acceptable - the difference is purely cosmetic. +is likewise acceptable - the difference is purely cosmetic (this does not apply +when command is passed as a variable, in this case it must be a list). The rest of the argument list is made up of the following keyword arguments: @@ -83,7 +135,7 @@ code of 0. In its context, these variables are bound: `process': The process object, as passed to the sentinel callback function. `status': The string exit status, as passed to the sentinel callback function. `pfuture-buffer': The buffer where the output of the process is collected, - including both stdin and stdout. You can use `pfuture-output-from-buffer' to + including both stdin and stdout. You can use `pfuture-callback-output' to quickly grab the buffer's content. ON-SUCCESS may take one of 3 forms: an unquoted sexp, a quoted function or an @@ -108,7 +160,8 @@ fall back to \"Pfuture Callback [$COMMAND]\". CONNECTION-TYPE will be passed to the :connection-process property of `make-process'. If not given it will fall back to 'pipe. -BUFFER is the buffer that will be used by the process to collect its output. +BUFFER is the buffer that will be used by the process to collect its output, +quickly collectible with `pfuture-output-from-buffer'. Providing a buffer outside of specific use-cases is not necessary, as by default pfuture will assign every launched command its own unique buffer and kill it after ON-SUCCESS or ON-ERROR have finished running. However, no such cleanup @@ -122,22 +175,23 @@ buffer is stored in its `buffer' property and is therefore accessible via \(process-get process 'buffer\)." (declare (indent 1)) (let* ((command (if (vectorp command) - (cl-map 'list #'identity command) + `(quote ,(cl-map 'list #'identity command)) command)) - (name (or name (concat "Pfuture Callback: [" (mapconcat #'identity command " ") "]"))) (connection-type (or connection-type (quote 'pipe))) (directory (or directory default-directory))) (unless (or on-success on-error) (setq on-success '(function ignore))) `(let* ((default-directory ,directory) - (pfuture-buffer (or ,buffer (generate-new-buffer ,name))) + (name (or ,name (format "Pfuture-Callback %s" ,command))) + (pfuture-buffer (or ,buffer (generate-new-buffer name))) (process (make-process - :name ,name - :command ',command + :name name + :command ,command :connection-type ,connection-type :filter ,(or filter '(function pfuture--append-output-to-buffer)) :sentinel (lambda (process status) + (ignore status) ,@(when on-status-change `((pfuture--decompose-fn-form ,on-status-change process status pfuture-buffer))) @@ -152,6 +206,11 @@ buffer is stored in its `buffer' property and is therefore accessible via (process-put process 'buffer pfuture-buffer) process))) +(defmacro pfuture-callback-output () + "Retrieve the output from the pfuture-buffer variable in the current scope. +Meant to be used with `pfuture-callback'." + `(pfuture-output-from-buffer pfuture-buffer)) + (cl-defun pfuture-await (process &key (timeout 1) (just-this-one t)) "Block until PROCESS has produced output and return it. @@ -167,26 +226,33 @@ details see documentation of `accept-process-output'." process timeout nil just-this-one)) (process-get process 'result)) +(cl-macrolet + ((define-getter (name doc variable ) + `(define-inline ,name (process) + ,doc + (declare (side-effect-free t)) + (inline-letevals (process) + (inline-quote + (process-get ,',process ',variable)))))) + (define-getter pfuture-result "Return the output of a pfuture PROCESS." stdout) + (define-getter pfuture-stderr "Return the error output of a pfuture PROCESS." stderr)) + (defun pfuture-await-to-finish (process) "Keep reading the output of PROCESS until it is done. Same as `pfuture-await', but will keep reading (and blocking) so long as the process is *alive*. If the process never quits this method will block forever. Use with caution!" + ;; If the sentinel hasn't run, disable it. We are going to delete + ;; the stderr process here. + (set-process-sentinel process nil) (let (inhibit-quit) - (accept-process-output process nil nil t) - (while (process-live-p process) - (accept-process-output process nil nil t))) - (process-get process 'result)) - -(defsubst pfuture-result (process) - "Return the output of a pfuture PROCESS." - (declare (side-effect-free t)) - (process-get process 'result)) - -(defun pfuture--append-output (process msg) - "Append PROCESS' MSG to the already saved output." - (process-put process 'result (concat (process-get process 'result) msg))) + (while (accept-process-output process))) + (let* ((plist (process-plist process)) + (stderr-process (plist-get plist 'stderr-process))) + (when stderr-process + (pfuture--delete-process stderr-process)) + (plist-get plist 'stdout))) (defun pfuture--append-output-to-buffer (process msg) "Append PROCESS' MSG to its output buffer." @@ -194,11 +260,31 @@ If the process never quits this method will block forever. Use with caution!" (goto-char (point-max)) (insert msg))) -(defsubst pfuture-output-from-buffer (buffer) +(defun pfuture--append-stdout (process msg) + "Append PROCESS' MSG to the already saved stdout output." + (let* ((process-plist (process-plist process)) + (previous-output (plist-get process-plist 'stdout))) + (plist-put process-plist 'stdout + (if (zerop (string-bytes previous-output)) + msg + (concat previous-output msg))))) + +(defun pfuture--append-stderr (process msg) + "Append PROCESS' MSG to the already saved stderr output." + (let* ((process-plist (process-plist process)) + (previous-output (plist-get process-plist 'stderr))) + (plist-put process-plist 'stderr + (if (zerop (string-bytes previous-output)) + msg + (concat previous-output msg))))) + +(define-inline pfuture-output-from-buffer (buffer) "Return the process output collected in BUFFER." (declare (side-effect-free t)) - (with-current-buffer buffer - (buffer-string))) + (inline-letevals (buffer) + (inline-quote + (with-current-buffer ,buffer + (buffer-string))))) (provide 'pfuture) diff --git a/packages/phoenix-dark-pink-theme-20170729.1403.el b/packages/phoenix-dark-pink-theme-20190821.48.el similarity index 96% rename from packages/phoenix-dark-pink-theme-20170729.1403.el rename to packages/phoenix-dark-pink-theme-20190821.48.el index 9205102..689bcef 100644 --- a/packages/phoenix-dark-pink-theme-20170729.1403.el +++ b/packages/phoenix-dark-pink-theme-20190821.48.el @@ -1,11 +1,11 @@ ;;; phoenix-dark-pink-theme.el --- Originally a port of the Sublime Text 2 theme -;; Copyright 2013-2017 J Irving +;; Copyright 2013-2019 J Irving ;; Author: J Irving ;; URL: http://github.com/j0ni/phoenix-dark-pink -;; Package-Version: 20170729.1403 -;; Version: 2 +;; Package-Version: 20190821.48 +;; Version: 3 ;; 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 @@ -43,16 +43,18 @@ (p12 "#815f8d") (p13 "#755273") - (fg "#cccccc") + (fg "#e0e0e0") (bg "#101010") (plegit "pink") (damned "red") - (alarmed "#f582a3") - (warned "#87003f") - (weirdyellow "#c0af7f") + (alarmed "#ff79c6") + (warned "#e64747") + (weirdyellow "#ffb86c") + (yaygreen "#50fa7b") + (dp0 "#201010") (dp1 "#31182d") (dp2 "#412b3f") (dp3 "#714161") @@ -66,7 +68,8 @@ (offwhite3 "#dddddd") (offwhite4 "#b3b3b3") - (silverfox "#787878") + (brightfox "#939393") + (silverfox "#7a7a7a") (sadsilverfox "#585858") (b1 "#202020") @@ -143,33 +146,36 @@ `(font-lock-comment-face ((t (:weight normal :underline nil :foreground ,silverfox + :background ,b1 :slant italic)))) `(font-lock-comment-delimiter-face ((t (:weight normal :underline nil - :foreground ,sadsilverfox - :inherit font-lock-comment-face)))) + :foreground ,silverfox + :inherit (font-lock-comment-face))))) `(font-lock-doc-face ((t (:weight normal :underline nil - :foreground ,damned + :foreground ,plegit + :background ,b1 :inherit (font-lock-string-face))))) `(font-lock-string-face ((t (:weight normal :underline nil + :background ,dp0 :foreground ,offpink3)))) `(font-lock-constant-face ((t (:weight normal :underline nil - :foreground ,p8)))) + :foreground ,p1)))) - `(font-lock-function-name-face ((t (:weight normal + `(font-lock-function-name-face ((t (:weight bold :underline nil :foreground ,offpink1)))) - `(font-lock-keyword-face ((t (:weight normal + `(font-lock-keyword-face ((t (:weight bold :underline nil - :foreground ,p3)))) + :foreground ,p1)))) `(font-lock-negation-char-face ((t (:weight normal :underline nil @@ -180,21 +186,19 @@ :foreground ,p3 :inherit (font-lock-builtin-face))))) - `(font-lock-regexp-grouping-backslash ((t (:weight normal - :underline nil - :inherit (bold))))) + `(font-lock-regexp-grouping-backslash ((t (:weight bold + :underline nil)))) - `(font-lock-regexp-grouping-construct ((t (:weight normal - :underline nil - :inherit (bold))))) + `(font-lock-regexp-grouping-construct ((t (:weight bold + :underline nil)))) `(font-lock-type-face ((t (:weight normal :underline nil - :foreground ,offwhite2)))) + :foreground ,p1)))) `(font-lock-variable-name-face ((t (:weight normal :underline nil - :foreground ,offwhite1)))) + :foreground ,fg)))) `(font-lock-warning-face ((t (:weight normal :underline nil @@ -214,7 +218,7 @@ :foreground ,silverfox)))) `(warning ((t (:weight normal - :foreground ,offpink1)))) + :foreground ,warned)))) `(link ((t (:weight normal :underline nil @@ -248,7 +252,7 @@ `(mode-line ((t (:weight normal :underline nil - :box (:style released-button :color ,dp3 :line-width 2) + :box (:style released-button :color ,dp2 :line-width 2) :foreground ,p3 :background ,b2)))) @@ -263,7 +267,7 @@ :underline nil :foreground ,offpink1)))) - `(mode-line-emphasis ((t (:weight normal + `(mode-line-emphasis ((t (:weight bold :underline nil)))) `(mode-line-highlight ((t (:weight normal @@ -520,14 +524,14 @@ ;; Rainbow delimiters `(rainbow-delimiters-depth-9-face ((t (:foreground ,p1)))) - `(rainbow-delimiters-depth-8-face ((t (:foreground ,p2)))) - `(rainbow-delimiters-depth-7-face ((t (:foreground ,p3)))) - `(rainbow-delimiters-depth-6-face ((t (:foreground ,p4)))) - `(rainbow-delimiters-depth-5-face ((t (:foreground ,p5)))) - `(rainbow-delimiters-depth-4-face ((t (:foreground ,p6)))) - `(rainbow-delimiters-depth-3-face ((t (:foreground ,p7)))) - `(rainbow-delimiters-depth-2-face ((t (:foreground ,p8)))) - `(rainbow-delimiters-depth-1-face ((t (:foreground ,p9)))) + `(rainbow-delimiters-depth-8-face ((t (:foreground ,p3)))) + `(rainbow-delimiters-depth-7-face ((t (:foreground ,p5)))) + `(rainbow-delimiters-depth-6-face ((t (:foreground ,p7)))) + `(rainbow-delimiters-depth-5-face ((t (:foreground ,p9)))) + `(rainbow-delimiters-depth-4-face ((t (:foreground ,p11)))) + `(rainbow-delimiters-depth-3-face ((t (:foreground ,p2)))) + `(rainbow-delimiters-depth-2-face ((t (:foreground ,p4)))) + `(rainbow-delimiters-depth-1-face ((t (:foreground ,p6)))) ;; Javascript @@ -741,7 +745,12 @@ `(message-mml ((t (:foreground ,p0)))) - `(indent-guide-face ((t (:foreground ,dp3))))) + ;; Clojure mode + `(clojure-keyword-face ((t (:foreground ,p9)))) + ;; `(clojure-keyword-face ((t (:foreground ,brightfox)))) + `(clojure-character-face ((t (:foreground ,p1)))) + + `(indent-guide-face ((t (:foreground ,p13))))) ;;;###autoload (when load-file-name @@ -749,6 +758,7 @@ (file-name-as-directory (file-name-directory load-file-name)))) (provide-theme 'phoenix-dark-pink) +(provide 'phoenix-dark-pink-theme) ;; Local Variables: ;; no-byte-compile: t diff --git a/packages/php-auto-yasnippets-20170331.114.tar b/packages/php-auto-yasnippets-20170331.114.tar index b4b5ff4..129d380 100644 Binary files a/packages/php-auto-yasnippets-20170331.114.tar and b/packages/php-auto-yasnippets-20170331.114.tar differ diff --git a/packages/php-mode-20180829.520.tar b/packages/php-mode-20180829.520.tar deleted file mode 100644 index a30315e..0000000 Binary files a/packages/php-mode-20180829.520.tar and /dev/null differ diff --git a/packages/php-mode-20190818.932.tar b/packages/php-mode-20190818.932.tar new file mode 100644 index 0000000..9f40c1e Binary files /dev/null and b/packages/php-mode-20190818.932.tar differ diff --git a/packages/phpcbf-20180519.838.el b/packages/phpcbf-20181228.423.el similarity index 93% rename from packages/phpcbf-20180519.838.el rename to packages/phpcbf-20181228.423.el index ccf4bbd..21f5429 100644 --- a/packages/phpcbf-20180519.838.el +++ b/packages/phpcbf-20181228.423.el @@ -4,7 +4,7 @@ ;; Author: nishimaki10 ;; URL: https://github.com/nishimaki10/emacs-phpcbf -;; Package-Version: 20180519.838 +;; Package-Version: 20181228.423 ;; Version: 0.9.2 ;; Package-Requires: ((s "1.9.0")) ;; Keywords: tools, php @@ -55,6 +55,11 @@ falling back to PEAR if none is found." :group 'phpcbf :type '(choice string (const nil))) +(defcustom phpcbf-exclude nil + "Exclude rule(s). Comma separate if multiple." + :group 'phpcbf + :type '(choice string (const nil))) + (defun phpcbf-executable () "Find the “phpcbf†executable or signal an error." (or (executable-find phpcbf-executable) @@ -64,6 +69,8 @@ falling back to PEAR if none is found." "Generate the options list for running “phpcbfâ€." (append (when phpcbf-standard (list (format "--standard=%s" phpcbf-standard))) + (if phpcbf-exclude + (list (format "--exclude=%s" phpcbf-exclude))) (list (s-chop-suffixes '("-unix" "-dos" "-mac") (format "--encoding=%s" buffer-file-coding-system)) diff --git a/packages/phpunit-20180829.1438.tar b/packages/phpunit-20180829.1438.tar index d8b5b9f..43783d1 100644 Binary files a/packages/phpunit-20180829.1438.tar and b/packages/phpunit-20180829.1438.tar differ diff --git a/packages/pipenv-20180719.547.el b/packages/pipenv-20190522.803.el similarity index 89% rename from packages/pipenv-20180719.547.el rename to packages/pipenv-20190522.803.el index 91ec101..45cfe5d 100644 --- a/packages/pipenv-20180719.547.el +++ b/packages/pipenv-20190522.803.el @@ -4,9 +4,9 @@ ;; Author: Paul Walsh ;; URL: https://github.com/pwalsh/pipenv.el -;; Package-Version: 20180719.547 +;; Package-Version: 20190522.803 ;; Version: 0.0.1-beta -;; Package-Requires: ((emacs "25.1")(f "0.19.0")(s "1.12.0")) +;; Package-Requires: ((emacs "25.1")(f "0.19.0")(s "1.12.0")(pyvenv "1.20")) ;; 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 @@ -31,6 +31,7 @@ (require 'python) (require 's) (require 'subr-x) +(require 'pyvenv) (defgroup pipenv nil "A Pipenv porcelain." @@ -134,10 +135,6 @@ ;; Interpret ANSI escape sequences from Pipenv (ansi-color-apply-on-region (point-min) (point-max))))) -(defun pipenv--process-filter-message-insert (process response) - "Filter for PROCESS, generate a message from RESPONSE." - (message (concat "Finished " (s-join " " (process-command process))))) - (defun pipenv--process-filter-variable-insert(process response) "Filter for PROCESS, which sets several global variables based on RESPONSE." (when (and @@ -150,7 +147,6 @@ "Pipenv default filter stack PROCESS and RESPONSE handling." (let ((clean-response (pipenv--clean-response response))) (pipenv--process-filter-variable-insert process clean-response) - (pipenv--process-filter-message-insert process clean-response) (pipenv--process-filter-buffer-insert process clean-response))) (defun pipenv--get-executables-dir () @@ -161,16 +157,6 @@ (file-name-as-directory python-shell-virtualenv-root) (if (eq system-type 'windows-nt) "Scripts" "bin")))) -(defun pipenv--push-venv-executables-to-exec-path () - "Push the directory of executables in an active virtual environment to PATH." - (when-let ((venv-executables (pipenv--get-executables-dir))) - (push venv-executables exec-path))) - -(defun pipenv--pull-venv-executables-from-exec-path () - "Pull the directory of executables in an active virtual environment from PATH." - (when-let ((venv-executables (pipenv--get-executables-dir))) - (setq exec-path (delete venv-executables exec-path)))) - (defun pipenv--make-pipenv-process (command &optional filter sentinel) "Make a Pipenv process from COMMAND; optional custom FILTER or SENTINEL." (make-process @@ -179,13 +165,16 @@ :command command :coding 'utf-8-unix :filter filter - :sentinel sentinel)) + :sentinel sentinel + :connection-type 'pipe + )) (defun pipenv--command (args) "Call Pipenv with ARGS and the default filter stack." (let ((command (cons pipenv-executable args)) - (filter 'pipenv--process-filter)) - (pipenv--make-pipenv-process command filter))) + (filter 'pipenv--process-filter) + (sentinel 'pipenv--messaging-sentinel)) + (pipenv--make-pipenv-process command filter sentinel))) ;; ;; Interactive commands that implement the Pipenv interface in Emacs. @@ -296,8 +285,12 @@ or (if none is given), installs all packages." (find-file ideal-path))) (defun pipenv--messaging-sentinel (process event) - "Send EVENT notifications for PROCESS to *Messages* buffer." - (message "Process %s: event %S" process (s-chomp event))) + "Send EVENT notifications for PROCESS to *Messages* buffer and to process buffer." + (let ((msg (format "%s %s" (s-join " " (process-command process)) (s-chomp event)))) + (message msg) + (with-current-buffer (process-buffer process) + (insert "\n") + (insert msg)))) (defun pipenv--check-output (&rest command) "Run COMMAND and return its standard output. @@ -346,7 +339,7 @@ to latest compatible versions." (interactive) (when (pipenv-project?) (pipenv--force-wait (pipenv-venv)) - (pipenv--push-venv-executables-to-exec-path) + (pyvenv-activate (directory-file-name python-shell-virtualenv-root)) (when (and (featurep 'flycheck) pipenv-with-flycheck) (pipenv-activate-flycheck)) t)) @@ -354,7 +347,7 @@ to latest compatible versions." (defun pipenv-deactivate () "Deactivate the Python version from Pipenv; back to defaults." (interactive) - (pipenv--pull-venv-executables-from-exec-path) + (pyvenv-deactivate) (setq python-shell-virtualenv-root nil) (when (and (featurep 'flycheck) pipenv-with-flycheck) (pipenv-deactivate-flycheck)) @@ -379,19 +372,33 @@ to latest compatible versions." (defun pipenv-executable-find (executable) "Find EXECUTABLE in the executable path of an activate virtual environment." (when (bound-and-true-p python-shell-virtualenv-root) - (locate-file executable (python-shell-calculate-exec-path)))) + (let ((exec-path (python-shell-calculate-exec-path))) + (executable-find executable)))) ;; ;; Integration with 3rd party packages. ;; +(defun pipenv--verify-python-checkers () + "Manually verify checkers for python-mode" + (setq checkers (flycheck-defined-checkers 'modes)) + (while checkers + (setq checker (car checkers)) + (when (memq 'python-mode (flycheck-checker-get checker 'modes)) + (setq flycheck-disabled-checkers (remq checker flycheck-disabled-checkers)) + (setq flycheck-enabled-checkers (remq checker flycheck-enabled-checkers)) + (flycheck-may-use-checker checker)) + (setq checkers (cdr checkers)))) + (defun pipenv-activate-flycheck () "Activate integration of Pipenv with Flycheck." - (setq flycheck-executable-find #'pipenv-executable-find)) + (setq flycheck-executable-find #'pipenv-executable-find) + (pipenv--verify-python-checkers)) (defun pipenv-deactivate-flycheck () "Deactivate integration of Pipenv with Flycheck." - (setq flycheck-executable-find #'executable-find)) + (setq flycheck-executable-find #'flycheck-default-executable-find) + (pipenv--verify-python-checkers)) (defun pipenv-activate-projectile () "Activate integration of Pipenv with Projectile." diff --git a/packages/pippel-20180710.856.tar b/packages/pippel-20180710.856.tar index 70a9de9..0fcdb05 100644 Binary files a/packages/pippel-20180710.856.tar and b/packages/pippel-20180710.856.tar differ diff --git a/packages/pkgbuild-mode-20181116.1331.el b/packages/pkgbuild-mode-20181216.1331.el similarity index 99% rename from packages/pkgbuild-mode-20181116.1331.el rename to packages/pkgbuild-mode-20181216.1331.el index 8adb77e..4b625c3 100644 --- a/packages/pkgbuild-mode-20181116.1331.el +++ b/packages/pkgbuild-mode-20181216.1331.el @@ -5,7 +5,7 @@ ;; Author: Juergen Hoetzel ;; Maintainer: Juergen Hoetzel ;; URL: https://github.com/juergenhoetzel/pkgbuild-mode -;; Package-Version: 20181116.1331 +;; Package-Version: 20181216.1331 ;; Package-Requires: ((emacs "25.1")) ;; Version: 1.0-snapshot ;; Keywords: languages @@ -549,6 +549,7 @@ with no args, if that value is non-nil." (easy-menu-define pkgbuild-call-menu pkgbuild-mode-map "Post menu for `pkgbuild-mode'." pkgbuild-mode-menu) (set (make-local-variable 'sh-basic-offset) 2) ;This is what judd uses + (set (make-local-variable 'compile-command) pkgbuild-makepkg-command) (sh-set-shell "/bin/bash") (easy-menu-add pkgbuild-mode-menu) ;; This does not work because makepkg req. saved file diff --git a/packages/plantuml-mode-20180816.1012.el b/packages/plantuml-mode-20180816.1012.el deleted file mode 100644 index e7c5b36..0000000 --- a/packages/plantuml-mode-20180816.1012.el +++ /dev/null @@ -1,477 +0,0 @@ -;;; plantuml-mode.el --- Major mode for PlantUML -*- lexical-binding: t; -*- - -;; Filename: plantuml-mode.el -;; Description: Major mode for PlantUML diagrams sources -;; Compatibility: Tested with Emacs 25 through 27 (current master) -;; Author: Zhang Weize (zwz) -;; Maintainer: Carlo Sciolla (skuro) -;; Keywords: uml plantuml ascii -;; Package-Version: 20180816.1012 -;; Version: 1.2.7 -;; Package-Requires: ((emacs "25.0")) - -;; 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 file 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 . - -;;; Commentary: -;; -;; A major mode for plantuml, see: http://plantuml.sourceforge.net/ -;; Plantuml is an open-source tool in java that allows to quickly write : -;; - sequence diagram, -;; - use case diagram, -;; - class diagram, -;; - activity diagram, -;; - component diagram, -;; - state diagram -;; - object diagram - -;;; Change log: -;; -;; version 1.2.7, 2018-08-15 Added support for indentation; Fixed the comiling error when installing with melpa -;; version 1.2.6, 2018-07-17 Introduced custom variable `plantuml-jar-args' to control which arguments are passed to PlantUML jar. Fix the warning of failing to specify types of 'defcustom' variables -;; version 1.2.5, 2017-08-19 #53 Fixed installation warnings -;; version 1.2.4, 2017-08-18 #60 Licensed with GPLv3+ to be compatible with Emacs -;; version 1.2.3, 2016-12-25 #50 unicode support in generated output -;; version 1.2.2, 2016-11-11 Fixed java commands handling under windows; support spaces in `plantuml-jar-path' -;; version 1.2.1, 2016-11-11 Support for paths like `~/.plantuml/plantuml.jar' for `plantuml-jar-path' (the tilde was previously unsupported) -;; version 1.2.0, 2016-11-09 Added `plantuml-preview-current-buffer', courtesy of @7mamu4 -;; version 1.1.1, 2016-11-08 Fix process handling with Windows native emacs; better file extention match for autoloading the mode -;; version 1.1.0, 2016-10-18 Make PlantUML run headless by default; introduced custom variable `plantuml-java-args' to control which arguments are passed to Plantuml. -;; version 1.0.1, 2016-10-17 Bugfix release: proper auto-mode-alist regex; init delayed at mode load; avoid calling hooks twice. -;; version 1.0.0, 2016-10-16 Moved the mode to plantuml-mode, superseding zwz/plantuml-mode and skuro/puml-mode. Added preview for the currently selected region. -;; version 0.6.7, 2016-10-11 [from puml-mode] Added deprecation warning in favor of plantuml-mode -;; version 0.6.6, 2016-07-19 [from puml-mode] Added autoload, minor bug fixes -;; version 0.6.5, 2016-03-24 [from puml-mode] Added UTF8 support and open in new window / frame shortcuts -;; version 0.6.4, 2015-12-12 [from puml-mode] Added support for comments (single and multiline) -- thanks to https://github.com/nivekuil -;; version 0.6.3, 2015-11-07 [from puml-mode] Added per-buffer configurability of output type (thanks to https://github.com/davazp) -;; version 0.6.2, 2015-11-07 [from puml-mode] Added debugging capabilities to improve issue analysis -;; version 0.6.1, 2015-09-26 [from puml-mode] Bugfix: use eq to compare symbols instead of cl-equalp -;; version 0.6, 2015-09-26 [from puml-mode] Fixed PNG preview -;; version 0.5, 2015-09-21 [from puml-mode] Added preview capabilities -;; version 0.4, 2015-06-14 [from puml-mode] Use a puml- prefix to distinguish from the other plantuml-mode -;; version 0.3, 2015-06-13 [from puml-mode] Compatibility with Emacs 24.x -;; version 0.2, 2010-09-20 [from puml-mode] Initialize the keywords from the -language output of plantuml.jar instead of the hard-coded way. -;; version 0.1, 2010-08-25 [from puml-mode] First version - -;;; Code: -(require 'thingatpt) - -(defgroup plantuml-mode nil - "Major mode for editing plantuml file." - :group 'languages) - -(defcustom plantuml-jar-path - (expand-file-name "~/plantuml.jar") - "The location of the PlantUML executable JAR." - :type 'string - :group 'plantuml) - -(defvar plantuml-mode-hook nil "Standard hook for plantuml-mode.") - -(defconst plantuml-mode-version "1.2.7" "The plantuml-mode version string.") - -(defvar plantuml-mode-debug-enabled nil) - -(defvar plantuml-font-lock-keywords nil) - -(defvar plantuml-mode-map - (let ((keymap (make-sparse-keymap))) - (define-key keymap (kbd "C-c C-c") 'plantuml-preview) - keymap) - "Keymap for plantuml-mode.") - -(defcustom plantuml-java-command "java" - "The java command used to execute PlantUML." - :type 'string - :group 'plantuml) - -(eval-and-compile - (defcustom plantuml-java-args (list "-Djava.awt.headless=true" "-jar") - "The parameters passed to `plantuml-java-command' when executing PlantUML." - :type '(repeat string) - :group 'plantuml)) - - -(eval-and-compile - (defcustom plantuml-jar-args (list "-charset" "UTF-8" ) - "The parameters passed to `plantuml.jar', when executing PlantUML." - :type '(repeat string) - :group 'plantuml)) - -(defcustom plantuml-suppress-deprecation-warning t - "To silence the deprecation warning when `puml-mode' is found upon loading." - :type 'boolean - :group 'plantuml) - -(defun plantuml-render-command (&rest arguments) - "Create a command line to execute PlantUML with arguments (as ARGUMENTS)." - (let* ((cmd-list (append plantuml-java-args (list (expand-file-name plantuml-jar-path)) plantuml-jar-args arguments)) - (cmd (mapconcat 'identity cmd-list "|"))) - (plantuml-debug (format "Command is [%s]" cmd)) - cmd-list)) - -;;; syntax table -(defvar plantuml-mode-syntax-table - (let ((synTable (make-syntax-table))) - (modify-syntax-entry ?\/ ". 14c" synTable) - (modify-syntax-entry ?' "< 23" synTable) - (modify-syntax-entry ?\n ">" synTable) - (modify-syntax-entry ?\r ">" synTable) - (modify-syntax-entry ?! "w" synTable) - (modify-syntax-entry ?@ "w" synTable) - (modify-syntax-entry ?# "'" synTable) - synTable) - "Syntax table for `plantuml-mode'.") - -(defvar plantuml-types nil) -(defvar plantuml-keywords nil) -(defvar plantuml-preprocessors nil) -(defvar plantuml-builtins nil) - -;; keyword completion -(defvar plantuml-kwdList nil "The plantuml keywords.") - -(defun plantuml-enable-debug () - "Enables debug messages into the *PLANTUML Messages* buffer." - (interactive) - (setq plantuml-mode-debug-enabled t)) - -(defun plantuml-disable-debug () - "Stops any debug messages to be added into the *PLANTUML Messages* buffer." - (interactive) - (setq plantuml-mode-debug-enabled nil)) - -(defun plantuml-debug (msg) - "Writes msg (as MSG) into the *PLANTUML Messages* buffer without annoying the user." - (if plantuml-mode-debug-enabled - (let* ((log-buffer-name "*PLANTUML Messages*") - (log-buffer (get-buffer-create log-buffer-name))) - (save-excursion - (with-current-buffer log-buffer - (goto-char (point-max)) - (insert msg) - (insert "\n")))))) - -(defun plantuml-init () - "Initialize the keywords or builtins from the cmdline language output." - (unless (or (eq system-type 'cygwin) (file-exists-p plantuml-jar-path)) - (error "Could not find plantuml.jar at %s" plantuml-jar-path)) - (with-temp-buffer - (let ((cmd-args (append (list plantuml-java-command nil t nil) - (plantuml-render-command "-language")))) - (apply 'call-process cmd-args) - (goto-char (point-min))) - (let ((found (search-forward ";" nil t)) - (word "") - (count 0) - (pos 0)) - (while found - (forward-char) - (setq word (current-word)) - (if (string= word "EOF") (setq found nil) - ;; else - (forward-line) - (setq count (string-to-number (current-word))) - (beginning-of-line 2) - (setq pos (point)) - (forward-line count) - (cond ((string= word "type") - (setq plantuml-types - (split-string - (buffer-substring-no-properties pos (point))))) - ((string= word "keyword") - (setq plantuml-keywords - (split-string - (buffer-substring-no-properties pos (point))))) - ((string= word "preprocessor") - (setq plantuml-preprocessors - (split-string - (buffer-substring-no-properties pos (point))))) - (t (setq plantuml-builtins - (append - plantuml-builtins - (split-string - (buffer-substring-no-properties pos (point))))))) - (setq found (search-forward ";" nil nil))))))) - -(defconst plantuml-preview-buffer "*PLANTUML Preview*") - -(defvar plantuml-output-type - (if (not (display-images-p)) - "utxt" - (cond ((image-type-available-p 'svg) "svg") - ((image-type-available-p 'png) "png") - (t "utxt"))) - "Specify the desired output type to use for generated diagrams.") - -(defun plantuml-read-output-type () - "Read from the minibuffer a output type." - (let* ((completion-ignore-case t) - (available-types - (append - (and (image-type-available-p 'svg) '("svg")) - (and (image-type-available-p 'png) '("png")) - '("utxt")))) - (completing-read (format "Output type [%s]: " plantuml-output-type) - available-types - nil - t - nil - nil - plantuml-output-type))) - -(defun plantuml-set-output-type (type) - "Set the desired output type (as TYPE) for the current buffer. -If the -major mode of the current buffer mode is not plantuml-mode, set the -default output type for new buffers." - (interactive (list (plantuml-read-output-type))) - (setq plantuml-output-type type)) - -(defun plantuml-is-image-output-p () - "Return true if the diagram output format is an image, false if it's text based." - (not (equal "utxt" plantuml-output-type))) - -(defun plantuml-output-type-opt () - "Create the flag to pass to PlantUML to produce the selected output format." - (concat "-t" plantuml-output-type)) - -(defmacro plantuml-start-process (buf) - "Run PlantUML as an Emacs process and puts the output into the given buffer (as BUF)." - `(start-process "PLANTUML" ,buf - plantuml-java-command - ,@plantuml-java-args - (expand-file-name plantuml-jar-path) - (plantuml-output-type-opt) - ,@plantuml-jar-args - "-p")) - -(defun plantuml-preview-string (prefix string) - "Preview diagram from PlantUML sources (as STRING), using prefix (as PREFIX) -to choose where to display it: -- 4 (when prefixing the command with C-u) -> new window -- 16 (when prefixing the command with C-u C-u) -> new frame. -- else -> new buffer" - (let ((b (get-buffer plantuml-preview-buffer))) - (when b - (kill-buffer b))) - - (let* ((imagep (and (display-images-p) - (plantuml-is-image-output-p))) - (process-connection-type nil) - (buf (get-buffer-create plantuml-preview-buffer)) - (coding-system-for-read (and imagep 'binary)) - (coding-system-for-write (and imagep 'binary))) - - (let ((ps (plantuml-start-process buf))) - (process-send-string ps string) - (process-send-eof ps) - (set-process-sentinel ps - (lambda (_ps event) - (unless (equal event "finished\n") - (error "PLANTUML Preview failed: %s" event)) - (cond - ((= prefix 16) - (switch-to-buffer-other-frame plantuml-preview-buffer)) - ((= prefix 4) - (switch-to-buffer-other-window plantuml-preview-buffer)) - (t (switch-to-buffer plantuml-preview-buffer))) - (when imagep - (image-mode) - (set-buffer-multibyte t))))))) - -(defun plantuml-preview-buffer (prefix) - "Preview diagram from the PlantUML sources in the current buffer. -Uses prefix (as PREFIX) to choose where to display it: -- 4 (when prefixing the command with C-u) -> new window -- 16 (when prefixing the command with C-u C-u) -> new frame. -- else -> new buffer" - (interactive "p") - (plantuml-preview-string prefix (buffer-string))) - -(defun plantuml-preview-region (prefix begin end) - "Preview diagram from the PlantUML sources in from BEGIN to END. -Uses the current region when called interactively. -Uses prefix (as PREFIX) to choose where to display it: -- 4 (when prefixing the command with C-u) -> new window -- 16 (when prefixing the command with C-u C-u) -> new frame. -- else -> new buffer" - (interactive "p\nr") - (plantuml-preview-string prefix (concat "@startuml\n" - (buffer-substring-no-properties - begin end) - "\n@enduml"))) - -(defun plantuml-preview-current-block (prefix) - "Preview diagram from the PlantUML sources from the previous @startuml to the next @enduml. -Uses prefix (as PREFIX) to choose where to display it: -- 4 (when prefixing the command with C-u) -> new window -- 16 (when prefixing the command with C-u C-u) -> new frame. -- else -> new buffer" - (interactive "p") - (save-restriction - (narrow-to-region - (search-backward "@startuml") (search-forward "@enduml")) - (plantuml-preview-buffer prefix))) - -(defun plantuml-preview (prefix) - "Preview diagram from the PlantUML sources. -Uses the current region if one is active, or the entire buffer otherwise. -Uses prefix (as PREFIX) to choose where to display it: -- 4 (when prefixing the command with C-u) -> new window -- 16 (when prefixing the command with C-u C-u) -> new frame. -- else -> new buffer" - (interactive "p") - (if mark-active - (plantuml-preview-region prefix (region-beginning) (region-end)) - (plantuml-preview-buffer prefix))) - -(defun plantuml-init-once () - "Ensure initialization only happens once." - (unless plantuml-kwdList - (plantuml-init) - (defvar plantuml-types-regexp (concat "^\\s *\\(" (regexp-opt plantuml-types 'words) "\\|\\<\\(note\\s +over\\|note\\s +\\(left\\|right\\|bottom\\|top\\)\\s +\\(of\\)?\\)\\>\\|\\<\\(\\(left\\|center\\|right\\)\\s +\\(header\\|footer\\)\\)\\>\\)")) - (defvar plantuml-keywords-regexp (concat "^\\s *" (regexp-opt plantuml-keywords 'words) "\\|\\(<\\|<|\\|\\*\\|o\\)\\(\\.+\\|-+\\)\\|\\(\\.+\\|-+\\)\\(>\\||>\\|\\*\\|o\\)\\|\\.\\{2,\\}\\|-\\{2,\\}")) - (defvar plantuml-builtins-regexp (regexp-opt plantuml-builtins 'words)) - (defvar plantuml-preprocessors-regexp (concat "^\\s *" (regexp-opt plantuml-preprocessors 'words))) - (defvar plantuml-indent-regexp-start "^[ \t]*\\(\\(?:.*\\)?\s*\\(?:[<>.*a-z-|]+\\)?\s*\\(?:\\[[a-zA-Z]+\\]\\)?\s+if\\|alt\\|else\\|note\s+over\\|note\sas\s.*\\|note\s+\\(\\(?:\\(?:buttom\\|left\\|right\\|top\\)\\)\\)\\(?:\s+of\\)?\\|\\(?:class\\|enum\\|package\\)\s+.*{\\)") - (defvar plantuml-indent-regexp-end "^[ \t]*\\(endif\\|else\\|end\\|end\s+note\\|.*}\\)") - - (setq plantuml-font-lock-keywords - `( - (,plantuml-types-regexp . font-lock-type-face) - (,plantuml-keywords-regexp . font-lock-keyword-face) - (,plantuml-builtins-regexp . font-lock-builtin-face) - (,plantuml-preprocessors-regexp . font-lock-preprocessor-face) - ;; note: order matters - )) - - (setq plantuml-kwdList (make-hash-table :test 'equal)) - (mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-types) - (mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-keywords) - (mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-builtins) - (mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-preprocessors) - (put 'plantuml-kwdList 'risky-local-variable t) - - ;; clear memory - (setq plantuml-types nil) - (setq plantuml-keywords nil) - (setq plantuml-builtins nil) - (setq plantuml-preprocessors nil) - (setq plantuml-types-regexp nil) - (setq plantuml-keywords-regexp nil) - (setq plantuml-builtins-regexp nil) - (setq plantuml-preprocessors-regexp nil))) - -(defun plantuml-complete-symbol () - "Perform keyword completion on word before cursor." - (interactive) - (let ((posEnd (point)) - (meat (thing-at-point 'symbol)) - maxMatchResult) - - (when (not meat) (setq meat "")) - - (setq maxMatchResult (try-completion meat plantuml-kwdList)) - (cond ((eq maxMatchResult t)) - ((null maxMatchResult) - (message "Can't find completion for \"%s\"" meat) - (ding)) - ((not (string= meat maxMatchResult)) - (delete-region (- posEnd (length meat)) posEnd) - (insert maxMatchResult)) - (t (message "Making completion list...") - (with-output-to-temp-buffer "*Completions*" - (display-completion-list - (all-completions meat plantuml-kwdList))) - (message "Making completion list...%s" "done"))))) - - -;; indentation - - -(defun plantuml-current-block-depth () - "Trace the current block indentation level by recursively looking back line by line." - ;; forward declare the lazy initialized constants - (defvar plantuml-indent-regexp-start) - (defvar plantuml-indent-regexp-end) - (save-excursion - (let ((relative-depth 0) - (bob-visited? nil)) - (beginning-of-line) - (forward-line -1) - (while (and (>= relative-depth 0) - (not bob-visited?)) - (if (bobp) - (setq bob-visited? t)) - (if (looking-at plantuml-indent-regexp-end) - (setq relative-depth (1- relative-depth))) - (if (looking-at plantuml-indent-regexp-start) - (setq relative-depth (1+ relative-depth))) - (forward-line -1)) - - (if (<= relative-depth 0) - 0 - relative-depth)))) - -(defun plantuml-indent-line () - "Indent the current line to its desired indentation level." - (interactive) - ;; forward declare the lazy initialized constants - (defvar plantuml-indent-regexp-start) - (defvar plantuml-indent-regexp-end) - (let ((original-indentation (current-indentation))) - (save-excursion - (beginning-of-line) - (if (bobp) - (indent-line-to 0) - (let ((depth (plantuml-current-block-depth))) - (when (looking-at plantuml-indent-regexp-end) - (setq depth (max (1- depth) 0))) - (indent-line-to (* tab-width depth))))) - (forward-char (- (current-indentation) - original-indentation)))) - - -;;;###autoload -(add-to-list 'auto-mode-alist '("\\.\\(plantuml\\|pum\\|plu\\)\\'" . plantuml-mode)) - -;;;###autoload -(define-derived-mode plantuml-mode prog-mode "plantuml" - "Major mode for plantuml. - -Shortcuts Command Name -\\[plantuml-complete-symbol] `plantuml-complete-symbol'" - (plantuml-init-once) - (make-local-variable 'plantuml-output-type) - (set (make-local-variable 'comment-start-skip) "\\('+\\|/'+\\)\\s *") - (set (make-local-variable 'comment-start) "/'") - (set (make-local-variable 'comment-end) "'/") - (set (make-local-variable 'comment-multi-line) t) - (set (make-local-variable 'comment-style) 'extra-line) - (set (make-local-variable 'indent-line-function) 'plantuml-indent-line) - (setq font-lock-defaults '((plantuml-font-lock-keywords) nil t))) - -(defun plantuml-deprecation-warning () - "Warns the user about the deprecation of the `puml-mode' project." - (if (and plantuml-suppress-deprecation-warning - (featurep 'puml-mode)) - (display-warning :warning - "`puml-mode' is now deprecated and no longer updated, but it's still present in your system.\ -You should move your configuration to use `plantuml-mode'. See https://github.com/sytac/plantuml-mode. \ -See more at https://github.com/skuro/puml-mode/issues/26"))) - -(add-hook 'plantuml-mode-hook 'plantuml-deprecation-warning) - -(provide 'plantuml-mode) -;;; plantuml-mode.el ends here diff --git a/packages/plantuml-mode-20190821.1234.el b/packages/plantuml-mode-20190821.1234.el new file mode 100644 index 0000000..4b62250 --- /dev/null +++ b/packages/plantuml-mode-20190821.1234.el @@ -0,0 +1,681 @@ +;;; plantuml-mode.el --- Major mode for PlantUML -*- lexical-binding: t; -*- + +;; Filename: plantuml-mode.el +;; Description: Major mode for PlantUML diagrams sources +;; Compatibility: Tested with Emacs 25 through 27 (current master) +;; Author: Zhang Weize (zwz) +;; Maintainer: Carlo Sciolla (skuro) +;; Keywords: uml plantuml ascii +;; Version: 1.2.9 +;; Package-Version: 20190821.1234 +;; Package-X-Original-Version: 1.2.9 +;; Package-Requires: ((dash "2.0.0") (emacs "25.0")) + +;; 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 file 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 . + +;;; Commentary: +;; +;; A major mode for plantuml, see: http://plantuml.sourceforge.net/ +;; Plantuml is an open-source tool in java that allows to quickly write : +;; - sequence diagram, +;; - use case diagram, +;; - class diagram, +;; - activity diagram, +;; - component diagram, +;; - state diagram +;; - object diagram + +;;; Change log: +;; +;; version 1.3.1, 2019-08-02 Fixed interactive behavior of `plantuml-set-exec-mode' +;; version 1.3.0, 2019-05-31 Added experimental support for multiple rendering modes and, specifically, preview using a PlantUML server +;; version 1.2.11, 2019-04-09 Added `plantuml-download-jar' +;; version 1.2.10, 2019-04-03 Avoid messing with window layouts and buffers -- courtesy of https://github.com/wailo +;; version 1.2.9, Revamped indentation support, now working with a greater number of keywords +;; version 1.2.8, 2019-01-07 Support indentation for activate / deactivate blocks; allow customization of `plantuml-java-args' +;; version 1.2.7, 2018-08-15 Added support for indentation; Fixed the comiling error when installing with melpa +;; version 1.2.6, 2018-07-17 Introduced custom variable `plantuml-jar-args' to control which arguments are passed to PlantUML jar. Fix the warning of failing to specify types of 'defcustom' variables +;; version 1.2.5, 2017-08-19 #53 Fixed installation warnings +;; version 1.2.4, 2017-08-18 #60 Licensed with GPLv3+ to be compatible with Emacs +;; version 1.2.3, 2016-12-25 #50 unicode support in generated output +;; version 1.2.2, 2016-11-11 Fixed java commands handling under windows; support spaces in `plantuml-jar-path' +;; version 1.2.1, 2016-11-11 Support for paths like `~/.plantuml/plantuml.jar' for `plantuml-jar-path' (the tilde was previously unsupported) +;; version 1.2.0, 2016-11-09 Added `plantuml-preview-current-buffer', courtesy of @7mamu4 +;; version 1.1.1, 2016-11-08 Fix process handling with Windows native emacs; better file extention match for autoloading the mode +;; version 1.1.0, 2016-10-18 Make PlantUML run headless by default; introduced custom variable `plantuml-java-args' to control which arguments are passed to Plantuml. +;; version 1.0.1, 2016-10-17 Bugfix release: proper auto-mode-alist regex; init delayed at mode load; avoid calling hooks twice. +;; version 1.0.0, 2016-10-16 Moved the mode to plantuml-mode, superseding zwz/plantuml-mode and skuro/puml-mode. Added preview for the currently selected region. +;; version 0.6.7, 2016-10-11 [from puml-mode] Added deprecation warning in favor of plantuml-mode +;; version 0.6.6, 2016-07-19 [from puml-mode] Added autoload, minor bug fixes +;; version 0.6.5, 2016-03-24 [from puml-mode] Added UTF8 support and open in new window / frame shortcuts +;; version 0.6.4, 2015-12-12 [from puml-mode] Added support for comments (single and multiline) -- thanks to https://github.com/nivekuil +;; version 0.6.3, 2015-11-07 [from puml-mode] Added per-buffer configurability of output type (thanks to https://github.com/davazp) +;; version 0.6.2, 2015-11-07 [from puml-mode] Added debugging capabilities to improve issue analysis +;; version 0.6.1, 2015-09-26 [from puml-mode] Bugfix: use eq to compare symbols instead of cl-equalp +;; version 0.6, 2015-09-26 [from puml-mode] Fixed PNG preview +;; version 0.5, 2015-09-21 [from puml-mode] Added preview capabilities +;; version 0.4, 2015-06-14 [from puml-mode] Use a puml- prefix to distinguish from the other plantuml-mode +;; version 0.3, 2015-06-13 [from puml-mode] Compatibility with Emacs 24.x +;; version 0.2, 2010-09-20 [from puml-mode] Initialize the keywords from the -language output of plantuml.jar instead of the hard-coded way. +;; version 0.1, 2010-08-25 [from puml-mode] First version + +;;; Code: +(require 'thingatpt) +(require 'dash) +(require 'xml) + +(defgroup plantuml-mode nil + "Major mode for editing plantuml file." + :group 'languages) + +(defcustom plantuml-jar-path + (expand-file-name "~/plantuml.jar") + "The location of the PlantUML executable JAR." + :type 'string + :group 'plantuml) + +(defcustom plantuml-executable-path + "plantuml" + "The location of the PlantUML executable." + :type 'string + :group 'plantuml) + +(defvar plantuml-mode-hook nil "Standard hook for plantuml-mode.") + +(defconst plantuml-mode-version "20190821.1234" "The plantuml-mode version string.") + +(defvar plantuml-mode-debug-enabled nil) + +(defvar plantuml-font-lock-keywords nil) + +(defvar plantuml-mode-map + (let ((keymap (make-sparse-keymap))) + (define-key keymap (kbd "C-c C-c") 'plantuml-preview) + keymap) + "Keymap for plantuml-mode.") + +(defcustom plantuml-java-command "java" + "The java command used to execute PlantUML." + :type 'string + :group 'plantuml) + +(defcustom plantuml-java-args (list "-Djava.awt.headless=true" "-jar" "--illegal-access=deny") + "The parameters passed to `plantuml-java-command' when executing PlantUML." + :type '(repeat string) + :group 'plantuml) + +(defcustom plantuml-jar-args (list "-charset" "UTF-8" ) + "The parameters passed to `plantuml.jar', when executing PlantUML." + :type '(repeat string) + :group 'plantuml) + +(defcustom plantuml-server-url "https://www.plantuml.com/plantuml" + "The base URL of the PlantUML server." + :type 'string + :group 'plantuml) + +(defcustom plantuml-executable-args (list "-headless") + "The parameters passed to plantuml executable when executing PlantUML." + :type '(repeat string) + :group 'plantuml) + +(defcustom plantuml-default-exec-mode 'server + "Default execution mode for PlantUML. Valid values are: +- `jar': run PlantUML as a JAR file (requires a local install of the PlantUML JAR file, see `plantuml-jar-path'" + :type 'symbol + :group 'plantuml + :options '(jar server executable)) + +(defcustom plantuml-suppress-deprecation-warning t + "To silence the deprecation warning when `puml-mode' is found upon loading." + :type 'boolean + :group 'plantuml) + +(defun plantuml-jar-render-command (&rest arguments) + "Create a command line to execute PlantUML with arguments (as ARGUMENTS)." + (let* ((cmd-list (append plantuml-java-args (list (expand-file-name plantuml-jar-path)) plantuml-jar-args arguments)) + (cmd (mapconcat 'identity cmd-list "|"))) + (plantuml-debug (format "Command is [%s]" cmd)) + cmd-list)) + +;;; syntax table +(defvar plantuml-mode-syntax-table + (let ((synTable (make-syntax-table))) + (modify-syntax-entry ?\/ ". 14c" synTable) + (modify-syntax-entry ?' "< 23" synTable) + (modify-syntax-entry ?\n ">" synTable) + (modify-syntax-entry ?\r ">" synTable) + (modify-syntax-entry ?! "w" synTable) + (modify-syntax-entry ?@ "w" synTable) + (modify-syntax-entry ?# "'" synTable) + synTable) + "Syntax table for `plantuml-mode'.") + +(defvar plantuml-types nil) +(defvar plantuml-keywords nil) +(defvar plantuml-preprocessors nil) +(defvar plantuml-builtins nil) + +;; keyword completion +(defvar plantuml-kwdList nil "The plantuml keywords.") + +;; PlantUML execution mode +(defvar-local plantuml-exec-mode nil + "The Plantuml execution mode override. See `plantuml-default-exec-mode' for acceptable values.") + +(defun plantuml-set-exec-mode (mode) + "Set the execution mode MODE for PlantUML." + (interactive (let* ((completion-ignore-case t) + (supported-modes '("jar" "server" "executable"))) + (list (completing-read (format "Exec mode [%s]: " plantuml-exec-mode) + supported-modes + nil + t + nil + nil + plantuml-exec-mode)))) + (if (member mode '("jar" "server" "executable")) + (setq plantuml-exec-mode (intern mode)) + (error (concat "Unsupported mode:" mode)))) + +(defun plantuml-get-exec-mode () + "Retrieves the currently active PlantUML exec mode." + (or plantuml-exec-mode + plantuml-default-exec-mode)) + +(defun plantuml-enable-debug () + "Enables debug messages into the *PLANTUML Messages* buffer." + (interactive) + (setq plantuml-mode-debug-enabled t)) + +(defun plantuml-disable-debug () + "Stops any debug messages to be added into the *PLANTUML Messages* buffer." + (interactive) + (setq plantuml-mode-debug-enabled nil)) + +(defun plantuml-debug (msg) + "Writes msg (as MSG) into the *PLANTUML Messages* buffer without annoying the user." + (if plantuml-mode-debug-enabled + (let* ((log-buffer-name "*PLANTUML Messages*") + (log-buffer (get-buffer-create log-buffer-name))) + (save-excursion + (with-current-buffer log-buffer + (goto-char (point-max)) + (insert msg) + (insert "\n")))))) + +(defun plantuml-download-jar () + "Download the latest PlantUML JAR file and install it into `plantuml-jar-path'." + (interactive) + (if (y-or-n-p (format "Download the latest PlantUML JAR file into %s? " plantuml-jar-path)) + (if (or (not (file-exists-p plantuml-jar-path)) + (y-or-n-p (format "The PlantUML jar file already exists at %s, overwrite? " plantuml-jar-path))) + (with-current-buffer (url-retrieve-synchronously "https://search.maven.org/solrsearch/select?q=g:net.sourceforge.plantuml+AND+a:plantuml&core=gav&start=0&rows=1&wt=xml") + (mkdir (file-name-directory plantuml-jar-path) t) + (let* ((parse-tree (xml-parse-region)) + (doc (->> parse-tree + (assq 'response) + (assq 'result) + (assq 'doc))) + (strs (xml-get-children doc 'str)) + (version (->> strs + (--filter (string-equal "v" (xml-get-attribute it 'name))) + (car) + (xml-node-children) + (car)))) + (message (concat "Downloading PlantUML v" version " into " plantuml-jar-path)) + (url-copy-file (format "https://search.maven.org/remotecontent?filepath=net/sourceforge/plantuml/plantuml/%s/plantuml-%s.jar" version version) plantuml-jar-path t) + (kill-buffer))) + (message "Aborted.")) + (message "Aborted."))) + +(defun plantuml-jar-get-language (buf) + "Retrieve the language specification from the PlantUML JAR file and paste it into BUF." + (unless (or (eq system-type 'cygwin) (file-exists-p plantuml-jar-path)) + (error "Could not find plantuml.jar at %s" plantuml-jar-path)) + (with-current-buffer buf + (let ((cmd-args (append (list plantuml-java-command nil t nil) + (plantuml-jar-render-command "-language")))) + (apply 'call-process cmd-args) + (goto-char (point-min))))) + +(defun plantuml-server-get-language (buf) + "Retrieve the language specification from the PlantUML server and paste it into BUF." + (let ((lang-url (concat plantuml-server-url "/language"))) + (with-current-buffer buf + (url-insert-file-contents lang-url)))) + +(defun plantuml-executable-get-language (buf) + "Retrieve the language specification from the PlantUML executable and paste it into BUF." + (with-current-buffer buf + (let ((cmd-args (append (list plantuml-executable-path nil t nil) (list "-language")))) + (apply 'call-process cmd-args) + (goto-char (point-min))))) + +(defun plantuml-get-language (mode buf) + "Retrieve the language spec using the preferred PlantUML execution mode MODE. Paste the result into BUF." + (let ((get-fn (pcase mode + ('jar #'plantuml-jar-get-language) + ('server #'plantuml-server-get-language) + ('executable #'plantuml-executable-get-language)))) + (if get-fn + (funcall get-fn buf) + (error "Unsupported execution mode %s" mode)))) + +(defun plantuml-init (mode) + "Initialize the keywords or builtins from the cmdline language output. Use exec mode MODE to load the language details." + (with-temp-buffer + (plantuml-get-language mode (current-buffer)) + (let ((found (search-forward ";" nil t)) + (word "") + (count 0) + (pos 0)) + (while found + (forward-char) + (setq word (current-word)) + (if (string= word "EOF") (setq found nil) + ;; else + (forward-line) + (setq count (string-to-number (current-word))) + (beginning-of-line 2) + (setq pos (point)) + (forward-line count) + (cond ((string= word "type") + (setq plantuml-types + (split-string + (buffer-substring-no-properties pos (point))))) + ((string= word "keyword") + (setq plantuml-keywords + (split-string + (buffer-substring-no-properties pos (point))))) + ((string= word "preprocessor") + (setq plantuml-preprocessors + (split-string + (buffer-substring-no-properties pos (point))))) + (t (setq plantuml-builtins + (append + plantuml-builtins + (split-string + (buffer-substring-no-properties pos (point))))))) + (setq found (search-forward ";" nil nil))))))) + +(defconst plantuml-preview-buffer "*PLANTUML Preview*") + +(defvar plantuml-output-type + (if (not (display-images-p)) + "txt" + (cond ((image-type-available-p 'svg) "svg") + ((image-type-available-p 'png) "png") + (t "txt"))) + "Specify the desired output type to use for generated diagrams.") + +(defun plantuml-read-output-type () + "Read from the minibuffer a output type." + (let* ((completion-ignore-case t) + (available-types + (append + (and (image-type-available-p 'svg) '("svg")) + (and (image-type-available-p 'png) '("png")) + '("txt")))) + (completing-read (format "Output type [%s]: " plantuml-output-type) + available-types + nil + t + nil + nil + plantuml-output-type))) + +(defun plantuml-set-output-type (type) + "Set the desired output type (as TYPE) for the current buffer. +If the +major mode of the current buffer mode is not plantuml-mode, set the +default output type for new buffers." + (interactive (list (plantuml-read-output-type))) + (setq plantuml-output-type type)) + +(defun plantuml-is-image-output-p () + "Return non-nil if the diagram output format is an image, false if it's text based." + (not (equal "txt" plantuml-output-type))) + +(defun plantuml-jar-output-type-opt (output-type) + "Create the flag to pass to PlantUML according to OUTPUT-TYPE. +Note that output type `txt' is promoted to `utxt' for better rendering." + (concat "-t" (pcase output-type + ("txt" "utxt") + (_ output-type)))) + +(defun plantuml-jar-start-process (buf) + "Run PlantUML as an Emacs process and puts the output into the given buffer (as BUF)." + (apply #'start-process + "PLANTUML" buf plantuml-java-command + `(,@plantuml-java-args + ,(expand-file-name plantuml-jar-path) + ,(plantuml-jar-output-type-opt plantuml-output-type) + ,@plantuml-jar-args + "-p"))) + +(defun plantuml-executable-start-process (buf) + "Run PlantUML as an Emacs process and puts the output into the given buffer (as BUF)." + (apply #'start-process + "PLANTUML" buf plantuml-executable-path + `(,@plantuml-executable-args + ,(plantuml-jar-output-type-opt plantuml-output-type) + "-p"))) + +(defun plantuml-update-preview-buffer (prefix buf) + "Show the preview in the preview buffer BUF. +Window is selected according to PREFIX: +- 4 (when prefixing the command with C-u) -> new window +- 16 (when prefixing the command with C-u C-u) -> new frame. +- else -> new buffer" + (let ((imagep (and (display-images-p) + (plantuml-is-image-output-p)))) + (cond + ((= prefix 16) (switch-to-buffer-other-frame buf)) + ((= prefix 4) (switch-to-buffer-other-window buf)) + (t (display-buffer buf))) + (when imagep + (with-current-buffer buf + (image-mode) + (set-buffer-multibyte t))))) + +(defun plantuml-jar-preview-string (prefix string buf) + "Preview the diagram from STRING by running the PlantUML JAR. +Put the result into buffer BUF. Window is selected according to PREFIX: +- 4 (when prefixing the command with C-u) -> new window +- 16 (when prefixing the command with C-u C-u) -> new frame. +- else -> new buffer" + (let* ((process-connection-type nil) + (ps (plantuml-jar-start-process buf))) + (process-send-string ps string) + (process-send-eof ps) + (set-process-sentinel ps + (lambda (_ps event) + (unless (equal event "finished\n") + (error "PLANTUML Preview failed: %s" event)) + (plantuml-update-preview-buffer prefix buf))))) + +(defun plantuml-server-preview-string (prefix string buf) + "Preview the diagram from STRING as rendered by the PlantUML server. +Put the result into buffer BUF and place it according to PREFIX: +- 4 (when prefixing the command with C-u) -> new window +- 16 (when prefixing the command with C-u C-u) -> new frame. +- else -> new buffer" + (let* ((url-request-location (concat plantuml-server-url "/" plantuml-output-type "/-base64-" (base64-encode-string string t)))) + (save-current-buffer + (save-match-data + (url-retrieve url-request-location + (lambda (status) + ;; TODO: error check + (goto-char (point-min)) + ;; skip the HTTP headers + (while (not (looking-at "\n")) + (forward-line)) + (kill-region (point-min) (+ 1 (point))) + (copy-to-buffer buf (point-min) (point-max)) + (plantuml-update-preview-buffer prefix buf))))))) + +(defun plantuml-executable-preview-string (prefix string buf) + "Preview the diagram from STRING by running the PlantUML JAR. +Put the result into buffer BUF. Window is selected according to PREFIX: +- 4 (when prefixing the command with C-u) -> new window +- 16 (when prefixing the command with C-u C-u) -> new frame. +- else -> new buffer" + (let* ((process-connection-type nil) + (ps (plantuml-executable-start-process buf))) + (process-send-string ps string) + (process-send-eof ps) + (set-process-sentinel ps + (lambda (_ps event) + (unless (equal event "finished\n") + (error "PLANTUML Preview failed: %s" event)) + (plantuml-update-preview-buffer prefix buf))))) + +(defun plantuml-exec-mode-preview-string (prefix mode string buf) + "Preview the diagram from STRING using the execution mode MODE. +Put the result into buffer BUF, selecting the window according to PREFIX: +- 4 (when prefixing the command with C-u) -> new window +- 16 (when prefixing the command with C-u C-u) -> new frame. +- else -> new buffer" + (let ((preview-fn (pcase mode + ('jar #'plantuml-jar-preview-string) + ('server #'plantuml-server-preview-string) + ('executable #'plantuml-executable-preview-string)))) + (if preview-fn + (funcall preview-fn prefix string buf) + (error "Unsupported execution mode %s" mode)))) + +(defun plantuml-preview-string (prefix string) + "Preview diagram from PlantUML sources (as STRING), using prefix (as PREFIX) +to choose where to display it." + (let ((b (get-buffer plantuml-preview-buffer))) + (when b + (kill-buffer b))) + + (let* ((imagep (and (display-images-p) + (plantuml-is-image-output-p))) + (buf (get-buffer-create plantuml-preview-buffer)) + (coding-system-for-read (and imagep 'binary)) + (coding-system-for-write (and imagep 'binary))) + (plantuml-exec-mode-preview-string prefix (plantuml-get-exec-mode) string buf))) + +(defun plantuml-preview-buffer (prefix) + "Preview diagram from the PlantUML sources in the current buffer. +Uses prefix (as PREFIX) to choose where to display it: +- 4 (when prefixing the command with C-u) -> new window +- 16 (when prefixing the command with C-u C-u) -> new frame. +- else -> new buffer" + (interactive "p") + (plantuml-preview-string prefix (buffer-string))) + +(defun plantuml-preview-region (prefix begin end) + "Preview diagram from the PlantUML sources in from BEGIN to END. +Uses the current region when called interactively. +Uses prefix (as PREFIX) to choose where to display it: +- 4 (when prefixing the command with C-u) -> new window +- 16 (when prefixing the command with C-u C-u) -> new frame. +- else -> new buffer" + (interactive "p\nr") + (plantuml-preview-string prefix (concat "@startuml\n" + (buffer-substring-no-properties + begin end) + "\n@enduml"))) + +(defun plantuml-preview-current-block (prefix) + "Preview diagram from the PlantUML sources from the previous @startuml to the next @enduml. +Uses prefix (as PREFIX) to choose where to display it: +- 4 (when prefixing the command with C-u) -> new window +- 16 (when prefixing the command with C-u C-u) -> new frame. +- else -> new buffer" + (interactive "p") + (save-restriction + (narrow-to-region + (search-backward "@startuml") (search-forward "@enduml")) + (plantuml-preview-buffer prefix))) + +(defun plantuml-preview (prefix) + "Preview diagram from the PlantUML sources. +Uses the current region if one is active, or the entire buffer otherwise. +Uses prefix (as PREFIX) to choose where to display it: +- 4 (when prefixing the command with C-u) -> new window +- 16 (when prefixing the command with C-u C-u) -> new frame. +- else -> new buffer" + (interactive "p") + (if mark-active + (plantuml-preview-region prefix (region-beginning) (region-end)) + (plantuml-preview-buffer prefix))) + +(defun plantuml-init-once (&optional mode) + "Ensure initialization only happens once. Use exec mode MODE to load the language details or by first querying `plantuml-get-exec-mode'." + (let ((mode (or mode (plantuml-get-exec-mode)))) + (unless plantuml-kwdList + (plantuml-init mode) + (defvar plantuml-types-regexp (concat "^\\s *\\(" (regexp-opt plantuml-types 'words) "\\|\\<\\(note\\s +over\\|note\\s +\\(left\\|right\\|bottom\\|top\\)\\s +\\(of\\)?\\)\\>\\|\\<\\(\\(left\\|center\\|right\\)\\s +\\(header\\|footer\\)\\)\\>\\)")) + (defvar plantuml-keywords-regexp (concat "^\\s *" (regexp-opt plantuml-keywords 'words) "\\|\\(<\\|<|\\|\\*\\|o\\)\\(\\.+\\|-+\\)\\|\\(\\.+\\|-+\\)\\(>\\||>\\|\\*\\|o\\)\\|\\.\\{2,\\}\\|-\\{2,\\}")) + (defvar plantuml-builtins-regexp (regexp-opt plantuml-builtins 'words)) + (defvar plantuml-preprocessors-regexp (concat "^\\s *" (regexp-opt plantuml-preprocessors 'words))) + + (defvar plantuml-indent-regexp-block-start "^.*{\s*$" + "Indentation regex for all plantuml elements that might define a {} block. +Plantuml elements like skinparam, rectangle, sprite, package, etc. +The opening { has to be the last visible character in the line (whitespace +might follow).") + (defvar plantuml-indent-regexp-note-start "^\s*\\(floating\s+\\)?[hr]?note[^:]*?$" "simplyfied regex; note syntax is especially inconsistent across diagrams") + (defvar plantuml-indent-regexp-group-start "^\s*\\(alt\\|else\\|opt\\|loop\\|par\\|break\\|critical\\|group\\)\\(?:\s+.+\\|$\\)" + "Indentation regex for plantuml group elements that are defined for sequence diagrams. +Two variants for groups: keyword is either followed by whitespace and some text +or it is followed by line end.") + (defvar plantuml-indent-regexp-activate-start "^\s*activate\s+.+$") + (defvar plantuml-indent-regexp-box-start "^\s*box\s+.+$") + (defvar plantuml-indent-regexp-ref-start "^ref\s+over\s+[^:]+?$") + (defvar plantuml-indent-regexp-title-start "^\s*title$") + (defvar plantuml-indent-regexp-header-start "^\s*\\(?:\\(?:center\\|left\\|right\\)\s+header\\|header\\)$") + (defvar plantuml-indent-regexp-footer-start "^\s*\\(?:\\(?:center\\|left\\|right\\)\s+footer\\|footer\\)$") + (defvar plantuml-indent-regexp-legend-start "^\s*\\(?:legend\\|legend\s+\\(?:bottom\\|top\\)\\|legend\s+\\(?:center\\|left\\|right\\)\\|legend\s+\\(?:bottom\\|top\\)\s+\\(?:center\\|left\\|right\\)\\)$") + (defvar plantuml-indent-regexp-oldif-start "^.*if\s+\".*\"\s+then$" "used in current activity diagram, sometimes already mentioned as deprecated") + (defvar plantuml-indent-regexp-macro-start "^\s*!definelong.*$") + (defvar plantuml-indent-regexp-start (list plantuml-indent-regexp-block-start + plantuml-indent-regexp-group-start + plantuml-indent-regexp-activate-start + plantuml-indent-regexp-box-start + plantuml-indent-regexp-ref-start + plantuml-indent-regexp-legend-start + plantuml-indent-regexp-note-start + plantuml-indent-regexp-oldif-start + plantuml-indent-regexp-title-start + plantuml-indent-regexp-header-start + plantuml-indent-regexp-footer-start + plantuml-indent-regexp-macro-start + plantuml-indent-regexp-oldif-start)) + (defvar plantuml-indent-regexp-end "^\s*\\(?:}\\|endif\\|else\s*.*\\|end\\|end\s+note\\|endhnote\\|endrnote\\|end\s+box\\|end\s+ref\\|deactivate\s+.+\\|end\s+title\\|endheader\\|endfooter\\|endlegend\\|!enddefinelong\\)$") + (setq plantuml-font-lock-keywords + `( + (,plantuml-types-regexp . font-lock-type-face) + (,plantuml-keywords-regexp . font-lock-keyword-face) + (,plantuml-builtins-regexp . font-lock-builtin-face) + (,plantuml-preprocessors-regexp . font-lock-preprocessor-face) + ;; note: order matters + )) + + (setq plantuml-kwdList (make-hash-table :test 'equal)) + (mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-types) + (mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-keywords) + (mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-builtins) + (mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-preprocessors) + (put 'plantuml-kwdList 'risky-local-variable t) + + ;; clear memory + (setq plantuml-types nil) + (setq plantuml-keywords nil) + (setq plantuml-builtins nil) + (setq plantuml-preprocessors nil) + (setq plantuml-types-regexp nil) + (setq plantuml-keywords-regexp nil) + (setq plantuml-builtins-regexp nil) + (setq plantuml-preprocessors-regexp nil)))) + +(defun plantuml-complete-symbol () + "Perform keyword completion on word before cursor." + (interactive) + (let ((posEnd (point)) + (meat (thing-at-point 'symbol)) + maxMatchResult) + + (when (not meat) (setq meat "")) + + (setq maxMatchResult (try-completion meat plantuml-kwdList)) + (cond ((eq maxMatchResult t)) + ((null maxMatchResult) + (message "Can't find completion for \"%s\"" meat) + (ding)) + ((not (string= meat maxMatchResult)) + (delete-region (- posEnd (length meat)) posEnd) + (insert maxMatchResult)) + (t (message "Making completion list...") + (with-output-to-temp-buffer "*Completions*" + (display-completion-list + (all-completions meat plantuml-kwdList))) + (message "Making completion list...%s" "done"))))) + + +;; indentation + + +(defun plantuml-current-block-depth () + "Trace the current block indentation level by recursively looking back line by line." + (save-excursion + (let ((relative-depth 0)) + ;; current line + (beginning-of-line) + (if (looking-at plantuml-indent-regexp-end) + (setq relative-depth (1- relative-depth))) + + ;; from current line backwards to beginning of buffer + (while (not (bobp)) + (forward-line -1) + (if (looking-at plantuml-indent-regexp-end) + (setq relative-depth (1- relative-depth))) + (if (-any? 'looking-at plantuml-indent-regexp-start) + (setq relative-depth (1+ relative-depth)))) + + (if (<= relative-depth 0) + 0 + relative-depth)))) + +(defun plantuml-indent-line () + "Indent the current line to its desired indentation level. +Restore point to same position in text of the line as before indentation." + (interactive) + ;; store position of point in line measured from end of line + (let ((original-position-eol (- (line-end-position) (point)))) + (save-excursion + (beginning-of-line) + (indent-line-to (* tab-width (plantuml-current-block-depth)))) + + ;; restore position in text of line + (goto-char (- (line-end-position) original-position-eol)))) + + +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.\\(plantuml\\|pum\\|plu\\)\\'" . plantuml-mode)) + +;;;###autoload +(define-derived-mode plantuml-mode prog-mode "plantuml" + "Major mode for plantuml. + +Shortcuts Command Name +\\[plantuml-complete-symbol] `plantuml-complete-symbol'" + (plantuml-init-once) + (make-local-variable 'plantuml-output-type) + (set (make-local-variable 'comment-start-skip) "\\('+\\|/'+\\)\\s *") + (set (make-local-variable 'comment-start) "/'") + (set (make-local-variable 'comment-end) "'/") + (set (make-local-variable 'comment-multi-line) t) + (set (make-local-variable 'comment-style) 'extra-line) + (set (make-local-variable 'indent-line-function) 'plantuml-indent-line) + (setq font-lock-defaults '((plantuml-font-lock-keywords) nil t))) + +(defun plantuml-deprecation-warning () + "Warns the user about the deprecation of the `puml-mode' project." + (if (and plantuml-suppress-deprecation-warning + (featurep 'puml-mode)) + (display-warning :warning + "`puml-mode' is now deprecated and no longer updated, but it's still present in your system. \ +You should move your configuration to use `plantuml-mode'. \ +See more at https://github.com/skuro/puml-mode/issues/26"))) + +(add-hook 'plantuml-mode-hook 'plantuml-deprecation-warning) + +(provide 'plantuml-mode) +;;; plantuml-mode.el ends here diff --git a/packages/polymode-20190714.2017.tar b/packages/polymode-20190714.2017.tar new file mode 100644 index 0000000..f5c2b30 Binary files /dev/null and b/packages/polymode-20190714.2017.tar differ diff --git a/packages/pony-mode-20170807.1522.tar b/packages/pony-mode-20170807.1522.tar index abea9f5..3e4aa58 100644 Binary files a/packages/pony-mode-20170807.1522.tar and b/packages/pony-mode-20170807.1522.tar differ diff --git a/packages/powerline-20180322.248.tar b/packages/powerline-20190323.213.tar similarity index 64% rename from packages/powerline-20180322.248.tar rename to packages/powerline-20190323.213.tar index e81a944..c0be52c 100644 Binary files a/packages/powerline-20180322.248.tar and b/packages/powerline-20190323.213.tar differ diff --git a/packages/powershell-20181011.1951.el b/packages/powershell-20190421.2038.el similarity index 97% rename from packages/powershell-20181011.1951.el rename to packages/powershell-20190421.2038.el index 26e853c..91ce545 100644 --- a/packages/powershell-20181011.1951.el +++ b/packages/powershell-20190421.2038.el @@ -6,7 +6,7 @@ ;; Author: Frédéric Perrin ;; URL: http://github.com/jschaf/powershell.el -;; Package-Version: 20181011.1951 +;; Package-Version: 20190421.2038 ;; Version: 0.3 ;; Package-Requires: ((emacs "24")) ;; Keywords: powershell, languages @@ -314,10 +314,12 @@ The text is assumed to be `regexp-opt' output." (defvar powershell-keywords (concat "\\_<" (regexp-opt - '("begin" "break" "catch" "class" "continue" "data" "do" "default" + '("begin" "break" "catch" "class" "continue" "data" "define" "do" "default" "dynamicparam" "else" "elseif" "end" "enum" "exit" "filter" "finally" - "for" "foreach" "from" "function" "if" "in" "param" "process" - "return" "switch" "throw" "trap" "try" "until" "where" "while") + "for" "foreach" "from" "function" "hidden" "if" "in" "param" "process" + "return" "static" "switch" "throw" "trap" "try" "until" "using" "var" "where" "while" + ;; Questionable, specific to workflow sessions + "inlinescript") t) "\\_>") "PowerShell keywords.") @@ -331,14 +333,18 @@ The text is assumed to be `regexp-opt' output." "-ceq" "-cne" "-cgt" "-cge" "-clt" "-cle" ;; explicitly case insensitive "-ieq" "-ine" "-igt" "-ige" "-ilt" "-ile" - "-band" "-bor" "-bxor" - "-and" "-or" "-xor" + "-band" "-bor" "-bxor" "-bnot" + "-and" "-or" "-xor" "-not" "!" "-like" "-notlike" "-clike" "-cnotlike" "-ilike" "-inotlike" "-match" "-notmatch" "-cmatch" "-cnotmatch" "-imatch" "-inotmatch" "-contains" "-notcontains" "-ccontains" "-cnotcontains" "-icontains" "-inotcontains" "-replace" "-creplace" "-ireplace" - "-is" "-as" "-f" + "-is" "-isnot" "-as" "-f" + "-in" "-cin" "-iin" "-notin" "-cnotin" "-inotin" + "-split" "-csplit" "-isplit" + "-join" + "-shl" "-shr" ;; Questionable --> specific to certain contexts "-casesensitive" "-wildcard" "-regex" "-exact" ;specific to case "-begin" "-process" "-end" ;specific to scriptblock @@ -351,7 +357,7 @@ The text is assumed to be `regexp-opt' output." "Names of scopes in PowerShell mode.") (defvar powershell-variable-drive-names - (append '("env" "function" "variable" "alias") powershell-scope-names) + (append '("env" "function" "variable" "alias" "hklm" "hkcu" "wsman") powershell-scope-names) "Names of scopes in PowerShell mode.") (defconst powershell-variables-regexp @@ -395,16 +401,21 @@ The text is assumed to be `regexp-opt' output." "^" "_" "args" "ConsoleFileName" "Error" "Event" + "EventArgs" "EventSubscriber" "ExecutionContext" "false" "Foreach" "HOME" "Host" - "input" "LASTEXITCODE" + "input" "lsCoreCLR" + "lsLinux" "lsMacOS" + "lsWindows" "LASTEXITCODE" "Matches" "MyInvocation" "NestedPromptLevel" "null" "PID" "PROFILE" "PSBoundParameters" "PSCmdlet" + "PSCommandPath" "PSCulture" "PSDebugContext" - "PSHOME" "PSScriptRoot" + "PSHOME" "PSITEM" + "PSScriptRoot" "PSSenderInfo" "PSUICulture" "PSVersionTable" "PWD" "ReportErrorShowExceptionClass" "ReportErrorShowInnerException" "ReportErrorShowSource" @@ -419,7 +430,8 @@ They are highlighted differently from the other variables.") (regexp-opt '("ConfirmPreference" "DebugPreference" "ErrorActionPreference" "ErrorView" - "FormatEnumerationLimit" "LogCommandHealthEvent" + "FormatEnumerationLimit" "InformationPreference" + "LogCommandHealthEvent" "LogCommandLifecycleEvent" "LogEngineHealthEvent" "LogEngineLifecycleEvent" "LogProviderHealthEvent" "LogProviderLifecycleEvent" "MaximumAliasCount" @@ -427,7 +439,8 @@ They are highlighted differently from the other variables.") "MaximumFunctionCount" "MaximumHistoryCount" "MaximumVariableCount" "OFS" "OutputEncoding" "ProgressPreference" - "PSEmailServer" "PSSessionApplicationName" + "PSDefaultParameterValues" "PSEmailServer" + "PSModuleAutoLoadingPreference" "PSSessionApplicationName" "PSSessionConfigurationName" "PSSessionOption" "VerbosePreference" "WarningPreference" "WhatIfPreference" ) t) @@ -771,14 +784,12 @@ that value is non-nil." (powershell-setup-menu) (powershell-setup-eldoc)) - ;;; PowerShell inferior mode -;; TODO: set this programmatically, relying on %WINDIR% ;;; Code: (defcustom powershell-location-of-exe - "c:\\windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe" - "A string, providing the location of the powershell.exe." + (or (executable-find "powershell") (executable-find "pwsh")) + "A string, providing the location of the powershell executable." :group 'powershell) (defcustom powershell-log-level 3 diff --git a/packages/prodigy-20180511.938.el b/packages/prodigy-20190714.1102.el similarity index 95% rename from packages/prodigy-20180511.938.el rename to packages/prodigy-20190714.1102.el index 2fdb543..9e89889 100644 --- a/packages/prodigy-20180511.938.el +++ b/packages/prodigy-20190714.1102.el @@ -5,7 +5,7 @@ ;; Author: Johan Andersson ;; Maintainer: Johan Andersson ;; Version: 0.7.0 -;; Package-Version: 20180511.938 +;; Package-Version: 20190714.1102 ;; URL: http://github.com/rejeep/prodigy.el ;; Package-Requires: ((s "1.8.0") (dash "2.4.0") (f "0.14.0") (emacs "24")) @@ -146,6 +146,7 @@ An example is restarting a service." (defvar prodigy-view-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "k") 'prodigy-view-clear-buffer) + (define-key map (kbd "c") prodigy-mode-map) map) "Keymap for `prodigy-view-mode'.") @@ -778,6 +779,17 @@ The completion system used is determined by (equal (plist-get service :name) name)) prodigy-services)) +(defun prodigy-find-service-in-buffer (&optional buffer) + "Find service associated with BUFFER. + +If BUFFER is a prodigy service's process buffer then return the +associated service definition." + (setq buffer (or (current-buffer) buffer)) + (-first + (lambda (service) + (equal (prodigy-buffer-name service) (buffer-name buffer))) + prodigy-services)) + (defun prodigy-service-id (service) "Return SERVICE identifier." (let* ((name (plist-get service :name)) @@ -974,11 +986,27 @@ accordingly." (defun prodigy-relevant-services () "Return list of relevant services. -If there are any marked services, those are returned. Otherwise, -the service at pos is returned. +If the service list buffer is selected and there are any marked +services, those are returned. Otherwise, the service at pos is +returned. + +If the service's process buffer is selected return the service +associated with this process. Note that the return value is always a list." - (or (prodigy-marked-services) (list (prodigy-service-at-pos)))) + (or (prodigy-marked-services) + (--when-let (prodigy-current-service) (list it)))) + +(defun prodigy-current-service () + "Return service at point or service associated with current buffer. + +If the service list buffer is selected the service at pos is +returned. + +If the service's process buffer is selected return the service +associated with this process." + (or (prodigy-service-at-pos) + (prodigy-find-service-in-buffer))) (defun prodigy-set-default-directory () "Set default directory to :cwd for service at point." @@ -1219,7 +1247,7 @@ started." (defun prodigy-copy-cmd () "Copy cmd at line." (interactive) - (let* ((service (prodigy-service-at-pos)) + (let* ((service (prodigy-current-service)) (envs (s-join " " (-map (lambda (env-var-value) (s-join "=" env-var-value)) @@ -1266,7 +1294,7 @@ SIGNINT signal." (defun prodigy-browse () "Browse service url at point if possible to figure out." (interactive) - (-when-let (service (prodigy-service-at-pos)) + (-when-let (service (prodigy-current-service)) (-if-let (url (prodigy-url service)) (progn (when (listp url) @@ -1310,14 +1338,14 @@ SIGNINT signal." (defun prodigy-jump-magit () "Jump to magit status mode for service at point." (interactive) - (-when-let (service (prodigy-service-at-pos)) + (-when-let (service (prodigy-current-service)) (magit-status-internal (prodigy-service-cwd service)))) (defun prodigy-jump-file-manager () "Jump to folder for service at point using selected file manager mode defined by `prodigy-file-manager'." (interactive) - (-when-let (service (prodigy-service-at-pos)) + (-when-let (service (prodigy-current-service)) (funcall prodigy-file-manager (prodigy-service-cwd service)))) (defun prodigy-next-with-status () @@ -1437,18 +1465,18 @@ The old service process is transfered to the new service." (when (featurep 'discover) (prodigy-discover-initialize)) (setq imenu-prev-index-position-function - #'prodigy--imenu-prev-index-position-function) + #'prodigy--imenu-prev-index-position) (setq imenu-extract-index-name-function - #'prodigy--imenu-extract-index-name-function)) + #'prodigy--imenu-extract-index-name)) -(defun prodigy--imenu-prev-index-position-function () +(defun prodigy--imenu-prev-index-position () "Move point to previous line in prodigy buffer. This function is used as a value for `imenu-prev-index-position-function'." (unless (bobp) (forward-line -1))) -(defun prodigy--imenu-extract-index-name-function () +(defun prodigy--imenu-extract-index-name () "Return imenu name for line at point. This function is used as a value for `imenu-extract-index-name-function'. Point should be at the @@ -1460,7 +1488,16 @@ beginning of the line." "Mode for viewing prodigy process output." (view-mode 1) (font-lock-mode 1) - (use-local-map prodigy-view-mode-map)) + (use-local-map prodigy-view-mode-map) + ;; Make the "c" binding point to prodigy-mode-map. Because the + ;; `view-mode' minor-mode map has higher priority, we need to add an + ;; entry to `minor-mode-overriding-map-alist'. + (let ((oldmap (cdr (assoc 'view-mode minor-mode-map-alist))) + (newmap (make-sparse-keymap))) + (set-keymap-parent newmap oldmap) + (define-key newmap (kbd "c") nil) + (make-local-variable 'minor-mode-overriding-map-alist) + (push `(view-mode . ,newmap) minor-mode-overriding-map-alist))) ;;;###autoload (defun prodigy () diff --git a/packages/projectile-20181106.1631.el b/packages/projectile-20190626.1315.el similarity index 87% rename from packages/projectile-20181106.1631.el rename to packages/projectile-20190626.1315.el index 995def8..54f239e 100644 --- a/packages/projectile-20181106.1631.el +++ b/packages/projectile-20190626.1315.el @@ -1,12 +1,12 @@ ;;; projectile.el --- Manage and navigate projects in Emacs easily -*- lexical-binding: t -*- -;; Copyright © 2011-2018 Bozhidar Batsov +;; Copyright © 2011-2019 Bozhidar Batsov ;; Author: Bozhidar Batsov ;; URL: https://github.com/bbatsov/projectile -;; Package-Version: 20181106.1631 +;; Package-Version: 20190626.1315 ;; Keywords: project, convenience -;; Version: 1.1.0-snapshot +;; Version: 2.1.0-snapshot ;; Package-Requires: ((emacs "25.1") (pkg-info "0.4")) ;; This file is NOT part of GNU Emacs. @@ -44,6 +44,7 @@ (require 'compile) (require 'grep) (eval-when-compile + (require 'find-dired) (require 'subr-x)) (eval-when-compile @@ -96,7 +97,7 @@ idea to pair the native indexing method with caching. The hybrid indexing method uses external tools (e.g. git, find, etc) to speed up the indexing process. Still, the files will be post-processed by Projectile for sorting/filtering purposes. -In this sense that approach is a hybrid between native and indexing +In this sense that approach is a hybrid between native indexing and alien indexing. The alien indexing method optimizes to the limit the speed @@ -169,6 +170,11 @@ A value of nil means the cache never expires." :type '(choice (const :tag "Disabled" nil) (integer :tag "Seconds"))) +(defcustom projectile-auto-update-cache t + "Wether the cache should automatically be updated when files are opened or deleted." + :group 'projectile + :type 'boolean) + (defcustom projectile-require-project-root 'prompt "Require the presence of a project root to operate when true. When set to 'prompt Projectile will ask you to select a project @@ -195,7 +201,7 @@ When nil Projectile will consider the current directory the project root." :group 'projectile :type 'string) -(make-obsolete-variable 'projectile-keymap-prefix "Use (define-key projectile-mode-map (kbd ...) 'projectile-command-map) instead." "1.1.0") +(make-obsolete-variable 'projectile-keymap-prefix "Use (define-key projectile-mode-map (kbd ...) 'projectile-command-map) instead." "2.0.0") (defcustom projectile-cache-file (expand-file-name "projectile.cache" user-emacs-directory) @@ -236,14 +242,17 @@ set to 'ggtags', then ggtags will be used for :package-version '(projectile . "0.14.0")) (defcustom projectile-sort-order 'default - "The sort order used for a project's files." + "The sort order used for a project's files. + +Note that files aren't sorted if `projectile-indexing-method' +is set to 'alien'." :group 'projectile :type '(radio - (const :tag "default" default) - (const :tag "recentf" recentf) - (const :tag "recently active" recently-active) - (const :tag "access time" access-time) - (const :tag "modification time" modification-time))) + (const :tag "Default (no sorting)" default) + (const :tag "Recently opened files" recentf) + (const :tag "Recently active buffers, then recently opened files" recently-active) + (const :tag "Access time (atime)" access-time) + (const :tag "Modification time (mtime)" modification-time))) (defcustom projectile-verbose t "Echo messages that are not errors." @@ -456,6 +465,11 @@ Any function that does not take arguments will do." :group 'projectile :type 'function) +(defcustom projectile-related-files-fn-function 'projectile-related-files-fn + "Function to find related files based on PROJECT-TYPE." + :group 'projectile + :type 'function) + (defcustom projectile-dynamic-mode-line t "If true, update the mode-line dynamically. Only file buffers are affected by this, as the update happens via @@ -464,7 +478,7 @@ Only file buffers are affected by this, as the update happens via See also `projectile-mode-line-function' and `projectile-update-mode-line'." :group 'projectile :type 'boolean - :package-version '(projectile . "1.1.0")) + :package-version '(projectile . "2.0.0")) (defcustom projectile-mode-line-function 'projectile-default-mode-line "The function to use to generate project-specific mode-line. @@ -472,7 +486,7 @@ The default function adds the project name and type to the mode-line. See also `projectile-update-mode-line'." :group 'projectile :type 'function - :package-version '(projectile . "1.1.0")) + :package-version '(projectile . "2.0.0")) ;;; Idle Timer @@ -630,7 +644,10 @@ Set to nil to disable listing submodules contents." :group 'projectile :type 'string) -(defcustom projectile-generic-command "find . -type f -print0" +(defcustom projectile-generic-command + (if (executable-find "fd") + "fd . -0 --type f --color=never" + "find . -type f -print0") "Command used by projectile to get the files in a generic project." :group 'projectile :type 'string) @@ -961,8 +978,8 @@ Invoked automatically when `projectile-mode' is enabled." (mapcar #'projectile-discover-projects-in-directory projectile-project-search-path)) -(defadvice delete-file (before purge-from-projectile-cache (filename &optional trash)) - (if (and projectile-enable-caching (projectile-project-p)) +(defun delete-file-projectile-remove-from-cache (filename &optional _trash) + (if (and projectile-enable-caching projectile-auto-update-cache (projectile-project-p)) (let* ((project-root (projectile-project-root)) (true-filename (file-truename filename)) (relative-filename (file-relative-name true-filename project-root))) @@ -1180,8 +1197,8 @@ function is executing." (projectile-get-sub-projects-files directory vcs))) (t (projectile-files-via-ext-command directory (projectile-get-ext-command vcs)))))) -(define-obsolete-function-alias 'projectile-dir-files-external 'projectile-dir-files-alien "1.1") -(define-obsolete-function-alias 'projectile-get-repo-files 'projectile-dir-files-alien "1.1") +(define-obsolete-function-alias 'projectile-dir-files-external 'projectile-dir-files-alien "2.0.0") +(define-obsolete-function-alias 'projectile-get-repo-files 'projectile-dir-files-alien "2.0.0") (defun projectile-get-ext-command (vcs) "Determine which external command to invoke based on the project's VCS. @@ -1258,14 +1275,17 @@ they are excluded from the results of this function." submodule)) submodules))) -(defun projectile-get-sub-projects-files (project-root vcs) +(defun projectile-get-sub-projects-files (project-root _vcs) "Get files from sub-projects for PROJECT-ROOT recursively." (projectile-flatten (mapcar (lambda (sub-project) - (mapcar (lambda (file) - (concat sub-project file)) + (let ((project-relative-path + (file-name-as-directory (file-relative-name + sub-project project-root)))) + (mapcar (lambda (file) + (concat project-relative-path file)) ;; TODO: Seems we forgot git hardcoded here - (projectile-files-via-ext-command sub-project projectile-git-command))) + (projectile-files-via-ext-command sub-project projectile-git-command)))) (projectile-get-all-sub-projects project-root)))) (defun projectile-get-repo-ignored-files (project vcs) @@ -1784,7 +1804,7 @@ https://github.com/abo-abo/swiper"))) ;; Calculate the list of files. (when (null files) (when projectile-enable-caching - (message "Projectile is initializing cache...")) + (message "Projectile is initializing cache for %s ..." project-root)) (setq files (if (eq projectile-indexing-method 'alien) ;; In alien mode we can just skip reading @@ -1841,7 +1861,16 @@ https://github.com/abo-abo/swiper"))) "Return a list of dirs for the current project." (projectile-project-dirs (projectile-ensure-project (projectile-project-root)))) -;;; Interactive commands +(defun projectile-get-other-files (file-name &optional flex-matching) + "Return a list of other files for FILE-NAME. +The list depends on `:related-files-fn' project option and +`projectile-other-file-alist'. For the latter, FLEX-MATCHING can be used +to match any basename." + (if-let ((plist (projectile--related-files-plist-by-kind file-name :other))) + (projectile--related-files-from-plist plist) + (projectile--other-extension-files file-name + (projectile-current-project-files) + flex-matching))) (defun projectile--find-other-file (&optional flex-matching ff-variant) "Switch between files with the same name but different extensions. @@ -1851,19 +1880,15 @@ Other file extensions can be customized with the variable instead of `find-file'. A typical example of such a defun would be `find-file-other-window' or `find-file-other-frame'" (let ((ff (or ff-variant #'find-file)) - (other-files (projectile-get-other-files - (buffer-file-name) - (projectile-current-project-files) - flex-matching))) + (other-files (projectile-get-other-files (buffer-file-name) flex-matching))) (if other-files - (let ((file-name (if (= (length other-files) 1) - (car other-files) - (projectile-completing-read "Switch to: " - other-files)))) + (let ((file-name (projectile--choose-from-candidates other-files))) (funcall ff (expand-file-name file-name (projectile-project-root)))) (error "No other file found")))) + +;;; Interactive commands ;;;###autoload (defun projectile-find-other-file (&optional flex-matching) "Switch between files with the same name but different extensions. @@ -1918,7 +1943,7 @@ If no associated other-file-extensions for the complete (nested) extension are f (throw 'break associated-extensions)) (setq current-extensions (projectile--file-name-extensions current-extensions)))))) -(defun projectile-get-other-files (current-file project-file-list &optional flex-matching) +(defun projectile--other-extension-files (current-file project-file-list &optional flex-matching) "Narrow to files with the same names but different extensions. Returns a list of possible files for users to choose. @@ -2244,12 +2269,182 @@ With a prefix arg INVALIDATE-CACHE invalidates the cache first." "Return only the test FILES." (cl-remove-if-not 'projectile-test-file-p files)) +(defun projectile--merge-related-files-fns (related-files-fns) + "Merge multiple RELATED-FILES-FNS into one function." + (lambda (path) + (let (merged-plist) + (dolist (fn related-files-fns merged-plist) + (let ((plist (funcall fn path))) + (cl-loop for (key value) on plist by #'cddr + do (let ((values (if (consp value) value (list value)))) + (if (plist-member merged-plist key) + (nconc (plist-get merged-plist key) values) + (setq merged-plist (plist-put merged-plist key values)))))))))) + +(defun projectile--related-files-plist (project-root file) + "Return a plist containing all related files information for FILE in PROJECT-ROOT." + (if-let ((rel-path (if (file-name-absolute-p file) + (file-relative-name file project-root) + file)) + (custom-function (funcall projectile-related-files-fn-function (projectile-project-type)))) + (funcall (cond ((functionp custom-function) + custom-function) + ((consp custom-function) + (projectile--merge-related-files-fns custom-function)) + (t + (error "Unsupported value type of :related-files-fn"))) + rel-path))) + +(defun projectile--related-files-plist-by-kind (file kind) + "Return a plist containing :paths and/or :predicate of KIND for FILE." + (if-let ((project-root (projectile-project-root)) + (plist (projectile--related-files-plist project-root file)) + (has-kind? (plist-member plist kind))) + (let* ((kind-value (plist-get plist kind)) + (values (if (cl-typep kind-value '(or string function)) + (list kind-value) + kind-value)) + (paths (delete-dups (cl-remove-if-not 'stringp values))) + (predicates (delete-dups (cl-remove-if-not 'functionp values)))) + (append + ;; Make sure that :paths exists even with nil if there is no predicates + (when (or paths (null predicates)) + (list :paths (cl-remove-if-not + (lambda (f) + (projectile-file-exists-p (expand-file-name f project-root))) + paths))) + (when predicates + (list :predicate (if (= 1 (length predicates)) + (car predicates) + (lambda (other-file) + (cl-some (lambda (predicate) + (funcall predicate other-file)) + predicates))))))))) + +(defun projectile--related-files-from-plist (plist) + "Return a list of files matching to PLIST from current project files." + (let* ((predicate (plist-get plist :predicate)) + (paths (plist-get plist :paths))) + (delete-dups (append + paths + (when predicate + (cl-remove-if-not predicate (projectile-current-project-files))))))) + +(defun projectile--related-files-kinds(file) + "Return a list o keywords meaning available related kinds for FILE." + (if-let ((project-root (projectile-project-root)) + (plist (projectile--related-files-plist project-root file))) + (cl-loop for key in plist by #'cddr + collect key))) + +(defun projectile--related-files (file kind) + "Return a list of related files of KIND for FILE." + (projectile--related-files-from-plist (projectile--related-files-plist-by-kind file kind))) + +(defun projectile--find-related-file (file &optional kind) + "Choose a file from files related to FILE as KIND. +If KIND is not provided, a list of possible kinds can be chosen." + (unless kind + (if-let ((available-kinds (projectile--related-files-kinds file))) + (setq kind (if (= (length available-kinds) 1) + (car available-kinds) + (intern (projectile-completing-read "Kind :" available-kinds)))) + (error "No related files found"))) + + (if-let ((candidates (projectile--related-files file kind))) + (projectile-expand-root (projectile--choose-from-candidates candidates)) + (error + "No matching related file as `%s' found for project type `%s'" + kind (projectile-project-type)))) + +;;;###autoload +(defun projectile-find-related-file-other-window () + "Open related file in other window." + (interactive) + (find-file-other-window + (projectile--find-related-file (buffer-file-name)))) + +;;;###autoload +(defun projectile-find-related-file-other-frame () + "Open related file in other frame." + (interactive) + (find-file-other-frame + (projectile--find-related-file (buffer-file-name)))) + +;;;###autoload +(defun projectile-find-related-file() + "Open related file." + (interactive) + (find-file + (projectile--find-related-file (buffer-file-name)))) + +;;;###autoload +(defun projectile-related-files-fn-groups(kind groups) + "Generate a related-files-fn which relates as KIND for files in each of GROUPS." + (lambda (path) + (if-let ((group-found (cl-find-if (lambda (group) + (member path group)) + groups))) + (list kind (cl-remove path group-found :test 'equal))))) + +;;;###autoload +(defun projectile-related-files-fn-extensions(kind extensions) + "Generate a related-files-fn which relates as KIND for files having EXTENSIONS." + (lambda (path) + (let* ((ext (file-name-extension path)) + (basename (file-name-base path)) + (basename-regexp (regexp-quote basename))) + (when (member ext extensions) + (list kind (lambda (other-path) + (and (string-match-p basename-regexp other-path) + (equal basename (file-name-base other-path)) + (let ((other-ext (file-name-extension other-path))) + (and (member other-ext extensions) + (not (equal other-ext ext))))))))))) + +;;;###autoload +(defun projectile-related-files-fn-test-with-prefix(extension test-prefix) + "Generate a related-files-fn which relates tests and impl for files with EXTENSION based on TEST-PREFIX." + (lambda (path) + (when (equal (file-name-extension path) extension) + (let* ((file-name (file-name-nondirectory path)) + (find-impl? (string-prefix-p test-prefix file-name)) + (file-name-to-find (if find-impl? + (substring file-name (length test-prefix)) + (concat test-prefix file-name)))) + (list (if find-impl? :impl :test) + (lambda (other-path) + (and (string-suffix-p file-name-to-find other-path) + (equal (file-name-nondirectory other-path) file-name-to-find)))))))) + +;;;###autoload +(defun projectile-related-files-fn-test-with-suffix(extension test-suffix) + "Generate a related-files-fn which relates tests and impl for files with EXTENSION based on TEST-SUFFIX." + (lambda (path) + (when (equal (file-name-extension path) extension) + (let* ((file-name (file-name-nondirectory path)) + (dot-ext (concat "." extension)) + (suffix-ext (concat test-suffix dot-ext)) + (find-impl? (string-suffix-p suffix-ext file-name)) + (file-name-to-find (if find-impl? + (concat (substring file-name 0 (- (length suffix-ext))) + dot-ext) + (concat (substring file-name 0 (- (length dot-ext))) + suffix-ext)))) + (list (if find-impl? :impl :test) + (lambda (other-path) + (and (string-suffix-p file-name-to-find other-path) + (equal (file-name-nondirectory other-path) file-name-to-find)))))))) + (defun projectile-test-file-p (file) "Check if FILE is a test file." - (or (cl-some (lambda (pat) (string-prefix-p pat (file-name-nondirectory file))) - (delq nil (list (funcall projectile-test-prefix-function (projectile-project-type))))) - (cl-some (lambda (pat) (string-suffix-p pat (file-name-sans-extension (file-name-nondirectory file)))) - (delq nil (list (funcall projectile-test-suffix-function (projectile-project-type))))))) + (let ((kinds (projectile--related-files-kinds file))) + (cond ((member :impl kinds) t) + ((member :test kinds) nil) + (t (or (cl-some (lambda (pat) (string-prefix-p pat (file-name-nondirectory file))) + (delq nil (list (funcall projectile-test-prefix-function (projectile-project-type))))) + (cl-some (lambda (pat) (string-suffix-p pat (file-name-sans-extension (file-name-nondirectory file)))) + (delq nil (list (funcall projectile-test-suffix-function (projectile-project-type)))))))))) (defun projectile-current-project-test-files () "Return a list of test files for the current project." @@ -2261,7 +2456,7 @@ The project types are symbols and they are linked to plists holding the properties of the various project types.") (cl-defun projectile-register-project-type - (project-type marker-files &key compilation-dir configure compile test run test-suffix test-prefix src-dir test-dir) + (project-type marker-files &key compilation-dir configure compile test run test-suffix test-prefix src-dir test-dir related-files-fn) "Register a project type with projectile. A project type is defined by PROJECT-TYPE, a set of MARKER-FILES, @@ -2276,7 +2471,12 @@ RUN which specifies a command that runs the project, TEST-SUFFIX which specifies test file suffix, and TEST-PREFIX which specifies test file prefix. SRC-DIR which specifies the path to the source relative to the project root. -TEST-DIR which specifies the path to the tests relative to the project root." +TEST-DIR which specifies the path to the tests relative to the project root. +RELATED-FILES-FN which specifies a custom function to find the related files such as +test/impl/other files as below: + CUSTOM-FUNCTION accepts FILE as relative path from the project root and returns + a plist containing :test, :impl or :other as key and the relative path/paths or + predicate as value. PREDICATE accepts a relative path as the input." (let ((project-plist (list 'marker-files marker-files 'compilation-dir compilation-dir 'configure-command configure @@ -2295,18 +2495,26 @@ TEST-DIR which specifies the path to the tests relative to the project root." (plist-put project-plist 'src-dir src-dir)) (when test-dir (plist-put project-plist 'test-dir test-dir)) + (when related-files-fn + (plist-put project-plist 'related-files-fn related-files-fn)) + (setq projectile-project-types (cons `(,project-type . ,project-plist) projectile-project-types)))) (defun projectile-cabal-project-p () "Check if a project contains *.cabal files but no stack.yaml file." - (and (projectile-verify-file-wildcard "*.cabal") + (and (projectile-verify-file-wildcard "?*.cabal") (not (projectile-verify-file "stack.yaml")))) +(defun projectile-dotnet-project-p () + (or (projectile-verify-file-wildcard "?*.csproj") + (projectile-verify-file-wildcard "?*.fsproj"))) + (defun projectile-go-project-p () "Check if a project contains Go source files." - (projectile-verify-file-wildcard "*.go")) + (or (projectile-verify-file "go.mod") + (projectile-verify-file-wildcard "*.go"))) (define-obsolete-variable-alias 'projectile-go-function 'projectile-go-project-test-function "1.0.0") (defcustom projectile-go-project-test-function #'projectile-go-project-p @@ -2330,8 +2538,12 @@ TEST-DIR which specifies the path to the tests relative to the project root." :compile "cabal build" :test "cabal test" :test-suffix "Spec") +(projectile-register-project-type 'dotnet #'projectile-dotnet-project-p + :compile "dotnet build" + :run "dotnet run" + :test "dotnet test") (projectile-register-project-type 'go projectile-go-project-test-function - :compile "go build ./..." + :compile "go build" :test "go test ./..." :test-suffix "_test") ;; File-based detection project types @@ -2395,7 +2607,7 @@ TEST-DIR which specifies the path to the tests relative to the project root." :test-prefix "test_" :test-suffix"_test") (projectile-register-project-type 'python-pip '("requirements.txt") - :compile "python setup.by build" + :compile "python setup.py build" :test "python -m unittest discover" :test-prefix "test_" :test-suffix"_test") @@ -2451,6 +2663,9 @@ TEST-DIR which specifies the path to the tests relative to the project root." :test-suffix "_test") (projectile-register-project-type 'clojure-cli '("deps.edn") :test-suffix "_test") +(projectile-register-project-type 'bloop '(".bloop") + :compile "bloop compile root" + :test "bloop test --propagate --reporter scalac root") ;; Ruby (projectile-register-project-type 'ruby-rspec '("Gemfile" "lib" "spec") :compile "bundle exec rake" @@ -2503,7 +2718,8 @@ TEST-DIR which specifies the path to the tests relative to the project root." ;; Rust (projectile-register-project-type 'rust-cargo '("Cargo.toml") :compile "cargo build" - :test "cargo test") + :test "cargo test" + :run "cargo run") ;; Racket (projectile-register-project-type 'racket '("info.rkt") @@ -2678,6 +2894,10 @@ Fallback to DEFAULT-VALUE for missing attributes." "Find default test files suffix based on PROJECT-TYPE." (projectile-project-type-attribute project-type 'test-suffix)) +(defun projectile-related-files-fn (project-type) + "Find relative file based on PROJECT-TYPE." + (projectile-project-type-attribute project-type 'related-files-fn)) + (defun projectile-src-directory (project-type) "Find default src directory based on PROJECT-TYPE." (projectile-project-type-attribute project-type 'src-dir "src/")) @@ -2710,55 +2930,66 @@ Fallback to DEFAULT-VALUE for missing attributes." (nreverse result)))) (lambda (a b) (> (car a) (car b))))) -(defun projectile-find-matching-test (file) - "Compute the name of the test matching FILE." - (let* ((basename (file-name-nondirectory (file-name-sans-extension file))) +(defun projectile--best-or-all-candidates-based-on-parents-dirs (file candidates) + "Return a list containing the best one one for FILE from CANDIDATES or all CANDIDATES." + (let ((grouped-candidates (projectile-group-file-candidates file candidates))) + (if (= (length (car grouped-candidates)) 2) + (list (car (last (car grouped-candidates)))) + (apply 'append (mapcar 'cdr grouped-candidates))))) + +(defun projectile--impl-to-test-predicate (impl-file) + "Return a predicate, which returns t for any test files for IMPL-FILE." + (let* ((basename (file-name-sans-extension (file-name-nondirectory impl-file))) (test-prefix (funcall projectile-test-prefix-function (projectile-project-type))) (test-suffix (funcall projectile-test-suffix-function (projectile-project-type))) - (candidates - (cl-remove-if-not - (lambda (current-file) - (let ((name (file-name-nondirectory - (file-name-sans-extension current-file)))) - (or (when test-prefix - (string-equal name (concat test-prefix basename))) - (when test-suffix - (string-equal name (concat basename test-suffix)))))) - (projectile-current-project-files)))) - (cond - ((null candidates) nil) - ((= (length candidates) 1) (car candidates)) - (t (let ((grouped-candidates (projectile-group-file-candidates file candidates))) - (if (= (length (car grouped-candidates)) 2) - (car (last (car grouped-candidates))) - (projectile-completing-read - "Switch to: " - (apply 'append (mapcar 'cdr grouped-candidates))))))))) + (prefix-name (when test-prefix (concat test-prefix basename))) + (suffix-name (when test-suffix (concat basename test-suffix)))) + (lambda (current-file) + (let ((name (file-name-sans-extension (file-name-nondirectory current-file)))) + (or (string-equal prefix-name name) + (string-equal suffix-name name)))))) + +(defun projectile--find-matching-test (impl-file) + "Return a list of test files for IMPL-FILE." + (if-let ((plist (projectile--related-files-plist-by-kind impl-file :test))) + (projectile--related-files-from-plist plist) + (if-let ((predicate (projectile--impl-to-test-predicate impl-file))) + (projectile--best-or-all-candidates-based-on-parents-dirs + impl-file (cl-remove-if-not predicate (projectile-current-project-files)))))) + +(defun projectile--test-to-impl-predicate (test-file) + "Return a predicate, which returns t for any impl files for TEST-FILE." + (let* ((basename (file-name-sans-extension (file-name-nondirectory test-file))) + (test-prefix (funcall projectile-test-prefix-function (projectile-project-type))) + (test-suffix (funcall projectile-test-suffix-function (projectile-project-type)))) + (lambda (current-file) + (let ((name (file-name-nondirectory (file-name-sans-extension current-file)))) + (or (when test-prefix (string-equal (concat test-prefix name) basename)) + (when test-suffix (string-equal (concat name test-suffix) basename))))))) + +(defun projectile--find-matching-file (test-file) + "Return a list of impl files tested by TEST-FILE." + (if-let ((plist (projectile--related-files-plist-by-kind test-file :impl))) + (projectile--related-files-from-plist plist) + (if-let ((predicate (projectile--test-to-impl-predicate test-file))) + (projectile--best-or-all-candidates-based-on-parents-dirs + test-file (cl-remove-if-not predicate (projectile-current-project-files)))))) + +(defun projectile--choose-from-candidates (candidates) + "Choose one item from CANDIDATES." + (if (= (length candidates) 1) + (car candidates) + (projectile-completing-read "Switch to: " candidates))) + +(defun projectile-find-matching-test (impl-file) + "Compute the name of the test matching IMPL-FILE." + (if-let ((candidates (projectile--find-matching-test impl-file))) + (projectile--choose-from-candidates candidates))) (defun projectile-find-matching-file (test-file) "Compute the name of a file matching TEST-FILE." - (let* ((basename (file-name-nondirectory (file-name-sans-extension test-file))) - (test-prefix (funcall projectile-test-prefix-function (projectile-project-type))) - (test-suffix (funcall projectile-test-suffix-function (projectile-project-type))) - (candidates - (cl-remove-if-not - (lambda (current-file) - (let ((name (file-name-nondirectory - (file-name-sans-extension current-file)))) - (or (when test-prefix - (string-equal (concat test-prefix name) basename)) - (when test-suffix - (string-equal (concat name test-suffix) basename))))) - (projectile-current-project-files)))) - (cond - ((null candidates) nil) - ((= (length candidates) 1) (car candidates)) - (t (let ((grouped-candidates (projectile-group-file-candidates test-file candidates))) - (if (= (length (car grouped-candidates)) 2) - (car (last (car grouped-candidates))) - (projectile-completing-read - "Switch to: " - (apply 'append (mapcar 'cdr grouped-candidates))))))))) + (if-let ((candidates (projectile--find-matching-file test-file))) + (projectile--choose-from-candidates candidates))) (defun projectile-grep-default-files () "Try to find a default pattern for `projectile-grep'. @@ -2799,6 +3030,128 @@ This is a subset of `grep-read-files', where either a matching entry from (format " (default %s)" default-value)))) (read-string (format "%s%s: " prefix-label default-label) nil nil default-value))) +(defvar projectile-grep-find-ignored-paths) +(defvar projectile-grep-find-unignored-paths) +(defvar projectile-grep-find-ignored-patterns) +(defvar projectile-grep-find-unignored-patterns) + +(defun projectile-rgrep-default-command (regexp files dir) + "Compute the command for \\[rgrep] to use by default. + +Extension of the Emacs 25.1 implementation of `rgrep-default-command', with +which it shares its arglist." + (require 'find-dired) ; for `find-name-arg' + (grep-expand-template + grep-find-template + regexp + (concat (shell-quote-argument "(") + " " find-name-arg " " + (mapconcat + #'shell-quote-argument + (split-string files) + (concat " -o " find-name-arg " ")) + " " + (shell-quote-argument ")")) + dir + (concat + (and grep-find-ignored-directories + (concat "-type d " + (shell-quote-argument "(") + ;; we should use shell-quote-argument here + " -path " + (mapconcat + 'identity + (delq nil (mapcar + #'(lambda (ignore) + (cond ((stringp ignore) + (shell-quote-argument + (concat "*/" ignore))) + ((consp ignore) + (and (funcall (car ignore) dir) + (shell-quote-argument + (concat "*/" + (cdr ignore))))))) + grep-find-ignored-directories)) + " -o -path ") + " " + (shell-quote-argument ")") + " -prune -o ")) + (and grep-find-ignored-files + (concat (shell-quote-argument "!") " -type d " + (shell-quote-argument "(") + ;; we should use shell-quote-argument here + " -name " + (mapconcat + #'(lambda (ignore) + (cond ((stringp ignore) + (shell-quote-argument ignore)) + ((consp ignore) + (and (funcall (car ignore) dir) + (shell-quote-argument + (cdr ignore)))))) + grep-find-ignored-files + " -o -name ") + " " + (shell-quote-argument ")") + " -prune -o ")) + (and projectile-grep-find-ignored-paths + (concat (shell-quote-argument "(") + " -path " + (mapconcat + (lambda (ignore) (shell-quote-argument + (concat "./" ignore))) + projectile-grep-find-ignored-paths + " -o -path ") + " " + (shell-quote-argument ")") + " -prune -o ")) + (and projectile-grep-find-ignored-patterns + (concat (shell-quote-argument "(") + (and (or projectile-grep-find-unignored-paths + projectile-grep-find-unignored-patterns) + (concat " " + (shell-quote-argument "("))) + " -path " + (mapconcat + (lambda (ignore) + (shell-quote-argument + (if (string-prefix-p "*" ignore) ignore + (concat "*/" ignore)))) + projectile-grep-find-ignored-patterns + " -o -path ") + (and (or projectile-grep-find-unignored-paths + projectile-grep-find-unignored-patterns) + (concat " " + (shell-quote-argument ")") + " -a " + (shell-quote-argument "!") + " " + (shell-quote-argument "(") + (and projectile-grep-find-unignored-paths + (concat " -path " + (mapconcat + (lambda (ignore) (shell-quote-argument + (concat "./" ignore))) + projectile-grep-find-unignored-paths + " -o -path "))) + (and projectile-grep-find-unignored-paths + projectile-grep-find-unignored-patterns + " -o") + (and projectile-grep-find-unignored-patterns + (concat " -path " + (mapconcat + (lambda (ignore) + (shell-quote-argument + (if (string-prefix-p "*" ignore) ignore + (concat "*/" ignore)))) + projectile-grep-find-unignored-patterns + " -o -path "))) + " " + (shell-quote-argument ")"))) + " " + (shell-quote-argument ")") + " -prune -o "))))) + ;;;###autoload (defun projectile-grep (&optional regexp arg) "Perform rgrep in the project. @@ -2825,18 +3178,26 @@ With REGEXP given, don't query the user for a regexp." (fboundp 'vc-git-grep)) (vc-git-grep search-regexp (or files "") root-dir) ;; paths for find-grep should relative and without trailing / - (let ((grep-find-ignored-directories - (cl-union (mapcar (lambda (f) (directory-file-name (file-relative-name f root-dir))) - (projectile-ignored-directories)) - grep-find-ignored-directories)) - (grep-find-ignored-files - (cl-union (append (mapcar (lambda (file) - (file-relative-name file root-dir)) - (projectile-ignored-files)) - (projectile--globally-ignored-file-suffixes-glob)) - grep-find-ignored-files))) + (let ((grep-find-ignored-files + (cl-union (projectile--globally-ignored-file-suffixes-glob) + grep-find-ignored-files)) + (projectile-grep-find-ignored-paths + (append (mapcar (lambda (f) (directory-file-name (file-relative-name f root-dir))) + (projectile-ignored-directories)) + (mapcar (lambda (file) + (file-relative-name file root-dir)) + (projectile-ignored-files)))) + (projectile-grep-find-unignored-paths + (append (mapcar (lambda (f) (directory-file-name (file-relative-name f root-dir))) + (projectile-unignored-directories)) + (mapcar (lambda (file) + (file-relative-name file root-dir)) + (projectile-unignored-files)))) + (projectile-grep-find-ignored-patterns (projectile-patterns-to-ignore)) + (projectile-grep-find-unignored-patterns (projectile-patterns-to-ensure))) (grep-compute-defaults) - (rgrep search-regexp (or files "* .*") root-dir)))) + (cl-letf (((symbol-function 'rgrep-default-command) #'projectile-rgrep-default-command)) + (rgrep search-regexp (or files "* .*") root-dir))))) (run-hooks 'projectile-grep-finished-hook))) ;;;###autoload @@ -2869,19 +3230,22 @@ regular expression." (error "Package 'ag' is not available"))) ;;;###autoload -(defun projectile-ripgrep (search-term) +(defun projectile-ripgrep (search-term &optional arg) "Run a Ripgrep search with `SEARCH-TERM' at current project root. -SEARCH-TERM is a regexp." - (interactive (list (projectile--read-search-string-with-default - "Ripgrep search for"))) +With an optional prefix argument ARG SEARCH-TERM is interpreted as a +regular expression." + (interactive + (list (projectile--read-search-string-with-default + (format "Ripgrep %ssearch for" (if current-prefix-arg "regexp " ""))) + current-prefix-arg)) (if (require 'ripgrep nil 'noerror) (let ((args (mapcar (lambda (val) (concat "--glob !" val)) (append projectile-globally-ignored-files projectile-globally-ignored-directories)))) (ripgrep-regexp search-term (projectile-project-root) - (if current-prefix-arg + (if arg args (cons "--fixed-strings" args)))) (error "Package `ripgrep' is not available"))) @@ -3116,17 +3480,22 @@ to run the replacement." (projectile-prepend-project-name (format "Replace %s with: " old-text)))) (files (projectile-files-with-string old-text directory))) - ;; Adapted from `tags-query-replace' for literal strings (not regexp) - (setq tags-loop-scan `(let ,(unless (equal old-text (downcase old-text)) - '((case-fold-search nil))) - (if (search-forward ',old-text nil t) - ;; When we find a match, move back to - ;; the beginning of it so - ;; perform-replace will see it. - (goto-char (match-beginning 0)))) - tags-loop-operate `(perform-replace ',old-text ',new-text t nil nil - nil multi-query-replace-map)) - (tags-loop-continue (or (cons 'list files) t)))) + (if (version< emacs-version "27") + ;; Adapted from `tags-query-replace' for literal strings (not regexp) + (progn + (setq tags-loop-scan `(let ,(unless (equal old-text (downcase old-text)) + '((case-fold-search nil))) + (if (search-forward ',old-text nil t) + ;; When we find a match, move back to + ;; the beginning of it so + ;; perform-replace will see it. + (goto-char (match-beginning 0)))) + tags-loop-operate `(perform-replace ',old-text ',new-text t nil nil + nil multi-query-replace-map)) + (tags-loop-continue (or (cons 'list files) t))) + (progn + (fileloop-initialize-replace old-text new-text files 'default) + (fileloop-continue))))) ;;;###autoload (defun projectile-replace-regexp (&optional arg) @@ -3267,7 +3636,7 @@ directory to open." (mapcar (lambda (f) (file-relative-name f project-root)) (cl-remove-if-not - (lambda (f) (string-prefix-p project-root f)) + (lambda (f) (string-prefix-p project-root (expand-file-name f))) recentf-list))))) (defun projectile-serialize-cache () @@ -3578,32 +3947,25 @@ If the prefix argument SHOW_PROMPT is non nil, the command can be edited." (unless (string= command executed-command) (ring-insert command-history executed-command)))) -(defadvice compilation-find-file (around projectile-compilation-find-file) +(defun compilation-find-file-projectile-find-compilation-buffer (orig-fun marker filename directory &rest formats) "Try to find a buffer for FILENAME, if we cannot find it, fallback to the original function." - (let ((filename (ad-get-arg 1)) - full-filename) - (ad-set-arg 1 - (or - (if (file-exists-p (expand-file-name filename)) - filename) - ;; Try to find the filename using projectile - (and (projectile-project-p) - (let ((root (projectile-project-root)) - (dirs (cons "" (projectile-current-project-dirs)))) - (when (setq full-filename - (car (cl-remove-if-not - #'file-exists-p - (mapcar - (lambda (f) - (expand-file-name - filename - (expand-file-name f root))) - dirs)))) - full-filename))) - ;; Fall back to the old argument - filename)) - ad-do-it)) + (when (and (not (file-exists-p (expand-file-name filename))) + (projectile-project-p)) + (let* ((root (projectile-project-root)) + (dirs (cons "" (projectile-current-project-dirs))) + (new-filename (car (cl-remove-if-not + #'file-exists-p + (mapcar + (lambda (f) + (expand-file-name + filename + (expand-file-name f root))) + dirs))))) + (when new-filename + (setq filename new-filename)))) + + (apply orig-fun `(,marker ,filename ,directory ,@formats))) (defun projectile-open-projects () "Return a list of all open projects. @@ -4288,7 +4650,8 @@ tramp." (unless (file-remote-p default-directory) (when projectile-dynamic-mode-line (projectile-update-mode-line)) - (projectile-cache-files-find-file-hook) + (when projectile-auto-update-cache + (projectile-cache-files-find-file-hook)) (projectile-track-known-projects-find-file-hook) (projectile-visit-project-tags-table))) @@ -4330,13 +4693,13 @@ Otherwise behave as if called interactively. (add-hook 'find-file-hook 'projectile-find-file-hook-function) (add-hook 'projectile-find-dir-hook #'projectile-track-known-projects-find-file-hook t) (add-hook 'dired-before-readin-hook #'projectile-track-known-projects-find-file-hook t t) - (ad-activate 'compilation-find-file) - (ad-activate 'delete-file)) + (advice-add 'compilation-find-file :around #'compilation-find-file-projectile-find-compilation-buffer) + (advice-add 'delete-file :before #'delete-file-projectile-remove-from-cache)) (t (remove-hook 'find-file-hook #'projectile-find-file-hook-function) (remove-hook 'dired-before-readin-hook #'projectile-track-known-projects-find-file-hook t) - (ad-deactivate 'compilation-find-file) - (ad-deactivate 'delete-file)))) + (advice-remove 'compilation-find-file #'compilation-find-file-projectile-find-compilation-buffer) + (advice-remove 'delete-file #'delete-file-projectile-remove-from-cache)))) ;;;###autoload (define-obsolete-function-alias 'projectile-global-mode 'projectile-mode "1.0") diff --git a/packages/projectile-rails-20181009.1317.el b/packages/projectile-rails-20190706.1231.el similarity index 96% rename from packages/projectile-rails-20181009.1317.el rename to packages/projectile-rails-20190706.1231.el index 2769f73..07efec9 100644 --- a/packages/projectile-rails-20181009.1317.el +++ b/packages/projectile-rails-20190706.1231.el @@ -4,8 +4,8 @@ ;; Author: Adam Sokolnicki ;; URL: https://github.com/asok/projectile-rails -;; Package-Version: 20181009.1317 -;; Version: 0.15.0 +;; Package-Version: 20190706.1231 +;; Version: 0.18.0 ;; Keywords: rails, projectile ;; Package-Requires: ((emacs "24.3") (projectile "0.12.0") (inflections "1.1") (inf-ruby "2.2.6") (f "0.13.0") (rake "0.3.2")) @@ -252,6 +252,31 @@ :group 'projectile-rails :type 'string) +(defcustom projectile-rails-custom-console-command nil + "When set it will be use instead of a preloader as the command for running console." + :group 'projectile-rails + :type 'string) + +(defcustom projectile-rails-custom-server-command nil + "When set it will be use instead of a preloader as the command for running server." + :group 'projectile-rails + :type 'string) + +(defcustom projectile-rails-custom-generate-command nil + "When set it will be use instead of a preloader as the command for running generate." + :group 'projectile-rails + :type 'string) + +(defcustom projectile-rails-custom-destroy-command nil + "When set it will be use instead of a preloader as the command for running destroy." + :group 'projectile-rails + :type 'string) + +(defcustom projectile-rails-expand-snippet-with-magic-comment nil + "When t the new file snippets will be expanded with the magic comment 'frozen_string_literal: true'. " + :group 'projectile-rails + :type 'boolean) + (defvar projectile-rails-extracted-region-snippet '(("erb" . "<%%= render '%s' %%>") ("haml" . "= render '%s'") @@ -282,18 +307,24 @@ ("scaffold" (("app/models/" "app/models/\\(.+\\)\\.rb$"))) ("task" (("lib/tasks/" "lib/tasks/\\(.+\\)\\.rake$"))))) -(defmacro projectile-rails-with-preloader (&rest cases) +(defun projectile-rails--command (&rest cases) "Checks for the presence of pre-loaders and returns corresponding value. CASES is a plist with props being :spring, :zeus or :vanilla. Each corresponds to a preloader (:vanilla means no preloader). If a preloader is running the value for the given prop is returned." - `(cond ((projectile-rails-spring-p) - ,(plist-get cases :spring)) - ((projectile-rails-zeus-p) - ,(plist-get cases :zeus)) - (t - ,(plist-get cases :vanilla)))) + (let ((custom-command (plist-get cases :custom))) + (cond + (custom-command + (projectile-rails--ensure-suffix custom-command " ")) + ((projectile-rails-spring-p) + (plist-get cases :spring)) + ((projectile-rails-zeus-p) + (plist-get cases :zeus)) + (t + (plist-get cases :vanilla))))) + +(defalias 'projectile-rails-with-preloader 'projectile-rails--command) (defmacro projectile-rails-with-root (body-form) "Run BODY-FORM within DEFAULT-DIRECTORY set to `projectile-rails-root'" @@ -414,6 +445,7 @@ The bound variable is \"filename\"." (projectile-completing-read ,prompt (projectile-rails-hash-keys choices)) (user-error "The completion system you're using does not allow inputting arbitrary value."))) (filepath (gethash filename choices))) + (if filepath (projectile-rails-goto-file filepath) (when ,newfile-template @@ -529,8 +561,7 @@ The bound variable is \"filename\"." (interactive) (projectile-rails-find-resource "component: " - `((,projectile-rails-component-dir - ,(concat projectile-rails-component-dir "\\(.+\\.[^.]+\\)$"))))) + `((,projectile-rails-component-dir "\\(.+\\.[^.]+\\)$")))) (defun projectile-rails-find-stylesheet () "Find a stylesheet file." @@ -661,7 +692,7 @@ The bound variable is \"filename\"." (interactive) (projectile-rails-find-current-resource (first projectile-rails-fixture-dirs) - "\\(?:test\\|spec\\)/\\(?:fixtures\\|factories\\|fabricators\\)/\\(?:${singular}\\(?:_fabricator\\)?\\|${plural}\\)\\.\\(?:yml\\|rb\\)" + "\\(?:${singular}\\(?:_fabricator\\)?\\|${plural}\\)\\.\\(?:yml\\|rb\\)" 'projectile-rails-find-fixture)) (defun projectile-rails-find-current-migration () @@ -776,7 +807,8 @@ The mode of the output buffer will be `projectile-rails-compilation-mode'." "Start a rails console, asking for which if ARG is not nil." (interactive "P") (projectile-rails-with-root - (let ((rails-console-command (projectile-rails-with-preloader + (let ((rails-console-command (projectile-rails--command + :custom projectile-rails-custom-console-command :spring (concat projectile-rails-spring-command " rails console") :zeus "zeus console" :vanilla (concat projectile-rails-vanilla-command " console")))) @@ -854,7 +886,8 @@ The buffer for interacting with SQL client is created via `sql-product-interacti (sqli-options (sql-get-product-feature product :sqli-options)) (sqli-program (sql-get-product-feature product :sqli-program)) (sql-comint-func (sql-get-product-feature product :sqli-comint-func)) - (commands (s-split " " (projectile-rails-with-preloader + (commands (s-split " " (projectile-rails--command + :custom projectile-rails-custom-dbconsole-command :spring (concat projectile-rails-spring-command " rails dbconsole") :zeus (concat projectile-rails-zeus-command " dbconsole") :vanilla (concat projectile-rails-vanilla-command " dbconsole"))))) @@ -903,6 +936,10 @@ This only works when yas package is installed." (defun projectile-rails--expand-snippet (snippet) "Turn on `yas-minor-mode' and expand SNIPPET." (yas-minor-mode +1) + + (when projectile-rails-expand-snippet-with-magic-comment + (setq snippet (format "# frozen_string_literal: true\n\n%s" snippet))) + (yas-expand-snippet snippet)) (defun projectile-rails-expand-corresponding-snippet () @@ -1058,9 +1095,10 @@ Will try to look for a template or partial file, and assets file." (if (member projectile-rails-server-buffer-name (mapcar 'buffer-name (buffer-list))) (switch-to-buffer projectile-rails-server-buffer-name) (projectile-rails-with-root - (compile (projectile-rails-with-preloader :spring (concat projectile-rails-spring-command " rails server") - :zeus (concat projectile-rails-zeus-command " server") - :vanilla (concat projectile-rails-vanilla-command " server")) + (compile (projectile-rails--command :spring (concat projectile-rails-spring-command " rails server") + :zeus (concat projectile-rails-zeus-command " server") + :vanilla (concat projectile-rails-vanilla-command " server") + :custom projectile-rails-custom-server-command) 'projectile-rails-server-mode)))) (defun projectile-rails--completion-in-region () @@ -1079,7 +1117,8 @@ Will try to look for a template or partial file, and assets file." "Runs rails generate command" (interactive) (projectile-rails-with-root - (let ((command-prefix (projectile-rails-with-preloader + (let ((command-prefix (projectile-rails--command + :custom projectile-rails-custom-generate-command :spring (concat projectile-rails-spring-command " rails generate ") :zeus (concat projectile-rails-zeus-command " generate ") :vanilla (concat projectile-rails-vanilla-command " generate ")))) @@ -1110,7 +1149,8 @@ Will try to look for a template or partial file, and assets file." "Runs rails destroy command." (interactive) (projectile-rails-with-root - (let ((command-prefix (projectile-rails-with-preloader + (let ((command-prefix (projectile-rails--command + :custom projectile-rails-custom-destroy-command :spring (concat projectile-rails-spring-command " rails destroy ") :zeus (concat projectile-rails-zeus-command " destroy ") :vanilla (concat projectile-rails-vanilla-command " destroy ")))) @@ -1388,7 +1428,10 @@ If file does not exist and ASK in not nil it will ask user to proceed." name) (defun projectile-rails-sanitize-dir-name (name) - (if (s-ends-with? "/" name) name (concat name "/"))) + (projectile-rails--ensure-suffix name "/")) + +(defun projectile-rails--ensure-suffix (name suffix) + (if (s-ends-with? suffix name) name (concat name suffix))) (defun projectile-rails-current-line () (save-excursion diff --git a/packages/proof-general-20181115.1610.tar b/packages/proof-general-20190821.848.tar similarity index 93% rename from packages/proof-general-20181115.1610.tar rename to packages/proof-general-20190821.848.tar index d9fdb6c..557a4f8 100644 Binary files a/packages/proof-general-20181115.1610.tar and b/packages/proof-general-20190821.848.tar differ diff --git a/packages/psc-ide-20181002.1319.tar b/packages/psc-ide-20190326.2110.tar similarity index 79% rename from packages/psc-ide-20181002.1319.tar rename to packages/psc-ide-20190326.2110.tar index adf4388..2da55d2 100644 Binary files a/packages/psc-ide-20181002.1319.tar and b/packages/psc-ide-20190326.2110.tar differ diff --git a/packages/psci-20180418.1233.tar b/packages/psci-20190308.24.tar similarity index 79% rename from packages/psci-20180418.1233.tar rename to packages/psci-20190308.24.tar index d620949..889fc8a 100644 Binary files a/packages/psci-20180418.1233.tar and b/packages/psci-20190308.24.tar differ diff --git a/packages/purescript-mode-20181028.838.tar b/packages/purescript-mode-20190522.2230.tar similarity index 91% rename from packages/purescript-mode-20181028.838.tar rename to packages/purescript-mode-20190522.2230.tar index b0d72b2..90c2374 100644 Binary files a/packages/purescript-mode-20181028.838.tar and b/packages/purescript-mode-20190522.2230.tar differ diff --git a/packages/pyim-20181109.1350.tar b/packages/pyim-20181109.1350.tar deleted file mode 100644 index bbdf6b9..0000000 Binary files a/packages/pyim-20181109.1350.tar and /dev/null differ diff --git a/packages/pyim-20190820.835.tar b/packages/pyim-20190820.835.tar new file mode 100644 index 0000000..6ad2c10 Binary files /dev/null and b/packages/pyim-20190820.835.tar differ diff --git a/packages/pyim-basedict-20170727.259.tar b/packages/pyim-basedict-20190719.1252.tar similarity index 91% rename from packages/pyim-basedict-20170727.259.tar rename to packages/pyim-basedict-20190719.1252.tar index 2b569b7..c07fd42 100644 Binary files a/packages/pyim-basedict-20170727.259.tar and b/packages/pyim-basedict-20190719.1252.tar differ diff --git a/packages/pythonic-20180920.2315.el b/packages/pythonic-20190725.1258.el similarity index 91% rename from packages/pythonic-20180920.2315.el rename to packages/pythonic-20190725.1258.el index 7e13c22..447c904 100644 --- a/packages/pythonic-20180920.2315.el +++ b/packages/pythonic-20190725.1258.el @@ -1,10 +1,10 @@ ;;; pythonic.el --- Utility functions for writing pythonic emacs package. -*- lexical-binding: t; -*- -;; Copyright (C) 2015-2018 by Artem Malyshev +;; Copyright (C) 2015-2019 by Artem Malyshev ;; Author: Artem Malyshev ;; URL: https://github.com/proofit404/pythonic -;; Package-Version: 20180920.2315 +;; Package-Version: 20190725.1258 ;; Version: 0.1.1 ;; Package-Requires: ((emacs "25") (s "1.9") (f "0.17.2")) @@ -33,6 +33,10 @@ (require 's) (require 'f) +(defgroup pythonic nil + "Utility functions for writing pythonic emacs package." + :group 'python) + ;;; Connection predicates. @@ -154,7 +158,15 @@ format." ;;; Docker Compose. -(defvar pythonic-docker-compose-filename "docker-compose.yml") +(defcustom pythonic-docker-compose-filename "docker-compose.yml" + "File name of the docker-compose project file." + :type 'string + :safe 'stringp) + +(defcustom pythonic-docker-compose-service-name nil + "Name of the default service to execute commands." + :type 'string + :safe 'stringp) (defvar pythonic-read-docker-compose-file-code " from __future__ import print_function @@ -209,6 +221,7 @@ print(json.dumps(yaml.safe_load(open(sys.argv[-1], 'r')))) (defun pythonic-set-docker-compose-alias () "Build alias string for current docker-compose project." + (hack-dir-local-variables-non-file-buffer) (unless (or (tramp-tramp-file-p default-directory) (pythonic-has-alias-p default-directory)) @@ -221,7 +234,11 @@ print(json.dumps(yaml.safe_load(open(sys.argv[-1], 'r')))) ;; should appears once in the selection and all volumes ;; should be added to the alias list. (volume (if (< 1 (length volumes)) - (assoc (completing-read "Service: " (mapcar 'car volumes) nil t) volumes) + (assoc + (if pythonic-docker-compose-service-name + pythonic-docker-compose-service-name + (completing-read "Service: " (mapcar 'car volumes) nil t)) + volumes) (car volumes))) (service (car volume)) (sub-project (f-join project (cadr volume))) @@ -237,16 +254,20 @@ print(json.dumps(yaml.safe_load(open(sys.argv[-1], 'r')))) ;;; Processes. +(defvar pythonic-interpreter python-shell-interpreter + "Interpreter to use for pythonic process calls.") + (cl-defun pythonic-call-process (&key file buffer display args cwd) "Pythonic wrapper around `call-process'. FILE is the input file. BUFFER is the output destination. DISPLAY specifies to redisplay BUFFER on new output. ARGS is the list of + arguments passed to `call-process'. CWD will be working directory for running process." (let ((default-directory (pythonic-aliased-path (or cwd default-directory)))) (python-shell-with-environment - (apply 'process-file python-shell-interpreter file buffer display args)))) + (apply 'process-file pythonic-interpreter file buffer display args)))) (cl-defun pythonic-start-process (&key process buffer args cwd filter sentinel (query-on-exit t)) "Pythonic wrapper around `start-process'. @@ -260,7 +281,7 @@ function if necessary. QUERY-ON-EXIT will be corresponding process flag." (let ((default-directory (pythonic-aliased-path (or cwd default-directory)))) (python-shell-with-environment - (let ((process (apply 'start-file-process process buffer python-shell-interpreter args))) + (let ((process (apply 'start-file-process process buffer pythonic-interpreter args))) (when filter (set-process-filter process filter)) (when sentinel diff --git a/packages/pyvenv-20180831.847.el b/packages/pyvenv-20181228.1722.el similarity index 98% rename from packages/pyvenv-20180831.847.el rename to packages/pyvenv-20181228.1722.el index 33d388a..9675df4 100644 --- a/packages/pyvenv-20180831.847.el +++ b/packages/pyvenv-20181228.1722.el @@ -4,8 +4,8 @@ ;; Author: Jorgen Schaefer ;; URL: http://github.com/jorgenschaefer/pyvenv -;; Package-Version: 20180831.847 -;; Version: 1.18 +;; Package-Version: 20181228.1722 +;; Version: 1.20 ;; Keywords: Python, Virtualenv, Tools ;; This program is free software; you can redistribute it and/or @@ -288,16 +288,15 @@ This is usually the base name of `pyvenv-virtual-env'.") ;;;###autoload (defun pyvenv-workon (name) - "Activate a virtual environment from $WORKON_HOME." + "Activate a virtual environment from $WORKON_HOME. + +If the virtual environment NAME is already active, this function +does not try to reactivate the environment." (interactive (list (completing-read "Work on: " (pyvenv-virtualenv-list) nil t nil 'pyvenv-workon-history nil nil))) - (when (not (or (equal name "") - ;; Some completion frameworks can return nil for the - ;; default, see - ;; https://github.com/jorgenschaefer/elpy/issues/144 - (equal name nil))) + (unless (member name (list "" nil pyvenv-virtual-env-name)) (pyvenv-activate (format "%s/%s" (pyvenv-workon-home) name)))) diff --git a/packages/racer-20181023.2304.el b/packages/racer-20190610.800.el similarity index 78% rename from packages/racer-20181023.2304.el rename to packages/racer-20190610.800.el index 74b0bc9..eec185d 100644 --- a/packages/racer-20181023.2304.el +++ b/packages/racer-20190610.800.el @@ -4,7 +4,7 @@ ;; Author: Phil Dawes ;; URL: https://github.com/racer-rust/emacs-racer -;; Package-Version: 20181023.2304 +;; Package-Version: 20190610.800 ;; Version: 1.3 ;; Package-Requires: ((emacs "24.3") (rust-mode "0.2.0") (dash "2.13.0") (s "1.10.0") (f "0.18.2") (pos-tip "0.4.6")) ;; Keywords: abbrev, convenience, matching, rust, tools @@ -69,7 +69,7 @@ (require 'thingatpt) (require 'button) (require 'help-mode) -(require 'pos-tip) +(autoload 'pos-tip-show-no-propertize "pos-tip") (defgroup racer nil "Code completion, goto-definition and docs browsing for Rust via racer." @@ -228,30 +228,55 @@ Evaluate BODY, then delete the temporary file." (insert-file-contents-literally file) (buffer-string))) +(defmacro racer--with-temp-buffers (stdout-sym stderr-sym &rest body) + (declare (indent 2) (debug (symbolp body))) + `(let ((kill-buffer-query-functions nil) + (,stdout-sym (generate-new-buffer " *racer-stdout*")) + (,stderr-sym (generate-new-buffer " *racer-stderr*"))) + (unwind-protect + (progn ,@body) + (when (buffer-name ,stdout-sym) + (kill-buffer ,stdout-sym)) + (when (buffer-name ,stderr-sym) + (kill-buffer ,stderr-sym))))) + +(defcustom racer-command-timeout nil + "Abandon completion if racer process fails to respond for that +many seconds (maybe float). nil means wait indefinitely." + :type 'number + :group 'racer) + (defun racer--shell-command (program args) - "Execute PROGRAM with ARGS. -Return a list (exit-code stdout stderr)." - (racer--with-temporary-file tmp-file-for-stderr - (let (exit-code stdout stderr) - ;; Create a temporary buffer for `call-process` to write stdout - ;; into. - (with-temp-buffer - (setq exit-code - (apply #'call-process program nil - (list (current-buffer) tmp-file-for-stderr) - nil args)) - (setq stdout (buffer-string))) - (setq stderr (racer--slurp tmp-file-for-stderr)) + "Execute PROGRAM with ARGS. Return a list (exit-code stdout +stderr)." + (racer--with-temp-buffers stdout stderr + (let (exit-code + stdout-result + stderr-result + (proc (make-process :name "*async-racer*" + :buffer stdout + :command (cons program args) + :connection-type 'pipe + :stderr stderr))) + (while + (and (process-live-p proc) + (with-local-quit + (accept-process-output proc racer-command-timeout)))) + (when (process-live-p proc) (kill-process proc)) + (setq exit-code (process-exit-status proc) + stderr-result (with-current-buffer stderr (buffer-string)) + stdout-result (with-current-buffer stdout (buffer-string))) (setq racer--prev-state (list :program program :args args :exit-code exit-code - :stdout stdout - :stderr stderr + :stdout stdout-result + :stderr stderr-result :default-directory default-directory :process-environment process-environment)) - (list exit-code stdout stderr)))) + (list exit-code stdout-result stderr-result)))) + (defun racer--call-at-point (command) "Call racer command COMMAND at point of current buffer. @@ -275,15 +300,19 @@ Return a list of all the lines returned by the command." (defun racer--read-rust-string (string) "Convert STRING, a rust string literal, to an elisp string." (when string - (->> string - ;; Remove outer double quotes. - (s-chop-prefix "\"") - (s-chop-suffix "\"") - ;; Replace escaped characters. - (s-replace "\\n" "\n") - (s-replace "\\\"" "\"") - (s-replace "\\'" "'") - (s-replace "\\;" ";")))) + ;; Remove outer double quotes. + (setq string (s-chop-prefix "\"" string)) + (setq string (s-chop-suffix "\"" string)) + ;; Translate escape sequences. + (replace-regexp-in-string + (rx "\\" (group anything)) + (lambda (whole-match) + (let ((escaped-char (match-string 1 whole-match))) + (if (equal escaped-char "n") + "\n" + escaped-char))) + string + t t))) (defun racer--split-parts (raw-output) "Given RAW-OUTPUT from racer, split on semicolons and doublequotes. @@ -320,10 +349,18 @@ split it into its constituent parts." :signature (nth 6 match-parts) :docstring (if (> (length docstring) 0) docstring nil))))) +(defun racer--order-descriptions (descriptions) + (sort descriptions + (lambda (a b) + (let ((a (or (plist-get a :docstring) "")) + (b (or (plist-get b :docstring) ""))) + (> (length a) (length b)))))) + (defun racer--describe-at-point (name) - "Get a description of the symbol at point matching NAME. -If there are multiple possibilities with this NAME, prompt -the user to choose." + "Get a descriptions of the symbols matching symbol at point and +NAME. If there are multiple possibilities with this NAME, prompt +the user to choose. Return a list of all possibilities that +start with the user's selection." (let* ((output-lines (save-excursion ;; Move to the end of the current symbol, to ;; increase racer accuracy. @@ -334,14 +371,20 @@ the user to choose." output-lines)) (relevant-matches (--filter (equal (plist-get it :name) name) all-matches))) - (if (> (length relevant-matches) 1) - ;; We might have multiple matches with the same name but - ;; different types. E.g. Vec::from. - (let ((signature - (completing-read "Multiple matches: " - (--map (plist-get it :signature) relevant-matches)))) - (--first (equal (plist-get it :signature) signature) relevant-matches)) - (-first-item relevant-matches)))) + (racer--order-descriptions + (if (> (length relevant-matches) 1) + ;; We might have multiple matches with the same name but + ;; different types. E.g. Vec::from. + (let ((signature + (completing-read "Multiple matches: " + (--map (plist-get it :signature) relevant-matches)))) + (-filter + (lambda (x) + (let ((sig (plist-get x :signature))) + (equal (substring sig 0 (min (length sig) (length signature))) + signature))) + relevant-matches)) + relevant-matches)))) (defun racer--help-buf (contents) "Create a *Racer Help* buffer with CONTENTS." @@ -381,7 +424,8 @@ the user to choose." (racer--url-button link-text link-target) ;; Otherwise, just discard the target. link-text))) - markdown)) + markdown + t t)) (defun racer--propertize-all-inline-code (markdown) "Given a single line MARKDOWN, replace all instances of `foo` or @@ -389,13 +433,18 @@ the user to choose." (let ((highlight-group (lambda (whole-match) (racer--syntax-highlight (match-string 1 whole-match))))) - (->> markdown - (replace-regexp-in-string - (rx "[`" (group (+? anything)) "`]") - highlight-group) - (replace-regexp-in-string - (rx "`" (group (+? anything)) "`") - highlight-group)))) + (setq markdown + (replace-regexp-in-string + (rx "[`" (group (+? anything)) "`]") + highlight-group + markdown + t t)) + (setq markdown + (replace-regexp-in-string + (rx "`" (group (+? anything)) "`") + highlight-group + markdown + t t)))) (defun racer--indent-block (str) "Indent every line in STR." @@ -542,29 +591,39 @@ For example, 'EnumKind' -> 'an enum kind'." "Return a *Racer Help* buffer for the function or type at point. If there are multiple candidates at point, use NAME to find the correct value." - (let ((description (racer--describe-at-point name))) - (when description - (let* ((name (plist-get description :name)) - (raw-docstring (plist-get description :docstring)) - (docstring (if raw-docstring - (racer--propertize-docstring raw-docstring) - "Not documented.")) - (kind (plist-get description :kind))) - (racer--help-buf - (format - "%s is %s defined in %s.\n\n%s%s" - name - (racer--kind-description kind) - (racer--src-button - (plist-get description :path) - (plist-get description :line) - (plist-get description :column)) - (if (equal kind "Module") - ;; No point showing the 'signature' of modules, which is - ;; just their full path. - "" - (format " %s\n\n" (racer--syntax-highlight (plist-get description :signature)))) - docstring)))))) + (let ((descriptions (racer--describe-at-point name))) + (when descriptions + (racer--help-buf + (let ((output "") + (first-iteration t)) + (dolist (description descriptions output) + (unless first-iteration + (setf output + (concat output (format "\n---------------------------------------------------------------\n")))) + (setf output + (concat + output + (let* ((name (plist-get description :name)) + (raw-docstring (plist-get description :docstring)) + (docstring (if raw-docstring + (racer--propertize-docstring raw-docstring) + "Not documented.")) + (kind (plist-get description :kind))) + (setf first-iteration nil) + (format + "%s is %s defined in %s.\n\n%s%s" + name + (racer--kind-description kind) + (racer--src-button + (plist-get description :path) + (plist-get description :line) + (plist-get description :column)) + (if (equal kind "Module") + ;; No point showing the 'signature' of modules, which is + ;; just their full path. + "" + (format " %s\n\n" (racer--syntax-highlight (plist-get description :signature)))) + docstring)))))))))) (defun racer-describe () "Show a *Racer Help* buffer for the function or type at point." @@ -612,6 +671,13 @@ Commands: :type 'boolean :group 'racer) +(defcustom racer-complete-insert-argument-placeholders + t + "If non-nil, insert argument placeholders after completion. +Note that this feature is only available when `company-mode' is installed." + :type 'boolean + :group 'racer) + (defun racer-complete-at-point () "Complete the symbol at point." (let* ((ppss (syntax-ppss)) @@ -632,32 +698,37 @@ Commands: :company-location #'racer-complete--location :exit-function #'racer-complete--insert-args))))) +(declare-function company-template-c-like-templatify 'company-template) + (defun racer-complete--insert-args (arg &optional _finished) "If a ARG is the name of a completed function, try to find and insert its arguments." - (let ((matchtype (get-text-property 0 'matchtype arg))) - (if (equal matchtype "Function") - (let* ((ctx (get-text-property 0 'ctx arg)) - (arguments (racer-complete--extract-args ctx))) - (insert arguments) - (company-template-c-like-templatify arguments))))) + (when (and racer-complete-insert-argument-placeholders + (require 'company-template nil t) + (equal "Function" + (get-text-property 0 'matchtype arg)) + ;; Don't add arguments if the user has already added + ;; some. + (not (eq (char-after) ?\())) + (let* ((ctx (get-text-property 0 'ctx arg)) + (arguments (racer-complete--extract-args ctx))) + (insert arguments) + (company-template-c-like-templatify arguments)))) (defun racer-complete--extract-args (str) "Extract function arguments from STR (excluding a possible self argument)." - (let* ((index (string-match - (rx - (or (seq "(" - (zero-or-more (not (any ","))) - "self)") - (seq "(" - (zero-or-more (seq (zero-or-more (not (any "("))) - "self" - (zero-or-more space) - ",")) - (zero-or-more space) - (group (zero-or-more (not (any ")")))) - ")"))) - str)) - (extract (match-string 1 str))) + (string-match + (rx + (or (seq "(" (zero-or-more (not (any ","))) "self)") + (seq "(" + (zero-or-more (seq (zero-or-more (not (any "("))) + "self" + (zero-or-more space) + ",")) + (zero-or-more space) + (group (zero-or-more (not (any ")")))) + ")"))) + str) + (let ((extract (match-string 1 str))) (if extract (format "(%s)" extract) "()"))) @@ -744,17 +815,20 @@ Commands: ;;;###autoload (defun racer-find-definition () "Run the racer find-definition command and process the results." - (interactive (racer--find-definition #'find-file))) + (interactive) + (racer--find-definition #'find-file)) ;;;###autoload (defun racer-find-definition-other-window () "Run the racer find-definition command and process the results." - (interactive (racer--find-definition #'find-file-other-window))) + (interactive) + (racer--find-definition #'find-file-other-window)) ;;;###autoload (defun racer-find-definition-other-frame () "Run the racer find-definition command and process the results." - (interactive (racer--find-definition #'find-file-other-frame))) + (interactive) + (racer--find-definition #'find-file-other-frame)) (defun racer--syntax-highlight (str) "Apply font-lock properties to a string STR of Rust code." @@ -769,13 +843,20 @@ Commands: (with-no-warnings (font-lock-fontify-buffer))) (setq result (buffer-string))) - (when (and - ;; If we haven't applied any properties yet, - (null (text-properties-at 0 result)) - ;; and if it's a standalone symbol, then assume it's a - ;; variable. - (string-match-p (rx bos (+ (any lower "_")) eos) str)) - (setq result (propertize str 'face 'font-lock-variable-name-face))) + + ;; If we haven't applied any text properties yet, apply some + ;; heuristics to try to find an appropriate colour. + (when (null (text-properties-at 0 result)) + (cond + ;; If it's a standalone symbol, then assume it's a + ;; variable. + ((string-match-p (rx bos (+ (any lower "_")) eos) str) + (setq result (propertize str 'face 'font-lock-variable-name-face))) + ;; If it starts with a backslash, treat it as a string. See + ;; .lines() on strings. + ((string-match-p (rx bos "\\") str) + (setq result (propertize str 'face 'font-lock-string-face))))) + result)) (defun racer--goto-func-name () @@ -803,13 +884,20 @@ If PATH is not in DIRECTORY, just abbreviate it." (concat "./" (f-relative path directory)) (f-abbrev path))) +(defcustom racer-eldoc-timeout 0.5 + "Abandon Eldoc hinting if racer process fails to respond for +that many seconds (maybe float)." + :type 'number + :group 'racer) + (defun racer-eldoc () "Show eldoc for context at point." (save-excursion (racer--goto-func-name) ;; If there's a variable at point: (-when-let* ((rust-sym (symbol-at-point)) - (comp-possibilities (racer-complete)) + (comp-possibilities (let ((racer-command-timeout racer-eldoc-timeout)) + (racer-complete))) (matching-possibility (--find (string= it (symbol-name rust-sym)) comp-possibilities)) (prototype (get-text-property 0 'ctx matching-possibility)) diff --git a/packages/racket-mode-20181117.229.tar b/packages/racket-mode-20190803.1820.tar similarity index 76% rename from packages/racket-mode-20181117.229.tar rename to packages/racket-mode-20190803.1820.tar index b40de91..c4df680 100644 Binary files a/packages/racket-mode-20181117.229.tar and b/packages/racket-mode-20190803.1820.tar differ diff --git a/packages/ranger-20170817.1557.el b/packages/ranger-20190412.624.el similarity index 82% rename from packages/ranger-20170817.1557.el rename to packages/ranger-20190412.624.el index 4e3685e..c6e3b4e 100644 --- a/packages/ranger-20170817.1557.el +++ b/packages/ranger-20190412.624.el @@ -1,9 +1,9 @@ ;;; ranger.el --- Make dired more like ranger -*- lexical-binding: t -*- -;; Copyright (C) 2015 Rich Alesi +;; Copyright (C) 2015-2017 Rich Alesi ;; Author : Rich Alesi -;; Version: 0.9.8.5 -;; Package-Version: 20170817.1557 +;; Version: 0.9.8.6 +;; Package-Version: 20190412.624 ;; Keywords: files, convenience, dired ;; Homepage: https://github.com/ralesi/ranger ;; Package-Requires: ((emacs "24.4")) @@ -105,21 +105,42 @@ :group 'ranger :type 'boolean) -(defcustom ranger-show-hidden t +(defcustom ranger-show-hidden 'hidden "When t it will show hidden files in directory." :group 'ranger - :type 'boolean) + :type '(radio (const :tag "Show All Files" :value 'format) + (const :tag "Hide Common Files" :value 'prefer) + (const :tag "Hide All Dotfiles" :value 'hidden))) + +(defcustom ranger-format-regexp + '("^\\.?#\\|^\\.$\\|^\\.\\.$") + "Regexp of filenames to hide." + :group 'ranger + :type 'list) (defcustom ranger-hidden-regexp - "^\\." + '("^\\.") "Regexp of filenames to hide." :group 'ranger - :type 'string) + :type 'list) -(defcustom ranger-omit-regexp "^\\.?#\\|^\\.$\\|^\\.\\.$" - "Regexp of omitted filetypes in ranger." +(defcustom ranger-prefer-regexp + '( + ;; vcs folders + "^\\.\\(git\\|hg\\|svn\\)$" + ;; compiled files + "\\.\\(pyc\\|o\\|elc\\|lock\\|css.map\\)$" + ;; generated files, caches or local pkgs + "^\\(node_modules\\|vendor\\|.\\(project\\|cask\\|yardoc\\|sass-cache\\)\\)$" + ;; org-mode folders + "^\\.\\(sync\\|export\\|attach\\)$" + ;; backup files + "~$" + "^#.*#$" + ) + "Regexp of custom filetypes to omit in ranger." :group 'ranger - :type 'string) + :type 'list) (defcustom ranger-history-length 30 "Length of history ranger will track." @@ -163,7 +184,7 @@ :group 'ranger :type 'boolean) -(defcustom ranger-listing-switches "-alGh" +(defcustom ranger-listing-switches "-alhF" "Default listing switchs for dired buffer." :group 'ranger :type 'string) @@ -429,9 +450,11 @@ Selective hiding of specific attributes can be controlled by MASK." (setq next (dired-move-to-filename)))))) (defun ranger-mask-show-details () + (interactive) (ranger-mask-details ranger-dired-display-mask)) (defun ranger-mask-hide-details () + (interactive) (ranger-mask-details ranger-dired-hide-mask)) (defun ranger-truncate () @@ -449,120 +472,120 @@ Selective hiding of specific attributes can be controlled by MASK." (defvar ranger-normal-mode-map (let ((map (make-sparse-keymap))) ;; basics - (define-key map "?" 'ranger-help) - (define-key map "du" 'ranger-show-size) - (define-key map "q" 'ranger-close) - ;; (define-key map (kbd "") 'ranger-close) - (define-key map "ZZ" 'ranger-close) - (define-key map "Q" 'ranger-disable) - (define-key map "ZQ" 'ranger-disable) - (define-key map (kbd "C-r") 'ranger-refresh) + (define-key map "?" 'ranger-help) + (define-key map "du" 'ranger-show-size) + (define-key map "q" 'ranger-close) + ;; (define-key map (kbd "") 'ranger-close) + (define-key map "ZZ" 'ranger-close) + (define-key map "Q" 'ranger-disable) + (define-key map "ZQ" 'ranger-disable) + (define-key map (kbd "C-r") 'ranger-refresh) ;; bookmarks - (define-key map (kbd "`") 'ranger-goto-mark) - (define-key map (kbd "'") 'ranger-goto-mark) - (define-key map "B" 'ranger-show-bookmarks) - (define-key map "m" 'ranger-create-mark) - (define-key map "um" 'ranger-remove-mark) + (define-key map (kbd "`") 'ranger-goto-mark) + (define-key map (kbd "'") 'ranger-goto-mark) + (define-key map "B" 'ranger-show-bookmarks) + (define-key map "m" 'ranger-create-mark) + (define-key map "um" 'ranger-remove-mark) ;; marking - (define-key map "v" 'dired-toggle-marks) - (define-key map (kbd "C-SPC") 'ranger-mark) - (define-key map (kbd "TAB") 'ranger-mark) - (define-key map (kbd "\"") 'dired-mark-files-regexp) - (define-key map (kbd "uv") 'dired-unmark-all-files) - (define-key map "t" 'ranger-toggle-mark) + (define-key map "v" 'dired-toggle-marks) + (define-key map (kbd "C-SPC") 'ranger-mark) + (define-key map (kbd "TAB") 'ranger-mark) + (define-key map (kbd "\"") 'dired-mark-files-regexp) + (define-key map (kbd "uv") 'dired-unmark-all-marks) + (define-key map "t" 'ranger-toggle-mark) ;; dired commands - (define-key map "!" 'dired-do-shell-command) - (define-key map "D" 'dired-do-delete) - (define-key map "R" 'dired-do-rename) + (define-key map "!" 'dired-do-shell-command) + (define-key map "D" 'dired-do-delete) + (define-key map "R" 'dired-do-rename) ;; navigation - (define-key map "-" 'ranger-up-directory) - (define-key map "G" 'ranger-goto-bottom) - (define-key map "h" 'ranger-up-directory) - (define-key map "j" 'ranger-next-file) - (define-key map "k" 'ranger-prev-file) - (define-key map "l" 'ranger-find-file) - (define-key map (kbd "C-f") 'ranger-page-down) - (define-key map (kbd "C-b") 'ranger-page-up) - (define-key map "J" 'ranger-half-page-down) - (define-key map "K" 'ranger-half-page-up) - (define-key map (kbd "C-d") 'ranger-half-page-down) - (define-key map (kbd "C-u") 'ranger-half-page-up) - (define-key map [left] 'ranger-up-directory) - (define-key map [down] 'ranger-next-file) - (define-key map [up] 'ranger-prev-file) - (define-key map [right] 'ranger-find-file) - (define-key map (kbd "RET") 'ranger-find-file) + (define-key map "-" 'ranger-up-directory) + (define-key map "G" 'ranger-goto-bottom) + (define-key map "h" 'ranger-up-directory) + (define-key map "j" 'ranger-next-file) + (define-key map "k" 'ranger-prev-file) + (define-key map "l" 'ranger-find-file) + (define-key map (kbd "C-f") 'ranger-page-down) + (define-key map (kbd "C-b") 'ranger-page-up) + (define-key map "J" 'ranger-half-page-down) + (define-key map "K" 'ranger-half-page-up) + (define-key map (kbd "C-d") 'ranger-half-page-down) + (define-key map (kbd "C-u") 'ranger-half-page-up) + (define-key map [left] 'ranger-up-directory) + (define-key map [down] 'ranger-next-file) + (define-key map [up] 'ranger-prev-file) + (define-key map [right] 'ranger-find-file) + (define-key map (kbd "RET") 'ranger-find-file) ;; jumping around - (define-key map "[" 'ranger-prev-parent) - (define-key map "]" 'ranger-next-parent) - (define-key map "}" 'ranger-find-file) - (define-key map "f" 'ranger-travel) + (define-key map "[" 'ranger-prev-parent) + (define-key map "]" 'ranger-next-parent) + (define-key map "}" 'ranger-find-file) + (define-key map "f" 'ranger-travel) ;; going - (define-key map "g" 'ranger-go) + (define-key map "g" 'ranger-go) ;; history - (define-key map "zz" 'ranger-show-history) - (define-key map "H" 'ranger-prev-history) - (define-key map "L" 'ranger-next-history) + (define-key map "zz" 'ranger-show-history) + (define-key map "H" 'ranger-prev-history) + (define-key map "L" 'ranger-next-history) ;; subtrees - (define-key map "I" 'ranger-insert-subdir) + (define-key map "I" 'ranger-insert-subdir) - (define-key map ">" 'dired-next-dirline) - (define-key map "<" 'dired-prev-dirline) + (define-key map ">" 'dired-next-dirline) + (define-key map "<" 'dired-prev-dirline) ;; preview windows - (define-key map "i" 'ranger-preview-toggle) - (define-key map (kbd "C-j") 'ranger-scroll-page-down) - (define-key map (kbd "C-k") 'ranger-scroll-page-up) - (define-key map "zp" 'ranger-toggle-details) + (define-key map "i" 'ranger-preview-toggle) + (define-key map (kbd "C-j") 'ranger-scroll-page-down) + (define-key map (kbd "C-k") 'ranger-scroll-page-up) + (define-key map "zp" 'ranger-toggle-details) ;; TODO map zc toggle_option collapse_preview - (define-key map "zi" 'ranger-toggle-literal) - (define-key map "zf" 'ranger-toggle-scale-images) + (define-key map "zi" 'ranger-toggle-literal) + (define-key map "zf" 'ranger-toggle-scale-images) ;; copy and paste - (define-key map "yy" 'ranger-copy) + (define-key map "yy" 'ranger-copy) ;; TODO undo copy - uy - (define-key map "ya" 'ranger-copy-append) + (define-key map "ya" 'ranger-copy-append) ;; TODO remove from copy - yr - (define-key map "dd" 'ranger-cut) + (define-key map "dd" 'ranger-cut) ;; TODO undo cut - ud - (define-key map "da" 'ranger-cut-append) + (define-key map "da" 'ranger-cut-append) ;; TODO remove from cut - dr - (define-key map "pp" 'ranger-paste) - (define-key map "po" 'ranger-paste-over) + (define-key map "pp" 'ranger-paste) + (define-key map "po" 'ranger-paste-over) ;; TODO paste link - pl - (define-key map "p?" 'ranger-show-copy-contents) + (define-key map "p?" 'ranger-show-copy-contents) ;; copy names and paths - (define-key map "yp" 'ranger-copy-absolute-file-paths) - (define-key map "yd" 'ranger-copy-current-dir-path) - (define-key map "yn" 'ranger-copy-filename) + (define-key map "yp" 'ranger-copy-absolute-file-paths) + (define-key map "yd" 'ranger-copy-current-dir-path) + (define-key map "yn" 'ranger-copy-filename) ;; settings - (define-key map "o" 'ranger-sort-criteria) - (define-key map "z+" 'ranger-more-parents) - (define-key map "z-" 'ranger-less-parents) - (define-key map "zh" 'ranger-toggle-dotfiles) - (define-key map (kbd "C-h") 'ranger-toggle-dotfiles) - (define-key map "zP" 'ranger-minimal-toggle) - (define-key map "zd" 'ranger-toggle-dir-first) + (define-key map "o" 'ranger-sort-criteria) + (define-key map "z+" 'ranger-more-parents) + (define-key map "z-" 'ranger-less-parents) + (define-key map "zh" 'ranger-toggle-dotfiles) + (define-key map (kbd "C-h") 'ranger-toggle-dotfiles) + (define-key map "zP" 'ranger-minimal-toggle) + (define-key map "zd" 'ranger-toggle-dir-first) ;; TODO map zf regexp filter ;; tabs - (define-key map (kbd "C-n") 'ranger-new-tab) - (define-key map (kbd "C-w") 'ranger-close-tab) - (define-key map (kbd "C-TAB") 'ranger-next-tab) - (define-key map (kbd "C-S-TAB") 'ranger-prev-tab) - (define-key map (kbd "M-") 'ranger-next-tab) - (define-key map (kbd "M-") 'ranger-prev-tab) - (define-key map "uq" 'ranger-restore-tab) + (define-key map (kbd "C-n") 'ranger-new-tab) + (define-key map (kbd "C-w") 'ranger-close-tab) + (define-key map (kbd "C-TAB") 'ranger-next-tab) + (define-key map (kbd "C-S-TAB") 'ranger-prev-tab) + (define-key map (kbd "M-") 'ranger-next-tab) + (define-key map (kbd "M-") 'ranger-prev-tab) + (define-key map "uq" 'ranger-restore-tab) ;; define M + number bindings to access tabs. (define-key map "\M-1" '(lambda () (interactive) (ranger-goto-tab 1))) @@ -579,20 +602,20 @@ Selective hiding of specific attributes can be controlled by MASK." ;; do (eval `(define-key map (concat "\\M-" ,(number-to-string num)) '(lambda() (interactive)(ranger-goto-tab ,num))))) ;; search - (define-key map "/" 'ranger-search) - (define-key map "n" 'ranger-search-next) - (define-key map "N" 'ranger-search-previous) + (define-key map "/" 'ranger-search) + (define-key map "n" 'ranger-search-next) + (define-key map "N" 'ranger-search-previous) ;; utilities - (define-key map (kbd "C-c C-e") 'wdired-change-to-wdired-mode) - (define-key map "S" 'ranger-pop-eshell) + (define-key map (kbd "C-c C-e") 'wdired-change-to-wdired-mode) + (define-key map "S" 'ranger-pop-eshell) ;; file opening - (define-key map "ws" 'ranger-open-file-vertically) - (define-key map "wv" 'ranger-open-file-horizontally) - (define-key map "wf" 'ranger-open-file-new-frame) - (define-key map "wj" 'ranger-open-file-other-window) - (define-key map "we" 'ranger-open-in-external-app) + (define-key map "ws" 'ranger-open-file-vertically) + (define-key map "wv" 'ranger-open-file-horizontally) + (define-key map "wf" 'ranger-open-file-new-frame) + (define-key map "wj" 'ranger-open-file-other-window) + (define-key map "we" 'ranger-open-in-external-app) ;; mouse (define-key map (kbd "") 'ranger-find-file) @@ -601,14 +624,163 @@ Selective hiding of specific attributes can be controlled by MASK." map) "Ranger mode map style using ranger style bindings.") +(defvar ranger-emacs-mode-map + (let ((map (make-sparse-keymap))) + ;; basics + (define-key map (kbd "C-h") 'ranger-help) + (define-key map (kbd "C-x C-c") 'ranger-close) + (define-key map (kbd "C-x k") 'ranger-disable) + (define-key map (kbd "C-l") 'ranger-refresh) + + ;; bookmarks + (define-key map (kbd "C-x rb") 'ranger-goto-mark) + (define-key map (kbd "C-x rB") 'ranger-show-bookmarks) + (define-key map (kbd "C-x rm") 'ranger-create-mark) + (define-key map (kbd "C-x ru") 'ranger-remove-mark) + + ;; marking + (define-key map (kbd "C-SPC") 'ranger-toggle-mark) + (define-key map (kbd "TAB") 'ranger-mark) + (define-key map (kbd "\"") 'dired-mark-files-regexp) + ;; (define-key map (kbd "uv") 'dired-unmark-all-marks) + + ;; dired commands + (define-key map (kbd "C-x du") 'ranger-show-size) + (define-key map (kbd "M-!") 'dired-do-shell-command) + (define-key map "D" 'dired-do-delete) + (define-key map "R" 'dired-do-rename) + + ;; navigation + (define-key map [home] 'ranger-goto-top) + (define-key map [end] 'ranger-goto-bottom) + (define-key map (kbd "M-v") 'ranger-page-down) + (define-key map (kbd "C-v") 'ranger-page-up) + (define-key map [pagedown] 'ranger-half-page-down) + (define-key map [pageup] 'ranger-half-page-up) + (define-key map (kbd "C-b") 'ranger-up-directory) + (define-key map (kbd "C-n") 'ranger-next-file) + (define-key map (kbd "C-p") 'ranger-prev-file) + (define-key map (kbd "C-f") 'ranger-find-file) + (define-key map [left] 'ranger-up-directory) + (define-key map [down] 'ranger-next-file) + (define-key map [up] 'ranger-prev-file) + (define-key map [right] 'ranger-find-file) + (define-key map (kbd "RET") 'ranger-find-file) + + ;; jumping around + (define-key map (kbd "M-[") 'ranger-prev-parent) + (define-key map (kbd "M-]") 'ranger-next-parent) + ;; (define-key map "f" 'ranger-travel) + + ;; going + (define-key map (kbd "C-x g") 'ranger-go) + + ;; history + ;; (define-key map "zz" 'ranger-show-history) + (define-key map (kbd "C-u C-SPC") 'ranger-prev-history) + + ;; subtrees + ;; (define-key map "I" 'ranger-insert-subdir) + + ;; (define-key map ">" 'dired-next-dirline) + ;; (define-key map "<" 'dired-prev-dirline) + + ;; preview windows + ;; (define-key map "i" 'ranger-preview-toggle) + ;; (define-key map (kbd "C-j") 'ranger-scroll-page-down) + ;; (define-key map (kbd "C-k") 'ranger-scroll-page-up) + ;; (define-key map "zp" 'ranger-toggle-details) + ;; TODO map zc toggle_option collapse_preview + ;; (define-key map "zi" 'ranger-toggle-literal) + ;; (define-key map "zf" 'ranger-toggle-scale-images) + + ;; copy and paste + ;; (define-key map "yy" 'ranger-copy) + ;; TODO undo copy - uy + ;; (define-key map "ya" 'ranger-copy-append) + ;; ;; TODO remove from copy - yr + ;; (define-key map "dd" 'ranger-cut) + ;; ;; TODO undo cut - ud + ;; (define-key map "da" 'ranger-cut-append) + ;; ;; TODO remove from cut - dr + ;; (define-key map "pp" 'ranger-paste) + ;; (define-key map "po" 'ranger-paste-over) + ;; ;; TODO paste link - pl + ;; (define-key map "p?" 'ranger-show-copy-contents) + + ;; ;; copy names and paths + ;; (define-key map "yp" 'ranger-copy-absolute-file-paths) + ;; (define-key map "yd" 'ranger-copy-current-dir-path) + ;; (define-key map "yn" 'ranger-copy-filename) + + ;; ;; settings + ;; (define-key map (kbd "C-x o") 'ranger-sort-criteria) + ;; (define-key map "z+" 'ranger-more-parents) + ;; (define-key map "z-" 'ranger-less-parents) + ;; (define-key map "zh" 'ranger-toggle-dotfiles) + ;; (define-key map (kbd "C-h") 'ranger-toggle-dotfiles) + ;; (define-key map "zP" 'ranger-minimal-toggle) + ;; (define-key map "zd" 'ranger-toggle-dir-first) + ;; TODO map zf regexp filter + + ;; tabs + (define-key map (kbd "C-n") 'ranger-new-tab) + (define-key map (kbd "C-w") 'ranger-close-tab) + (define-key map (kbd "C-TAB") 'ranger-next-tab) + (define-key map (kbd "C-S-TAB") 'ranger-prev-tab) + (define-key map (kbd "M-") 'ranger-next-tab) + (define-key map (kbd "M-") 'ranger-prev-tab) + (define-key map "uq" 'ranger-restore-tab) + + ;; define M + number bindings to access tabs. + (define-key map "\M-1" '(lambda () (interactive) (ranger-goto-tab 1))) + (define-key map "\M-2" '(lambda () (interactive) (ranger-goto-tab 2))) + (define-key map "\M-3" '(lambda () (interactive) (ranger-goto-tab 3))) + (define-key map "\M-4" '(lambda () (interactive) (ranger-goto-tab 4))) + (define-key map "\M-5" '(lambda () (interactive) (ranger-goto-tab 5))) + (define-key map "\M-6" '(lambda () (interactive) (ranger-goto-tab 6))) + (define-key map "\M-7" '(lambda () (interactive) (ranger-goto-tab 7))) + (define-key map "\M-8" '(lambda () (interactive) (ranger-goto-tab 8))) + (define-key map "\M-9" '(lambda () (interactive) (ranger-goto-tab 9))) + (define-key map "\M-0" '(lambda () (interactive) (ranger-goto-tab 0))) + + ;; search + ;; (define-key map "/" 'ranger-search) + ;; (define-key map "n" 'ranger-search-next) + ;; (define-key map "N" 'ranger-search-previous) + + ;; utilities + (define-key map (kbd "C-c C-e") 'wdired-change-to-wdired-mode) + ;; (define-key map "S" 'ranger-pop-eshell) + + ;; file opening + (define-key map (kbd "C-x ws") 'ranger-open-file-vertically) + (define-key map (kbd "C-x wv") 'ranger-open-file-horizontally) + (define-key map (kbd "C-x wf") 'ranger-open-file-new-frame) + (define-key map (kbd "C-x wj") 'ranger-open-file-other-window) + (define-key map (kbd "C-x we") 'ranger-open-in-external-app) + + ;; mouse + (define-key map (kbd "") 'ranger-find-file) + (define-key map (kbd "") 'ranger-up-directory) + + map) + "Ranger mode map style using emacs style bindings.") + (defvar ranger-mode-map (let ((map (make-sparse-keymap))) ;; define bindings based on (cl-case ranger-map-style ('ranger (set-keymap-parent map ranger-normal-mode-map)) + ('dired + (set-keymap-parent map dired-mode-map)) ('emacs - (set-keymap-parent map ranger-normal-mode-map))) + (progn + ;; allow all emacs modes to overwrite dired mapping + (set-keymap-parent ranger-emacs-mode-map dired-mode-map) + (set-keymap-parent map ranger-emacs-mode-map) + ))) ;; define a prefix for all dired commands (define-prefix-command 'ranger-dired-map nil "Dired-prefix") (setq ranger-dired-map (copy-tree dired-mode-map)) @@ -682,7 +854,7 @@ to not replace existing value." (tab-index nil) (history nil) (minimal nil)) - + (ranger-id (make-ranger)) @@ -727,13 +899,9 @@ to not replace existing value." (when ranger-key (define-key ranger-mode-map ranger-key 'ranger-to-dired)) - ;; TODO visual mode bindings don't seem to work - ;; normalize keymaps to work with evil mode (with-eval-after-load "evil" ;; turn off evilified buffers for evilify usage (evil-set-initial-state 'ranger-mode 'motion) - (evil-make-overriding-map ranger-mode-map 'motion) - (evil-normalize-keymaps) ;; allow cursor to be cleared (when ranger-hide-cursor @@ -745,6 +913,17 @@ to not replace existing value." ;; make sure isearch is cleared before we delete the buffer on exit (add-hook 'ranger-mode-hook '(lambda () (setq isearch--current-buffer nil)))) +;; TODO visual mode bindings don't seem to work +;; normalize keymaps to work with evil mode + +(add-hook 'ranger-mode-hook #'ranger--normalize-keymaps) + +(defun ranger--normalize-keymaps () + (when (boundp 'evil-mode) + ;; turn off evilified buffers for evilify usage + (evil-make-overriding-map ranger-mode-map 'motion) + (evil-normalize-keymaps))) + ;; wdired integration (eval-after-load 'wdired '(progn @@ -1229,7 +1408,10 @@ ranger-`CHAR'." (defun ranger-toggle-dotfiles () "Show/hide dot-files." (interactive) - (setq ranger-show-hidden (not ranger-show-hidden)) + (setq ranger-show-hidden (cl-case ranger-show-hidden + ('format 'prefer) + ('prefer 'hidden) + ('hidden 'format))) (ranger-setup) (message (format "Show Dotfiles: %s" ranger-show-hidden))) @@ -1250,22 +1432,22 @@ ranger-`CHAR'." (defun ranger-filter-files () "Omit and filter files in ranger." - (let ((omit-re (if (not ranger-show-hidden) - (concat ranger-omit-regexp - "\\|" - ranger-hidden-regexp) - ranger-omit-regexp))) - (ranger-omit-files omit-re))) - -(defun ranger-omit-files (&optional regexp) - (interactive "sOmit files (regexp): ") - (let ((omit-re (or regexp ranger-omit-regexp)) + (let ((omit-re (append ranger-format-regexp + (cl-case ranger-show-hidden + ('prefer ranger-prefer-regexp) + ('hidden ranger-prefer-regexp ranger-hidden-regexp))))) + (ranger-omit-files omit-re))) + +(defun ranger-omit-files (regexp) + (interactive) + (let ((omit-re (mapconcat 'concat regexp "\\|")) (old-modified-p (buffer-modified-p)) count) (or (string= omit-re "") (let ((dired-marker-char 16)) (if (dired-mark-unmarked-files omit-re nil nil 'no-dir) (progn + (ranger--message "deleting hidden files") (setq count (dired-do-kill-lines nil "")) (force-mode-line-update))))) ;; Try to preserve modified state of buffer. So `%*' doesn't appear @@ -1305,6 +1487,7 @@ ranger-`CHAR'." `ranger-persistent-sort' is nil." ;; TODO dired-sort-other only does this: ;; (setq dired-actual-switches switches) + (setq-local ls-lisp-dirs-first ranger-listing-dir-first) (dired-sort-other (concat dired-listing-switches (when (or force @@ -1424,8 +1607,10 @@ currently selected file in ranger. `IGNORE-HISTORY' will not update history-ring (progn (ranger--message "opening directory: %s" find-name) (ranger-save-window-settings) + (ranger--message "settings saved: %s" find-name) (unless ignore-history (ranger-update-history find-name)) + (advice-add 'dired-readin :after #'ranger-setup-dired-buffer) (switch-to-buffer ;; TODO make separate buffer of directory if more than one already exists. (or (car (or (dired-buffers-for-dir find-name) ())) @@ -1438,7 +1623,9 @@ currently selected file in ranger. `IGNORE-HISTORY' will not update history-ring (r--fset ranger-minimal t) (r--fset ranger-minimal nil)) (ranger-parent-child-select) + (ranger--message "setting up ranger windows: %s" find-name) (ranger-mode) + (ranger--message "DONE") ;; (dired-unadvertise find-name) ) (progn @@ -1761,8 +1948,7 @@ R : ranger . el location (defun ranger-sub-window-setup () "Parent window options." ;; allow mouse click to jump to that directory - (make-local-variable 'mouse-1-click-follows-link) - (setq mouse-1-click-follows-link nil) + (setq-local mouse-1-click-follows-link nil) (local-set-key (kbd "") 'ranger-find-file) ;; set header-line (when ranger-modify-header @@ -2040,7 +2226,7 @@ is set, show literally instead of actual buffer." ) (with-current-buffer preview-buffer (setq-local cursor-type nil) - (setq mouse-1-click-follows-link nil) + (setq-local mouse-1-click-follows-link nil) (local-set-key (kbd "") #'(lambda () (interactive) (select-window ranger-window) @@ -2142,32 +2328,12 @@ fraction of the total frame size" new-window reuse-window) - ;; (walk-window-tree - ;; (lambda (window) - ;; (progn - ;; (when (not (eq current-window window)) - ;; (when (eq (window-parameter window 'window-slot) slot) - ;; (setq reuse-window window)) - ;; (when (eq (window-parameter window 'window-slot) (+ slot 1)) - ;; (setq current-window window)) - ;; ))) - ;; nil nil 'nomini) - - ;; (if reuse-window - ;; (progn - ;; (shrink-window (- window-size (window-width reuse-window)) t) - ;; ;; (set-window-parameter reuse-window 'window-slot slot) - ;; (window--display-buffer - ;; buffer reuse-window 'reuse alist display-buffer-mark-dedicated) - ;; ) - ;; (remove-hook 'window-configuration-change-hook 'ranger-window-check) + ;; new window (setq new-window (split-window current-window window-size side)) - + ;; set parameters (set-window-parameter new-window 'window-slot slot) - (window--display-buffer - buffer new-window 'window alist display-buffer-mark-dedicated) - ;; (add-hook 'window-configuration-change-hook 'ranger-window-check) - ;; ) + ;; now set up the window + (window--display-buffer buffer new-window 'window alist) )) (defun ranger-show-flags () @@ -2235,71 +2401,73 @@ fraction of the total frame size" (config (r--aget ranger-f-alist (window-frame)))) - (when (or config - prev-buffer) - (r--aremove ranger-w-alist (selected-window)) - - (if minimal - (when (and prev-buffer - (buffer-live-p prev-buffer)) - (switch-to-buffer prev-buffer) - (goto-char prev-point)) - (when (and config - (window-configuration-p config)) - (set-window-configuration config) - (r--aremove ranger-f-alist (window-frame)))) - - ;; TODO make separate tabs for each ranger window - ;; (r--aremove ranger-t-alist ranger-current-tab) - - ;; revert appearance - (advice-remove 'dired-readin #'ranger-setup-dired-buffer) - (ranger-revert-appearance (or buffer ranger-buffer)) - (advice-add 'dired-readin :after #'ranger-setup-dired-buffer) - (setq ranger-pre-saved nil) - - ;; if no more ranger frames or windows - (when (not (or (ranger-windows-exists-p) - (ranger-frame-exists-p))) - (message "Reverting all buffers") - ;; remove all hooks and advices - ;; TODO use established dired-after-readin-hook - (advice-remove 'dired-readin #'ranger-setup-dired-buffer) - (remove-hook 'window-configuration-change-hook 'ranger-window-check) - - ;; revert setting for minimal - (r--fset ranger-minimal nil) - - ;; delete and cleanup buffers - (let ((all-ranger-buffers - (cl-remove-duplicates - (append - ranger-preview-buffers - ranger-parent-buffers - ranger-visited-buffers - (list ranger-buffer)) - :test (lambda (x y) (or (null y) (eq x y))) - ))) - (ranger--message "Cleaning all buffers : %s" all-ranger-buffers) - - (if ranger-cleanup-on-disable - (mapc 'ranger-kill-buffer all-ranger-buffers) - (mapc 'ranger-revert-appearance all-ranger-buffers))) - - ;; kill preview buffer - (when (get-buffer "*ranger-prev*") - (kill-buffer (get-buffer "*ranger-prev*"))) - - (setq ranger-f-alist ()) - (setq ranger-w-alist ()) - - ;; clear variables - (setq ranger-preview-buffers () - ranger-visited-buffers () - ranger-parent-buffers ())) - - ;; clear ranger-show-file-details information - (message "%s" "")))) + (if (or config prev-buffer) + (progn + (r--aremove ranger-w-alist (selected-window)) + + (if minimal + (when (and prev-buffer + (buffer-live-p prev-buffer)) + (switch-to-buffer prev-buffer) + (goto-char prev-point)) + (when (and config + (window-configuration-p config)) + (set-window-configuration config) + (r--aremove ranger-f-alist (window-frame)))) + + ;; TODO make separate tabs for each ranger window + ;; (r--aremove ranger-t-alist ranger-current-tab) + + ;; revert appearance + (advice-remove 'dired-readin #'ranger-setup-dired-buffer) + (ranger-revert-appearance (or buffer ranger-buffer)) + (advice-add 'dired-readin :after #'ranger-setup-dired-buffer) + (setq ranger-pre-saved nil) + + ;; if no more ranger frames or windows + (when (not (or (ranger-windows-exists-p) + (ranger-frame-exists-p))) + (message "Reverting all buffers") + ;; remove all hooks and advices + ;; TODO use established dired-after-readin-hook + (advice-remove 'dired-readin #'ranger-setup-dired-buffer) + (remove-hook 'window-configuration-change-hook 'ranger-window-check) + + ;; revert setting for minimal + (r--fset ranger-minimal nil) + + ;; delete and cleanup buffers + (let ((all-ranger-buffers + (cl-remove-duplicates + (append + ranger-preview-buffers + ranger-parent-buffers + ranger-visited-buffers + (list ranger-buffer)) + :test (lambda (x y) (or (null y) (eq x y))) + ))) + (ranger--message "Cleaning all buffers : %s" all-ranger-buffers) + + (if ranger-cleanup-on-disable + (mapc 'ranger-kill-buffer all-ranger-buffers) + (mapc 'ranger-revert-appearance all-ranger-buffers))) + + ;; kill preview buffer + (when (get-buffer "*ranger-prev*") + (kill-buffer (get-buffer "*ranger-prev*"))) + + (setq ranger-f-alist ()) + (setq ranger-w-alist ()) + + ;; clear variables + (setq ranger-preview-buffers () + ranger-visited-buffers () + ranger-parent-buffers ())) + + ;; clear ranger-show-file-details information + (message "%s" "")) + ;; config is gone, kill buffer + ))) (defun ranger-revert-appearance (buffer) "Revert the `BUFFER' to pre-ranger defaults without closing ranger session." @@ -2391,8 +2559,8 @@ fraction of the total frame size" ;; when still in ranger's window, make sure ranger's primary window and buffer are still here. (when ranger-window-props ;; Unless selected window does not have ranger buffer - (when (and (memq (selected-window) ranger-windows) - (not (eq major-mode 'ranger-mode))) + (when (and (memq (selected-window) ranger-windows) + (not (eq major-mode 'ranger-mode))) (ranger--message "Window Check : Ranger window is not the selected window ** buffer: %s: %s @@ -2405,8 +2573,11 @@ fraction of the total frame size" (defun ranger-windows-exists-p () "Test if any ranger-windows are live." - (mapcar 'window-live-p - (r--akeys ranger-w-alist))) + (member t + (mapcar (lambda (l) + (and (window-live-p (car l)) + (buffer-live-p (cddr l)))) + ranger-w-alist))) (defun ranger-frame-exists-p () "Test if any ranger-frames are live." @@ -2499,10 +2670,14 @@ CALLBACK is passed the received mouse event." (defun ranger--header-rhs () (concat (propertize - (format "%s / %s" - (if ranger-show-hidden ".." "") + (format "[%s]%s" + ;; (if ranger-show-literal "raw" "act") - ranger-parent-depth) + ranger-parent-depth + (cl-case ranger-show-hidden + ('format "..") + ('prefer "._") + ('hidden "__"))) 'face 'font-lock-comment-face) (when (> (length ranger-t-alist) 1) (format " %s" (ranger--header-tabs))) @@ -2570,7 +2745,7 @@ CALLBACK is passed the received mouse event." (+ lm 1 (* num (+ ;; account for graphical margin - 3 + (if window-divider-mode 2 3) ;; account for scroll bar and fringe (if (eq fringe-mode 0) -2 0) (if scroll-bar-mode 3 0))))))) @@ -2618,11 +2793,14 @@ properly provides the modeline in dired mode. " (progn (forward-line 1) (point))) (forward-line 1)) ;; check sorting mode and sort with directories first - (when (and ranger-listing-dir-first - (not (string-match "[XStU]+" switches))) - (if (string-match "r" switches) - (sort-regexp-fields nil "^.*\n" "^[ ]*." (point) (point-max)) - (sort-regexp-fields t "^.*\n" "^[ ]*." (point) (point-max)))) + ;; (when (and ranger-listing-dir-first + ;; (not (string-match "[XStU]+" switches))) + ;; ;; [d]rwxrwxrwx should come before [-]rw-rw-rw- + ;; (sort-regexp-fields (not (string-match "r" switches)) + ;; "^.*\n" + ;; "^[ ]*." + ;; (point) + ;; (point-max))) (set-buffer-modified-p nil))))) ;;;###autoload @@ -2679,11 +2857,12 @@ properly provides the modeline in dired mode. " (defun ranger-minimal-toggle () (interactive) - (let ((minimal (r--fget ranger-minimal))) + (let ((minimal (r--fget ranger-minimal)) + (dir default-directory)) (ranger-revert) (if minimal - (ranger) - (deer)))) + (ranger dir) + (deer dir)))) ;;;###autoload (defun ranger (&optional path) @@ -2730,6 +2909,22 @@ properly provides the modeline in dired mode. " "Setup all associated ranger windows." (interactive) + ;; (setq eshell-ls-use-in-dired t) + (setq ls-lisp-ignore-case nil) + (setq ls-lisp-verbosity nil) + (setq ls-lisp-uid-s-fmt "%-8s") + (setq ls-lisp-gid-s-fmt "%-8s") + ;; don't mix dotfiles with directories + (setq ls-lisp-UCA-like-collation nil) + ;; (setq ls-lisp-use-insert-directory-program nil) + + (setq ls-lisp-format-time-list + '("%Y-%m-%d %H:%M" + "%Y-%m-%d %H:%M")) + + (setq ls-lisp-use-insert-directory-program nil) + (require 'ls-lisp) + (unless (derived-mode-p 'dired-mode) (error "Run it from dired buffer")) @@ -2781,7 +2976,10 @@ properly provides the modeline in dired mode. " (add-to-list 'ranger-visited-buffers ranger-buffer) (ranger-sort t) + (ranger--message "sorting") (ranger-show-flags) + (ranger--message "setting flags") + (ranger--message "starting filter") (ranger-filter-files) ;; omit files after buffer refresh @@ -2818,9 +3016,12 @@ properly provides the modeline in dired mode. " ;; hide details line at top - show symlink targets (funcall 'add-to-invisibility-spec 'dired-hide-details-information) + (funcall 'add-to-invisibility-spec 'dired-hide-details-hide-information-lines) + ;; (setq dired-hide-details-hide-symlink-targets nil) - (ranger--message "Ranger loaded")) + (ranger--message "Ranger loaded") + ) (defun ranger-hide-the-cursor () (when (and buffer-read-only ranger-hide-cursor) @@ -2828,7 +3029,7 @@ properly provides the modeline in dired mode. " (hl-line-mode t)) (defvar ranger--debug nil) -(defvar ranger--debug-period 0.5) +(defvar ranger--debug-period 1.5) ;; TODO make a ranger debug pane as the bottom window @@ -2866,8 +3067,9 @@ properly provides the modeline in dired mode. " \\{ranger-mode-map}" :group 'ranger (setq-local cursor-type nil) + ;; (setq-local ranger-mode nil) (use-local-map ranger-mode-map) - (advice-add 'dired-readin :after #'ranger-setup-dired-buffer) + ;; (advice-add 'dired-readin :after #'ranger-setup-dired-buffer) (ranger-setup) (add-hook 'window-configuration-change-hook 'ranger-window-check) (setq-local mouse-1-click-follows-link nil) diff --git a/packages/rcirc-styles-20160207.250.el b/packages/rcirc-styles-20160207.250.el new file mode 100644 index 0000000..1db01c1 --- /dev/null +++ b/packages/rcirc-styles-20160207.250.el @@ -0,0 +1,599 @@ +;;; rcirc-styles.el --- support mIRC-style color and attribute codes + +;; Package-Version: 20160207.250 +;; Package-X-Original-Version: 20160206.001 +;; Copyright 2016 Aaron Miller +;; Package-Requires: ((cl-lib "0.5")) + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2 of +;; the License, or (at your option) any later version. + +;; This program is distributed in the hope that it will be +;; useful, but WITHOUT ANY WARRANTY; without even the implied +;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +;; PURPOSE. See the GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public +;; License along with this program; if not, write to the Free +;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +;; MA 02111-1307 USA + +;;; Commentary: + +;; The de facto standard for IRC color codes, as originally +;; implemented in mIRC, can be found at +;; http://en.wikichip.org/wiki/irc/colors . + +;; As may be expected from the context, it's a bit ad hoc and not the +;; easiest thing in the world to parse correctly, which may explain why a +;; prior attempt to satisfy this use case, under the name of +;; "rcirc-controls.el", attempted to do so with a recondite yet woefully +;; inadequate regexp. + +;; Rather than attempt to fix the regexp, and even if successful make +;; it even more incomprehensible than it started out being, I decided +;; it'd be easier and more maintainable to write a string-walking +;; parser. + +;; So I did that. In addition to those cases supported in the previous +;; library, this code correctly handles: +;; * Background colors, including implicit backgrounds when a new code +;; provides only a foreground color. +;; * Colors at codes between 8 and 15 (and correct colors for codes < 8). +;; * Color specifications implicitly terminated by EOL. +;; * Color specifications implicitly terminated by new color +;; specifications. +;; * The ^O character terminating color specifications. + +;; While I was at it, I noticed some areas in which the both the stock +;; attribute markup function in rcirc, and the one provided in +;; the previous library, could use improving. + +;; So I did that too, and the following cases are now correctly handled: +;; * Implicit termination of attribute markup by EOL. +;; * ^V as the specifier for reverse video, rather than italics. +;; * ^] as the specifier for italics. + +;; There are a couple of attribute codes which I've only seen +;; mentioned in a few places, and haven't been able to confirm +;; whether or how widely they're used: +;; * ^F for flashing text; +;; * ^K for fixed-width text. +;; Since these appear to be so ill-used, I'm not terribly anxious to +;; support them in rcirc, but they are on my radar. If you want one or +;; both of these, open an issue! + +;; As far as I'm aware, this code implements correct and, subject to +;; the preceding caveats, complete support for mIRC colors and +;; attributes. If I've missed something, let me know! + +;; Finally, a note: Since this package entirely obsoletes +;; rcirc-controls, it will attempt rather vigorously to disable its +;; predecessor, by removing rcirc-controls' hooks from +;; `rcirc-markup-text-functions' if they are installed. Not to do so, +;; when both packages are loaded, would result in severely broken +;; style markup behavior. + +;;; Usage: + +;; Once installed, this package will activate when +;; `package-activate' is called in your init process. If you happen +;; to have rcirc-controls.el installed, and it's already been +;; activated, then rcirc-styles will supersede it at that time. + +;; You don't need to do anything to see styled text sent by other IRC +;; users in your channels; it'll Just Workâ„¢. + +;; If you want to send styled text of your own, you have a couple of +;; methods available. + +;; First, you can always just insert color and attribute codes +;; directly: for example, =C-q C-c 1 , 13= to insert the color code +;; for black text on a pink background, or =C-q C-b= to insert the +;; attribute code for bold text. + +;; Second, you can use the convenience functions which rcirc-styles +;; provides since version 1.3 for this purpose: +;; `rcirc-styles-insert-color' and +;; `rcirc-styles-insert-attribute'. Both are interactive functions, so +;; can be invoked via M-x, and both provide completion of valid +;; values and will not accept invalid ones. + +;; Version 1.3 also introduces a convenience function, +;; `rcirc-styles-toggle-preview', for previewing styled input as it +;; will appear once sent, so that you can see how your text will look +;; before actually sending it. Invoke this function to toggle between +;; editable input with literal style codes, and a read-only preview of +;; the same input with styles applied. + +;; All of these convenience functions are also bound to a keymap, +;; `rcirc-styles-map', which you can attach to a key sequence in +;; `rcirc-mode-map' for additional convenice. For example, if you +;; include in your init file + +;; (define-key rcirc-mode-map (kbd "C-c C-s") rcirc-styles-map) + +;; then the following keybindings will be available in rcirc buffers: +;; - C-c C-s C-c: insert a color code +;; - C-c C-s C-a: insert an attribute code +;; - C-c C-s C-p: toggle styled preview mode + +;; In a future version, I plan to automate the binding to +;; =rcirc-mode-map= and make it customizable; in the meantime, the +;; above snippet should suffice for most purposes. (If you want to see +;; customization implemented faster, comment on the relevant Github +;; issue[1] and ask!) + +;; Also in a future version, I plan to add shortcut keybindings for +;; commonly used attributes, so that e.g. C-c C-s b will insert the +;; bold attribute code directly, rather than requiring all of C-c C-s +;; C-a bold RET. (As above, if you want to see it faster, use the +;; relevant Github issue [2] to let me know!) + +;; [1] https://github.com/aaron-em/rcirc-styles.el/issues/7 +;; [2] https://github.com/aaron-em/rcirc-styles.el/issues/8 + +;;; Contributing: + +;; The canonical version of this package lives in a Git repository +;; [REPO] maintained through Github. To request a feature or report a +;; bug, open an issue there with as much detail as you can provide +;; about what you'd like to see, or what went wrong and how. To +;; contribute a feature or fix a bug, open a pull request with your +;; code. Don't hesitate to do either; if you have an opinion on how to +;; make rcirc-styles better, I want to hear about it! + +;;; Code: + +(require 'cl-lib) +(require 'rcirc) + +;; +;; Functions and variables related to attribute and color markup. +;; + +(defalias 'rcirc-styles-set-face-inverse-video + (symbol-function + (if (version< emacs-version "24.4.0") + 'set-face-inverse-video-p + 'set-face-inverse-video)) + "Which function we use to set inverse video on a face; + `set-face-inverse-video-p' was deprecated in 24.4 in favor of + `set-face-inverse-video', so we need to check the version and + change which function we call accordingly.") + +(defvar rcirc-styles-attribute-alist + '(("\C-b" . bold) + ("\C-]" . italic) + ("\C-_" . underline) + ("\C-v" . inverse) + ("\C-o" . default)) + "mIRC text attribute specification characters.") + +(defvar rcirc-styles-color-vector ["white" + "black" + "blue" + "green" + "red" + "brown" + "purple" + "orange" + "yellow" + "light green" + "cyan" + "light cyan" + "light blue" + "pink" + "gray" + "light gray"] + "Vector of color names for the numbers 0-15.") + +;; Colors and attributes are actually orthogonal, with the exception +;; of the ^O sequence that turns off both. So we need to handle them +;; accordingly, with one function to mark up attributes, another to +;; mark up colors, and a third which executes after both and cleans up +;; the leftover ^Os. + +;; Since these functions are order-dependent (in that things go +;; horribly wrong if the ^Os are removed before both of the markup +;; functions have run), we wrap them all in a single defun, in a safe +;; execution order, and hang that off the +;; `rcirc-markup-text-functions' hook. + +(if (not (facep 'inverse)) + (progn + (make-face 'inverse) + (funcall 'rcirc-styles-set-face-inverse-video 'inverse t))) + +(defun rcirc-styles-markup-colors (&rest ignore) + "Mark up received messages with foreground and background colors, +according to the de facto IRC standard at +http://en.wikichip.org/wiki/irc/colors. + +This function is intended to be hung off `rcirc-styles-markup-styles', +which is rather magical. It probably will not do what you have in +mind when invoked outside that context." + (let* (;; a list of char ranges we'll want to delete, as (offset . length) + deletes + ;; a list of ranges we'll want to facify, as plists (see below) + ranges + ;; the current foreground and background colors, if any + fg bg + ;; which kind of specification, if any, we found here + found-fg found-bg) + + ;; begin from the start of the new message + (goto-char (point-min)) + + ;; walk along the message + (while (not (cl-equalp (point) (point-max))) + (setq found-fg nil) + (setq found-bg nil) + + ;; ^O means "turn off all formatting" + (if (looking-at "\C-o") + (progn + (setq fg nil) + (setq bg nil))) + + ;; ^C introduces a color code + (if (not (looking-at "\C-c")) + ;; if we're not looking at a color code, just move ahead to the next char + (forward-char 1) + ;; otherwise, parse the color code and capture the facification info + (let ((delete-from (point)) + (delete-length 1) + range) + + ;; advance past ^C and set a default range to remove it + (forward-char 1) + + ;; we have a foreground color spec + (if (looking-at "\\([0-9]\\{1,2\\}\\)") + (progn + (setq found-fg t) + ;; capture the specified color + (setq fg (string-to-number (match-string 1))) + ;; extend the delete length to include it + (setq delete-length (+ delete-length + (length (match-string 1)))) + ;; move point past it + (forward-char (length (match-string 1))))) + + ;; we have a background color spec + (if (looking-at ",\\([0-9]\\{1,2\\}\\)") + (progn + (setq found-bg t) + ;; capture it + (setq bg (string-to-number (match-string 1))) + ;; extend delete length over it + (setq delete-length (+ delete-length 1 + (length (match-string 1)))) + ;; move point past it + (forward-char (1+ (length (match-string 1)))))) + + ;; if we have a bare ^C, treat it like ^O (discontinue color specs) + (if (and (not found-fg) + (not found-bg)) + (progn + (setq fg nil) + (setq bg nil))) + + ;; if we got any color specs, update ranges and deletes + (and (or found-fg found-bg) + (setq range `(:from ,(point) + ;; range ends at: + :to ,(save-excursion + ;; either the next relevant control char + (or (re-search-forward "\C-o\\|\C-c" nil t) + ;; or the last char before whitespace to eol + (re-search-forward "[:space:]*$" nil t) + ;; or, failing all else, point-max + (point-max))) + :fg ,fg + :bg ,bg)) + (setq ranges (push range ranges)) + + ;; finally, move point to the next unexamined char, + ;; unless we're already at end of buffer + (and (not (equal (point) (point-max))) + (forward-char 1))) + + (setq deletes (push + `(,delete-from . ,delete-length) + deletes))))) + + ;; facify all the known ranges, ignoring unspecified or + ;; out-of-range color values + (dolist (range ranges) + (let ((fg (plist-get range :fg)) + (bg (plist-get range :bg)) + face) + (when (and fg (< fg 16)) + (setq face (push (cons 'foreground-color + (aref rcirc-styles-color-vector fg)) + face))) + (when (and bg (< bg 16)) + (setq face (push (cons 'background-color + (aref rcirc-styles-color-vector bg)) + face))) + (rcirc-add-face (plist-get range :from) (plist-get range :to) + face))) + + ;; delete all the deletion ranges, getting rid of literal control codes + ;; NB `deletes' is in last-to-first order, so we can just iterate + ;; NB it like this without needing to adjust as we go + (dolist (pair deletes) + (goto-char (car pair)) + (delete-char (cdr pair))))) + +(defun rcirc-styles-markup-attributes (&rest ignore) + "Mark up received messages with text attributes. + +This function marks up newly received IRC messages with text +attributes (bold, italic, underline, and reverse video) according to +the de facto IRC standard at http://en.wikichip.org/wiki/irc/colors. + +rcirc as shipped in Emacs 24 actually includes a function by this +name, but it does not support reverse video, and it uses the +wrong control character for italics; it also fails to recognize +implicit termination of attributes by EOL, and fails to mark up +such cases. + +This function is intended to be hung off `rcirc-styles-markup-styles', +which is rather magical. It probably will not do what you have in +mind when invoked outside that context." + (let* (deletes + ranges + attrs + advanced) + (goto-char (point-min)) + (while (not (cl-equalp (point) (point-max))) + (setq advanced nil) + + ;; ^O means "turn off all formatting" + (if (looking-at "\C-o") + (progn + (setq attrs nil))) + + ;; Check each attribute character in turn, to see if we're + ;; looking at it. + (dolist (pair rcirc-styles-attribute-alist) + (let ((char (car pair)) + (face (cdr pair))) + ;; If so, and if it's not C-o, toggle that attribute in `attrs'... + (when (and (not (eq face 'default)) + (looking-at char)) + (setq deletes (push `(,(point) . 1) deletes)) + (forward-char 1) + (setq advanced t) + (setq attrs + (if (member face attrs) + (cl-remove-if #'(lambda (e) (eq face e)) attrs) + (push face attrs))) + ;; ...and, when there are attributes to apply, push a + ;; range that does so. + (when attrs + (setq ranges (push + `(:from ,(point) + :to ,(save-excursion + ;; either the next relevant control char + (or (re-search-forward + (concat "\C-o\\|" char) nil t) + ;; or the last char before whitespace to eol + (re-search-forward "[:space:]*$" nil t) + ;; or, failing all else, point-max + (point-max))) + :attrs ,attrs) + ranges)))))) + (and (not advanced) + (forward-char 1))) + + ;; As in `rcirc-styles-markup-colors', q.v. + (dolist (range ranges) + (let (face) + (dolist (attr (plist-get range :attrs)) + (setq face (push attr face))) + (rcirc-add-face (plist-get range :from) (plist-get range :to) face))) + + ;; As in `rcirc-styles-markup-colors', q.v. + (dolist (pair deletes) + (goto-char (car pair)) + (delete-char (cdr pair))))) + +(defun rcirc-styles-markup-remove-control-o (&rest ignore) + "Remove all the ^O characters from a string. + +This function is intended to be hung off `rcirc-styles-markup-styles', +which is rather magical. It probably will not do what you have in +mind when invoked outside that context." + (while (re-search-forward "\C-o" nil t) + (backward-delete-char 1))) + +(defun rcirc-styles-markup-styles (&rest ignore) + "Apply rcirc-styles color/attribute markup. + +This function is intended to be hung off +`rcirc-markup-text-functions', which invokes some magic to +constrain point within the bounds of the newly received +message. It probably will not do what you have in mind when +invoked outside that context." + (goto-char (point-min)) + (save-excursion + (rcirc-styles-markup-colors)) + (save-excursion + (rcirc-styles-markup-attributes)) + (save-excursion + (rcirc-styles-markup-remove-control-o))) + +;; +;; Functions and variables related to convenient attribute and color insertion. +;; + +(defun rcirc-styles--read-color (prompt &optional allow-empty) + "Prompt for a color name, providing completion over known +values." + (let ((colors (mapcar #'identity rcirc-styles-color-vector)) + val) + (while (not (or (and allow-empty (string= val "")) + (not (null (member val colors))))) + (setq val + (completing-read (concat prompt + (and allow-empty " (RET for none)") + ": ") + colors nil (not allow-empty) nil nil ""))) + (if (and (stringp val) + (not (string= val ""))) + val + nil))) + +(defun rcirc-styles-insert-color (&optional fg bg) + "Insert at point a color code representing foreground FG and +background BG. + +When called interactively, prompt for both values, providing +completion over known values." + (interactive (list + (rcirc-styles--read-color "Foreground" t) + (rcirc-styles--read-color "Background" t))) + (insert "\C-c") + (and (not (null fg)) + (insert + (number-to-string + (cl-position fg rcirc-styles-color-vector :test #'string=)))) + (and (not (null bg)) + (insert + "," + (number-to-string + (cl-position bg rcirc-styles-color-vector :test #'string=))))) + +(defun rcirc-styles--read-attribute nil + "Prompt for an attribute name, providing completion over known +values." + (let ((val "")) + (while (not (rassoc (intern val) rcirc-styles-attribute-alist)) + (setq val (completing-read + "Attribute: " + (mapcar #'(lambda (pair) (symbol-name (cdr pair))) + rcirc-styles-attribute-alist) nil t))) + val)) + +(defun rcirc-styles-insert-attribute (attr) + "Insert at point an attribute code representing the desired +attribute ATTR. + +When called interactively, prompt for an attribute name, + providing completion over known values." + (interactive (list (rcirc-styles--read-attribute))) + (insert (car (rassoc (intern attr) rcirc-styles-attribute-alist)))) + +;; +;; Functions and variables related to previewing styled text. +;; + +(defvar rcirc-styles-previewed-input nil + "Literal input currently under preview with +`rcirc-styles-preview'.") +(defvar rcirc-styles-previewing nil + "Whether we are currently previewing input in this buffer with +`rcirc-styles-preview'.") +(make-variable-buffer-local 'rcirc-styles-previewed-input) +(make-variable-buffer-local 'rcirc-styles-previewing) + +(defun rcirc-styles-toggle-preview nil + "Switch the current buffer's state between literal input and a +read-only preview of styled input. + + This function has no effect in non-rcirc buffers." + (interactive) + (when (eq major-mode 'rcirc-mode) + (with-silent-modifications + (if rcirc-styles-previewing + (rcirc-styles--hide-preview) + (rcirc-styles--show-preview))))) + +(defun rcirc-styles--show-preview nil + "Put the current rcirc buffer in preview mode. + +Calling this function by hand may well hose your buffer +state. Don't do that." + (when (and (not rcirc-styles-previewing) + (not rcirc-styles-previewed-input) + (< rcirc-prompt-end-marker (point-max))) + (let (input preview) + (goto-char rcirc-prompt-end-marker) + (setq input (buffer-substring (point) (point-max))) + (with-temp-buffer + (insert input) + (rcirc-styles-markup-styles) + (setq preview + (propertize (buffer-substring (point-min) (point-max)) + 'read-only "In preview mode - C-c C-s C-p to continue editing"))) + (goto-char rcirc-prompt-end-marker) + (delete-region (point) (point-max)) + (insert preview) + (setq rcirc-styles-previewed-input input) + (setq rcirc-styles-previewing t) + (message "Previewing styled input - C-c C-s C-p to continue editing")))) + +(defun rcirc-styles--hide-preview nil + "Take the current rcirc buffer out of preview mode. + +Calling this function by hand may well hose your buffer +state. Don't do that." + (when (and rcirc-styles-previewing + rcirc-styles-previewed-input) + (goto-char rcirc-prompt-end-marker) + (setq inhibit-read-only t) + (delete-region (point) (point-max)) + (insert rcirc-styles-previewed-input) + (setq inhibit-read-only nil) + (setq rcirc-styles-previewed-input nil) + (setq rcirc-styles-previewing nil) + (message "Editing input - C-c C-s C-p to preview styles"))) + +;; +;; Keymap definition and bindings; administrative etc. +;; + +(defvar rcirc-styles-map + (make-sparse-keymap) + "Keymap binding `rcirc-styles-insert' functions.") + +(define-key rcirc-styles-map + (kbd "C-p") #'rcirc-styles-toggle-preview) +(define-key rcirc-styles-map + (kbd "C-a") #'rcirc-styles-insert-attribute) +(define-key rcirc-styles-map + (kbd "C-c") #'rcirc-styles-insert-color) + +(defun rcirc-styles-disable-rcirc-controls nil + "Disable rcirc-controls.el, if it is installed." + (and (functionp 'rcirc-markup-controls) + (remove-hook 'rcirc-markup-text-functions #'rcirc-markup-controls)) + (and (functionp 'rcirc-markup-colors) + (remove-hook 'rcirc-markup-text-functions #'rcirc-markup-colors))) + +(defun rcirc-styles-activate nil + "Activate rcirc-styles.el; if necessary, disable rcirc-controls." + ;; forcibly supersede broken rcirc-controls.el to avoid broken behavior + (when (featurep 'rcirc-controls) + (message "rcirc-styles obsoletes rcirc-controls; disabling rcirc-controls.") + (rcirc-styles-disable-rcirc-controls)) + + ;; rcirc.el already added this hook (and defined it, badly) - we need + ;; to get rid of it... + (remove-hook 'rcirc-markup-text-functions 'rcirc-markup-attributes) + ;; ...then add our own hook that does all our markup. + (add-hook 'rcirc-markup-text-functions 'rcirc-styles-markup-styles)) + +;; activate package on load +(rcirc-styles-activate) +;; activate package (again, idempotently) once init is complete, to +;; ensure we catch and supersede rcirc-controls if installed +(add-hook 'after-init-hook #'rcirc-styles-activate) +(provide 'rcirc-styles) + +;;; rcirc-styles.el ends here diff --git a/packages/realgud-20180925.10.tar b/packages/realgud-20190724.2001.tar similarity index 83% rename from packages/realgud-20180925.10.tar rename to packages/realgud-20190724.2001.tar index 921eadf..68c0782 100644 Binary files a/packages/realgud-20180925.10.tar and b/packages/realgud-20190724.2001.tar differ diff --git a/packages/reason-mode-20190710.1037.tar b/packages/reason-mode-20190710.1037.tar new file mode 100644 index 0000000..63f940d Binary files /dev/null and b/packages/reason-mode-20190710.1037.tar differ diff --git a/packages/reformatter-20190529.2238.el b/packages/reformatter-20190529.2238.el new file mode 100644 index 0000000..e4283c7 --- /dev/null +++ b/packages/reformatter-20190529.2238.el @@ -0,0 +1,244 @@ +;;; reformatter.el --- Define commands which run reformatters on the current buffer -*- lexical-binding: t; -*- + +;; Copyright (C) 2019 Steve Purcell + +;; Author: Steve Purcell +;; Keywords: convenience, tools +;; Homepage: https://github.com/purcell/reformatter.el +;; Package-Requires: ((emacs "24.3")) +;; Package-Version: 20190529.2238 +;; Package-X-Original-Version: 0 + +;; 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 . + +;;; Commentary: + +;; This library lets elisp authors easily define an idiomatic command +;; to reformat the current buffer using a command-line program, +;; together with an optional minor mode which can apply this command +;; automatically on save. + +;; In its initial release it supports only reformatters which read +;; from stdin and write to stdout, but a more versatile interface will +;; be provided as development continues. + +;; As an example, let's define a reformat command that applies the +;; "dhall format" command. We'll assume here that we've already defined a +;; variable `dhall-command' which holds the string name or path of the +;; dhall executable: + +;; (reformatter-define dhall-format +;; :program dhall-command +;; :args '("format")) + +;; The `reformatter-define' macro expands to code which generates +;; `dhall-format-buffer' and `dhall-format-region' interactive +;; commands, and a local minor mode called +;; `dhall-format-on-save-mode'. The :args" and :program expressions +;; will be evaluated at runtime, so they can refer to variables that +;; may (later) have a buffer-local value. A custom variable will be +;; generated for the mode lighter, with the supplied value becoming +;; the default. + +;; The generated minor mode allows idiomatic per-directory or per-file +;; customisation, via the "modes" support baked into Emacs' file-local +;; and directory-local variables mechanisms. For example, users of +;; the above example might add the following to a project-specific +;; .dir-locals.el file: + +;; ((dhall-mode +;; (mode . dhall-format-on-save))) + +;; See the documentation for `reformatter-define', which provides a +;; number of options for customising the generated code. + +;; Library authors might like to provide autoloads for the generated +;; code, e.g.: + +;; ;;;###autoload (autoload 'dhall-format-buffer "current-file" nil t) +;; ;;;###autoload (autoload 'dhall-format-region "current-file" nil t) +;; ;;;###autoload (autoload 'dhall-format-on-save-mode "current-file" nil t) + +;;; Code: +(eval-when-compile + (require 'cl-lib)) +(require 'ansi-color) + +;;;###autoload +(cl-defmacro reformatter-define (name &key program args (mode t) lighter keymap group) + "Define a reformatter command with NAME. + +When called, the reformatter will use PROGRAM and any ARGS to +reformat the current buffer. The contents of the buffer will be +passed as standard input to the reformatter, which should output +them to standard output. A nonzero exit code will be reported as +failure, and the output of the command to standard error will be +displayed to the user. + +The macro accepts the following keyword arguments: + +:program (required) + + Provides a form which should evaluate to a string at runtime, + e.g. a literal string, or the name of a variable which holds + the program path. + +:args + + If provided, this is a form which evaluates to a list of + strings at runtime. Default is the empty list. + +:mode + + Unless nil, also generate a minor mode that will call the + reformatter command from `before-save-hook' when enabled. + Default is t. + +:group + + If provided, this is the custom group used for any generated + modes or custom variables. Don't forget to declare this group + using a `defgroup' form. + +:lighter + + If provided, this is a mode lighter string which will be used + for the \"-on-save\" minor mode. It should have a leading + space. The supplied value will be used as the default for a + generated custom variable which specifies the mode lighter. + Default is nil, ie. no lighter. + +:keymap + + If provided, this is the symbol name of the \"-on-save\" mode's + keymap, which you must declare yourself. Default is no keymap. +" + (declare (indent defun)) + (cl-assert (symbolp name)) + (cl-assert program) + ;; Note: we skip using `gensym' here because the macro arguments are only + ;; referred to once below, but this may have to change later. + (let* ((buffer-fn-name (intern (format "%s-buffer" name))) + (region-fn-name (intern (format "%s-region" name))) + (minor-mode-form + (when mode + (let ((on-save-mode-name (intern (format "%s-on-save-mode" name))) + (lighter-name (intern (format "%s-on-save-mode-lighter" name)))) + `(progn + (defcustom ,lighter-name ,lighter + ,(format "Mode lighter for `%s'." on-save-mode-name) + :group ,group + :type 'string) + (define-minor-mode ,on-save-mode-name + ,(format "When enabled, call `%s' when this buffer is saved. + +To enable this unconditionally in a major mode, add this mode +to the major mode's hook. To enable it in specific files or directories, +use the local variables \"mode\" mechanism, e.g. in \".dir-locals.el\" you +might use: + + ((some-major-mode + (mode . %s-on-save))) + " buffer-fn-name name) nil + :global nil + :lighter ,lighter-name + :keymap ,keymap + :group ,group + (if ,on-save-mode-name + (add-hook 'before-save-hook ',buffer-fn-name nil t) + (remove-hook 'before-save-hook ',buffer-fn-name t)))))))) + `(progn + (defun ,region-fn-name (beg end &optional display-errors) + "Reformats the region from BEG to END. +When called interactively, or with prefix argument +DISPLAY-ERRORS, shows a buffer if the formatting fails." + (interactive "rp") + (let* ((err-file (make-temp-file ,(symbol-name name))) + (out-file (make-temp-file ,(symbol-name name))) + ;; Setting this coding system might not universally be + ;; the best default, but was apparently necessary for + ;; some hand-rolled reformatter functions that this + ;; library was written to replace. + (coding-system-for-read 'utf-8) + (coding-system-for-write 'utf-8)) + (unwind-protect + (let* ((error-buffer (get-buffer-create ,(format "*%s errors*" name))) + (retcode + (apply 'call-process-region beg end ,program + nil (list (list :file out-file) err-file) + nil + ,args))) + (with-current-buffer error-buffer + (let ((inhibit-read-only t)) + (insert-file-contents err-file nil nil nil t) + (ansi-color-apply-on-region (point-min) (point-max))) + (special-mode)) + (if (zerop retcode) + (save-restriction + ;; This replacement method minimises + ;; disruption to marker positions and the + ;; undo list + (narrow-to-region beg end) + (reformatter-replace-buffer-contents-from-file out-file) + ;; In future this might be made optional, or a user-provided + ;; ":after" form could be inserted for execution + (whitespace-cleanup)) + (if display-errors + (display-buffer error-buffer) + (message ,(concat (symbol-name name) " failed: see %s") (buffer-name error-buffer))))) + (delete-file err-file) + (delete-file out-file)))) + + (defun ,buffer-fn-name (&optional display-errors) + "Reformats the current buffer. +When called interactively, or with prefix argument +DISPLAY-ERRORS, shows a buffer if the formatting fails." + (interactive "p") + (message "Formatting buffer") + (,region-fn-name (point-min) (point-max) display-errors)) + + ;; This alias will be removed in a future version + (defalias ',name ',buffer-fn-name) + + ,minor-mode-form))) + +(defconst reformatter--can-use-replace-buffer-contents + (when (fboundp 'replace-buffer-contents) + (with-temp-buffer + (insert "\u2666\nabc\n") + (let ((a (current-buffer))) + (with-temp-buffer + (insert "\u2666\naXbc\n") + (replace-buffer-contents a) + (string= (buffer-string) "\u2666\nabc\n"))))) + "Non-nil if `replace-buffer-contents' is present and correct in this Emacs. +Notably, in Emacs 26.1 and corresponding development snapshots, +this function was present but very broken in the presence of +unicode characters.") + +(defun reformatter-replace-buffer-contents-from-file (file) + "Replace the accessible portion of the current buffer with the contents of FILE." + (if reformatter--can-use-replace-buffer-contents + (let ((tmp (generate-new-buffer " *temp*"))) + (unwind-protect + (progn + (with-current-buffer tmp + (insert-file-contents file nil nil nil t)) + (replace-buffer-contents tmp)) + (kill-buffer tmp))) + (insert-file-contents file nil nil nil t))) + + +(provide 'reformatter) +;;; reformatter.el ends here diff --git a/packages/request-20170201.147.el b/packages/request-20190819.1735.el similarity index 89% rename from packages/request-20170201.147.el rename to packages/request-20190819.1735.el index e282ade..4b80afa 100644 --- a/packages/request-20170201.147.el +++ b/packages/request-20190819.1735.el @@ -5,8 +5,9 @@ ;; Free Software Foundation, Inc. ;; Author: Takafumi Arakaki +;; URL: https://github.com/tkf/emacs-request +;; Package-Version: 20190819.1735 ;; Package-Requires: ((emacs "24.4")) -;; Package-Version: 20170201.147 ;; Version: 0.3.0 ;; This file is NOT part of GNU Emacs. @@ -96,14 +97,16 @@ Automatically set to `curl' if curl command is found." (defcustom request-log-level -1 "Logging level for request. -One of `error'/`warn'/`info'/`verbose'/`debug'. +One of `error'/`warn'/`info'/`verbose'/`debug'/`trace'/`blather'. -1 means no logging." :type '(choice (integer :tag "No logging" -1) (const :tag "Level error" error) (const :tag "Level warn" warn) (const :tag "Level info" info) (const :tag "Level Verbose" verbose) - (const :tag "Level DEBUG" debug))) + (const :tag "Level DEBUG" debug) + (const :tag "Level TRACE" trace) + (const :tag "Level BLATHER" blather))) (defcustom request-message-level 'warn "Logging level for request. @@ -113,13 +116,16 @@ See `request-log-level'." (const :tag "Level warn" warn) (const :tag "Level info" info) (const :tag "Level Verbose" verbose) - (const :tag "Level DEBUG" debug))) + (const :tag "Level DEBUG" debug) + (const :tag "Level TRACE" trace) + (const :tag "Level BLATHER" blather))) ;;; Utilities (defun request--safe-apply (function &rest arguments) - (condition-case err + "Apply FUNCTION with ARGUMENTS, suppressing any errors." + (condition-case nil (apply #'apply function arguments) ((debug error)))) @@ -390,6 +396,7 @@ Example:: (files nil) (parser nil) (headers nil) + (encoding 'utf-8) (success nil) (error nil) (complete nil) @@ -405,18 +412,19 @@ Request.el has a single entry point. It is `request'. ==================== ======================================================== Keyword argument Explanation ==================== ======================================================== -TYPE (string) type of request to make: POST/GET/PUT/DELETE -PARAMS (alist) set \"?key=val\" part in URL -DATA (string/alist) data to be sent to the server -FILES (alist) files to be sent to the server (see below) -PARSER (symbol) a function that reads current buffer and return data -HEADERS (alist) additional headers to send with the request -SUCCESS (function) called on success -ERROR (function) called on error -COMPLETE (function) called on both success and error -TIMEOUT (number) timeout in second -STATUS-CODE (alist) map status code (int) to callback -SYNC (bool) If `t', wait until request is done. Default is `nil'. +TYPE (string) type of request to make: POST/GET/PUT/DELETE +PARAMS (alist) set \"?key=val\" part in URL +DATA (string/alist) data to be sent to the server +FILES (alist) files to be sent to the server (see below) +PARSER (symbol) a function that reads current buffer and return data +HEADERS (alist) additional headers to send with the request +ENCODING (symbol) encoding for request body (utf-8 by default) +SUCCESS (function) called on success +ERROR (function) called on error +COMPLETE (function) called on both success and error +TIMEOUT (number) timeout in second +STATUS-CODE (alist) map status code (int) to callback +SYNC (bool) If `t', wait until request is done. Default is `nil'. ==================== ======================================================== @@ -566,6 +574,7 @@ and requests.request_ (Python). (request--urlencode-alist params)))) (setq settings (plist-put settings :url url)) (setq settings (plist-put settings :response response)) + (setq settings (plist-put settings :encoding encoding)) (setf (request-response-settings response) settings) (setf (request-response-url response) url) (setf (request-response--backend response) request-backend) @@ -574,11 +583,6 @@ and requests.request_ (Python). (request--choose-backend 'request-sync) (request--choose-backend 'request)) url settings) - (when timeout - (request-log 'debug "Start timer: timeout=%s sec" timeout) - (setf (request-response--timer response) - (run-at-time timeout nil - #'request-response--timeout-callback response))) response) (defun request--clean-header (response) @@ -631,7 +635,7 @@ then kill the current buffer." (with-current-buffer buffer (request-log 'trace "(buffer-string) at %S =\n%s" buffer (buffer-string)) - (when (/= (request-response-status-code response) 204) + (unless (equal (request-response-status-code response) 204) (goto-char (point-min)) (setf (request-response-data response) (funcall parser))))))) @@ -655,11 +659,19 @@ then kill the current buffer." (done-p (request-response-done-p response))) ;; Parse response header - (request--clean-header response) - (request--cut-header response) ;; Note: Try to do this even `error-thrown' is set. For example, ;; timeout error can occur while downloading response body and ;; header is there in that case. + (let* ((response-url (request-response-url response)) + (scheme (and (stringp response-url) + (url-type (url-generic-parse-url response-url)))) + (curl-file-p (and (stringp scheme) + (not (string-match-p "^http" scheme)) + (eq (request-response--backend response) 'curl)))) + ;; curl does not add a header for say file:///foo/bar + (unless curl-file-p + (request--clean-header response) + (request--cut-header response))) ;; Parse response body (request-log 'debug "error-thrown = %S" error-thrown) @@ -715,28 +727,21 @@ then kill the current buffer." (setf (request-response-error-thrown response) '(error . ("Timeout"))) (let* ((buffer (request-response--buffer response)) (proc (and (buffer-live-p buffer) (get-buffer-process buffer)))) - (when proc - ;; This will call `request--callback': - (funcall (request--choose-backend 'terminate-process) proc)) - - (cl-symbol-macrolet ((done-p (request-response-done-p response))) - (unless done-p - ;; This code should never be executed. However, it occurs - ;; sometimes with `url-retrieve' backend. - ;; FIXME: In Emacs 24.3.50 or later, this is always executed in - ;; request-get-timeout test. Find out if it is fine. - (request-log 'error "Callback is not called when stopping process! \ -Explicitly calling from timer.") - (when (buffer-live-p buffer) - (cl-destructuring-bind (&key code &allow-other-keys) - (with-current-buffer buffer - (goto-char (point-min)) - (request--parse-response-at-point)) - (setf (request-response-status-code response) code))) - (apply #'request--callback - buffer - (request-response-settings response)) - (setq done-p t))))) + (if proc + ;; This will call `request--callback': + (funcall (request--choose-backend 'terminate-process) proc) + (cl-symbol-macrolet ((done-p (request-response-done-p response))) + (unless done-p + (when (buffer-live-p buffer) + (cl-destructuring-bind (&key code &allow-other-keys) + (with-current-buffer buffer + (goto-char (point-min)) + (request--parse-response-at-point)) + (setf (request-response-status-code response) code))) + (apply #'request--callback + buffer + (request-response-settings response)) + (setq done-p t)))))) (defun request-response--cancel-timer (response) (request-log 'debug "REQUEST-RESPONSE--CANCEL-TIMER") @@ -789,6 +794,7 @@ associated process is exited." (buffer (url-retrieve url #'request--url-retrieve-callback (nconc (list :response response) settings))) (proc (get-buffer-process buffer))) + (request--install-timeout timeout response) (setf (request-response--buffer response) buffer) (process-put proc :request-response response) (request-log 'debug "Start querying: %s" url) @@ -797,14 +803,13 @@ associated process is exited." (cl-defun request--url-retrieve-callback (status &rest settings &key response url &allow-other-keys) - (declare (special url-http-method - url-http-response-status)) (request-log 'debug "-URL-RETRIEVE-CALLBACK") (request-log 'debug "status = %S" status) - (request-log 'debug "url-http-method = %s" url-http-method) - (request-log 'debug "url-http-response-status = %s" url-http-response-status) + (when (featurep 'url-http) + (request-log 'debug "url-http-method = %s" url-http-method) + (request-log 'debug "url-http-response-status = %s" url-http-response-status) + (setf (request-response-status-code response) url-http-response-status)) - (setf (request-response-status-code response) url-http-response-status) (let ((redirect (plist-get status :redirect))) (when redirect (setf (request-response-url response) redirect))) @@ -892,7 +897,7 @@ Currently it is used only for testing.") (make-directory (file-name-directory (request--curl-cookie-jar)) t))) (cl-defun request--curl-command - (url &key type data headers timeout response files* unix-socket + (url &key type data headers timeout response files* unix-socket encoding &allow-other-keys &aux (cookie-jar (convert-standard-filename @@ -918,11 +923,14 @@ Currently it is used only for testing.") (when data (let ((tempfile (request--make-temp-file))) (push tempfile (request-response--tempfiles response)) - (let ((file-coding-system-alist nil) - (coding-system-for-write 'binary)) + ;; We dynamic-let the global `buffer-file-coding-system' to `no-conversion' + ;; in case the user-configured `encoding' doesn't fly. + ;; If we do not dynamic-let the global, `select-safe-coding-system' would + ;; plunge us into an undesirable interactive dialogue. + (let ((buffer-file-coding-system 'no-conversion) + (select-safe-coding-system-accept-default-p (lambda (&rest _) t))) (with-temp-file tempfile - (setq buffer-file-coding-system 'binary) - (set-buffer-multibyte nil) + (setq-local buffer-file-coding-system encoding) (insert data))) (list "--data-binary" (concat "@" (request-untrampify-filename tempfile))))) (when type (list "--request" type)) @@ -962,14 +970,9 @@ Currently it is used only for testing.") (defun request--make-temp-file () "Create a temporary file." (if (file-remote-p default-directory) - (let ((tramp-temp-name-prefix request-temp-prefix) - (vec (tramp-dissect-file-name default-directory))) - (tramp-make-tramp-file-name - (tramp-file-name-method vec) - (tramp-file-name-user vec) - (tramp-file-name-host vec) - (tramp-make-tramp-temp-file vec) - (tramp-file-name-hop vec))) + (let ((temporary-file-directory + (tramp-get-remote-tmpdir (tramp-dissect-file-name default-directory)))) + (make-temp-file request-temp-prefix)) (make-temp-file request-temp-prefix))) (defun request--curl-normalize-files (files) @@ -999,8 +1002,16 @@ temporary file paths." "Failed delete file %s. Got: %S" f err)))) files)) +(defun request--install-timeout (timeout response) + "Out-of-band trigger after TIMEOUT seconds to prevent hangs." + (when (numberp timeout) + (request-log 'debug "Start timer: timeout=%s sec" timeout) + (setf (request-response--timer response) + (run-at-time timeout nil + #'request-response--timeout-callback response)))) + (cl-defun request--curl (url &rest settings - &key type data files headers timeout response + &key type data files headers timeout response encoding semaphore &allow-other-keys) "cURL-based request backend. @@ -1021,15 +1032,7 @@ removed from the buffer before it is shown to the parser function. (let* (;; Use pipe instead of pty. Otherwise, curl process hangs. (process-connection-type nil) ;; Avoid starting program in non-existing directory. - (home-directory (if (file-remote-p default-directory) - (let ((vec (tramp-dissect-file-name default-directory))) - (tramp-make-tramp-file-name - (tramp-file-name-method vec) - (tramp-file-name-user vec) - (tramp-file-name-host vec) - "~/" - (tramp-file-name-hop vec))) - "~/")) + (home-directory (or (file-remote-p default-directory) "~/")) (default-directory (expand-file-name home-directory)) (buffer (generate-new-buffer " *request curl*")) (command (cl-destructuring-bind @@ -1037,14 +1040,19 @@ removed from the buffer before it is shown to the parser function. (request--curl-normalize-files files) (setf (request-response--tempfiles response) tempfiles) (apply #'request--curl-command url :files* files* - :response response settings))) + :response response :encoding encoding settings))) (proc (apply #'start-file-process "request curl" buffer command))) + (request--install-timeout timeout response) (request-log 'debug "Run: %s" (mapconcat 'identity command " ")) (setf (request-response--buffer response) buffer) (process-put proc :request-response response) - (set-process-coding-system proc 'binary 'binary) + (set-process-coding-system proc encoding encoding) (set-process-query-on-exit-flag proc nil) - (set-process-sentinel proc #'request--curl-callback))) + (set-process-sentinel proc 'request--curl-callback) + (when semaphore + (set-process-sentinel proc (lambda (&rest args) + (apply #'request--curl-callback args) + (apply semaphore args)))))) (defun request--curl-read-and-delete-tail-info () "Read a sexp at the end of buffer and remove it and preceding character. @@ -1157,19 +1165,27 @@ START-URL is the URL requested." (setf (request-response-url response) url-effective) (setf (request-response-history response) history) (setf (request-response-error-thrown response) - (or error (when (>= code 400) `(error . (http ,code))))) + (or error (and (numberp code) (>= code 400) `(error . (http ,code))))) (apply #'request--callback buffer settings)))))) (cl-defun request--curl-sync (url &rest settings &key response &allow-other-keys) - ;; To make timeout work, use polling approach rather than using - ;; `call-process'. (let (finished) (prog1 (apply #'request--curl url - :complete (lambda (&rest _) (setq finished t)) + :semaphore (lambda (&rest _) (setq finished t)) settings) (let ((proc (get-buffer-process (request-response--buffer response)))) - (while (and (not finished) (request--process-live-p proc)) - (accept-process-output proc)))))) + (with-local-quit + (cl-loop with iter = 0 + until (or (>= iter 10) finished) + if (request--process-live-p proc) + do (accept-process-output proc 0.3) + else + do (cl-incf iter) and + do (sleep-for 0 300) + end + finally (when (>= iter 10) + (request-log 'verbose + "request--curl-sync: semaphore never called")))))))) (defun request--curl-get-cookies (host localpart secure) (request--netscape-get-cookies (request--curl-cookie-jar) diff --git a/packages/request-deferred-20160419.2305.el b/packages/request-deferred-20181129.317.el similarity index 96% rename from packages/request-deferred-20160419.2305.el rename to packages/request-deferred-20181129.317.el index d6e1d00..cf7a050 100644 --- a/packages/request-deferred-20160419.2305.el +++ b/packages/request-deferred-20181129.317.el @@ -3,8 +3,9 @@ ;; Copyright (C) 2012 Takafumi Arakaki ;; Author: Takafumi Arakaki +;; URL: https://github.com/tkf/emacs-request +;; Package-Version: 20181129.317 ;; Package-Requires: ((deferred "0.3.1") (request "0.2.0")) -;; Package-Version: 20160419.2305 ;; Version: 0.2.0 ;; This file is NOT part of GNU Emacs. diff --git a/packages/restclient-20180316.1551.el b/packages/restclient-20190502.2214.el similarity index 97% rename from packages/restclient-20180316.1551.el rename to packages/restclient-20190502.2214.el index ec13a62..335530d 100644 --- a/packages/restclient-20180316.1551.el +++ b/packages/restclient-20190502.2214.el @@ -6,7 +6,7 @@ ;; Maintainer: Pavel Kurnosov ;; Created: 01 Apr 2012 ;; Keywords: http -;; Package-Version: 20180316.1551 +;; Package-Version: 20190502.2214 ;; This file is not part of GNU Emacs. ;; This file is public domain software. Do what you want. @@ -237,7 +237,8 @@ (match-string-no-properties 1) "/" (match-string-no-properties 2)) - restclient-content-type-modes)))) + restclient-content-type-modes + t)))) (forward-line)) 0))) (setq end-of-headers (point)) (while (and (looking-at restclient-empty-line-regexp) @@ -274,7 +275,12 @@ (insert-image (create-image img nil t)))) ((eq guessed-mode 'js-mode) - (let ((json-special-chars (remq (assoc ?/ json-special-chars) json-special-chars))) + (let ((json-special-chars (remq (assoc ?/ json-special-chars) json-special-chars)) + ;; Emacs 27 json.el uses `replace-buffer-contents' for + ;; pretty-printing which is great because it keeps point and + ;; markers intact but can be very slow with huge minimalized + ;; JSON. We don't need that here. + (json-pretty-print-max-secs 0)) (ignore-errors (json-pretty-print-buffer))) (restclient-prettify-json-unicode))) @@ -309,6 +315,7 @@ The buffer contains the raw HTTP response sent by the server." (unless raw (restclient-prettify-response method url)) (buffer-enable-undo) + (restclient-response-mode) (run-hooks 'restclient-response-loaded-hook) (if stay-in-window (display-buffer (current-buffer) t) @@ -596,6 +603,15 @@ Optional argument STAY-IN-WINDOW do not move focus to response buffer if t." ("\C-c\C-a" . restclient-toggle-body-visibility-or-indent)) :group 'restclient) +(define-minor-mode restclient-response-mode + "Minor mode to allow additional keybindings in restclient response buffer." + :init-value nil + :lighter nil + :keymap '(("q" . (lambda () + (interactive) + (quit-window (get-buffer-window (current-buffer)))))) + :group 'restclient) + ;;;###autoload (define-derived-mode restclient-mode fundamental-mode "REST Client" "Turn on restclient mode." diff --git a/packages/rjsx-mode-20180913.2224.el b/packages/rjsx-mode-20190614.2215.el similarity index 97% rename from packages/rjsx-mode-20180913.2224.el rename to packages/rjsx-mode-20190614.2215.el index 49d2d2f..5928c34 100644 --- a/packages/rjsx-mode-20180913.2224.el +++ b/packages/rjsx-mode-20190614.2215.el @@ -4,7 +4,7 @@ ;; Author: Felipe Ochoa ;; URL: https://github.com/felipeochoa/rjsx-mode/ -;; Package-Version: 20180913.2224 +;; Package-Version: 20190614.2215 ;; Package-Requires: ((emacs "24.4") (js2-mode "20170504")) ;; Version: 1.1 ;; Keywords: languages @@ -35,6 +35,7 @@ (require 'js2-mode) (eval-when-compile (require 'subr-x)) (require 'newcomment) +(require 'sgml-mode) (defgroup rjsx-mode nil "Support for JSX." @@ -49,7 +50,7 @@ parsing supports the magic `rjsx-electric-lt' and :type 'integer) ;;;###autoload -(define-derived-mode rjsx-mode js2-jsx-mode "RJSX" +(define-derived-mode rjsx-mode js2-mode "RJSX" "Major mode for editing JSX files." :lighter ":RJSX" :group 'rjsx-mode @@ -974,6 +975,43 @@ NEW-NAME is the name to give the tag." (define-key rjsx-mode-map (kbd "C-c C-r") 'rjsx-rename-tag-at-point) + +(defun rjsx-jump-closing-tag () + "Go to closing tag of tag at point." + (interactive) + (let* ((tag (rjsx--tag-at-point)) + (closer (and tag (rjsx-node-closing-tag tag)))) + (cond + ((null tag) (message "No JSX tag found at point")) + ((null closer) (message "JSX tag is self closing")) + (t + (goto-char (+ 1 (js2-node-abs-pos closer))))))) + + +(defun rjsx-jump-opening-tag () + "Go to opening tag of tag at point." + (interactive) + (let ((tag (rjsx--tag-at-point))) + (if (null tag) (message "No JSX tag found at point") + (goto-char (+ 1 (js2-node-abs-pos tag)))))) + +(defun rjsx-jump-tag () + "Switch between opening and closing tag of tag at point." + (interactive) + (let* ((tag (rjsx--tag-at-point)) + (closer (and tag (rjsx-node-closing-tag tag)))) + (cond + ((null tag) (message "No JSX tag found at point")) + ((null closer) (message "No closing JSX tag found at point")) + ((eq (line-number-at-pos (js2-node-abs-pos tag)) (line-number-at-pos)) (rjsx-jump-closing-tag)) + ((eq (line-number-at-pos (js2-node-abs-pos closer)) (line-number-at-pos)) (rjsx-jump-opening-tag)) + (t + (rjsx-jump-opening-tag))))) + + + +(define-key rjsx-mode-map (kbd "C-c C-j") 'rjsx-jump-tag) + ;; Utilities diff --git a/packages/robe-20171116.2049.tar b/packages/robe-20190521.58.tar similarity index 75% rename from packages/robe-20171116.2049.tar rename to packages/robe-20190521.58.tar index 2732c6b..9378685 100644 Binary files a/packages/robe-20171116.2049.tar and b/packages/robe-20190521.58.tar differ diff --git a/packages/rspec-mode-20180614.1148.tar b/packages/rspec-mode-20190609.1123.tar similarity index 79% rename from packages/rspec-mode-20180614.1148.tar rename to packages/rspec-mode-20190609.1123.tar index d04d8d5..9e68107 100644 Binary files a/packages/rspec-mode-20180614.1148.tar and b/packages/rspec-mode-20190609.1123.tar differ diff --git a/packages/rtags-20181117.2108.el b/packages/rtags-20190820.502.el similarity index 94% rename from packages/rtags-20181117.2108.el rename to packages/rtags-20190820.502.el index a853630..e0b8eeb 100644 --- a/packages/rtags-20181117.2108.el +++ b/packages/rtags-20190820.502.el @@ -5,8 +5,8 @@ ;; Author: Jan Erik Hanssen ;; Anders Bakken ;; URL: http://rtags.net -;; Package-Version: 20181117.2108 -;; Version: 2.10 +;; Package-Version: 20190820.502 +;; Version: 2.33.128 ;; This file is not part of GNU Emacs. @@ -45,6 +45,7 @@ (defalias 'defun* 'cl-defun)) (require 'bookmark) (require 'cc-mode) +(require 'asm-mode) (require 'tramp) (require 'simple) (require 'compile) @@ -73,8 +74,8 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defconst rtags-protocol-version 127) -(defconst rtags-package-version "2.20") +(defconst rtags-protocol-version 128) +(defconst rtags-package-version "2.33") (defconst rtags-popup-available (require 'popup nil t)) (defconst rtags-supported-major-modes '(c-mode c++-mode objc-mode) "Major modes RTags supports.") (defconst rtags-verbose-results-delimiter "------------------------------------------") @@ -123,7 +124,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defcustom rtags-enabled t "Whether RTags is enabled. We try to do nothing when it's not." - :group 'rtags :type 'boolean :safe 'booleanp) @@ -139,7 +139,6 @@ compilation-finish-functions)))) (defcustom rtags-suspend-during-compilation nil "Suspend during compilation." - :group 'rtags :type 'boolean :safe 'booleanp :set (lambda (var val) @@ -147,15 +146,20 @@ (rtags-set-suspend-during-compilation-enabled))) +(defcustom rtags-verify-protocol-version t + "Set to nil if you don't want to verify the protocol version. +Note that all sorts of wrong things could happen when running +with mismatched versions" + :type 'boolean + :safe 'booleanp) + (defcustom rtags-use-mark-as-current-symbol nil "Use mark, when visible as default for rtags-find-symbol." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-completing-read-behavior 'insert-default "Behavior for completing-read" - :group 'rtags :type '(choice (const :tag "insert default" insert-default) (const :tag "default when empty" default-when-empty) @@ -165,94 +169,79 @@ (defcustom rtags-use-bookmarks t "Whether RTags uses bookmarks for locations." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-find-file-absolute nil "Whether `rtags-find-file' shows absolute paths." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-wrap-results t "Whether `rtags-next-match'/`rtags-previous-match' wraps around." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-close-taglist-on-focus-lost nil "Whether `rtags-taglist' should close when it loses focus." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-close-taglist-on-selection t "Whether `rtags-taglist' should close when something is selected." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-follow-symbol-try-harder t "Fall back to string-matching, if follow symbol fails." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-reindex-on-save nil "Explicitly reindex files on save. This is only useful if your file system watching is not working." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-use-filename-completion t "Whether RTags special filename completion is enabled. Set to nil to enable ido-ubiquitous etc." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-diagnostics-use-pipe t "Whether diagnostics should use pipes. If you're running Emacs in cygwin you might have to set this to nil." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-autostart-diagnostics nil "Whether RTags automatically will restart diagnostics." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-spellcheck-enabled t "Whether RTags does syntax checking with overlays etc to mark errors, warnings and fixups." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-multiple-targets t "Whether RTags will offer multiple choices for `rtags-find-symbol-at-point' when appropriate, warnings and fixups." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-verbose-results nil "Print more verbose results buffer." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-sort-references-by-input t "Whether RTags sorts the references based on the input to `rtags-find-references'." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-completions-enabled nil "Whether completions are enabled." - :group 'rtags :type 'boolean :safe 'booleanp) @@ -291,7 +280,6 @@ nil (Unset) means don't reparse preemptively. Setting this variable directly has no effect, either set this variable using the Customize interface, `rtags-set-periodic-reparse-timeout', `customize-set-variable' or `custom-set-variables'." - :group 'rtags :type '(choice (const :tag "Unset" nil) number) :risky nil :set (lambda (var val) @@ -301,31 +289,26 @@ the Customize interface, `rtags-set-periodic-reparse-timeout', (defcustom rtags-update-current-project-timer-interval .5 "Interval for update current project timer." - :group 'rtags :type 'number :safe 'numberp) (defcustom rtags-imenu-syntax-highlighting nil "Set to t to enable syntax highlight in rtags-imenu. If rtags-imenu-syntax-highlighting is set to a number this is considered the max number of lines to highlight" - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-wildcard-symbol-names t "Allow use of * and ? to match symbol names." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-tracking nil "When on automatically jump to symbol under cursor in *RTags* buffer." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-tramp-enabled nil "Enable tramp support." - :group 'rtags :type 'boolean :safe 'booleanp) @@ -387,7 +370,11 @@ the Customize interface, `rtags-set-periodic-reparse-timeout', ;; (defcustom rtags-socket-file "" "Socket file to pass to rc." - :group 'rtags + :type 'string + :safe 'stringp) + +(defcustom rtags-socket-address"" + "Socket address to pass to rc." :type 'string :safe 'stringp) @@ -404,83 +391,68 @@ appropriate format string for `error'. For example, \"Unable to connect to the RTags server. See BLAH to start it\") (t (rtags-error-message-default type))))" - :group 'rtags :type 'function) (defcustom rtags-find-file-prompt "Find files" "What prompt to use for `rtags-find-file'." - :group 'rtags :type 'string :type 'stringp) (defcustom rtags-track-container nil - "When on continually update current container (function/class/namespace) -on intervals." - :group 'rtags + "When on continually update current container (function/class/namespace) on intervals." :type 'boolean :safe 'booleanp) (defcustom rtags-error-timer-interval .5 "Interval for minibuffer error timer." - :group 'rtags :type 'number :safe 'numberp) (defcustom rtags-display-current-error-as-message t "Display error under cursor using (message)." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-display-current-error-as-tooltip nil "Display error under cursor using `popup-tip' (requires 'popup)." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-display-summary-as-tooltip rtags-popup-available "Display help / summary text using `popup-tip' (requires 'popup)." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-tooltips-enabled (and rtags-popup-available t) "Display help / summary text when hovering over symbols." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-error-timer-interval .5 "Interval for minibuffer error timer." - :group 'rtags :type 'number :safe 'numberp) (defcustom rtags-tracking-timer-interval .5 "Interval for tracking timer." - :group 'rtags :type 'number :safe 'numberp) (defcustom rtags-container-timer-interval .5 "Interval for container timer." - :group 'rtags :type 'number :safe 'numberp) (defcustom rtags-current-container-hook nil "Run after RTags has set the current container." - :group 'rtags :type 'hook) (defcustom rtags-is-indexable 'rtags-is-indexable-default - "What function to call for expansions." - :group 'rtags + "defun for determining what files are indexable by rtags." :type 'function) (defcustom rtags-bury-buffer-function 'rtags-bury-or-delete "The function used to bury or kill the current rtags buffer." - :group 'rtags :type '(radio (function-item rtags-bury-or-delete) (function-item quit-window) @@ -489,22 +461,18 @@ on intervals." (defcustom rtags-after-find-file-hook nil "Run after RTags has jumped to a location possibly in a new file." - :group 'rtags :type 'hook) (defcustom rtags-mode-hook nil "Run when `rtags-mode' is started." - :group 'rtags :type 'hook) (defcustom rtags-diagnostics-hook nil "Run after diagnostics have been parsed." - :group 'rtags :type 'hook) (defcustom rtags-diagnostics-summary-in-mode-line t "Display diagnostics count (warnings, errors, fixits) in the mode line" - :group 'rtags :type 'boolean :set (lambda (var val) (set var val) @@ -514,123 +482,112 @@ on intervals." (defcustom rtags-completions-hook nil "Run after completions have been parsed." - :group 'rtags :type 'hook) (defcustom rtags-edit-hook nil "Run before RTags tries to modify a buffer (from rtags-rename) return t if RTags is allowed to modify this file." - :group 'rtags :type 'hook) (defcustom rtags-switch-to-buffer-hook nil "Run after RTags has switched to a buffer" - :group 'rtags :type 'hook) (defcustom rtags-jump-to-first-match t "If t, jump to first match." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-highlight-current-line t "If t, highlight the current line in *RTags* buffer." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-timeout nil "Max amount of ms to wait before timing out requests." - :group 'rtags :type '(choice (const :tag "Unset" nil) integer) :safe 'integerp) +(defcustom rtags-rc-binary-name "rc" + "Name of rc binary file." + :type 'string + :risky t) + +(defcustom rtags-rdm-binary-name "rdm" + "Name of rdm binary file." + :type 'string + :risky t) + (defcustom rtags-path nil "Path to RTags executables." - :group 'rtags :type '(choice (const :tag "Unset" nil) directory) :risky t) (defcustom rtags-rc-config-path nil "Path to for configuration file for rc." - :group 'rtags :type '(choice (const :tag "Unset" nil) directory) :risky t) (defcustom rtags-install-path nil "Path to install rtags using rtags-package-install RTags executables." - :group 'rtags :type '(choice (const :tag "Unset" nil) directory) :risky t) (defcustom rtags-max-bookmark-count 100 "How many bookmarks to keep on the stack." - :group 'rtags :type 'integer :safe 'integerp) (defcustom rtags-rc-log-enabled nil "If t, log rc commands and responses." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-show-containing-function nil "If t, pass -o to rc to include containing function." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-enable-unsaved-reparsing nil "Whether rtags will reparse unsaved buffers as needed." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-reparse-timeout nil "Max number of ms you're willing to wait for a reparse to finish." - :group 'rtags :type '(choice (const :tag "Unset" nil) integer) :safe 'integerp) (defcustom rtags-find-file-case-insensitive nil "Treat files case-insensitively." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-symbolnames-case-insensitive nil "Treat symbol names case-insensitively." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-find-file-prefer-exact-match t "Jump directly to files that exactly match the filename for `rtags-find-file'." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-other-window-window-size-percentage 30 "Percentage size of other buffer." - :group 'rtags :type 'integer) (defcustom rtags-split-window-function 'split-window "Function to split window. default is `split-window'." - :group 'rtags :type 'function) (defcustom rtags-results-buffer-other-window nil "Open rtags find results buffer in `other-window'." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-other-window-function #'(lambda () (other-window 1)) "Function select another window. default is (`other-window' 1)." - :group 'rtags :type 'function) (defcustom rtags-buffer-follows-sandbox-id-match 'ask @@ -645,7 +602,6 @@ return t if RTags is allowed to modify this file." Note: If *RTags Diagnostics* is not running, then the 'match check' is not performed, because sandbox tracking is not needed then. Note: It is recommended to run each sandbox is separate Emacs process." - :group 'rtags :type '(choice (const :tag "Perform query without update" nil) (const :tag "Ask the user" ask) @@ -654,30 +610,25 @@ Note: It is recommended to run each sandbox is separate Emacs process." (defcustom rtags-includes-func 'rtags-dummy-includes-func "Function to return flags and include flags for rdm." - :group 'rtags :type 'function) (defcustom rtags-rdm-includes "" "Additional include paths." - :group 'rtags :type 'string :safe 'stringp) (defcustom rtags-process-flags "" "Flags for rdm." - :group 'rtags :type 'string :safe 'stringp) (defcustom rtags-rdm-process-use-pipe nil "If t, use pipes to communicate with rdm." - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-popup-results-buffer t "Popup the *RTags* buffer when more than one search result is obtained." - :group 'rtags :type 'boolean :safe 'booleanp) @@ -687,13 +638,11 @@ Note: It is recommended to run each sandbox is separate Emacs process." (const :tag "RTags (default)" default) (const :tag "Helm" helm) (const :tag "Ivy" ivy)) - :group 'rtags :type 'symbol :risky t) (defcustom rtags-imenu-kind-filter "-references,-vardecl,-parmdecl,-inclusiondirective,-*literal*,-enumconstantdecl,-classdecl-,-structdecl-,-classtemplate-,-statements,-lambdaexpr" "Argument passed to --kind-filter for `rtags-imenu'." - :group 'rtags :type 'string :safe 'stringp) @@ -709,14 +658,12 @@ Effected interactive functions: - `rtags-find-references-at-point' - `rtags-find-all-references-at-point' - `rtags-print-class-hierarchy'" - :group 'rtags :type 'boolean :safe 'booleanp) (defcustom rtags-use-multiple-cursors nil "When non-nil, commands like `rtags-rename-symbol' may use features of the package `multiple-cursors', if it is installed." - :group 'rtags :type 'boolean :safe 'booleanp) @@ -724,64 +671,58 @@ of the package `multiple-cursors', if it is installed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Faces ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defface rtags-path nil "Path" :group 'rtags) -(defface rtags-context nil "Context" :group 'rtags) +(defface rtags-path nil "Path") +(defface rtags-context nil "Context") (defface rtags-warnline - '((((class color) (background light) (supports :underline (:style wave))) - :underline (:style wave :color "black") - :foreground "black" :background "yellow") - (((class color) (background dark) (supports :underline (:style wave))) - :underline (:style wave :color "white") - :foreground "white" :background "OrangeRed") - (t - :underline t :inherit error)) - "Face used for marking error lines." - :group 'rtags) + '((((class color) (background light) (supports :underline (:style wave))) + :underline (:style wave :color "black") + :foreground "black" :background "yellow") + (((class color) (background dark) (supports :underline (:style wave))) + :underline (:style wave :color "white") + :foreground "white" :background "OrangeRed") + (t + :underline t :inherit error)) + "Face used for marking error lines.") (defface rtags-errline - '((((class color) (background light) (supports :underline (:style wave))) - :underline (:style wave :color "red") - :foreground "red" :background "yellow") - (((class color) (background dark) (supports :underline (:style wave))) - :underline (:style wave :color "white") - :foreground "white" :background "red") - (t - :underline t :inherit error)) - "Face used for marking warning lines." - :group 'rtags) + '((((class color) (background light) (supports :underline (:style wave))) + :underline (:style wave :color "red") + :foreground "red" :background "yellow") + (((class color) (background dark) (supports :underline (:style wave))) + :underline (:style wave :color "white") + :foreground "white" :background "red") + (t + :underline t :inherit error)) + "Face used for marking warning lines.") (defface rtags-fixitline - '((((class color) (background light) (supports :underline (:style wave))) - :underline (:style wave :color "brown") - :foreground "brown" :background "yellow" :slant italic) - (((class color) (background dark) (supports :underline (:style wave))) - :underline (:style wave :color "white") - :foreground "white" :background "brown" :slant italic) - (t - :underline t :inherit error)) - "Face used for marking fixit lines." - :group 'rtags) + '((((class color) (background light) (supports :underline (:style wave))) + :underline (:style wave :color "brown") + :foreground "brown" :background "yellow" :slant italic) + (((class color) (background dark) (supports :underline (:style wave))) + :underline (:style wave :color "white") + :foreground "white" :background "brown" :slant italic) + (t + :underline t :inherit error)) + "Face used for marking fixit lines.") (defface rtags-current-line - '((((class color) (background dark)) (:background "gray19")) - (((class color) (background light)) (:background "LightGray")) - (t (:bold t))) - "Face used for highlighting current line." - :group 'rtags) + '((((class color) (background dark)) (:background "gray19")) + (((class color) (background light)) (:background "LightGray")) + (t (:bold t))) + "Face used for highlighting current line.") (defface rtags-skippedline - '((((class color) (background dark)) (:background "gray12")) - (((class color) (background light)) (:background "light gray"))) - "Face used for marking skipped lines." - :group 'rtags) + '((((class color) (background dark)) (:background "gray12")) + (((class color) (background light)) (:background "light gray"))) + "Face used for marking skipped lines.") (defface rtags-argument-face - '((((class color) (background dark)) (:background "blue")) ;; e.g. white on blue - (((class color) (background light)) (:background "cyan" )) ;; e.g. black on cyan - (t (:bold t))) - "Face used for marking error lines." - :group 'rtags) + '((((class color) (background dark)) (:background "blue")) ;; e.g. white on blue + (((class color) (background light)) (:background "cyan" )) ;; e.g. black on cyan + (t (:bold t))) + "Face used for marking error lines.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Logic @@ -817,7 +758,7 @@ of the package `multiple-cursors', if it is installed." (let ((suffix (and (string-match "\.\\([^.]+\\)$" filename) (match-string 1 filename)))) (or (not suffix) (and (member (downcase suffix) - (list "cpp" "h" "cc" "c" "cp" "cxx" "m" "mm" "tcc" "txx" "moc" "hxx" "hh" "hpp" "inc")) + (list "cpp" "h" "cc" "c" "cp" "cxx" "m" "mm" "tcc" "txx" "moc" "hxx" "hh" "hpp" "inc" "tpp")) t)))))) (defun rtags-get-buffer (&optional name) @@ -1245,26 +1186,31 @@ Function based on org-babel-tramp-handle-call-process-region" (apply 'call-process-region start end program delete buffer display args))) +(defun rtags--alter-path-in-tramp-location (tramp-location new-location) + "Set path part of TRAMP-LOCATION to NEW-LOCATION." + + ;; From helm-files.el + ;; `tramp-dissect-file-name' returns a list in emacs-26 + ;; whereas in 24.5 it returns a vector, thus the car is a + ;; symbol (`tramp-file-name') which is not needed as argument + ;; for `tramp-make-tramp-file-name' so transform the cdr in + ;; vector, and for 24.5 use directly the returned value. + (let ((location-vec + (cl-loop with v = (rtags--tramp-cons-or-vector + (tramp-dissect-file-name tramp-location)) + for i across v collect i))) + (setf (nth (if (= (length location-vec) 5) 3 5) location-vec) new-location) + (apply #'tramp-make-tramp-file-name location-vec))) + (defun rtags-trampify (absolute-location) - "if absolute-location is tramped, then return it. -Otherwise if default-directory is tramp one, then uses it to convert -absolute-location to remote. absolute-location can of course be a path" + "If ABSOLUTE-LOCATION is a tramp location return it unmodified. +Otherwise if `default-directory' is a remote location, then use it to convert +ABSOLUTE-LOCATION to a remote location." (if (or (not rtags-tramp-enabled) (not (tramp-tramp-file-p default-directory)) (tramp-tramp-file-p absolute-location)) absolute-location - ;; From helm-files.el - ;; `tramp-dissect-file-name' returns a list in emacs-26 - ;; whereas in 24.5 it returns a vector, thus the car is a - ;; symbol (`tramp-file-name') which is not needed as argument - ;; for `tramp-make-tramp-file-name' so transform the cdr in - ;; vector, and for 24.5 use directly the returned value. - (let ((location-vec - (cl-loop with v = (rtags--tramp-cons-or-vector - (tramp-dissect-file-name default-directory)) - for i across v collect i))) - (setf (nth (if (= (length location-vec) 5) 3 5) location-vec) absolute-location) - (apply #'tramp-make-tramp-file-name location-vec)))) + (rtags--alter-path-in-tramp-location default-directory absolute-location))) (defun rtags--tramp-cons-or-vector (vector-or-cons) "Return VECTOR-OR-CONS as a vector." @@ -1294,6 +1240,20 @@ to only call this when `rtags-socket-file' is defined. (concat "--socket-file=" (car rtags--socket-file-cache))) +(defvar rtags--socket-address-cache '("" "")) +(defun rtags--get-socket-address-switch () + "Private function which, validates on first access that +`rtags-socket-address' exists and returns +--socket-address=/expanded/path/to/socket/address. Caller is expected +to only call this when `rtags-socket-address' is defined. +" + (when (not (string-equal (car rtags--socket-address-cache) rtags-socket-address)) + (setq rtags--socket-address-cache (list rtags-socket-address (expand-file-name rtags-socket-address))) + (unless (car rtags--socket-address-cache) + (rtags--error 'rtags-socket-address-does-not-exist rtags-socket-address))) + + (concat "--socket-address=" (car rtags--socket-address-cache))) + (defun rtags--convert-output-buffer (arg) (cond ((null arg) nil) ((eq t arg) (current-buffer)) @@ -1317,7 +1277,7 @@ to only call this when `rtags-socket-file' is defined. silent-query &allow-other-keys) (save-excursion - (let ((rc (rtags-executable-find "rc")) + (let ((rc (rtags-executable-find rtags-rc-binary-name)) (tempfile)) (if (not rc) (unless noerror (rtags--error 'rtags-cannot-find-rc)) @@ -1329,7 +1289,8 @@ to only call this when `rtags-socket-file' is defined. (setq arguments (mapcar 'rtags-untrampify arguments)) ;; other way to ignore colors would IMHO be to configure tramp, ;; but: do we need colors from rc? - (push (format "-t%d" rtags-protocol-version) arguments) + (when rtags-verify-protocol-version + (push (format "-t%d" rtags-protocol-version) arguments)) (push "-z" arguments) (setq path (rtags-untrampify path)) (when path-filter @@ -1370,10 +1331,13 @@ to only call this when `rtags-socket-file' is defined. (when (> (length rtags-socket-file) 0) (push (rtags--get-socket-file-switch) arguments)) + (when (> (length rtags-socket-address) 0) + (push (rtags--get-socket-address-switch) arguments)) + (when rtags-rc-log-enabled (rtags-log (concat rc " " (rtags-combine-strings arguments)))) (if async - (let ((proc (apply #'start-file-process "rc" (current-buffer) rc arguments))) + (let ((proc (apply #'start-file-process rtags-rc-binary-name (current-buffer) rc arguments))) (set-process-query-on-exit-flag proc nil) (when (car async) (set-process-filter proc (car async))) @@ -1403,7 +1367,7 @@ to only call this when `rtags-socket-file' is defined. (erase-buffer) (setq rtags-last-request-not-indexed t)) ((equal result "Aborted") - (rtags--error 'rtags-program-exited-abnormal "rc" result)) + (rtags--error 'rtags-program-exited-abnormal rtags-rc-binary-name result)) (t))) ;; other error (and (> (point-max) (point-min)) (equal result rtags-exit-code-success)))))))) @@ -1418,6 +1382,16 @@ to only call this when `rtags-socket-file' is defined. (rtags--error 'rtags-set-buffer-file-read-only (rtags-buffer-file-name))) (setq buffer-read-only t)) +(defvar rtags-asm-mode-map (make-sparse-keymap)) +(define-key rtags-asm-mode-map (kbd "q") 'rtags-call-bury-or-delete) +(set-keymap-parent rtags-asm-mode-map c++-mode-map) +(define-derived-mode rtags-asm-mode asm-mode "rtags-asm" + ;; Do not run any hooks from `asm-mode', as this could cause issues with, e.g. flycheck + (set (make-local-variable 'asm-mode-hook) nil) + (when (rtags-buffer-file-name) + (rtags--error 'rtags-set-buffer-file-read-only (rtags-buffer-file-name))) + (setq buffer-read-only t)) + (defun rtags-sources (&optional file) (with-temp-buffer (rtags-call-rc :path file "--sources" file) @@ -1471,6 +1445,22 @@ It uses the stored compile command from the RTags database for preprocessing." (rtags-preprocess-mode)) (display-buffer preprocess-buffer))))) +;;;###autoload +(defun rtags-asm-file (&optional buffer) + "Assemble buffer. +If optional BUFFER is given, use BUFFER instead of `current-buffer'. +It uses the stored compile command from the RTags database for assembling." + (interactive) + (when (or (not (rtags-called-interactively-p)) (rtags-sandbox-id-matches)) + (unless buffer (setq buffer (current-buffer))) + (let ((asm-buffer (rtags-get-buffer (format "*RTags assembled %s*" (rtags-buffer-file-name buffer))))) + (rtags-delete-rtags-windows) + (rtags-location-stack-push) + (with-current-buffer asm-buffer + (rtags-call-rc :path (rtags-buffer-file-name buffer) "--asm" (rtags-buffer-file-name buffer)) + (rtags-asm-mode)) + (display-buffer asm-buffer)))) + (defvar rtags-completing-read-default-value nil) (defun rtags-setup-minibuffer-hook () (when (> (length rtags-completing-read-default-value) 0) @@ -1513,7 +1503,6 @@ It uses the stored compile command from the RTags database for preprocessing." (defcustom rtags-completing-read-behavior 'insert-default-marked "Behavior for completing-read" - :group 'rtags :type '(choice (const :tag "insert default" insert-default) (const :tag "default when empty" helm) @@ -1666,6 +1655,17 @@ instead of file from `current-buffer'. (rtags-call-rc :path fn "--dependencies" fn args (unless rtags-print-filenames-relative "-K")) (rtags-mode)))) +(defun rtags-print-include-path () + "Print include path of the current symbol in cursor." + (interactive) + (let ((dep-buffer (rtags-get-buffer "*RTags Include Path*")) + (arg (rtags-current-location))) + (rtags-delete-rtags-windows) + (rtags-location-stack-push) + (rtags-switch-to-buffer dep-buffer) + (rtags-call-rc "--include-path" arg) + (rtags-mode))) + (defun rtags-find-dead-functions (&optional prefix buffer) "Print information about uncalled functions in buffer." (interactive "P") @@ -2391,42 +2391,53 @@ instead of file from `current-buffer'. ;; (message (format "rtags-goto-location \"%s\"" location)) (setq location (rtags-absolutify location skip-trampification)) - (when (> (length location) 0) - (cond ((string-match "\\(.*\\) includes /.*" location) - (rtags-find-file-or-buffer (match-string-no-properties 1 location) other-window)) - ((and (string-match "[^ ]* should include /" location) - (string= (buffer-substring-no-properties (point-at-bol) (+ (point-at-bol) (length location))) + (let* ((is-location-remote (tramp-tramp-file-p location)) + (path-segment (if is-location-remote + (tramp-file-name-localname (tramp-dissect-file-name location)) location)) - (save-excursion - (if (search-backward-regexp "[ (]" (point-at-bol) t) - (forward-char 1) - (goto-char (point-at-bol))) - (let ((pos (point))) - (search-forward-regexp " ") - (rtags-goto-location (buffer-substring-no-properties pos (1- (point))) nobookmark other-window)))) - ((string-match "\\(.*?\\):\\([0-9]+\\):\\([0-9]+\\):?" location) - (let ((line (string-to-number (match-string-no-properties 2 location))) - (column (string-to-number (match-string-no-properties 3 location)))) - (rtags-find-file-or-buffer (match-string-no-properties 1 location) other-window) - (push-mark nil t) - (rtags-goto-line-col line column))) - ((string-match "\\(.*?\\):\\([0-9]+\\):?" location) - (let ((line (string-to-number (match-string-no-properties 2 location)))) - (rtags-find-file-or-buffer (match-string-no-properties 1 location) other-window) - (push-mark nil t) - (goto-char (point-min)) - (forward-line (1- line)))) - ((string-match "\\(.*?\\),\\([0-9]+\\)" location) - (let ((offset (string-to-number (match-string-no-properties 2 location)))) - (rtags-find-file-or-buffer (match-string-no-properties 1 location) other-window) - (push-mark nil t) - (rtags-goto-offset offset))) - (t - (when (string-match "^[ \t]+\\(.*\\)$" location) - (setq location (match-string-no-properties 1 location))) - (rtags-find-file-or-buffer location other-window))) - (unless nobookmark (rtags-location-stack-push)) - (run-hooks 'rtags-after-find-file-hook))) + (visit-location (lambda (is-location-remote location path-segment submatch other-window) + (setq path-segment (match-string-no-properties submatch path-segment)) + (rtags-find-file-or-buffer + (if is-location-remote + (rtags--alter-path-in-tramp-location location path-segment) + path-segment) + other-window)))) + (when (> (length path-segment) 0) + (cond ((string-match "\\(.*\\) includes /.*" path-segment) + (rtags-find-file-or-buffer (match-string-no-properties 1 path-segment) other-window)) + ((and (string-match "[^ ]* should include /" path-segment) + (string= (buffer-substring-no-properties (point-at-bol) (+ (point-at-bol) (length path-segment))) + path-segment)) + (save-excursion + (if (search-backward-regexp "[ (]" (point-at-bol) t) + (forward-char 1) + (goto-char (point-at-bol))) + (let ((pos (point))) + (search-forward-regexp " ") + (rtags-goto-location (buffer-substring-no-properties pos (1- (point))) nobookmark other-window)))) + ((string-match "\\(.*?\\):\\([0-9]+\\):\\([0-9]+\\):?" path-segment) + (let ((line (string-to-number (match-string-no-properties 2 path-segment))) + (column (string-to-number (match-string-no-properties 3 path-segment)))) + (funcall visit-location is-location-remote location path-segment 1 other-window) + (push-mark nil t) + (rtags-goto-line-col line column))) + ((string-match "\\(.*?\\):\\([0-9]+\\):?" path-segment) + (let ((line (string-to-number (match-string-no-properties 2 path-segment)))) + (funcall visit-location is-location-remote location path-segment 1 other-window) + (push-mark nil t) + (goto-char (point-min)) + (forward-line (1- line)))) + ((string-match "\\(.*?\\),\\([0-9]+\\)" path-segment) + (let ((offset (string-to-number (match-string-no-properties 2 path-segment)))) + (funcall visit-location is-location-remote location path-segment 1 other-window) + (push-mark nil t) + (rtags-goto-offset offset))) + (t + (when (string-match "^[ \t]+\\(.*\\)$" path-segment) + (setq path-segment (match-string-no-properties 1 path-segment))) + (rtags-find-file-or-buffer location other-window))) + (unless nobookmark (rtags-location-stack-push)) + (run-hooks 'rtags-after-find-file-hook)))) (defvar rtags-location-stack-index 0) (defvar rtags-location-stack nil) @@ -2566,6 +2577,7 @@ of PREFIX or not, if doesn't contain one, one will be added." (define-key map (kbd (concat prefix "P")) 'rtags-dependency-tree-all) (define-key map (kbd (concat prefix "e")) 'rtags-reparse-file) (define-key map (kbd (concat prefix "E")) 'rtags-preprocess-file) + (define-key map (kbd (concat prefix "_")) 'rtags-asm-file) (define-key map (kbd (concat prefix "R")) 'rtags-rename-symbol) (define-key map (kbd (concat prefix "M")) 'rtags-symbol-info) (define-key map (kbd (concat prefix "U")) 'rtags-display-summary-as-message) @@ -2580,7 +2592,7 @@ of PREFIX or not, if doesn't contain one, one will be added." (define-key map (kbd (concat prefix "I")) 'rtags-imenu) (define-key map (kbd (concat prefix "T")) 'rtags-taglist) (define-key map (kbd (concat prefix "h")) 'rtags-print-class-hierarchy) - (define-key map (kbd (concat prefix "a")) 'rtags-print-source-arguments) + (define-key map (kbd (concat prefix "a")) 'rtags-expand-auto) (define-key map (kbd (concat prefix "A")) 'rtags-find-functions-called-by-this-function) (define-key map (kbd (concat prefix "l")) 'rtags-list-results) (define-key map (kbd (concat prefix "Z")) 'rtags-location-stack-visualize)) @@ -3577,10 +3589,10 @@ of diagnostics count" (rtags-clear-diagnostics)))) ;;;###autoload -(defun rtags-diagnostics (&optional restart nodirty) +(defun rtags-diagnostics (&optional restart) (interactive "P") (when rtags-enabled - (let ((rc (rtags-executable-find "rc"))) + (let ((rc (rtags-executable-find rtags-rc-binary-name))) (when rc (when restart (rtags-stop-diagnostics)) @@ -3590,8 +3602,6 @@ of diagnostics count" (let ((rtags-diagnostics-starting t)) (with-current-buffer buf (rtags-diagnostics-mode)) - (unless nodirty - (rtags-reparse-file)) (let ((process-connection-type (not rtags-diagnostics-use-pipe))) ;; use a pipe if rtags-diagnostics-use-pipe is t (let ((rawbuf (get-buffer rtags-diagnostics-raw-buffer-name))) (when rawbuf @@ -3920,6 +3930,19 @@ other window instead of the current one." (let ((cur (rtags-dependency-tree-current-file))) (when cur (rtags-goto-location (car cur) nil other-window)))) + ((string= (buffer-name) "*RTags Include Path*") + (let (start path) + (save-excursion + (setq start (if (search-backward " " (point-at-bol) t) + (1+ (point)) + (point-at-bol)))) + (save-excursion + (setq path (buffer-substring-no-properties start + (if (search-forward " " (point-at-eol) t) + (1- (point)) + (point-at-eol))))) + (unless (string= "->" path) + (rtags-goto-location path)))) ((string= (buffer-name) "*RTags Location Stack*") (let ((index (- (length rtags-location-stack) line))) (setq rtags-location-stack-index index) @@ -4327,7 +4350,7 @@ which can be overridden by specifying DEFAULT-FILE" (not (and (tramp-tramp-file-p default-directory) (not rtags-tramp-enabled))) (file-directory-p default-directory)) (setq rtags-last-update-current-project-buffer (current-buffer)) - (let* ((rc (rtags-executable-find "rc")) + (let* ((rc (rtags-executable-find rtags-rc-binary-name)) (path (rtags-untrampify (or (rtags-buffer-file-name) default-directory))) (arguments (list "-T" path "--diagnose" path "--silent-query"))) (when (and rtags-completions-enabled @@ -4556,7 +4579,7 @@ definition." (defun rtags-quit-rdm () "Quit the RTags process (rdm)." (interactive) - (let ((rc (rtags-executable-find "rc"))) + (let ((rc (rtags-executable-find rtags-rc-binary-name))) (when rc (process-file rc nil nil nil "--quit-rdm")))) @@ -4569,7 +4592,7 @@ definition." (defun rtags-command () "Shell command used to start the `rtags-server' process." (format "%s %s %s" - (rtags-executable-find "rdm") + (rtags-executable-find rtags-rdm-binary-name) (rtags-rdm-includes) rtags-process-flags)) @@ -4591,7 +4614,7 @@ definition." (defun rtags-start-process-unless-running () "Launch the RTags process (rdm) if it's not already started." (interactive) - (let ((rtags-server-executable (rtags-executable-find "rdm"))) + (let ((rtags-server-executable (rtags-executable-find rtags-rdm-binary-name))) (cond ;; Already started, nothing need to be done ((or (and (processp rtags-rdm-process) @@ -4602,7 +4625,7 @@ definition." (pname (cdr (assoc 'comm attrs))) (uid (cdr (assoc 'euid attrs)))) (when (and (eq uid (user-uid)) - (or (string-equal pname "rdm") + (or (string-equal pname rtags-rdm-binary-name) (string-equal pname "rdm.exe"))) (return t)))))) @@ -4888,15 +4911,22 @@ so it knows what files may be queried which helps with responsiveness. (interactive) ;; (message "rtags-update-buffer-list") (when rtags-enabled - (let* ((buffers (rtags-visible-buffers)) - (arg (if buffers - (mapconcat 'rtags-buffer-file-name buffers ";") - ";"))) + (let* ((visible (rtags-visible-buffers)) + (list) + (arg)) + (mapc (lambda (buf) + (cond ((memq buf visible) + (push (cons buf t) list)) + ((funcall rtags-is-indexable buf) + (push (cons buf nil) list)) + (t))) (buffer-list)) + (setq arg (concat "--set-buffers=" (mapconcat (lambda (arg) + (concat (if (cdr arg) "+" "-") (rtags-buffer-file-name (car arg)))) list ";"))) (when rtags-rc-log-enabled (rtags-log (concat "--set-buffers files: " arg))) (when (not (string= rtags-previous-buffer-list arg)) (setq rtags-previous-buffer-list arg) - (rtags-call-rc :noerror t :silent-query t :output nil :silent t :path t "--set-buffers" arg))))) + (rtags-call-rc :noerror t :silent-query t :output nil :silent t :path t arg))))) (add-hook 'window-configuration-change-hook 'rtags-update-buffer-list) @@ -5123,7 +5153,7 @@ the class. (interactive) (when (or (not (rtags-called-interactively-p)) (rtags-sandbox-id-matches)) (let ((filename (rtags-untrampify (rtags-buffer-file-name))) - (rc (rtags-executable-find "rc")) + (rc (rtags-executable-find rtags-rc-binary-name)) (rtags-buffer-name "*RTags check includes*") (arguments)) (setq arguments (mapcar (lambda (a) (concat a filename)) '("--current-file=" "--check-includes="))) @@ -5183,7 +5213,7 @@ the class. (erase-buffer) (let ((proc (start-process "RTags Tokens Async" buf - (rtags-executable-find "rc") + (rtags-executable-find rtags-rc-binary-name) "--elisp" "--tokens-include-symbols" "--tokens" (cond ((and from to) (format "%s:%d-%d" path from to)) @@ -5301,10 +5331,19 @@ the user enter missing field manually." (switch-to-buffer (process-buffer process))) (t nil)))) +(defun rtags-expand-auto () + (interactive) + (let* ((symbolinfo (rtags-symbol-info-internal)) + (auto (cdr (assoc 'auto symbolinfo))) + (type (and auto (cdr (assoc 'type symbolinfo))))) + (when type + (save-excursion + (when (re-search-backward "\\" nil t) + (kill-forward-chars 4) + (insert type)))))) (defcustom rtags-install-cmake-args nil "Additional arguments to cmake when building rtags with rtags-install." - :group 'rtags :type 'string :safe 'stringp) @@ -5327,36 +5366,36 @@ the user enter missing field manually." (with-temp-buffer (insert "#!/bin/bash -x\n" (format "FILE=\"rtags-%s.tar.bz2\"\n" rtags-package-version) - "URL=\"https://andersbakken.github.io/rtags-releases/$FILE\"\n" + (format "URL=\"https://github.com/Andersbakken/rtags/releases/download/v%s/$FILE\"\n" rtags-package-version) "ARGS=\"--progress -L -o $FILE\"\n" "CMAKEARGS=" (combine-and-quote-strings (append (and rtags-install-cmake-args (list rtags-install-cmake-args)) (if (listp cmakeargs) cmakeargs (list cmakeargs)))) "\n" - "[ -e \"$FILE\" ] && ARGS=\"$ARGS -C -\"\n" - "ARGS=\"$ARGS $URL\"\n" - "echo \"Downloading rtags from $URL\"\n" - "if ! curl $ARGS; then\n" - " echo \"Failed to download $FILE from $URL\" >&2\n" - " exit 1\n" - "fi\n" - "\n" - "if ! tar xfj \"$FILE\"; then\n" - " echo \"Failed to untar $FILE\" >&2\n" - " rm \"$FILE\"\n" - " exit 2\n" - "fi\n" - "\n" - "cd \"`echo $FILE | sed -e 's,\.tar.bz2,,'`\"\n" - "if ! cmake . ${CMAKEARGS}; then\n" - " echo Failed to cmake\n" - " rm -rf CMakeCache.txt\n" - " exit 3\n" - "fi\n" - "make\n" - "exit $?\n") + "[ -e \"$FILE\" ] && ARGS=\"$ARGS -C -\"\n" + "ARGS=\"$ARGS $URL\"\n" + "echo \"Downloading rtags from $URL\"\n" + "if ! curl $ARGS; then\n" + " echo \"Failed to download $FILE from $URL\" >&2\n" + " exit 1\n" + "fi\n" + "\n" + "if ! tar xfj \"$FILE\"; then\n" + " echo \"Failed to untar $FILE\" >&2\n" + " rm \"$FILE\"\n" + " exit 2\n" + "fi\n" + "\n" + "cd \"`echo $FILE | sed -e 's,\.tar.bz2,,'`\"\n" + "if ! cmake . ${CMAKEARGS}; then\n" + " echo Failed to cmake\n" + " rm -rf CMakeCache.txt\n" + " exit 3\n" + "fi\n" + "make\n" + "exit $?\n") (rtags--write-region (point-min) (point-max) "install-rtags.sh")) - (switch-to-buffer (rtags-get-buffer "*RTags install*")) + (switch-to-buffer (rtags-get-buffer rtags-install-buffer-name)) (setq buffer-read-only t) - (setq rtags-install-process (start-process "*RTags install*" (current-buffer) "bash" (concat dir "/install-rtags.sh"))) + (setq rtags-install-process (start-file-process rtags-install-buffer-name (current-buffer) "bash" (rtags-untrampify (concat dir "/install-rtags.sh")))) (set-process-sentinel rtags-install-process 'rtags-install-process-sentinel) (set-process-filter rtags-install-process 'rtags-install-process-filter)))) @@ -5392,8 +5431,10 @@ customize the messages" "RTags: No matches to rename. Is point on a valid symbol to rename and is the file indexed?") ((eq type 'rtags-socket-file-does-not-exist) "RTags: socket file, %S, does not exist") + ((eq type 'rtags-socket-address-does-not-exist) + "RTags: socket address, %S, does not exist") ((eq type 'rtags-cannot-find-rc) - "RTags: Can't find rc") + (concat "RTags: Can't find " rtags-rc-binary-name)) ((eq type 'rtags-no-file-chosen) "RTags: No file chosen") ((eq type 'rtags-no-file-here) @@ -5411,7 +5452,7 @@ customize the messages" ((eq type 'rtags-cannot-start-process) (concat "RTags: Can't start the process `%s'. " - "Please check the value of the variable `rtags-path'.")) + "Please check the value of the variables `rtags-path' and `rtags-rdm-binary-name'.")) ((eq type 'rtags-malines-doesnt-work-with-location-length) "RTags: maxlines doesn't work with location/length") ((eq type 'rtags-buffer-is-not-visiting-a-file) diff --git a/packages/rubocop-20170312.611.el b/packages/rubocop-20190326.1424.el similarity index 90% rename from packages/rubocop-20170312.611.el rename to packages/rubocop-20190326.1424.el index 1d2be14..ba46583 100644 --- a/packages/rubocop-20170312.611.el +++ b/packages/rubocop-20190326.1424.el @@ -4,7 +4,7 @@ ;; Author: Bozhidar Batsov ;; URL: https://github.com/bbatsov/rubocop-emacs -;; Package-Version: 20170312.611 +;; Package-Version: 20190326.1424 ;; Version: 0.5.0 ;; Keywords: project, convenience ;; Package-Requires: ((emacs "24")) @@ -69,6 +69,16 @@ :group 'rubocop :type 'string) +(defcustom rubocop-autocorrect-on-save nil + "Runs `rubocop-autocorrect-current-file' automatically on save." + :group 'rubocop + :type 'boolean) + +(defcustom rubocop-prefer-system-executable nil + "Runs rubocop with the system executable even if inside a bundled project." + :group 'rubocop + :type 'boolean) + (defun rubocop-local-file-name (file-name) "Retrieve local filename if FILE-NAME is opened via TRAMP." (cond ((tramp-tramp-file-p file-name) @@ -112,7 +122,7 @@ When NO-ERROR is non-nil returns nil instead of raise an error." "Build the full command to be run based on COMMAND and PATH. The command will be prefixed with `bundle exec` if RuboCop is bundled." (concat - (if (rubocop-bundled-p) "bundle exec " "") + (if (and (not rubocop-prefer-system-executable) (rubocop-bundled-p)) "bundle exec " "") command (rubocop-build-requires) " " @@ -183,6 +193,10 @@ Alternatively prompt user for directory." (interactive) (rubocop--file-command rubocop-autocorrect-command)) +(defun rubocop-autocorrect-current-file-silent () + (if rubocop-autocorrect-on-save + (save-window-excursion (rubocop-autocorrect-current-file)))) + (defun rubocop-bundled-p () "Check if RuboCop has been bundled." (let ((gemfile-lock (expand-file-name "Gemfile.lock" (rubocop-project-root)))) @@ -216,7 +230,10 @@ Alternatively prompt user for directory." "Minor mode to interface with RuboCop." :lighter " RuboCop" :keymap rubocop-mode-map - :group 'rubocop) + :group 'rubocop + (cond + (rubocop-mode (add-hook 'before-save-hook 'rubocop-autocorrect-current-file-silent nil t)) + (t (remove-hook 'before-save-hook 'rubocop-autocorrect-current-file-silent t)))) (provide 'rubocop) diff --git a/packages/rubocopfmt-20181009.1703.el b/packages/rubocopfmt-20181009.1703.el new file mode 100644 index 0000000..d841fee --- /dev/null +++ b/packages/rubocopfmt-20181009.1703.el @@ -0,0 +1,296 @@ +;;; rubocopfmt.el --- Minor-mode to format Ruby code with RuboCop on save + +;; Version: 0.3.0 +;; Package-Version: 20181009.1703 +;; Keywords: convenience wp edit ruby rubocop +;; Package-Requires: ((cl-lib "0.5")) +;; URL: https://github.com/jimeh/rubocopfmt.el +;; Author: Jim Myhrberg + +;; This file is not part of GNU Emacs. + +;;; License: +;; +;; Copyright (c) 2014 The go-mode Authors. All rights reserved. +;; Portions Copyright (c) 2018 Jim Myhrberg. +;; +;; Redistribution and use in source and binary forms, with or without +;; modification, are permitted provided that the following conditions are +;; met: +;; +;; * Redistributions of source code must retain the above copyright +;; notice, this list of conditions and the following disclaimer. +;; * Redistributions in binary form must reproduce the above +;; copyright notice, this list of conditions and the following disclaimer +;; in the documentation and/or other materials provided with the +;; distribution. +;; * Neither the name of the copyright holder nor the names of its +;; contributors may be used to endorse or promote products derived from +;; this software without specific prior written permission. +;; +;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +;;; Commentary: +;; +;; This library formats Ruby code by using rubocop and it's --auto-correct +;; option. + +;;; Code: + +(require 'cl-lib) + +(defgroup rubocopfmt nil + "Minor mode for formatting Ruby buffers with rubocop." + :group 'languages + :link '(url-link "https://github.com/jimeh/rubocopfmt.el")) + +(defcustom rubocopfmt-rubocop-command "rubocop" + "Name of rubocop executable." + :type 'string + :group 'rubocopfmt) + +(defcustom rubocopfmt-use-bundler-when-possible t + "When t and Gemfile is present, run rubocop with 'bundle exec'." + :type 'boolean + :group 'rubocopfmt) + +(defcustom rubocopfmt-disabled-cops + '("Lint/Debugger" ; Don't remove debugger calls. + "Lint/UnusedBlockArgument" ; Don't rename unused block arguments. + "Lint/UnusedMethodArgument" ; Don't rename unused method arguments. + "Style/EmptyMethod" ; Don't remove blank line in empty methods. + ) + "A list of RuboCop cops to disable during auto-correction. +These cops are disabled because they cause confusion during +interactive use within a text-editor." + :type '(repeat string) + :group 'rubocopfmt) + +(defcustom rubocopfmt-show-errors 'buffer + "Where to display rubocopfmt error output. +It can either be displayed in its own buffer, in the echo area, +or not at all. + +Please note that Emacs outputs to the echo area when writing +files and will overwrite rubocopfmt's echo output if used from +inside a `before-save-hook'." + :type '(choice + (const :tag "Own buffer" buffer) + (const :tag "Echo area" echo) + (const :tag "None" nil)) + :group 'rubocopfmt) + +(defcustom rubocopfmt-major-modes '(ruby-mode enh-ruby-mode) + "List of major modes to format on save when rubocopfmt-mode is enabled." + :type '(repeat symbol) + :group 'rubocopfmt) + + +(defun rubocopfmt--apply-rcs-patch (patch-buffer) + "Apply an RCS-formatted diff from PATCH-BUFFER to the current buffer." + (let ((target-buffer (current-buffer)) + ;; Relative offset between buffer line numbers and line numbers + ;; in patch. + ;; + ;; Line numbers in the patch are based on the source file, so + ;; we have to keep an offset when making changes to the + ;; buffer. + ;; + ;; Appending lines decrements the offset (possibly making it + ;; negative), deleting lines increments it. This order + ;; simplifies the forward-line invocations. + (line-offset 0)) + (save-excursion + (with-current-buffer patch-buffer + (goto-char (point-min)) + (while (not (eobp)) + (unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)") + (error "Invalid rcs patch or internal error in rubocopfmt--apply-rcs-patch")) + (forward-line) + (let ((action (match-string 1)) + (from (string-to-number (match-string 2))) + (len (string-to-number (match-string 3)))) + (cond + ((equal action "a") + (let ((start (point))) + (forward-line len) + (let ((text (buffer-substring start (point)))) + (with-current-buffer target-buffer + (cl-decf line-offset len) + (goto-char (point-min)) + (forward-line (- from len line-offset)) + (insert text))))) + ((equal action "d") + (with-current-buffer target-buffer + (rubocopfmt--goto-line (- from line-offset)) + (cl-incf line-offset len) + (rubocopfmt--delete-whole-line len))) + (t + (error "Invalid rcs patch or internal error in rubocopfmt--apply-rcs-patch"))))))))) + +(defun rubocopfmt--delete-whole-line (&optional arg) + "Delete the current line without putting it in the `kill-ring'. +Derived from function `kill-whole-line'. ARG is defined as for that +function." + (setq arg (or arg 1)) + (if (and (> arg 0) + (eobp) + (save-excursion (forward-visible-line 0) (eobp))) + (signal 'end-of-buffer nil)) + (if (and (< arg 0) + (bobp) + (save-excursion (end-of-visible-line) (bobp))) + (signal 'beginning-of-buffer nil)) + (cond ((zerop arg) + (delete-region (progn (forward-visible-line 0) (point)) + (progn (end-of-visible-line) (point)))) + ((< arg 0) + (delete-region (progn (end-of-visible-line) (point)) + (progn (forward-visible-line (1+ arg)) + (unless (bobp) + (backward-char)) + (point)))) + (t + (delete-region (progn (forward-visible-line 0) (point)) + (progn (forward-visible-line arg) (point)))))) + +(defun rubocopfmt--goto-line (line) + "Move cursor to LINE." + (goto-char (point-min)) + (forward-line (1- line))) + +(defun rubocopfmt--bundled-path-p (directory) + "Check if there is a Gemfile in DIRECTORY, or any parent of DIRECTORY." + (rubocopfmt--file-search-upward directory "Gemfile")) + +(defun rubocopfmt--file-search-upward (directory file) + "Search DIRECTORY for FILE and return its full path if found, or NIL if not. + +If FILE is not found in DIRECTORY, the parent of DIRECTORY will be searched." + (let ((parent-dir (file-truename (concat (file-name-directory directory) "../"))) + (current-path (if (not (string= (substring directory (- (length directory) 1)) "/")) + (concat directory "/" file) + (concat directory file)))) + + (if (file-exists-p current-path) + current-path + (when (and (not (string= (file-truename directory) parent-dir)) + (< (length parent-dir) (length (file-truename directory)))) + (rubocopfmt--file-search-upward parent-dir file))))) + +(defun rubocopfmt--parse-result (resultbuf tmpfile) + "Parse Rubocop result in RESULTBUF and write corrections to TMPFILE." + (let ((split 0)) + (with-current-buffer resultbuf + (goto-char (point-min)) + ;; Only find the separator when RuboCop has printed complaints. + (setq split (search-forward "\n====================\n" nil t)) + + ;; If no RuboCop complaints were printed, we need to find the separator at + ;; the beginning of the buffer. This separation helps prevent false + ;; positive separator matches. + (unless split + (setq split (search-forward "====================\n" nil t))) + + (if split + (when (> split 22) + (goto-char (point-min)) + (when (search-forward "[Corrected]" split t) + (write-region split (point-max) tmpfile) + t)) + (rubocopfmt--process-errors resultbuf) + nil)))) + +(defun rubocopfmt--process-errors (resultbuf) + "Display contents of RESULTBUF as errors." + (if (eq rubocopfmt-show-errors 'echo) + (with-current-buffer resultbuf + (message (buffer-string)))) + + (if (eq rubocopfmt-show-errors 'buffer) + (let ((errbuf (get-buffer-create "*Rubocopfmt Errors*"))) + (with-current-buffer errbuf + (erase-buffer) + (goto-char (point-min)) + (insert-buffer-substring resultbuf)) + (display-buffer errbuf)))) + + +;;;###autoload +(defun rubocopfmt () + "Format the current buffer with rubocop." + (interactive) + (let* ((coding-system-for-read 'utf-8) + (coding-system-for-write 'utf-8) + (tmpfile (make-temp-file "rubocopfmt" nil ".rb")) + (resultbuf (get-buffer-create "*Rubocopfmt Result*")) + (patchbuf (get-buffer-create "*Rubocopfmt Patch*")) + (buffer-file (file-truename buffer-file-name)) + (src-dir (file-name-directory buffer-file)) + (src-file (file-name-nondirectory buffer-file)) + (fmt-command rubocopfmt-rubocop-command) + (fmt-args (list "--stdin" src-file + "--auto-correct" + "--format" "emacs"))) + + (if (and rubocopfmt-use-bundler-when-possible + (rubocopfmt--bundled-path-p src-dir)) + (setq fmt-command "bundle" + fmt-args (append (list "exec" rubocopfmt-rubocop-command) + fmt-args))) + + (if rubocopfmt-disabled-cops + (setq fmt-args (append fmt-args (list "--except" + (combine-and-quote-strings + rubocopfmt-disabled-cops ","))))) + + (unwind-protect + (save-restriction + (widen) + (write-region nil nil tmpfile) + (with-current-buffer resultbuf (erase-buffer)) + (with-current-buffer patchbuf (erase-buffer)) + + (let ((current-directory src-dir)) + (message "Calling rubocop from directory \"%s\": %s %s" + src-dir fmt-command (mapconcat 'identity fmt-args " ")) + (apply #'call-process-region (point-min) (point-max) + fmt-command nil resultbuf nil fmt-args) + (if (rubocopfmt--parse-result resultbuf tmpfile) + (call-process-region (point-min) (point-max) "diff" + nil patchbuf nil "-n" "-" tmpfile))) + + (if (= (buffer-size patchbuf) 0) + (message "Buffer is already rubocopfmted") + (rubocopfmt--apply-rcs-patch patchbuf) + (message "Applied rubocopfmt"))) + + (delete-file tmpfile) + (kill-buffer resultbuf) + (kill-buffer patchbuf)))) + +;;;###autoload +(define-minor-mode rubocopfmt-mode + "Enable format-on-save for `ruby-mode' buffers via rubocopfmt." + :lighter " fmt" + (if rubocopfmt-mode + (add-hook 'before-save-hook 'rubocopfmt-before-save t t) + (remove-hook 'before-save-hook 'rubocopfmt-before-save t))) + +(defun rubocopfmt-before-save () + "Format buffer via rubocopfmt if major mode is `ruby-mode'." + (interactive) + (when (member major-mode rubocopfmt-major-modes) (rubocopfmt))) + +(provide 'rubocopfmt) +;;; rubocopfmt.el ends here diff --git a/packages/ruby-hash-syntax-20180324.209.el b/packages/ruby-hash-syntax-20190109.2227.el similarity index 95% rename from packages/ruby-hash-syntax-20180324.209.el rename to packages/ruby-hash-syntax-20190109.2227.el index acc42db..0340904 100644 --- a/packages/ruby-hash-syntax-20180324.209.el +++ b/packages/ruby-hash-syntax-20190109.2227.el @@ -1,9 +1,9 @@ -;;; ruby-hash-syntax.el --- Toggle ruby hash syntax between classic and 1.9 styles +;;; ruby-hash-syntax.el --- Toggle ruby hash syntax between => and 1.9+ styles ;; Copyright (C) 2013-2017 Steve Purcell ;; Author: Steve Purcell -;; Package-Version: 20180324.209 +;; Package-Version: 20190109.2227 ;; Package-X-Original-Version: 0 ;; URL: https://github.com/purcell/ruby-hash-syntax ;; Keywords: languages diff --git a/packages/ruby-test-mode-20171016.1631.el b/packages/ruby-test-mode-20190412.909.el similarity index 89% rename from packages/ruby-test-mode-20171016.1631.el rename to packages/ruby-test-mode-20190412.909.el index 4ddca72..35b3762 100644 --- a/packages/ruby-test-mode-20171016.1631.el +++ b/packages/ruby-test-mode-20190412.909.el @@ -5,12 +5,12 @@ ;; Author: Roman Scherer ;; Caspar Florian Ebeling -;; +;; URL: https://github.com/ruby-test-mode/ruby-test-mode +;; Package-Version: 20190412.909 ;; Maintainer: Roman Scherer ;; Created: 09.02.08 ;; Version: 1.7 -;; Package-Version: 20171016.1631 -;; Keywords: ruby unit test rspec +;; Keywords: ruby unit test rspec tools ;; Package-Requires: ((ruby-mode "1.0") (pcre2el "1.8")) ;; This file is not part of GNU Emacs. @@ -80,6 +80,10 @@ Test Driven Development in Ruby." "test" "Define the default test library.") +(defvar ruby-test-last-run + nil + "The last ruby test run.") + (defvar ruby-test-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "C-c C-t n") 'ruby-test-run) @@ -219,21 +223,27 @@ mode." :group 'ruby-test) (defmacro ruby-test-with-ruby-directory (filename form) - "Run the provided FORM with default-directory set to ruby or rails root." + "Set to ruby or rails root inferred from FILENAME and run the provided FORM with `default-directory` bound." `(let ((default-directory (or (ruby-test-rails-root ,filename) (ruby-test-ruby-root ,filename) default-directory))) ,form)) -(defun select (fn ls) - "Create a list from elements of list LS for which FN is non-nil." +(defun ruby-test-select (fn ls) + "Call FN and create a list from elements of list LS for which FN is non-nil." (let ((result nil)) (dolist (item ls) (if (funcall fn item) (setq result (cons item result)))) (reverse result))) -(defalias 'find-all 'select) +(defalias 'find-all 'ruby-test-select) + +(defun ruby-test-minitest-p (filename) + "Return non-nil if FILENAME is a minitest." + (and (stringp filename) + (or (and (string-match "test\.rb$" filename) (file-exists-p "test/minitest_helper.rb")) + (and (string-match "spec\.rb$" filename) (file-exists-p "spec/minitest_helper.rb"))))) (defun ruby-test-spec-p (filename) "Return non-nil if FILENAME is a spec." @@ -268,7 +278,7 @@ test; or the last run test (if there was one)." (window-list)))) (if (boundp 'ruby-test-last-run) (nconc files (list ruby-test-last-run))) - (setq ruby-test-last-run (car (select 'ruby-test-any-p (select 'identity files)))))) + (setq ruby-test-last-run (car (ruby-test-select 'ruby-test-any-p (ruby-test-select 'identity files)))))) (defun ruby-test-find-target-filename (filename mapping) "Find the target filename. @@ -353,7 +363,7 @@ and replace the match with the second element." (let ((filename (ruby-test-find-file))) (if filename (ruby-test-with-ruby-directory filename - (ruby-test-run-command (ruby-test-command filename))) + (ruby-test-run-command (ruby-test-command filename))) (message ruby-test-not-found-message)))) ;;;###autoload @@ -365,9 +375,9 @@ and replace the match with the second element." (if (and filename test-file-buffer) (ruby-test-with-ruby-directory filename - (with-current-buffer test-file-buffer - (let ((line (line-number-at-pos (point)))) - (ruby-test-run-command (ruby-test-command filename line))))) + (with-current-buffer test-file-buffer + (let ((line (line-number-at-pos (point)))) + (ruby-test-run-command (ruby-test-command filename line))))) (message ruby-test-not-found-message)))) (defun ruby-test-run-command (command) @@ -376,12 +386,31 @@ and replace the match with the second element." (defun ruby-test-command (filename &optional line-number) "Return the command to run a unit test or a specification depending on the FILENAME and LINE-NUMBER." - (cond ((ruby-test-spec-p filename) + (cond ((ruby-test-minitest-p filename) + (ruby-test-minitest-command filename line-number)) + ((ruby-test-spec-p filename) (ruby-test-spec-command filename line-number)) ((ruby-test-p filename) (ruby-test-test-command filename line-number)) (t (message "File is not a known ruby test file")))) +(defun ruby-test-minitest-command (filename &optional line-number) + "Return command to run minitest in FILENAME at LINE-NUMBER." + (let (command options name-options) + (if (file-exists-p ".zeus.sock") + (setq command "zeus test") + (setq command "bundle exec ruby")) + (if (ruby-test-gem-root filename) + (setq options (cons "-rrubygems" options))) + (setq options (cons "-I'lib:test:spec'" options)) + (if line-number + (let ((test-case (ruby-test-find-testcase-at filename line-number))) + (if test-case + (setq name-options (format "-n \"/%s/\"" test-case)) + (error "No test case at %s:%s" filename line-number))) + (setq name-options "")) + (format "%s %s %s %s" command (mapconcat 'identity options " ") filename name-options))) + (defun ruby-test-spec-command (filename &optional line-number) "Return command to run spec in FILENAME at LINE-NUMBER." (let ((command @@ -401,7 +430,7 @@ and replace the match with the second element." (setq command "zeus test") (setq command "bundle exec ruby")) (if (ruby-test-gem-root filename) - (setq options (cons "-rubygems" options))) + (setq options (cons "-rrubygems" options))) (setq options (cons "-I'lib:test'" options)) (if line-number (let ((test-case (ruby-test-find-testcase-at filename line-number))) @@ -427,7 +456,7 @@ FILENAME is tested to t by evaluating the ROOT-PREDICATE." root-predicate)))) (defun ruby-test-project-root-p (directory candidates) - "Return t if one of the filenames in CANDIDATES is existing relative to the given DIRECTORY." + "Return t if the given DIRECTORY has one of the filenames in CANDIDATES." (let ((found nil)) (while (and (not found) (car candidates)) (setq found diff --git a/packages/ruby-tools-20151209.1615.tar b/packages/ruby-tools-20151209.1615.tar index 94284b8..575232d 100644 Binary files a/packages/ruby-tools-20151209.1615.tar and b/packages/ruby-tools-20151209.1615.tar differ diff --git a/packages/rust-mode-20181008.1628.el b/packages/rust-mode-20190517.2037.el similarity index 96% rename from packages/rust-mode-20181008.1628.el rename to packages/rust-mode-20190517.2037.el index 79c4b1a..982c77a 100644 --- a/packages/rust-mode-20181008.1628.el +++ b/packages/rust-mode-20190517.2037.el @@ -1,7 +1,7 @@ ;;; rust-mode.el --- A major emacs mode for editing Rust source code -*-lexical-binding: t-*- ;; Version: 0.4.0 -;; Package-Version: 20181008.1628 +;; Package-Version: 20190517.2037 ;; Author: Mozilla ;; Url: https://github.com/rust-lang/rust-mode ;; Keywords: languages @@ -40,6 +40,8 @@ (defconst rust-re-vis "pub") (defconst rust-re-unsafe "unsafe") (defconst rust-re-extern "extern") +(defconst rust-re-generic + (concat "<[[:space:]]*'" rust-re-ident "[[:space:]]*>")) (defconst rust-re-union (rx-to-string `(seq @@ -79,7 +81,8 @@ Like `looking-back' but for fixed strings rather than regexps (so that it's not (defun rust-looking-back-macro () "Non-nil if looking back at an ident followed by a !" - (save-excursion (backward-char) (and (= ?! (char-after)) (rust-looking-back-ident)))) + (if (> (- (point) (point-min)) 1) + (save-excursion (backward-char) (and (= ?! (char-after)) (rust-looking-back-ident))))) ;; Syntax definitions and helpers (defvar rust-mode-syntax-table @@ -130,6 +133,13 @@ When nil, `where' will be aligned with `fn' or `trait'." :group 'rust-mode :safe #'booleanp) +(defcustom rust-indent-return-type-to-arguments t + "Indent a line starting with the `->' (RArrow) following a function, aligning +to the function arguments. When nil, `->' will be indented one level." + :type 'boolean + :group 'rust-mode + :safe #'booleanp) + (defcustom rust-playpen-url-format "https://play.rust-lang.org/?code=%s" "Format string to use when submitting code to the playpen." :type 'string @@ -398,8 +408,10 @@ buffer." (back-to-indentation) (current-column)))))) - ;; A function return type is indented to the corresponding function arguments - ((looking-at "->") + ;; A function return type is indented to the corresponding + ;; function arguments, if -to-arguments is selected. + ((and rust-indent-return-type-to-arguments + (looking-at "->")) (save-excursion (backward-list) (or (rust-align-to-expr-after-brace) @@ -522,7 +534,7 @@ buffer." ;; Font-locking definitions and helpers (defconst rust-mode-keywords - '("as" "async" + '("as" "async" "await" "box" "break" "const" "continue" "crate" "do" "dyn" @@ -562,7 +574,9 @@ buffer." (defun rust-re-grab (inner) (concat "\\(" inner "\\)")) (defun rust-re-shy (inner) (concat "\\(?:" inner "\\)")) (defun rust-re-item-def (itype) - (concat (rust-re-word itype) "[[:space:]]+" (rust-re-grab rust-re-ident))) + (concat (rust-re-word itype) + (rust-re-shy rust-re-generic) "?" + "[[:space:]]+" (rust-re-grab rust-re-ident))) (defun rust-re-item-def-imenu (itype) (concat "^[[:space:]]*" (rust-re-shy (concat (rust-re-word rust-re-vis) "[[:space:]]+")) "?" @@ -1092,41 +1106,44 @@ should be considered a paired angle bracket." (group "'"))) "A regular expression matching a character literal.")) -(defun rust--syntax-propertize-raw-string (end) +(defun rust--syntax-propertize-raw-string (str-start end) "A helper for rust-syntax-propertize. -If point is already in a raw string, this will apply the -appropriate string syntax to the character up to the end of the -raw string, or to END, whichever comes first." - (let ((str-start (nth 8 (syntax-ppss)))) - (when str-start - (when (save-excursion - (goto-char str-start) - (looking-at "r\\(#*\\)\\(\"\\)")) - ;; In a raw string, so try to find the end. - (let ((hashes (match-string 1))) - ;; Match \ characters at the end of the string to suppress - ;; their normal character-quote syntax. - (when (re-search-forward (concat "\\(\\\\*\\)\\(\"" hashes "\\)") end t) - (put-text-property (match-beginning 1) (match-end 1) - 'syntax-table (string-to-syntax "_")) - (put-text-property (1- (match-end 2)) (match-end 2) - 'syntax-table (string-to-syntax "|")) - (goto-char (match-end 0)))))))) +This will apply the appropriate string syntax to the character +from the STR-START up to the end of the raw string, or to END, +whichever comes first." + (when (save-excursion + (goto-char str-start) + (looking-at "r\\(#*\\)\\(\"\\)")) + ;; In a raw string, so try to find the end. + (let ((hashes (match-string 1))) + ;; Match \ characters at the end of the string to suppress + ;; their normal character-quote syntax. + (when (re-search-forward (concat "\\(\\\\*\\)\\(\"" hashes "\\)") end t) + (put-text-property (match-beginning 1) (match-end 1) + 'syntax-table (string-to-syntax "_")) + (put-text-property (1- (match-end 2)) (match-end 2) + 'syntax-table (string-to-syntax "|")) + (goto-char (match-end 0)))))) (defun rust-syntax-propertize (start end) "A `syntax-propertize-function' to apply properties from START to END." (goto-char start) - (rust--syntax-propertize-raw-string end) + (let ((str-start (rust-in-str-or-cmnt))) + (when str-start + (rust--syntax-propertize-raw-string str-start end))) (funcall (syntax-propertize-rules ;; Character literals. (rust--char-literal-rx (1 "\"") (2 "\"")) ;; Raw strings. ("\\(r\\)#*\"" - (1 (prog1 "|" - (goto-char (match-end 0)) - (rust--syntax-propertize-raw-string end)))) + (0 (ignore + (goto-char (match-end 0)) + (unless (save-excursion (nth 8 (syntax-ppss (match-beginning 0)))) + (put-text-property (match-beginning 1) (match-end 1) + 'syntax-table (string-to-syntax "|")) + (rust--syntax-propertize-raw-string (match-beginning 0) end))))) ("[<>]" (0 (ignore (when (save-match-data @@ -1499,6 +1516,16 @@ This is written mainly to be used as `end-of-defun-function' for Rust." (interactive) (compile "cargo build")) +(defun rust-run () + "Run using `cargo run`" + (interactive) + (compile "cargo run")) + +(defun rust-test () + "Test using `cargo test`" + (interactive) + (compile "cargo test")) + (defvar rust-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "C-c C-f") 'rust-format-buffer) @@ -1582,14 +1609,13 @@ This is written mainly to be used as `end-of-defun-function' for Rust." (when rust-format-on-save (unless (executable-find rust-rustfmt-bin) (error "Could not locate executable \"%s\"" rust-rustfmt-bin)))) - + (defvar rustc-compilation-regexps (let ((file "\\([^\n]+\\)") (start-line "\\([0-9]+\\)") (start-col "\\([0-9]+\\)")) - (let ((re (concat "^ *--> " file ":" start-line ":" start-col ; --> 1:2:3 - ))) - (cons re '(1 2 3)))) + (let ((re (concat "^\\(?:error\\|\\(warning\\)\\)[^-]+--> \\(" file ":" start-line ":" start-col "\\)"))) + (cons re '(3 4 5 (1) 2)))) "Specifications for matching errors in rustc invocations. See `compilation-error-regexp-alist' for help on their format.") diff --git a/packages/sailfish-scratchbox-20171202.1332.el b/packages/sailfish-scratchbox-20171202.1332.el new file mode 100644 index 0000000..9393b68 --- /dev/null +++ b/packages/sailfish-scratchbox-20171202.1332.el @@ -0,0 +1,151 @@ +;;; sailfish-scratchbox.el --- Sailfish OS scratchbox inside the emacs. + +;; Copyright (C) 2017 Victor Polevoy + +;; Author: V. V. Polevoy +;; Version: 1.2.2 +;; Package-Version: 20171202.1332 +;; Keywords: sb2, mb2, building, scratchbox, sailfish +;; URL: https://github.com/vityafx/sailfish-scratchbox.el +;; License: MIT + +;;; Commentary: + +;; This package provides easier way to run sailfish os sdk scripts +;; and tools as 'mb2 build' for example. + +;;; Code: +(require 'compile) + + +(defgroup sailfish-scratchbox nil + "Sailfish scratchbox utils" + :group 'tools) + +(defcustom sailfish-scratchbox-interpreter "bash -ic" + "The interpreter to run the scripts with." + :type 'string + :group 'sailfish-scratchbox + :safe #'stringp) + +(defcustom sailfish-scratchbox-which-sdk "sdk" + "The path of the sdk environment script." + :type 'string + :group 'sailfish-scratchbox + :safe #'stringp) + +(defcustom sailfish-scratchbox-mb2-build "mb2 build" + "The command of the mb2 build script." + :type 'string + :group 'sailfish-scratchbox + :safe #'stringp) + +(defcustom sailfish-scratchbox-mb2-build-options "" + "The mb2-build script options." + :type 'string + :group 'sailfish-scratchbox + :safe #'stringp) + +(defcustom sailfish-scratchbox-build-buffer-name "*scratchbox build*" + "The sailfish scratchbox build buffer name." + :type 'string + :group 'sailfish-scratchbox + :safe #'stringp) + +(defcustom sailfish-scratchbox-deploy-buffer-name "*scratchbox deploy*" + "The sailfish scratchbox build buffer name." + :type 'string + :group 'sailfish-scratchbox + :safe #'stringp) + +(defcustom sailfish-scratchbox-deploy-rpms-command "scp RPMS/*.rpm nemo@192.168.2.15:/home/nemo" + "The sailfish scratchbox deploy command. +User must have his identity installed onto the phone is the command invokes scp." + :type 'string + :group 'sailfish-scratchbox + :safe #'stringp) + +(defcustom sailfish-scratchbox-install-in-sdk "sb2 -R rpm -i RPMS/*.rpm --force --verbose" + "The sailfish scratchbox command to install project packages into the sdk." + :type 'string + :group 'sailfish-scratchbox + :safe #'stringp) + + +(defun scratchbox-project-root () + "Return project root." + (or (locate-dominating-file buffer-file-name ".git/") (locate-dominating-file buffer-file-name "rpm/"))) + +(defun scratchbox-mb2-build-generate-command () + "Compile a full cmd line for invoking mb2 build script. + +Something like 'sdk mb2 build'" + (concat sailfish-scratchbox-interpreter " " (shell-quote-argument (concat sailfish-scratchbox-which-sdk " " + sailfish-scratchbox-mb2-build)) + " " sailfish-scratchbox-mb2-build-options)) + +(defun scratchbox-install-rpms-generate-command () + "Compile a full cmd line for installing rpm packages into a target." + (concat sailfish-scratchbox-interpreter " " (shell-quote-argument (concat sailfish-scratchbox-which-sdk " " + sailfish-scratchbox-install-in-sdk)))) + +(define-compilation-mode sailfish-scratchbox-compilation-mode "sailfish scratchbox" + "Sailfish scratchbox compilation mode") + +(defun run-with-project-path (function-to-run) + "Run the FUNCTION-TO-RUN if the current buffer is inside a project." + (let ((root-dir (scratchbox-project-root))) + (if root-dir + (funcall function-to-run root-dir) + (message "(%s) does not seem to be inside a valid sailfish os project." (buffer-name))))) + +(defun scratchbox-mb2-build-run (project-root-path) + "Run the mb2 build script on the project with PROJECT-ROOT-PATH." + (save-some-buffers (not compilation-ask-about-save) + (when (boundp 'compilation-save-buffers-predicate) + compilation-save-buffers-predicate)) + (when (get-buffer sailfish-scratchbox-build-buffer-name) + (kill-buffer sailfish-scratchbox-build-buffer-name)) + (let ((command-to-run (scratchbox-mb2-build-generate-command))) + (with-current-buffer (get-buffer-create sailfish-scratchbox-build-buffer-name) + (setq default-directory project-root-path) + (compilation-start command-to-run 'sailfish-scratchbox-compilation-mode (lambda (m) (buffer-name)))))) + +(defun scratchbox-deploy-rpms-run (project-root-path) + "Run the deploy command with PROJECT-ROOT-PATH." + (when (get-buffer sailfish-scratchbox-deploy-buffer-name) + (kill-buffer sailfish-scratchbox-deploy-buffer-name)) + (let ((command-to-run sailfish-scratchbox-deploy-rpms-command)) + (with-current-buffer (get-buffer-create sailfish-scratchbox-deploy-buffer-name) + (setq default-directory project-root-path) + (compilation-start command-to-run 'sailfish-scratchbox-compilation-mode (lambda (m) (buffer-name)))))) + +(defun scratchbox-install-rpms-run (project-root-path) + "Run the install rpm packages command with PROJECT-ROOT-PATH." + (when (get-buffer sailfish-scratchbox-deploy-buffer-name) + (kill-buffer sailfish-scratchbox-deploy-buffer-name)) + (let ((command-to-run (scratchbox-install-rpms-generate-command))) + (with-current-buffer (get-buffer-create sailfish-scratchbox-deploy-buffer-name) + (setq default-directory project-root-path) + (compilation-start command-to-run 'sailfish-scratchbox-compilation-mode (lambda (m) (buffer-name)))))) + +;;;###autoload +(defun sailfish-scratchbox-mb2-build () + "Build the project inside the sdk this file is in." + (interactive) + (run-with-project-path 'scratchbox-mb2-build-run)) + +;;;###autoload +(defun sailfish-scratchbox-deploy-rpms () + "Copy the the built project artifacts to the phone." + (interactive) + (run-with-project-path 'scratchbox-deploy-rpms-run)) + +;;;###autoload +(defun sailfish-scratchbox-install-rpms () + "Install project rpm packages into the sailfish os scratchbox." + (interactive) + (run-with-project-path 'scratchbox-install-rpms-run)) + +(provide 'sailfish-scratchbox) +;;; sailfish-scratchbox.el ends here diff --git a/packages/salt-mode-20181015.1025.el b/packages/salt-mode-20181225.1157.el similarity index 95% rename from packages/salt-mode-20181015.1025.el rename to packages/salt-mode-20181225.1157.el index eb9f878..ca27550 100644 --- a/packages/salt-mode-20181015.1025.el +++ b/packages/salt-mode-20181225.1157.el @@ -5,7 +5,7 @@ ;; Author: Ben Hayden ;; Maintainer: Glynn Forrest ;; URL: https://github.com/glynnforrest/salt-mode -;; Package-Version: 20181015.1025 +;; Package-Version: 20181225.1157 ;; Keywords: languages ;; Version: 0.1 ;; Package-Requires: ((emacs "24.4") (yaml-mode "0.0.12") (mmm-mode "0.5.4") (mmm-jinja2 "0.1")) @@ -560,15 +560,32 @@ https://docs.saltstack.com/en/latest/topics/orchestrate/orchestrate_runner.html" ;; (define-key map (kbd "C-M-p") 'salt-mode-backward-state-id) map) "Keymap for `salt-mode'.") +(defvar-local salt-mode--file-type 'salt + "The type of SLS file the buffer is currently visiting, either 'salt or 'top.") + +(defun salt-mode--detect-file-type () + "Suggest the value of salt-mode--file-type according to the current file." + (if (null buffer-file-name) 'salt + (if (equal (file-name-nondirectory buffer-file-name) "top.sls") + 'top 'salt))) + +(defun salt-mode-set-file-type (type) + "Set the file type of the current file and refresh font locking." + (interactive (list (intern (completing-read "Set file type: " '("salt" "top"))))) + (if (not (member type '(salt top))) + (error (format "File type must be 'salt or 'top, %s given." type))) + (setq salt-mode--file-type type) + (salt-mode--set-keywords)) + (defun salt-mode--set-keywords () - "Set keywords appropriate for the current SLS file type." + "Set keywords appropriate for the value of salt-mode--file-type." (font-lock-remove-keywords nil salt-mode-top-file-keywords) (font-lock-remove-keywords nil salt-mode-keywords) (font-lock-add-keywords nil - (cond ((null buffer-file-name) + (cond ((equal salt-mode--file-type 'salt) salt-mode-keywords) - ((equal (file-name-nondirectory buffer-file-name) "top.sls") + ((equal salt-mode--file-type 'top) salt-mode-top-file-keywords) (t salt-mode-keywords))) (if (fboundp 'font-lock-flush) @@ -594,8 +611,7 @@ required.)" (setq-local yaml-indent-offset salt-mode-indent-level) (setq-local eldoc-documentation-function #'salt-mode--eldoc) - (salt-mode--set-keywords) - (add-hook 'buffer-list-update-hook #'salt-mode--set-keywords nil t) + (salt-mode-set-file-type (salt-mode--detect-file-type)) (unless mmm-in-temp-buffer (salt-mode-refresh-data t))) diff --git a/packages/sass-mode-20161007.626.el b/packages/sass-mode-20190502.53.el similarity index 98% rename from packages/sass-mode-20161007.626.el rename to packages/sass-mode-20190502.53.el index d3786e9..8be0cf0 100644 --- a/packages/sass-mode-20161007.626.el +++ b/packages/sass-mode-20190502.53.el @@ -4,7 +4,7 @@ ;; Author: Natalie Weizenbaum ;; URL: http://github.com/nex3/haml/tree/master -;; Package-Version: 20161007.626 +;; Package-Version: 20190502.53 ;; Version: 3.0.16 ;; Created: 2007-03-15 ;; By: Natalie Weizenbaum @@ -121,7 +121,7 @@ beginning of non-whitespace on the current line until one matches. If it has SUBEXP and FACE, then SUBEXP is highlighted using FACE. If it has FN, FN is run.") -(defun sass-highlight-line (limit) +(cl-defun sass-highlight-line (limit) "Highlight a single line using some Sass single-line syntax. This syntax is taken from `sass-line-keywords'. LIMIT is the limit of the search." @@ -139,7 +139,7 @@ LIMIT is the limit of the search." (setq fn subexp-or-fn)) (when fn (funcall fn)) (end-of-line) - (cl-return t))))))) + (cl-return-from sass-highlight-line t))))))) (defun sass-highlight-selector () "Highlight a CSS selector starting at `point' and ending at `end-of-line'." diff --git a/packages/sayid-20181024.1838.el b/packages/sayid-20181223.835.el similarity index 86% rename from packages/sayid-20181024.1838.el rename to packages/sayid-20181223.835.el index 84d4aa2..8eba1b9 100644 --- a/packages/sayid-20181024.1838.el +++ b/packages/sayid-20181223.835.el @@ -4,7 +4,7 @@ ;; Author: Bill Piel ;; Version: 0.0.17 -;; Package-Version: 20181024.1838 +;; Package-Version: 20181223.835 ;; URL: https://github.com/clojure-emacs/sayid ;; Package-Requires: ((cider "0.14.0")) @@ -22,8 +22,8 @@ ;;; Commentary: -;; Sayid is a debugger for clojure. This package, sayid.el, is a client -;; for the sayid nrepl middleware. +;; Sayid is a debugger for Clojure. This package, sayid.el, is a client +;; for the sayid nREPL middleware. ;; To enable, use something like this: @@ -131,15 +131,15 @@ "Sayid nesting, depth 10." :group 'sayid) -(defvar sayid-trace-ns-dir) -(defvar sayid-meta) +(defvar sayid-trace-ns-dir nil) +(defvar sayid-meta nil) (defvar sayid-buf-spec '("*sayid*" . sayid-mode)) (defvar sayid-traced-buf-spec '("*sayid-traced*" . sayid-traced-mode)) (defvar sayid-pprint-buf-spec '("*sayid-pprint*" . sayid-pprint-mode)) (defvar sayid-selected-buf sayid-buf-spec) -(defvar sayid-ring) +(defvar sayid-ring '()) ;;;###autoload (defun sayid--inject-jack-in-dependencies () @@ -489,7 +489,7 @@ Disable traces, load buffer, enable traces, clear log." (let ((current (sayid-peek-first-in-ring))) (if current (sayid-swap-first-in-ring (list (car current) - (sayid-buf-point))))))) + (sayid-buf-point))))))) (defun sayid-push-buf-state-to-ring (content) "Push buffer content CONTENT to ring." @@ -518,7 +518,7 @@ Disable traces, load buffer, enable traces, clear log." (interactive) (sayid-select-traced-buf) (sayid-req-insert-content (list "op" "sayid-show-traced" - "ns" ns)) + "ns" ns)) (sayid-select-default-buf)) ;;;###autoload @@ -751,8 +751,8 @@ Disable traces, load buffer, enable traces, clear log." "Query workspace for id, with optional modifier." (interactive) (sayid-req-insert-content (list "op" "sayid-buf-query-id-w-mod" - "trace-id" (get-text-property (point) 'id) - "mod" (read-string "query modifier: ")))) + "trace-id" (get-text-property (point) 'id) + "mod" (read-string "query modifier: ")))) ;;;###autoload (defun sayid-query-id () @@ -767,16 +767,16 @@ Disable traces, load buffer, enable traces, clear log." "Query workspace for function, with optional modifier." (interactive) (sayid-req-insert-content (list "op" "sayid-buf-query-fn-w-mod" - "fn-name" (get-text-property (point) 'fn-name) - "mod" (read-string "query modifier: ")))) + "fn-name" (get-text-property (point) 'fn-name) + "mod" (read-string "query modifier: ")))) ;;;###autoload (defun sayid-query-fn () "Query workspace for function." (interactive) (sayid-req-insert-content (list "op" "sayid-buf-query-fn-w-mod" - "fn-name" (get-text-property (point) 'fn-name) - "mod" ""))) + "fn-name" (get-text-property (point) 'fn-name) + "mod" ""))) ;;;###autoload (defun sayid-buf-def-at-point () @@ -801,8 +801,8 @@ Disable traces, load buffer, enable traces, clear log." (interactive) (sayid-select-pprint-buf) (sayid-req-insert-content (list "op" "sayid-buf-pprint-at-point" - "trace-id" (get-text-property (point) 'id) - "path" (get-text-property (point) 'path))) + "trace-id" (get-text-property (point) 'id) + "path" (get-text-property (point) 'path))) (goto-char 1) (sayid-select-default-buf)) @@ -892,28 +892,28 @@ Place expression in kill ring." nil (cadr buf-state)))) -(defvar sayid-clj-mode-keys (make-sparse-keymap)) - -(define-key sayid-clj-mode-keys (kbd "f") 'sayid-query-form-at-point) -(define-key sayid-clj-mode-keys (kbd "!") 'sayid-load-enable-clear) -(define-key sayid-clj-mode-keys (kbd "w") 'sayid-get-workspace) -(define-key sayid-clj-mode-keys (kbd "t y") 'sayid-trace-all-ns-in-dir) -(define-key sayid-clj-mode-keys (kbd "t p") 'sayid-trace-ns-by-pattern) -(define-key sayid-clj-mode-keys (kbd "t b") 'sayid-trace-ns-in-file) -(define-key sayid-clj-mode-keys (kbd "t e") 'sayid-trace-fn-enable) -(define-key sayid-clj-mode-keys (kbd "t E") 'sayid-trace-enable-all) -(define-key sayid-clj-mode-keys (kbd "t d") 'sayid-trace-fn-disable) -(define-key sayid-clj-mode-keys (kbd "t D") 'sayid-trace-disable-all) -(define-key sayid-clj-mode-keys (kbd "t n") 'sayid-inner-trace-fn) -(define-key sayid-clj-mode-keys (kbd "t o") 'sayid-outer-trace-fn) -(define-key sayid-clj-mode-keys (kbd "t r") 'sayid-remove-trace-fn) -(define-key sayid-clj-mode-keys (kbd "t K") 'sayid-kill-all-traces) -(define-key sayid-clj-mode-keys (kbd "c") 'sayid-clear-log) -(define-key sayid-clj-mode-keys (kbd "x") 'sayid-reset-workspace) -(define-key sayid-clj-mode-keys (kbd "s") 'sayid-show-traced) -(define-key sayid-clj-mode-keys (kbd "S") 'sayid-show-traced-ns) -(define-key sayid-clj-mode-keys (kbd "V s") 'sayid-set-view) -(define-key sayid-clj-mode-keys (kbd "h") 'sayid-show-help) +(defvar sayid-clj-mode-keys + (let ((map (make-sparse-keymap))) + (define-key map (kbd "f") 'sayid-query-form-at-point) + (define-key map (kbd "!") 'sayid-load-enable-clear) + (define-key map (kbd "w") 'sayid-get-workspace) + (define-key map (kbd "t y") 'sayid-trace-all-ns-in-dir) + (define-key map (kbd "t p") 'sayid-trace-ns-by-pattern) + (define-key map (kbd "t b") 'sayid-trace-ns-in-file) + (define-key map (kbd "t e") 'sayid-trace-fn-enable) + (define-key map (kbd "t E") 'sayid-trace-enable-all) + (define-key map (kbd "t d") 'sayid-trace-fn-disable) + (define-key map (kbd "t D") 'sayid-trace-disable-all) + (define-key map (kbd "t n") 'sayid-inner-trace-fn) + (define-key map (kbd "t o") 'sayid-outer-trace-fn) + (define-key map (kbd "t r") 'sayid-remove-trace-fn) + (define-key map (kbd "t K") 'sayid-kill-all-traces) + (define-key map (kbd "c") 'sayid-clear-log) + (define-key map (kbd "x") 'sayid-reset-workspace) + (define-key map (kbd "s") 'sayid-show-traced) + (define-key map (kbd "S") 'sayid-show-traced-ns) + (define-key map (kbd "V s") 'sayid-set-view) + (define-key map (kbd "h") 'sayid-show-help))) (defun sayid-show-help () "Show sayid help buffer." @@ -944,34 +944,31 @@ h -- show this help "Define 'clojure-mode' keybindings." (define-key clojure-mode-map prefix sayid-clj-mode-keys)) - -(defvar sayid-mode-map) - -(setq sayid-mode-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "") 'sayid-buffer-nav-from-point) - (define-key map (kbd "d") 'sayid-buf-def-at-point) - (define-key map (kbd "f") 'sayid-query-fn) - (define-key map (kbd "F") 'sayid-query-fn-w-mod) - (define-key map (kbd "i") 'sayid-query-id) - (define-key map (kbd "I") 'sayid-query-id-w-mod) - (define-key map (kbd "w") 'sayid-get-workspace) - (define-key map (kbd "n") 'sayid-buffer-nav-to-next) - (define-key map (kbd "N") 'sayid-buf-replay-with-inner-trace) - (define-key map (kbd "p") 'sayid-buffer-nav-to-prev) - (define-key map (kbd "P") 'sayid-buf-pprint-at-point) - (define-key map (kbd "v") 'sayid-toggle-view) - (define-key map (kbd "V") 'sayid-set-view) - (define-key map (kbd "") 'sayid-buf-back) - (define-key map (kbd "") 'sayid-buf-forward) - (define-key map (kbd "l") 'sayid-buf-back) - (define-key map (kbd "L") 'sayid-buf-forward) - (define-key map (kbd "c i") 'sayid-buf-inspect-at-point) - (define-key map (kbd "g") 'sayid-gen-instance-expr) - (define-key map (kbd "C") 'sayid-clear-log) - (define-key map (kbd "h") 'sayid-buf-show-help) - (define-key map (kbd "q") 'quit-window) - map)) +(defvar sayid-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "") 'sayid-buffer-nav-from-point) + (define-key map (kbd "d") 'sayid-buf-def-at-point) + (define-key map (kbd "f") 'sayid-query-fn) + (define-key map (kbd "F") 'sayid-query-fn-w-mod) + (define-key map (kbd "i") 'sayid-query-id) + (define-key map (kbd "I") 'sayid-query-id-w-mod) + (define-key map (kbd "w") 'sayid-get-workspace) + (define-key map (kbd "n") 'sayid-buffer-nav-to-next) + (define-key map (kbd "N") 'sayid-buf-replay-with-inner-trace) + (define-key map (kbd "p") 'sayid-buffer-nav-to-prev) + (define-key map (kbd "P") 'sayid-buf-pprint-at-point) + (define-key map (kbd "v") 'sayid-toggle-view) + (define-key map (kbd "V") 'sayid-set-view) + (define-key map (kbd "") 'sayid-buf-back) + (define-key map (kbd "") 'sayid-buf-forward) + (define-key map (kbd "l") 'sayid-buf-back) + (define-key map (kbd "L") 'sayid-buf-forward) + (define-key map (kbd "c i") 'sayid-buf-inspect-at-point) + (define-key map (kbd "g") 'sayid-gen-instance-expr) + (define-key map (kbd "C") 'sayid-clear-log) + (define-key map (kbd "h") 'sayid-buf-show-help) + (define-key map (kbd "q") 'quit-window) + map)) (defun sayid-buf-show-help () "Show sayid buffer help buffer." @@ -1003,25 +1000,21 @@ h -- help (setq truncate-lines t) (buffer-disable-undo)) - - -(defvar sayid-traced-mode-map) - -(setq sayid-traced-mode-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "") 'sayid-traced-buf-enter) - (define-key map (kbd "e") 'sayid-traced-buf-enable) - (define-key map (kbd "d") 'sayid-traced-buf-disable) - (define-key map (kbd "E") 'sayid-trace-enable-all) - (define-key map (kbd "D") 'sayid-trace-disable-all) - (define-key map (kbd "i") 'sayid-traced-buf-inner-trace-fn) - (define-key map (kbd "o") 'sayid-traced-buf-outer-trace-fn) - (define-key map (kbd "r") 'sayid-traced-buf-remove-trace) - (define-key map (kbd "") 'sayid-show-traced) - (define-key map (kbd "l") 'sayid-show-traced) - (define-key map (kbd "h") 'sayid-traced-buf-show-help) - (define-key map (kbd "q") 'quit-window) - map)) +(defvar sayid-traced-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "") 'sayid-traced-buf-enter) + (define-key map (kbd "e") 'sayid-traced-buf-enable) + (define-key map (kbd "d") 'sayid-traced-buf-disable) + (define-key map (kbd "E") 'sayid-trace-enable-all) + (define-key map (kbd "D") 'sayid-trace-disable-all) + (define-key map (kbd "i") 'sayid-traced-buf-inner-trace-fn) + (define-key map (kbd "o") 'sayid-traced-buf-outer-trace-fn) + (define-key map (kbd "r") 'sayid-traced-buf-remove-trace) + (define-key map (kbd "") 'sayid-show-traced) + (define-key map (kbd "l") 'sayid-show-traced) + (define-key map (kbd "h") 'sayid-traced-buf-show-help) + (define-key map (kbd "q") 'quit-window) + map)) (defun sayid-traced-buf-show-help () "Show sayid traced buffer help buffer." @@ -1046,20 +1039,18 @@ q -- quit window (setq truncate-lines t)) -(defvar sayid-pprint-mode-map) - -(setq sayid-pprint-mode-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "h") 'sayid-pprint-buf-show-help) - (define-key map (kbd "o") 'sayid-pprint-buf-out) - (define-key map (kbd "i") 'sayid-pprint-buf-in) - (define-key map (kbd "p") 'sayid-pprint-buf-prev) - (define-key map (kbd "n") 'sayid-pprint-buf-next) - (define-key map (kbd "") 'sayid-pprint-buf-show-path) - (define-key map (kbd "") 'sayid-pprint-buf-exit) - (define-key map (kbd "l") 'sayid-pprint-buf-exit) - (define-key map (kbd "q") 'quit-window) - map)) +(defvar sayid-pprint-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "h") 'sayid-pprint-buf-show-help) + (define-key map (kbd "o") 'sayid-pprint-buf-out) + (define-key map (kbd "i") 'sayid-pprint-buf-in) + (define-key map (kbd "p") 'sayid-pprint-buf-prev) + (define-key map (kbd "n") 'sayid-pprint-buf-next) + (define-key map (kbd "") 'sayid-pprint-buf-show-path) + (define-key map (kbd "") 'sayid-pprint-buf-exit) + (define-key map (kbd "l") 'sayid-pprint-buf-exit) + (define-key map (kbd "q") 'quit-window) + map)) (defun sayid-pprint-buf-show-help () "Show sayid pretty-print buffer help buffer." @@ -1084,9 +1075,9 @@ q -- quit window ;;;###autoload (defun sayid-setup-package (&optional clj-mode-prefix) - "Setup the sayid package. Optionally takes CLJ-MODE-PREFIX, -which is used as the prefix for clojure-mode keybindings. -Default prefix is 'C-c s'." + "Setup the sayid package. +Optionally takes CLJ-MODE-PREFIX, which is used as the prefix for +clojure-mode keybindings. Default prefix is 'C-c s'." (interactive) (sayid-set-clj-mode-keys (or clj-mode-prefix (kbd "C-c s")))) diff --git a/packages/sbt-mode-20180511.1622.tar b/packages/sbt-mode-20180511.1622.tar index 4c5c7c7..dea3989 100644 Binary files a/packages/sbt-mode-20180511.1622.tar and b/packages/sbt-mode-20180511.1622.tar differ diff --git a/packages/scad-mode-20180109.209.el b/packages/scad-mode-20190413.1246.el similarity index 94% rename from packages/scad-mode-20180109.209.el rename to packages/scad-mode-20190413.1246.el index 751bf9d..0ad5763 100644 --- a/packages/scad-mode-20180109.209.el +++ b/packages/scad-mode-20190413.1246.el @@ -5,7 +5,7 @@ ;; Created: March 2010 ;; Modified: 28 Mar 2015 ;; Keywords: languages -;; Package-Version: 20180109.209 +;; Package-Version: 20190413.1246 ;; URL: https://raw.github.com/openscad/openscad/master/contrib/scad-mode.el ;; Version: 91.0 @@ -175,6 +175,11 @@ nil. If you want to set the style with file local variables use the `c-file-style' variable") +(defvar scad-completions + (append '("module" "function" "use" "include") + scad-keywords scad-functions scad-modules) + "List of known words for completion.") + (put 'scad-mode 'c-mode-prefix "scad-") ;;;###autoload (define-derived-mode scad-mode prog-mode "SCAD" @@ -187,6 +192,8 @@ initialization, then `scad-mode-hook'. Key bindings: \\{scad-mode-map}" + (add-hook 'completion-at-point-functions + 'scad-completion-at-point nil 'local) (c-initialize-cc-mode) ;; (setq local-abbrev-table scad-mode-abbrev-table ;; abbrev-mode t) @@ -197,6 +204,14 @@ Key bindings: (c-run-mode-hooks 'c-mode-common-hook 'scad-mode-hook) (c-update-modeline)) +(defun scad-completion-at-point () + "Completion at point function." + (let ((bounds (bounds-of-thing-at-point 'word))) + (when bounds + (list (car bounds) (cdr bounds) + scad-completions + :exclusive "no")))) + ;; From: http://stackoverflow.com/questions/14520073/add-words-for-dynamic-expansion-to-emacs-mode (defun scad-prime-dabbrev () "Makes a hidden scad-mode buffer containing all the scad keywords, so dabbrev expansion just works." diff --git a/packages/scala-mode-20170802.1132.tar b/packages/scala-mode-20170802.1132.tar index 67d53bf..6512258 100644 Binary files a/packages/scala-mode-20170802.1132.tar and b/packages/scala-mode-20170802.1132.tar differ diff --git a/packages/selectric-mode-20170216.1111.tar b/packages/selectric-mode-20170216.1111.tar index bacc803..a4e2133 100644 Binary files a/packages/selectric-mode-20170216.1111.tar and b/packages/selectric-mode-20170216.1111.tar differ diff --git a/packages/sesman-20181109.1100.tar b/packages/sesman-20190623.1123.tar similarity index 97% rename from packages/sesman-20181109.1100.tar rename to packages/sesman-20190623.1123.tar index d3f3910..121d679 100644 Binary files a/packages/sesman-20181109.1100.tar and b/packages/sesman-20190623.1123.tar differ diff --git a/packages/seti-theme-20161208.1636.el b/packages/seti-theme-20190201.1848.el similarity index 98% rename from packages/seti-theme-20161208.1636.el rename to packages/seti-theme-20190201.1848.el index 2e9b341..371aa50 100644 --- a/packages/seti-theme-20161208.1636.el +++ b/packages/seti-theme-20190201.1848.el @@ -3,7 +3,7 @@ ;; ;; Author: Vlad Piersec ;; Version: 0.2 -;; Package-Version: 20161208.1636 +;; Package-Version: 20190201.1848 ;; Keywords: themes ;; URL: https://github.com/caisah/seti-theme ;; @@ -167,6 +167,8 @@ ;; Lines `(linum ((t (:foreground ,text-4 :weight light :height 0.9)))) + `(line-number ((t (:inherit linum)))) + `(line-number-current-line ((t (:inherit linum)))) `(fringe ((t (:background ,background-3 :foreground ,text-4)))) `(left-margin ((t (nil)))) `(hl-line ((t (:background ,background-4))))) diff --git a/packages/shrink-path-20170813.247.el b/packages/shrink-path-20190208.1335.el similarity index 98% rename from packages/shrink-path-20170813.247.el rename to packages/shrink-path-20190208.1335.el index b3f3676..582ed72 100644 --- a/packages/shrink-path-20170813.247.el +++ b/packages/shrink-path-20190208.1335.el @@ -4,7 +4,7 @@ ;; Author: Benjamin Andresen ;; Version: 0.3.1 -;; Package-Version: 20170813.247 +;; Package-Version: 20190208.1335 ;; URL: https://gitlab.com/bennya/shrink-path.el ;; Package-Requires: ((emacs "24") (s "1.6.1") (dash "1.8.0") (f "0.10.0")) @@ -50,7 +50,7 @@ "Return fish-style truncated string based on FULL-PATH. Optional parameter TRUNCATE-ALL will cause the function to truncate the last directory too." - (let* ((home (getenv "HOME")) + (let* ((home (expand-file-name "~")) (path (replace-regexp-in-string (s-concat "^" home) "~" full-path)) (split (s-split "/" path 'omit-nulls)) diff --git a/packages/shut-up-20180628.1830.el b/packages/shut-up-20180628.1830.el deleted file mode 100644 index db5326f..0000000 --- a/packages/shut-up-20180628.1830.el +++ /dev/null @@ -1,150 +0,0 @@ -;;; shut-up.el --- Shut up would you! -*- lexical-binding: t; -*- - -;; Copyright (C) 2013, 2014 Johan Andersson -;; Copyright (C) 2014, 2015 Sebastian Wiesner - -;; Author: Johan Andersson -;; Maintainer: Johan Andersson -;; Package-Requires: ((cl-lib "0.3") (emacs "24")) -;; Package-Version: 20180628.1830 -;; Version: 0.3.2 -;; URL: http://github.com/rejeep/shut-up.el - -;; This file is NOT part of GNU Emacs. - -;;; License: - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;;; Code: - -(require 'cl-lib) -(eval-when-compile - (defvar dired-use-ls-dired)) - -;; NOTE: This variable has been added in most recent version of -;; Emacs. It's declared here to support lexical binding and to avoid -;; compiler warnings. -(defvar inhibit-message nil) - -(defvar shut-up-ignore nil - "When non-nil, do not hide output inside `shut-up'. - -Changes to this variable inside a `shut-up' block has no -effect.") - -;; Preserve the original definition of `write-region' -(unless (fboundp 'shut-up-write-region-original) - (fset 'shut-up-write-region-original (symbol-function 'write-region))) - -(defun shut-up-write-region (start end filename - &optional append visit lockname mustbenew) - "Like `write-region', but try to suppress any messages." - (unless visit - (setq visit 'no-message)) - ;; Call our "copy" of `write-region', because if this function is used to - ;; override `write-region', calling `write-region' directly here would result - ;; in any endless recursion. - (shut-up-write-region-original start end filename - append visit lockname mustbenew)) - -(unless (fboundp 'shut-up-load-original) - (fset 'shut-up-load-original (symbol-function 'load))) - -(defun shut-up-load (file &optional noerror _nomessage nosuffix must-suffix) - "Like `load', but try to be quiet about it." - (shut-up-load-original file noerror :nomessage nosuffix must-suffix)) - -(defun shut-up-buffer-string (buffer) - "Get the contents of BUFFER. - -When BUFFER is alive, return its contents without properties. -Otherwise return nil." - (when (buffer-live-p buffer) - (with-current-buffer buffer - (buffer-substring-no-properties (point-min) (point-max))))) - -(defun shut-up-insert-to-buffer (object buffer) - "Insert OBJECT into BUFFER. - -If BUFFER is not live, do nothing." - (when (buffer-live-p buffer) - (with-current-buffer buffer - (cl-typecase object - (character (insert-char object 1)) - (string (insert object)) - (t (princ object #'insert-char)))))) - -;;;###autoload -(defmacro shut-up (&rest body) - "Evaluate BODY with silenced output. - -While BODY is evaluated, all output is redirected to a buffer, -unless `shut-up-ignore' is non-nil. This affects: - -- `message' -- All functions using `standard-output' (e.g. `print', `princ', etc.) - -Inside BODY, the buffer is bound to the lexical variable -`shut-up-sink'. Additionally provide a lexical function -`shut-up-current-output', which returns the current contents of -`shut-up-sink' when called with no arguments. - -Changes to the variable `shut-up-ignore' inside BODY does not -have any affect." - (declare (indent 0)) - `(let ((shut-up-sink (generate-new-buffer " *shutup*")) - (inhibit-message t)) - (cl-labels ((shut-up-current-output () (or (shut-up-buffer-string shut-up-sink) ""))) - (if shut-up-ignore - (progn ,@body) - (unwind-protect - ;; Override `standard-output', for `print' and friends, and - ;; monkey-patch `message' - (cl-letf ((standard-output - (lambda (char) - (shut-up-insert-to-buffer char shut-up-sink))) - ((symbol-function 'message) - (lambda (fmt &rest args) - (when fmt - (let ((text (concat (apply #'format fmt args) "\n"))) - (shut-up-insert-to-buffer text shut-up-sink))))) - ((symbol-function 'write-region) #'shut-up-write-region) - ((symbol-function 'load) #'shut-up-load)) - ,@body) - (and (buffer-name shut-up-sink) - (kill-buffer shut-up-sink))))))) - -;;;###autoload -(defun shut-up-silence-emacs () - "Silence Emacs. - -Change Emacs settings to reduce the output. - -WARNING: This function has GLOBAL SIDE-EFFECTS. You should only -call this function in `noninteractive' sessions." - ;; Loading vc-git... - (remove-hook 'find-file-hooks 'vc-find-file-hook) - - ;; ls does not support --dired; see `dired-use-ls-dired' for more details. - (eval-after-load "dired" - '(setq dired-use-ls-dired nil))) - -(provide 'shut-up) - -;;; shut-up.el ends here diff --git a/packages/simple-httpd-20180528.1603.el b/packages/simple-httpd-20190110.1505.el similarity index 96% rename from packages/simple-httpd-20180528.1603.el rename to packages/simple-httpd-20190110.1505.el index 07e1895..ebf3ca0 100644 --- a/packages/simple-httpd-20180528.1603.el +++ b/packages/simple-httpd-20190110.1505.el @@ -4,7 +4,7 @@ ;; Author: Christopher Wellons ;; URL: https://github.com/skeeto/emacs-http-server -;; Package-Version: 20180528.1603 +;; Package-Version: 20190110.1505 ;; Version: 1.5.1 ;; Package-Requires: ((cl-lib "0.3")) @@ -179,6 +179,11 @@ :group 'simple-httpd :type 'boolean) +(defcustom httpd-show-backtrace-when-error nil + "If true, show backtrace on error page." + :group 'simple-httpd + :type 'boolean) + (defcustom httpd-start-hook nil "Hook to run when the server has started." :group 'simple-httpd @@ -695,6 +700,23 @@ element is the fragment." (push (if p1 (httpd-parse-args (substring uri (1+ p1) p2))) retval) (push (substring uri 0 (or p1 p2)) retval))) +(defun httpd-escape-html-buffer () + "Escape current buffer contents to be safe for inserting into HTML." + (setf (point) (point-min)) + (while (search-forward-regexp "[<>&]" nil t) + (replace-match + (cl-case (aref (match-string 0) 0) + (?< "<") + (?> ">") + (?& "&"))))) + +(defun httpd-escape-html (string) + "Escape STRING so that it's safe to insert into an HTML document." + (with-temp-buffer + (insert string) + (httpd-escape-html-buffer) + (buffer-string))) + ;; Path handling (defun httpd-status (path) @@ -856,8 +878,21 @@ optionally inserting object INFO into page. If PROC is T use the (httpd-log `(error ,status ,info)) (with-temp-buffer (let ((html (or (cdr (assq status httpd-html)) "")) - (erro (url-insert-entities-in-string (format "error: %s" info)))) - (insert (format html (if info erro "")))) + (contents + (if (not info) + "" + (with-temp-buffer + (let ((standard-output (current-buffer))) + (insert "error: ") + (princ info) + (insert "\n") + (when httpd-show-backtrace-when-error + (insert "backtrace: ") + (princ (backtrace)) + (insert "\n")) + (httpd-escape-html-buffer) + (buffer-string)))))) + (insert (format html contents))) (httpd-send-header proc "text/html" status))) (defun httpd--error-safe (&rest args) diff --git a/packages/skewer-mode-20180706.1807.tar b/packages/skewer-mode-20180706.1807.tar index 82a0e3b..7969c7c 100644 Binary files a/packages/skewer-mode-20180706.1807.tar and b/packages/skewer-mode-20180706.1807.tar differ diff --git a/packages/slack-20181113.336.tar b/packages/slack-20181113.336.tar deleted file mode 100644 index bca7e5a..0000000 Binary files a/packages/slack-20181113.336.tar and /dev/null differ diff --git a/packages/slack-20190803.1406.tar b/packages/slack-20190803.1406.tar new file mode 100644 index 0000000..1c0b136 Binary files /dev/null and b/packages/slack-20190803.1406.tar differ diff --git a/packages/slime-20181112.1346.tar b/packages/slime-20190818.1634.tar similarity index 97% rename from packages/slime-20181112.1346.tar rename to packages/slime-20190818.1634.tar index 04919ac..2250b4a 100644 Binary files a/packages/slime-20181112.1346.tar and b/packages/slime-20190818.1634.tar differ diff --git a/packages/slime-company-20180119.1843.el b/packages/slime-company-20190117.1538.el similarity index 83% rename from packages/slime-company-20180119.1843.el rename to packages/slime-company-20190117.1538.el index 8fd0043..cee7c0c 100644 --- a/packages/slime-company-20180119.1843.el +++ b/packages/slime-company-20190117.1538.el @@ -4,8 +4,8 @@ ;; ;; Author: Ole Arndt ;; Keywords: convenience, lisp, abbrev -;; Package-Version: 20180119.1843 -;; Version: 1.1 +;; Package-Version: 20190117.1538 +;; Version: 1.2 ;; Package-Requires: ((emacs "24.4") (slime "2.13") (company "0.9.0")) ;; ;; This file is free software; you can redistribute it and/or modify @@ -127,13 +127,35 @@ be active in derived modes as well." :group 'slime-company :type '(repeat symbol)) -(defun slime-company-just-one-space (_) - (just-one-space)) +(defun slime-company-just-one-space (completion-string) + (unless (string-suffix-p ":" completion-string) + (just-one-space))) (defsubst slime-company-active-p () "Test if the slime-company backend should be active in the current buffer." (apply #'derived-mode-p slime-company-major-modes)) +(define-derived-mode slime-company-doc-mode help-mode "Doc" + "Documentation mode for slime-company." + (setq font-lock-defaults + '((("^\\([^ ]\\{4,\\}\\)\\b" . (1 font-lock-function-name-face t)) + ("^[ ]*\\b\\([A-Z][A-Za-z0-9_ %\\*\\-]+:\\)\\([ ]\\|$\\)" + . (1 font-lock-doc-face)) + ("^\\([A-Z][A-Za-z ]+:\\)\\([ ]\\|$\\)" + . (1 font-lock-doc-face t)) + ("(\\(FUNCTION\\|VALUES\\|OR\\|EQL\\|LAMBDA\\)\\b" + . (1 font-lock-keyword-face)) + ("[ (]+\\(&[A-Z0-9\\-]+\\)\\b" . (1 font-lock-type-face)) + ("[ (]+\\(:[A-Z0-9\\-]+\\)\\b" . (1 font-lock-builtin-face)) + ("\\b\\(T\\|t\\|NIL\\|nil\\|NULL\\|null\\)\\b" . (1 font-lock-constant-face)) + ("\\b[+-]?[0-9/\\.]+[sdeSDE]?\\+?[0-9]*\\b" . font-lock-constant-face) + ("#[xX][+-]?[0-9A-F/]+\\b" . font-lock-constant-face) + ("#[oO][+-]?[0-7/]+\\b" . font-lock-constant-face) + ("#[bB][+-]?[01/]+\\b" . font-lock-constant-face) + ("#[0-9]+[rR][+-]?[0-9A-Z/]+\\b" . font-lock-constant-face) + ("\\b\\([A-Z0-9:+%<>#*\\.\\-]\\{2,\\}\\)\\b" + . (1 font-lock-variable-name-face)))))) + ;;; ---------------------------------------------------------------------------- ;;; * Activation @@ -236,9 +258,11 @@ be active in derived modes as well." (cl:symbol-name (cl:read-from-string ,pkg-name))))) (slime-eval `(swank:describe-symbol ,candidate))))) (with-current-buffer (company-doc-buffer) - (insert doc) - (goto-char (point-min)) - (current-buffer)))) + (slime-company-doc-mode) + (setq buffer-read-only nil) + (insert doc) + (goto-char (point-min)) + (current-buffer)))) (defun slime-company--location (candidate) (let ((source-buffer (current-buffer))) @@ -253,9 +277,21 @@ be active in derived modes as well." (defun slime-company--post-completion (candidate) (slime-company--echo-arglist candidate) - (when slime-company-after-completion + (when (functionp slime-company-after-completion) (funcall slime-company-after-completion candidate))) +(defun slime-company--in-string-or-comment () + "Return non-nil if point is within a string or comment. +In the REPL we disregard anything not in the current input area." + (save-restriction + (when (derived-mode-p 'slime-repl-mode) + (narrow-to-region slime-repl-input-start-mark (point))) + (let* ((sp (syntax-ppss)) + (beg (nth 8 sp))) + (when (or (eq (char-after beg) ?\") + (nth 4 sp)) + beg)))) + ;;; ---------------------------------------------------------------------------- ;;; * Company backend function @@ -268,7 +304,7 @@ be active in derived modes as well." (when (and (slime-company-active-p) (slime-connected-p) (or slime-company-complete-in-comments-and-strings - (null (company-in-string-or-comment)))) + (null (slime-company--in-string-or-comment)))) (company-grab-symbol))) (candidates (slime-company--fetch-candidates-async (substring-no-properties arg))) diff --git a/packages/smartparens-20181028.1005.tar b/packages/smartparens-20190728.2037.tar similarity index 97% rename from packages/smartparens-20181028.1005.tar rename to packages/smartparens-20190728.2037.tar index 926accb..e8dc3f6 100644 Binary files a/packages/smartparens-20181028.1005.tar and b/packages/smartparens-20190728.2037.tar differ diff --git a/packages/solarized-theme-20181030.1912.tar b/packages/solarized-theme-20190809.1202.tar similarity index 92% rename from packages/solarized-theme-20181030.1912.tar rename to packages/solarized-theme-20190809.1202.tar index d2ba3e5..de3dc95 100644 Binary files a/packages/solarized-theme-20181030.1912.tar and b/packages/solarized-theme-20190809.1202.tar differ diff --git a/packages/spaceline-20180628.746.tar b/packages/spaceline-20181223.2024.tar similarity index 97% rename from packages/spaceline-20180628.746.tar rename to packages/spaceline-20181223.2024.tar index 9043b84..ac7541e 100644 Binary files a/packages/spaceline-20180628.746.tar and b/packages/spaceline-20181223.2024.tar differ diff --git a/packages/spaceline-all-the-icons-20170829.820.tar b/packages/spaceline-all-the-icons-20190325.1602.tar similarity index 98% rename from packages/spaceline-all-the-icons-20170829.820.tar rename to packages/spaceline-all-the-icons-20190325.1602.tar index 8369322..178cc8e 100644 Binary files a/packages/spaceline-all-the-icons-20170829.820.tar and b/packages/spaceline-all-the-icons-20190325.1602.tar differ diff --git a/packages/spacemacs-theme-20190820.816.tar b/packages/spacemacs-theme-20190820.816.tar new file mode 100644 index 0000000..21a2829 Binary files /dev/null and b/packages/spacemacs-theme-20190820.816.tar differ diff --git a/packages/sparql-mode-20180320.1802.tar b/packages/sparql-mode-20180320.1802.tar index 8d8d731..38d63cc 100644 Binary files a/packages/sparql-mode-20180320.1802.tar and b/packages/sparql-mode-20180320.1802.tar differ diff --git a/packages/sql-indent-1.3.tar b/packages/sql-indent-1.4.tar similarity index 87% rename from packages/sql-indent-1.3.tar rename to packages/sql-indent-1.4.tar index 729215e..eb60eae 100644 Binary files a/packages/sql-indent-1.3.tar and b/packages/sql-indent-1.4.tar differ diff --git a/packages/srefactor-20180703.1810.tar b/packages/srefactor-20180703.1810.tar index 309882b..4cc29b9 100644 Binary files a/packages/srefactor-20180703.1810.tar and b/packages/srefactor-20180703.1810.tar differ diff --git a/packages/stan-mode-20180110.2241.tar b/packages/stan-mode-20190805.1427.tar similarity index 88% rename from packages/stan-mode-20180110.2241.tar rename to packages/stan-mode-20190805.1427.tar index 88b33c6..fe00926 100644 Binary files a/packages/stan-mode-20180110.2241.tar and b/packages/stan-mode-20190805.1427.tar differ diff --git a/packages/subatomic-theme-20160126.1538.el b/packages/subatomic-theme-20190607.1022.el similarity index 99% rename from packages/subatomic-theme-20160126.1538.el rename to packages/subatomic-theme-20190607.1022.el index e536a16..4d2fb43 100644 --- a/packages/subatomic-theme-20160126.1538.el +++ b/packages/subatomic-theme-20190607.1022.el @@ -5,7 +5,7 @@ ;; Author: John Olsson ;; Maintainer: John Olsson ;; URL: https://github.com/cryon/subatomic -;; Package-Version: 20160126.1538 +;; Package-Version: 20190607.1022 ;; Created: 25th December 2012 ;; Version: 1.8.1 ;; Keywords: color-theme, blue, low contrast @@ -124,7 +124,7 @@ The theme has to be reloaded after changing anything in this group." `(powerline-active2 ((t (:background ,midnight-1)))) - `(modeline-inactive + `(mode-line-inactive ((t (:background ,midnight-2 :foreground ,mystic-blue)))) `(powerline-inactive1 diff --git a/packages/sublime-themes-20170606.1844.tar b/packages/sublime-themes-20170606.1844.tar index 525cc0b..1c32efc 100644 Binary files a/packages/sublime-themes-20170606.1844.tar and b/packages/sublime-themes-20170606.1844.tar differ diff --git a/packages/swift-mode-20181117.1202.tar b/packages/swift-mode-20190609.507.tar similarity index 90% rename from packages/swift-mode-20181117.1202.tar rename to packages/swift-mode-20190609.507.tar index f775cd1..a220688 100644 Binary files a/packages/swift-mode-20181117.1202.tar and b/packages/swift-mode-20190609.507.tar differ diff --git a/packages/swiper-20181008.1731.el b/packages/swiper-20181008.1731.el deleted file mode 100644 index 4fc04bb..0000000 --- a/packages/swiper-20181008.1731.el +++ /dev/null @@ -1,1058 +0,0 @@ -;;; swiper.el --- Isearch with an overview. Oh, man! -*- lexical-binding: t -*- - -;; Copyright (C) 2015-2018 Free Software Foundation, Inc. - -;; Author: Oleh Krehel -;; URL: https://github.com/abo-abo/swiper -;; Package-Version: 20181008.1731 -;; Version: 0.10.0 -;; Package-Requires: ((emacs "24.1") (ivy "0.9.0")) -;; 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 . - -;;; 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.") - -(defface swiper-match-face-2 - '((t (:inherit isearch))) - "Face for `swiper' matches modulo 1.") - -(defface swiper-match-face-3 - '((t (:inherit match))) - "Face for `swiper' matches modulo 2.") - -(defface swiper-match-face-4 - '((t (:inherit isearch-fail))) - "Face for `swiper' matches modulo 3.") - -(defface swiper-line-face - '((t (:inherit highlight))) - "Face for current `swiper' line.") - -(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)) - -(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." - :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.") - -(defun swiper-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-map'") - (let* ((enable-recursive-minibuffers t) - (from (ivy--regex ivy-text)) - (to (minibuffer-with-setup-hook - (lambda () - (setq minibuffer-default - (if (string-match "\\`\\\\_<\\(.*\\)\\\\_>\\'" ivy-text) - (match-string 1 ivy-text) - ivy-text))) - (read-from-minibuffer (format "Query replace %s with: " from))))) - (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)))))))) - -(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-background) -(defvar avy-all-windows) -(defvar avy-style) -(defvar avy-keys) -(declare-function avy--regex-candidates "ext:avy") -(declare-function avy--process "ext:avy") -(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-candidate () - (let* ((avy-all-windows nil) - ;; 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) - swiper-faces)) - (setq min-overlay-start (overlay-start ov)))) - visible-overlays)) - (offset (if (eq (ivy-state-caller ivy-last) 'swiper) 1 0)) - (candidates (append - (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 ((cands)) - (while (< (point) (point-max)) - (push (cons (+ (point) offset) - (selected-window)) - cands) - (forward-line)) - cands)))))) - (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)))) - -;;;###autoload -(defun swiper-avy () - "Jump to one of the current swiper candidates." - (interactive) - (unless (require 'avy nil 'noerror) - (error "Package avy isn't installed")) - (unless (string= ivy-text "") - (let ((candidate (swiper--avy-candidate))) - (if (window-minibuffer-p (cdr candidate)) - (let ((cand-text (save-excursion - (goto-char (car candidate)) - (buffer-substring-no-properties - (line-beginning-position) - (line-end-position))))) - (ivy-set-index (cl-position cand-text ivy--old-cands :test #'string=)) - (ivy--exhibit) - (ivy-done) - (ivy-call)) - (ivy-quit-and-run - (avy-action-goto (avy-candidate-beg 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." - (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))) - (unless (string= ivy-text "") - (ivy-exit-with-action - (lambda (_) - (let (cand) - (while (setq cand (pop cands)) - (swiper--action cand) - (when cands - (mc/create-fake-cursor-at-point)))) - (multiple-cursors-mode 1)))))) - -(defun swiper-recenter-top-bottom (&optional arg) - "Call (`recenter-top-bottom' ARG)." - (interactive "P") - (with-ivy-window - (recenter-top-bottom arg))) - -(defvar swiper-font-lock-exclude - '(bbdb-mode - bookmark-bmenu-mode - package-menu-mode - gnus-summary-mode - gnus-article-mode - gnus-group-mode - emms-playlist-mode - emms-stream-mode - eshell-mode - erc-mode - forth-mode - forth-block-mode - helpful-mode - nix-mode - org-agenda-mode - dired-mode - jabber-chat-mode - elfeed-search-mode - elfeed-show-mode - fundamental-mode - Man-mode - woman-mode - mu4e-view-mode - mu4e-headers-mode - notmuch-tree-mode - notmuch-search-mode - help-mode - debbugs-gnu-mode - occur-mode - occur-edit-mode - bongo-mode - bongo-library-mode - magit-popup-mode - adoc-mode - bongo-playlist-mode - eww-mode - treemacs-mode - twittering-mode - vc-dir-mode - rcirc-mode - circe-channel-mode - circe-server-mode - circe-query-mode - sauron-mode - w3m-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))) - -(defun swiper-font-lock-ensure () - "Ensure the entired 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 nubmer.") - -(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") - -(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 (and visual-line-mode - ;; super-slow otherwise - (< (buffer-size) 20000) - (< n-lines 400)) - (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 0) - (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)) - (let ((str (swiper--line))) - (setq str (ivy-cleanup-string str)) - (let ((line-number-str - (format swiper--format-spec (cl-incf 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 str)) - (push str candidates)) - (funcall advancer 1)) - (nreverse candidates)))))) - -(defvar swiper--opoint 1 - "The point when `swiper' starts.") - -;;;###autoload -(defun swiper (&optional initial-input) - "`isearch' with an overview. -When non-nil, INITIAL-INPUT is the initial search pattern." - (interactive) - (swiper--ivy (swiper--candidates) initial-input)) - -(defvar swiper--current-window-start nil) - -(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 (&optional revert) - "Generate a custom occur buffer for `swiper'. -When REVERT is non-nil, regenerate the current *ivy-occur* buffer. -When capture groups are present in the input, print them instead of lines." - (let* ((buffer (ivy-state-buffer ivy-last)) - (fname (propertize - (with-ivy-window - (if (buffer-file-name buffer) - (file-name-nondirectory - (buffer-file-name buffer)) - (buffer-name buffer))) - 'face - 'compilation-info)) - (re (progn (string-match "\"\\(.*\\)\"" (buffer-name)) - (match-string 1 (buffer-name)))) - (re (mapconcat #'identity (ivy--split re) ".*?")) - (cands - (mapcar - (lambda (s) - (let* ((n (get-text-property 0 'swiper-line-number s)) - (i (string-match-p "[ \t\n\r]+\\'" n))) - (when i (setq n (substring n 0 i))) - (put-text-property 0 (length n) 'face 'compilation-line-number n) - (format "%s:%s:%s" fname n (substring s 1)))) - (if (not revert) - ivy--old-cands - (setq ivy--old-re nil) - (let ((ivy--regex-function 'swiper--re-builder)) - (ivy--filter re (with-current-buffer buffer - (swiper--candidates)))))))) - (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)) - (setq swiper--current-window-start nil) - (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n" - default-directory)) - (insert (format "%d candidates:\n" (length cands))) - (ivy--occur-insert-lines - (mapcar - (lambda (cand) (concat "./" cand)) - cands)) - (goto-char (point-min)) - (forward-line 4)))) - -(ivy-set-occur 'swiper 'swiper-occur) - -(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)) - (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) - ".") - ((string-match "^\\^" str) - (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))) - (if (zerop ivy--subexps) - (prog1 (format "^ ?\\(%s\\)" re) - (setq ivy--subexps 1)) - (format "^ %s" re)))) - ((eq (bound-and-true-p search-default-mode) 'char-fold-to-regexp) - (mapconcat #'char-fold-to-regexp (ivy--split str) ".*")) - (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) - -(defun swiper--ivy (candidates &optional initial-input) - "Select one of CANDIDATES and move there. -When non-nil, INITIAL-INPUT is the initial search pattern." - (swiper--init) - (setq swiper-invocation-face - (plist-get (text-properties-at (point)) 'face)) - (let ((preselect - (if swiper-use-visual-line - (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 preselect - :require-match t - :update-fn #'swiper--update-input-ivy - :unwind #'swiper--cleanup - :action #'swiper--action - :re-builder #'swiper--re-builder - :history 'swiper-history - :caller 'swiper)) - (point)) - (unless (or res swiper-stay-on-quit) - (goto-char swiper--opoint)) - (when (and (null res) (> (length ivy-text) 0)) - (cl-pushnew ivy-text swiper-history)) - (when swiper--reveal-mode - (reveal-mode 1))))) - -(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)) - (i 0)) - (while (and (< i (length s)) - (text-property-any - i (1+ i) - 'face swiper-invocation-face - s)) - (cl-incf i)) - (eq i (length s))))) - 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.") - -(defun swiper--cleanup () - "Clean up the overlays." - (while swiper--overlays - (delete-overlay (pop swiper--overlays))) - (save-excursion - (goto-char (point-min)) - (isearch-clean-overlays))) - -(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* ((regexp-or-regexps (funcall ivy--regex-function ivy-text)) - (regexps - (if (listp regexp-or-regexps) - (mapcar #'car (cl-remove-if-not #'cdr regexp-or-regexps)) - (list regexp-or-regexps)))) - (dolist (re regexps) - (let* ((re (replace-regexp-in-string - " " "\t" - re)) - (str (get-text-property 0 'swiper-line-number (ivy-state-current ivy-last))) - (num (if (string-match "^[0-9]+" str) - (string-to-number (match-string 0 str)) - 0))) - (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)) - (unless (and (>= (point) (window-start)) - (<= (point) (window-end (ivy-state-window ivy-last) t))) - (recenter)) - (setq swiper--current-window-start (window-start)))) - (swiper--add-overlays - re - (max (window-start) swiper--point-min) - (min (window-end (selected-window) t) swiper--point-max)))))))) - -(defun swiper--add-overlays (re &optional beg end wnd) - "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))) - (let ((ov (if visual-line-mode - (make-overlay - (save-excursion - (beginning-of-visual-line) - (point)) - (save-excursion - (end-of-visual-line) - (point))) - (make-overlay - (line-beginning-position) - (1+ (line-end-position)))))) - (overlay-put ov 'face 'swiper-line-face) - (overlay-put ov 'window wnd) - (push ov swiper--overlays) - (let* ((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) - (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))))))) - (let ((mb (match-beginning 0)) - (me (match-end 0))) - (unless (> (- me mb) 2017) - (swiper--add-overlay mb me - (if (zerop ivy--subexps) - (cadr swiper-faces) - (car swiper-faces)) - wnd 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)))) - (swiper--add-overlay - bm em - (nth (1+ (mod (+ i 2) (1- (length swiper-faces)))) - swiper-faces) - wnd i) - (cl-incf i)))))))))))) - -(defun swiper--add-overlay (beg end face wnd priority) - "Add overlay bound by BEG and END to `swiper--overlays'. -FACE, WND and PRIORITY are properties corresponding to -the face, window and priority of the overlay." - (let ((overlay (make-overlay beg end))) - (push overlay swiper--overlays) - (overlay-put overlay 'face face) - (overlay-put overlay 'window wnd) - (overlay-put overlay 'priority priority))) - -(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--action (x) - "Goto line X." - (let ((ln (1- (read (or (get-text-property 0 'swiper-line-number x) - (and (string-match ":\\([0-9]+\\):.*\\'" x) - (match-string-no-properties 1 x)))))) - (re (ivy--regex 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 swiper--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) - (cond (swiper-action-recenter - (recenter)) - (swiper--current-window-start - (set-window-start (selected-window) swiper--current-window-start))) - (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 ", "))) - -(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)) - (ivy-read "Swiper: " swiper-multi-candidates - :action #'swiper-multi-action-2 - :unwind #'swiper--cleanup - :caller 'swiper-multi)) - -(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- (read (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." - (if (and (< (length str) 3)) - (list "" (format "%d chars more" (- 3 (length ivy-text)))) - (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))) - (if (stringp re-full) - (setq re re-full) - (setq re (caar 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)))))) - -(defvar swiper-window-width 80) - -(defun swiper--all-format-function (cands) - "Format CANDS for `swiper-all'. -See `ivy-format-function' 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-format-function #'swiper--all-format-function)) - (ivy-read "swiper-all: " 'swiper-all-function - :action #'swiper-all-action - :unwind #'swiper--cleanup - :update-fn (lambda () - (swiper-all-action (ivy-state-current ivy-last))) - :dynamic-collection t - :keymap swiper-all-map - :initial-input initial-input - :caller 'swiper-multi))) - -(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* ((ww (window-width)) - (res nil) - (column-2 (apply #'max - (mapcar - (lambda (b) - (length (buffer-name b))) - buffers))) - (column-1 (- ww 4 column-2 1))) - (dolist (buf buffers) - (with-current-buffer buf - (setq res - (append - (mapcar - (lambda (s) - (setq s (concat (ivy--truncate-string s column-1) " ")) - (let ((len (length s))) - (put-text-property - (1- len) len 'display - (concat - (make-string - (max 0 - (- ww (string-width s) (length (buffer-name)) 3)) - ?\ ) - (buffer-name)) - s) - (put-text-property 0 len 'buffer buf s) - s)) - (swiper--candidates 4)) - res)) - nil)) - res)) - -(provide 'swiper) - -;;; swiper.el ends here diff --git a/packages/swiper-20190801.1110.el b/packages/swiper-20190801.1110.el new file mode 100644 index 0000000..f10f6a5 --- /dev/null +++ b/packages/swiper-20190801.1110.el @@ -0,0 +1,1624 @@ +;;; swiper.el --- Isearch with an overview. Oh, man! -*- lexical-binding: t -*- + +;; Copyright (C) 2015-2018 Free Software Foundation, Inc. + +;; Author: Oleh Krehel +;; URL: https://github.com/abo-abo/swiper +;; Package-Version: 20190801.1110 +;; Version: 0.12.0 +;; Package-Requires: ((emacs "24.1") (ivy "0.12.0")) +;; 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 . + +;;; 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 + (goto-char (window-start)) + (while (re-search-forward re end t) + (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))))))) + +(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 + :update-fn #'swiper--query-replace-updatefn) + 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))))) + +(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 (&optional initial-input) + "`isearch-forward' with an overview. +When non-nil, INITIAL-INPUT is the initial search pattern." + (interactive) + (swiper--ivy (swiper--candidates) initial-input)) + +;;;###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 (&optional revert) + "Generate a custom occur buffer for `swiper'. +When REVERT is non-nil, regenerate the current *ivy-occur* buffer. +When capture groups are present in the input, print them instead of lines." + (let* ((buffer (ivy-state-buffer ivy-last)) + (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 + (if (not revert) + ivy--old-cands + (setq ivy--old-re nil) + (save-window-excursion + (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)) + (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n" + default-directory)) + (insert (format "%d candidates:\n" (length cands))) + (ivy--occur-insert-lines + (mapcar + (lambda (cand) (concat "./" cand)) + cands)) + (goto-char (point-min)) + (forward-line 4)))) + +(ivy-set-occur 'swiper 'swiper-occur) + +(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))) + (if (zerop ivy--subexps) + (prog1 (format "^ ?\\(%s\\)" re) + (setq ivy--subexps 1)) + (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) + +(defun swiper--ivy (candidates &optional initial-input) + "Select one of CANDIDATES and move there. +When non-nil, INITIAL-INPUT is the initial search pattern." + (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 + :update-fn #'swiper--update-input-ivy + :unwind #'swiper--cleanup + :action #'swiper--action + :re-builder #'swiper--re-builder + :history 'swiper-history + :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))))) + +(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)) + (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))) + (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 + :unwind #'swiper--cleanup + :caller 'swiper-multi))) + +(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 + :unwind #'swiper--cleanup + :update-fn 'auto + :dynamic-collection t + :keymap swiper-all-map + :initial-input initial-input + :caller 'swiper-multi))) + +(add-to-list 'ivy-format-functions-alist '(swiper-multi . 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) + (let (cands) + (save-excursion + (goto-char (if backward (point-max) (point-min))) + (while (funcall (if backward #'re-search-backward #'re-search-forward) re nil t) + (when (swiper-match-usable-p) + (let ((pos (if (or backward swiper-goto-start-of-match) + (match-beginning 0) + (point)))) + (push pos cands))))) + (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-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)) + (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 + :update-fn 'auto + :unwind #'swiper--cleanup + :re-builder #'swiper--re-builder + :history 'swiper-history + :caller 'swiper-isearch)) + (point)) + (unless (or res swiper-stay-on-quit) + (goto-char swiper--opoint)) + (isearch-clean-overlays) + (unless (or res (string= ivy-text "")) + (cl-pushnew ivy-text swiper-history))))) + +;;;###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))) + +(add-to-list 'ivy-format-functions-alist '(swiper-isearch . swiper-isearch-format-function)) +(ivy-set-occur 'swiper-isearch 'swiper-occur) + +(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 diff --git a/packages/symbol-overlay-20190608.442.el b/packages/symbol-overlay-20190608.442.el new file mode 100644 index 0000000..91d9cf1 --- /dev/null +++ b/packages/symbol-overlay-20190608.442.el @@ -0,0 +1,763 @@ +;;; symbol-overlay.el --- Highlight symbols with keymap-enabled overlays + +;; Copyright (C) 2017 wolray + +;; Author: wolray +;; Version: 4.1 +;; Package-Version: 20190608.442 +;; URL: https://github.com/wolray/symbol-overlay/ +;; Keywords: faces, matching +;; Package-Requires: ((emacs "24.3")) + +;; 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 . + +;;; Commentary: + +;; Highlighting symbols with overlays while providing a keymap for various +;; operations about highlighted symbols. It was originally inspired by the +;; package `highlight-symbol'. The fundamental difference is that in +;; `symbol-overlay' every symbol is highlighted by the Emacs built-in function +;; `overlay-put' rather than the `font-lock' mechanism used in +;; `highlight-symbol'. + +;; Advantages + +;; When highlighting symbols in a buffer of regular size and language, +;; `overlay-put' behaves as fast as the traditional highlighting method +;; `font-lock'. However, for a buffer of major-mode with complicated keywords +;; syntax, like haskell-mode, `font-lock' is quite slow even the buffer is less +;; than 100 lines. Besides, when counting the number of highlighted +;; occurrences, `highlight-symbol' will call the function `how-many' twice, +;; which could also result in an unpleasant delay in a large buffer. Those +;; problems don't exist in `symbol-overlay'. + +;; When putting overlays on symbols, an auto-activated overlay-inside keymap +;; will enable you to call various useful commands with a single keystroke. + +;; Toggle all overlays of symbol at point: `symbol-overlay-put' +;; Jump between locations of symbol at point: `symbol-overlay-jump-next' & +;; `symbol-overlay-jump-prev' +;; Switch to the closest symbol highlighted nearby: +;; `symbol-overlay-switch-forward' & `symbol-overlay-switch-backward' +;; Minor mode for auto-highlighting symbol at point: `symbol-overlay-mode' +;; Remove all highlighted symbols in the buffer: `symbol-overlay-remove-all' +;; Copy symbol at point: `symbol-overlay-save-symbol' +;; Toggle overlays to be showed in buffer or only in scope: +;; `symbol-overlay-toggle-in-scope' +;; Jump back to the position before a recent jump: `symbol-overlay-echo-mark' +;; Jump to the definition of symbol at point: `symbol-overlay-jump-to-definition' +;; Isearch symbol at point literally: +;; `symbol-overlay-isearch-literally' +;; Query replace symbol at point: `symbol-overlay-query-replace' +;; Rename symbol at point on all its occurrences: `symbol-overlay-rename' + +;; Usage + +;; To use `symbol-overlay' in your Emacs, you need only to bind these keys: +;; (require 'symbol-overlay) +;; (global-set-key (kbd "M-i") 'symbol-overlay-put) +;; (global-set-key (kbd "M-n") 'symbol-overlay-switch-forward) +;; (global-set-key (kbd "M-p") 'symbol-overlay-switch-backward) +;; (global-set-key (kbd "") 'symbol-overlay-mode) +;; (global-set-key (kbd "") 'symbol-overlay-remove-all) + +;; Default key-bindings are defined in `symbol-overlay-map'. +;; You can re-bind the commands to any keys you prefer by simply writing +;; (define-key symbol-overlay-map (kbd "your-prefer-key") 'any-command) + +;;; Code: + +(require 'cl-lib) +(require 'thingatpt) +(require 'seq) + +(defgroup symbol-overlay nil + "Highlight symbols with keymap-enabled overlays." + :group 'convenience) + +;;; Faces + +(defface symbol-overlay-default-face + '((t (:inherit highlight))) + "Symbol Overlay default face" + :group 'symbol-overlay) + +(defface symbol-overlay-face-1 + '((t (:background "dodger blue" :foreground "black"))) + "Symbol Overlay default candidate 1" + :group 'symbol-overlay) + +(defface symbol-overlay-face-2 + '((t (:background "hot pink" :foreground "black"))) + "Symbol Overlay default candidate 2" + :group 'symbol-overlay) + +(defface symbol-overlay-face-3 + '((t (:background "yellow" :foreground "black"))) + "Symbol Overlay default candidate 3" + :group 'symbol-overlay) + +(defface symbol-overlay-face-4 + '((t (:background "orchid" :foreground "black"))) + "Symbol Overlay default candidate 4" + :group 'symbol-overlay) + +(defface symbol-overlay-face-5 + '((t (:background "red" :foreground "black"))) + "Symbol Overlay default candidate 5" + :group 'symbol-overlay) + +(defface symbol-overlay-face-6 + '((t (:background "salmon" :foreground "black"))) + "Symbol Overlay default candidate 6" + :group 'symbol-overlay) + +(defface symbol-overlay-face-7 + '((t (:background "spring green" :foreground "black"))) + "Symbol Overlay default candidate 7" + :group 'symbol-overlay) + +(defface symbol-overlay-face-8 + '((t (:background "turquoise" :foreground "black"))) + "Symbol Overlay default candidate 8" + :group 'symbol-overlay) + +;;; Options + +(defcustom symbol-overlay-faces '(symbol-overlay-face-1 + symbol-overlay-face-2 + symbol-overlay-face-3 + symbol-overlay-face-4 + symbol-overlay-face-5 + symbol-overlay-face-6 + symbol-overlay-face-7 + symbol-overlay-face-8) + "Faces used for overlays." + :type '(repeat face) + :group 'symbol-overlay) + +(defcustom symbol-overlay-displayed-window t + "See `symbol-overlay-maybe-put-temp'." + :group 'symbol-overlay + :type 'boolean) + +(defcustom symbol-overlay-idle-time 0.5 + "Idle time after every command and before the temporary highlighting." + :group 'symbol-overlay + :type 'float) + +(defcustom symbol-overlay-ignore-functions + '((c-mode . symbol-overlay-ignore-function-c) + (c++-mode . symbol-overlay-ignore-function-c++) + (python-mode . symbol-overlay-ignore-function-python) + (go-mode . symbol-overlay-ignore-function-go)) + "Functions to determine whether a symbol should be ignored. + +This is an association list that maps a MAJOR-MODE symbol to a +function that determines whether a symbol should be ignored. +For instance, such a function could use a major mode's font-lock +definitions to prevent a language's keywords from getting highlighted." + :group 'symbol-overlay + :type '(repeat (cons (function :tag "Mode") function))) + +;;; Internal + +(defvar symbol-overlay-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "i") 'symbol-overlay-put) + (define-key map (kbd "h") 'symbol-overlay-map-help) + (define-key map (kbd "p") 'symbol-overlay-jump-prev) + (define-key map (kbd "n") 'symbol-overlay-jump-next) + (define-key map (kbd "<") 'symbol-overlay-jump-first) + (define-key map (kbd ">") 'symbol-overlay-jump-last) + (define-key map (kbd "w") 'symbol-overlay-save-symbol) + (define-key map (kbd "t") 'symbol-overlay-toggle-in-scope) + (define-key map (kbd "e") 'symbol-overlay-echo-mark) + (define-key map (kbd "d") 'symbol-overlay-jump-to-definition) + (define-key map (kbd "s") 'symbol-overlay-isearch-literally) + (define-key map (kbd "q") 'symbol-overlay-query-replace) + (define-key map (kbd "r") 'symbol-overlay-rename) + map) + "Keymap automatically activated inside overlays. +You can re-bind the commands to any keys you prefer.") + +(defvar-local symbol-overlay-keywords-alist nil) +(put 'symbol-overlay-keywords-alist 'permanent-local t) + +(defun symbol-overlay-map-help () + "Display the bindings in `symbol-overlay-map'." + (interactive) + (let ((buf (get-buffer-create "*Help*"))) + (with-help-window "*Help*" + (with-current-buffer buf + (insert (substitute-command-keys "\\{symbol-overlay-map}")))))) + +;;;###autoload +(define-minor-mode symbol-overlay-mode + "Minor mode for auto-highlighting symbol at point." + nil " SO" (make-sparse-keymap) + (if symbol-overlay-mode + (progn + (add-hook 'post-command-hook 'symbol-overlay-post-command nil t) + (symbol-overlay-update-timer symbol-overlay-idle-time)) + (remove-hook 'post-command-hook 'symbol-overlay-post-command t) + (symbol-overlay-remove-temp))) + +(defun symbol-overlay-get-list (dir &optional symbol exclude) + "Get all highlighted overlays in the buffer. +If SYMBOL is non-nil, get the overlays that belong to it. +DIR is an integer. +If EXCLUDE is non-nil, get all overlays excluding those belong to SYMBOL." + (let ((lists (progn (overlay-recenter (point)) (overlay-lists))) + (func (if (> dir 0) 'cdr (if (< dir 0) 'car nil)))) + (seq-filter + '(lambda (ov) + (let ((value (overlay-get ov 'symbol))) + (and value + (or (not symbol) + (if (string= value symbol) (not exclude) + (and exclude (not (string= value "")))))))) + (if func (funcall func lists) + (append (car lists) (cdr lists)))))) + +(defun symbol-overlay-get-symbol (&optional noerror) + "Get the symbol at point. +If NOERROR is non-nil, just return nil when no symbol is found." + (or (thing-at-point 'symbol) + (unless noerror (user-error "No symbol at point")))) + +(defun symbol-overlay-regexp (symbol) + "Return a regexp to match SYMBOL." + (concat "\\_<" (regexp-quote symbol) "\\_>")) + +(defun symbol-overlay-assoc (symbol) + "Get SYMBOL's associated list in `symbol-overlay-keywords-alist'." + (assoc symbol symbol-overlay-keywords-alist)) + +(defun symbol-overlay-maybe-remove (keyword) + "Delete the KEYWORD list and all its overlays." + (when keyword + (mapc 'delete-overlay (symbol-overlay-get-list 0 (car keyword))) + (setq symbol-overlay-keywords-alist + (delq keyword symbol-overlay-keywords-alist)) + (cddr keyword))) + +(defvar-local symbol-overlay-temp-symbol nil + "Symbol for temporary highlighting.") + +(defvar-local symbol-overlay-scope nil + "If non-nil, force to narrow to scope before temporary highlighting.") + +(defun symbol-overlay-narrow (scope &optional window) + "Narrow to a specific region. +Region might be current scope or displayed window, +depending on SCOPE and WINDOW." + (if scope + (let ((pt (point)) + min max p) + (save-excursion + (save-restriction + (narrow-to-defun) + (setq min (point-min) + max (point-max) + p (or (/= pt (point)) (= pt (point-max)))))) + (save-excursion + (and p (setq min (progn (backward-paragraph) (point)) + max (progn (forward-paragraph) (point)))) + (narrow-to-region min max))) + (when window + (narrow-to-region (window-start) (window-end))))) + +(defun symbol-overlay-remove-temp () + "Delete all temporary overlays." + (mapc 'delete-overlay (symbol-overlay-get-list 0 "")) + (setq symbol-overlay-temp-symbol nil)) + +(defun symbol-overlay-maybe-put-temp () + "Highlight symbol at point when there are more than 2 occurrences. +This only effects symbols in the current displayed window if +`symbol-overlay-displayed-window' is non-nil." + (when symbol-overlay-mode + (let* ((case-fold-search nil) + (symbol (symbol-overlay-get-symbol t)) + p) + (when (and symbol + (not (symbol-overlay-assoc symbol)) + (not (symbol-overlay-ignored-p symbol))) + (symbol-overlay-remove-temp) + (save-excursion + (save-restriction + (symbol-overlay-narrow symbol-overlay-scope + symbol-overlay-displayed-window) + (goto-char (point-min)) + (let ((re (symbol-overlay-regexp symbol))) + (re-search-forward re nil t) + (save-match-data + (while (re-search-forward re nil t) + (symbol-overlay-put-one symbol) + (or p (setq p t)))) + (when p + (symbol-overlay-put-one symbol) + (setq symbol-overlay-temp-symbol symbol))))))))) + +(defun symbol-overlay-ignored-p (symbol) + "Determine whether SYMBOL should be temporarily highlighted." + (let ((f (cdr (assoc major-mode symbol-overlay-ignore-functions)))) + (when f + (funcall f symbol)))) + +(defvar symbol-overlay-timer nil + "Timer for temporary highlighting.") + +(defun symbol-overlay-update-timer (value) + "Update `symbol-overlay-timer' with new idle-time VALUE." + (and symbol-overlay-timer (cancel-timer symbol-overlay-timer)) + (setq symbol-overlay-timer + (and value (> value 0) + (run-with-idle-timer value t 'symbol-overlay-maybe-put-temp)))) + +(defun symbol-overlay-post-command () + "Installed on `post-command-hook'." + (unless (string= (symbol-overlay-get-symbol t) symbol-overlay-temp-symbol) + (symbol-overlay-remove-temp))) + +(defun symbol-overlay-put-one (symbol &optional face) + "Put overlay on current occurrence of SYMBOL after a match. +If FACE is non-nil, use it as the overlay’s face. +Otherwise apply `symbol-overlay-default-face'." + (let ((ov (make-overlay (match-beginning 0) (match-end 0)))) + (if face (progn (overlay-put ov 'face face) + (overlay-put ov 'keymap symbol-overlay-map) + (overlay-put ov 'evaporate t) + (overlay-put ov 'symbol symbol)) + (overlay-put ov 'face 'symbol-overlay-default-face) + (overlay-put ov 'symbol "")))) + +(defun symbol-overlay-put-all (symbol scope &optional keyword) + "Put overlays on all occurrences of SYMBOL in the buffer. +The face is randomly picked from `symbol-overlay-faces'. +If SCOPE is non-nil, put overlays only on occurrences in scope. +If KEYWORD is non-nil, remove it then use its color on new overlays." + (let* ((case-fold-search nil) + (limit (length symbol-overlay-faces)) + (face (or (symbol-overlay-maybe-remove keyword) + (elt symbol-overlay-faces (random limit)))) + (alist symbol-overlay-keywords-alist) + (faces (mapcar 'cddr alist)) + (pt (point))) + (if (< (length alist) limit) + (while (seq-position faces face) + (setq face (elt symbol-overlay-faces (random limit)))) + (setq face (symbol-overlay-maybe-remove (car (last alist))))) + (and symbol-overlay-temp-symbol (symbol-overlay-remove-temp)) + (save-excursion + (save-restriction + (symbol-overlay-narrow scope) + (goto-char (point-min)) + (let ((re (symbol-overlay-regexp symbol))) + (while (re-search-forward re nil t) + (symbol-overlay-put-one symbol face))))) + (setq keyword `(,symbol ,scope . ,face)) + (push keyword symbol-overlay-keywords-alist) + keyword)) + +(defun symbol-overlay-maybe-count (keyword &optional show-color) + "Show the number of KEYWORD's occurrences. +If SHOW-COLOR is non-nil, display the color used by current overlay." + (when keyword + (let* ((symbol (car keyword)) + (before (symbol-overlay-get-list -1 symbol)) + (after (symbol-overlay-get-list 1 symbol)) + (count (length before)) + ;; Log to echo area but not *Messages* + message-log-max) + (message (concat symbol + ": %d/%d" + (and (cadr keyword) " in scope") + (and show-color (format " (%s)" (cddr keyword)))) + (+ count 1) + (+ count (length after)))))) + +(defun symbol-overlay-match-keyword-list (symbol keywords) + "Return non-nil is SYMBOL is among KEYWORDS. +KEYWORDS is a list of strings. SYMBOL is expected to be a return +value of `symbol-overlay-get-symbol'." + (cl-find symbol keywords :test #'string=)) + +(defun symbol-overlay-refresh (beg end len) + "Refresh overlays. Installed on `after-change-functions'. +BEG, END and LEN are the beginning, end and length of changed text." + (unless (or (minibufferp) + (not (or symbol-overlay-keywords-alist + symbol-overlay-temp-symbol))) + (let ((case-fold-search nil) + (re "\\(\\sw\\|\\s_\\)+")) + (save-excursion + (save-match-data + (goto-char end) + (and (looking-at-p re) + (setq end (re-search-forward "\\_>"))) + (goto-char beg) + (and (not (looking-at-p "\\_<")) + (looking-at-p (concat "\\(" re "\\|\\_>\\)")) + (setq beg (re-search-backward "\\_<"))) + (mapc #'(lambda (ov) + (and (overlay-get ov 'symbol) + (delete-overlay ov))) + (overlays-in beg end)) + (mapc #'(lambda (keyword) + (let* ((symbol (car keyword)) + (re (symbol-overlay-regexp symbol))) + (goto-char beg) + (while (re-search-forward re end t) + (symbol-overlay-put-one symbol (cddr keyword))))) + symbol-overlay-keywords-alist)))))) + +(add-hook 'after-change-functions 'symbol-overlay-refresh) + +(defun symbol-overlay-after-revert () + "Restore overlays after the buffer was reverted." + (save-restriction + (widen) + (symbol-overlay-refresh (point-min) (point-max) nil))) + +(add-hook 'after-revert-hook 'symbol-overlay-after-revert) + +;;; Language-Specific Ignore + +(defvar c-font-lock-extra-types) +(defun symbol-overlay-ignore-function-c (symbol) + "Determine whether SYMBOL should be ignored (C Language)." + (symbol-overlay-match-keyword-list + symbol + (append c-font-lock-extra-types + '("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")))) + +(defvar c++-font-lock-extra-types) +(defun symbol-overlay-ignore-function-c++ (symbol) + "Determine whether SYMBOL should be ignored (C++)." + (symbol-overlay-match-keyword-list + symbol + (append c++-font-lock-extra-types + '("alignas" "alignof" "asm" "auto" "bool" "break" + "case" "catch" "char" "char16_t" "char32_t" "class" + "const" "const_cast" "constexpr" "continue" + "decltype" "default" "delete" "do" "double" + "dynamic_cast" "else" "enum" "explicit" "export" + "extern" "false" "final" "float" "for" "friend" + "goto" "if" "inline" "int" "long" "mutable" + "namespace" "new" "noexcept" "nullptr" "operator" + "override" "private" "protected" "public" "register" + "reinterpret_cast" "return" "short" "signed" + "sizeof" "static" "static_assert" "static_cast" + "struct" "switch" "template" "this" "thread_local" + "throw" "true" "try" "typedef" "typeid" "typename" + "union" "unsigned" "using" "virtual" "void" + "volatile" "wchar_t" "while")))) + +(defvar python-font-lock-keywords) +(defun symbol-overlay-ignore-function-python (symbol) + "Determine whether SYMBOL should be ignored (Python)." + (let* ((keyword-symbol (car python-font-lock-keywords)) + (keyword (if (stringp keyword-symbol) + keyword-symbol + (symbol-name keyword-symbol)))) + (string-match-p keyword symbol))) + +(defvar go-builtins) +(defvar go-constants) +(defvar go-mode-keywords) +(defun symbol-overlay-ignore-function-go (symbol) + "Determine whether SYMBOL should be ignored (Go)." + ;; Remove \_< and \_> so we can string compare with keywords + (or (symbol-overlay-match-keyword-list symbol go-builtins) + (symbol-overlay-match-keyword-list symbol go-constants) + (symbol-overlay-match-keyword-list symbol go-mode-keywords))) + +;;; Commands + +;;;###autoload +(defun symbol-overlay-put () + "Toggle all overlays of symbol at point." + (interactive) + (unless (minibufferp) + (let* ((symbol (symbol-overlay-get-symbol)) + (keyword (symbol-overlay-assoc symbol))) + (symbol-overlay-adjust-position) + (if keyword + (if (symbol-overlay-maybe-reput symbol keyword) + (symbol-overlay-maybe-count keyword) + (symbol-overlay-maybe-remove keyword) + (symbol-overlay-maybe-put-temp)) + (symbol-overlay-maybe-count + (symbol-overlay-put-all symbol symbol-overlay-scope) + t))))) + +(defun symbol-overlay-adjust-position () + "Backward one char if at the end of the symbol." + (when (looking-at-p "\\_>") (backward-char))) + +;;;###autoload +(defun symbol-overlay-count () + "Show count of symbol at point." + (interactive) + (unless (minibufferp) + (let* ((symbol (symbol-overlay-get-symbol)) + (keyword (symbol-overlay-assoc symbol))) + (symbol-overlay-adjust-position) + (symbol-overlay-maybe-count keyword)))) + +;;;###autoload +(defun symbol-overlay-remove-all () + "Remove all highlighted symbols in the buffer. +When called interactively, then also reset +`symbol-overlay-keywords-alist'." + (interactive) + (unless (minibufferp) + (mapc 'delete-overlay (symbol-overlay-get-list 0)) + (when (called-interactively-p 'any) + (setq symbol-overlay-keywords-alist nil)))) + +(add-hook 'before-revert-hook 'symbol-overlay-remove-all) + +;;;###autoload +(defun symbol-overlay-save-symbol () + "Copy symbol at point." + (interactive) + (unless (minibufferp) + (let ((bounds (bounds-of-thing-at-point 'symbol))) + (kill-ring-save (car bounds) (cdr bounds)) + (message "Current symbol saved")))) + +;;;###autoload +(defun symbol-overlay-toggle-in-scope () + "Toggle overlays to be showed in buffer or only in scope." + (interactive) + (unless (minibufferp) + (let* ((symbol (symbol-overlay-get-symbol)) + (keyword (symbol-overlay-assoc symbol))) + (if keyword + (let ((scope (not (cadr keyword)))) + (symbol-overlay-maybe-count + (symbol-overlay-put-all symbol scope keyword)) + (setq symbol-overlay-scope scope)) + (setq symbol-overlay-scope (not symbol-overlay-scope)))))) + +(defun symbol-overlay-maybe-reput (symbol keyword) + "Put overlays on SYMBOL that is not highlighted in scope. +KEYWORD provides the scope information." + (when (and (cadr keyword) + (not (seq-find #'(lambda (ov) + (string= (overlay-get ov 'symbol) symbol)) + (overlays-at + (car (bounds-of-thing-at-point 'symbol)))))) + (symbol-overlay-put-all symbol t keyword))) + +;;;###autoload +(defun symbol-overlay-echo-mark () + "Jump back to the mark." + (interactive) + (let* ((pt (mark)) + (symbol (symbol-overlay-get-symbol)) + (keyword (symbol-overlay-assoc symbol))) + (and pt (goto-char pt)) + (symbol-overlay-maybe-reput symbol keyword))) + +(defun symbol-overlay-jump-call (jump-function dir) + "A general jumping process during which JUMP-FUNCTION is called to jump. +DIR must be non-zero." + (unless (minibufferp) + (let* ((symbol (symbol-overlay-get-symbol)) + (keyword (symbol-overlay-assoc symbol))) + (push-mark nil t) + (funcall jump-function symbol dir) + (when keyword + (symbol-overlay-maybe-reput symbol keyword) + (symbol-overlay-maybe-count keyword))))) + +(defun symbol-overlay-basic-jump (symbol dir) + "Jump to SYMBOL's next location in the direction DIR. +DIR must be non-zero." + (let* ((case-fold-search nil) + (bounds (bounds-of-thing-at-point 'symbol)) + (offset (- (point) (if (> dir 0) (cdr bounds) (car bounds)))) + target + (re (symbol-overlay-regexp symbol))) + (goto-char (- (point) offset)) + (setq target (re-search-forward re nil t dir)) + (unless target + (goto-char (if (> dir 0) (point-min) (point-max))) + (setq target (re-search-forward re nil nil dir))) + (goto-char (+ target offset)))) + +;;;###autoload +(defun symbol-overlay-jump-next () + "Jump to the next location of symbol at point." + (interactive) + (symbol-overlay-adjust-position) + (symbol-overlay-jump-call 'symbol-overlay-basic-jump 1)) + +;;;###autoload +(defun symbol-overlay-jump-prev () + "Jump to the previous location of symbol at point." + (interactive) + (symbol-overlay-adjust-position) + (symbol-overlay-jump-call 'symbol-overlay-basic-jump -1)) + +;;;###autoload +(defun symbol-overlay-jump-first () + "Jump to the first location." + (interactive) + (symbol-overlay-adjust-position) + (let* ((symbol (symbol-overlay-get-symbol)) + (before (symbol-overlay-get-list -1 symbol)) + (count (length before))) + (symbol-overlay-jump-call 'symbol-overlay-basic-jump (- count)))) + +;;;###autoload +(defun symbol-overlay-jump-last () + "Jump to the last location." + (interactive) + (symbol-overlay-adjust-position) + (let* ((symbol (symbol-overlay-get-symbol)) + (after (symbol-overlay-get-list 1 symbol)) + (count (length after))) + (symbol-overlay-jump-call 'symbol-overlay-basic-jump (- count 1)))) + +(defvar-local symbol-overlay-definition-function + '(lambda (symbol) (concat "(?def[a-z-]* " (symbol-overlay-regexp symbol))) + "An one-argument function that returns a regexp.") + +;;;###autoload +(defun symbol-overlay-jump-to-definition () + "Jump to the definition of symbol at point. +The definition syntax should be defined in a function stored in +`symbol-overlay-definition-function' that returns the definition's regexp +with the input symbol." + (interactive) + (symbol-overlay-jump-call + '(lambda (symbol dir) + (let ((pt (point)) p) + (symbol-overlay-basic-jump symbol dir) + (while (not (or p (save-excursion + (beginning-of-line) + (skip-chars-forward " \t") + (looking-at-p + (funcall symbol-overlay-definition-function + symbol))))) + (symbol-overlay-basic-jump symbol dir) + (and (= pt (point)) (setq p t))))) + 1)) + +(defun symbol-overlay-switch-symbol (dir) + "Switch to the closest symbol highlighted nearby, in the direction DIR. +DIR must be 1 or -1." + (unless (minibufferp) + (let* ((symbol (symbol-overlay-get-symbol t)) + (list (symbol-overlay-get-list dir symbol t))) + (or list + (user-error (concat "No more " + (if (> dir 0) "forward" "backward") + " symbols"))) + (push-mark nil t) + (goto-char (overlay-start (car list))) + (symbol-overlay-maybe-count + (symbol-overlay-assoc (symbol-overlay-get-symbol)))))) + +;;;###autoload +(defun symbol-overlay-switch-forward () + "Switch forward to another symbol." + (interactive) + (symbol-overlay-switch-symbol 1)) + +;;;###autoload +(defun symbol-overlay-switch-backward () + "Switch backward to another symbol." + (interactive) + (symbol-overlay-switch-symbol -1)) + +;;;###autoload +(defun symbol-overlay-isearch-literally () + "Isearch symbol at point literally." + (interactive) + (unless (minibufferp) + (let ((symbol (symbol-overlay-get-symbol))) + (beginning-of-thing 'symbol) + (isearch-forward nil t) + (isearch-yank-string symbol)))) + +;;;###autoload +(defun symbol-overlay-query-replace () + "Query replace symbol at point." + (interactive) + (unless (minibufferp) + (let* ((case-fold-search nil) + (symbol (symbol-overlay-get-symbol)) + (keyword (symbol-overlay-assoc symbol)) + (scope (cadr keyword)) + defaults new) + (and scope (user-error "Query-replace invalid in scope")) + (beginning-of-thing 'symbol) + (push-mark nil t) + (setq new (read-string "Replacement: " symbol) + defaults (cons symbol new)) + (unless (string= new symbol) + (symbol-overlay-maybe-remove (symbol-overlay-assoc new)) + (setq keyword (symbol-overlay-put-all new scope keyword)) + (query-replace-regexp (symbol-overlay-regexp symbol) new) + (setq query-replace-defaults + (if (< emacs-major-version 25) `,defaults `(,defaults)))) + (when (string= new (symbol-overlay-get-symbol t)) + (beginning-of-thing 'symbol) + (symbol-overlay-maybe-count keyword))))) + +;;;###autoload +(defun symbol-overlay-rename () + "Rename symbol at point on all its occurrences." + (interactive) + (unless (minibufferp) + (let* ((case-fold-search nil) + (symbol (symbol-overlay-get-symbol)) + (keyword (symbol-overlay-assoc symbol)) + (scope (if keyword (cadr keyword) symbol-overlay-scope)) + new) + (beginning-of-thing 'symbol) + (push-mark nil t) + (setq new (read-string (concat "Rename" (and scope " in scope") ": ") + symbol)) + (unless (string= new symbol) + (symbol-overlay-maybe-remove (symbol-overlay-assoc new)) + (save-excursion + (save-restriction + (symbol-overlay-narrow scope) + (goto-char (point-min)) + (let ((inhibit-modification-hooks t) + (re (symbol-overlay-regexp symbol))) + (while (re-search-forward re nil t) (replace-match new t))))) + (when keyword + (setq keyword (symbol-overlay-put-all new scope keyword)))) + (when (string= new (symbol-overlay-get-symbol t)) + (symbol-overlay-maybe-count keyword))))) + +;;; _ +(provide 'symbol-overlay) +;; Local Variables: +;; indent-tabs-mode: nil +;; End: +;;; symbol-overlay.el ends here diff --git a/packages/systemd-20180629.2106.tar b/packages/systemd-20180629.2106.tar index 373357b..1df94c2 100644 Binary files a/packages/systemd-20180629.2106.tar and b/packages/systemd-20180629.2106.tar differ diff --git a/packages/tablist-20170220.335.tar b/packages/tablist-20190414.643.tar similarity index 98% rename from packages/tablist-20170220.335.tar rename to packages/tablist-20190414.643.tar index b22779d..4cd5634 100644 Binary files a/packages/tablist-20170220.335.tar and b/packages/tablist-20190414.643.tar differ diff --git a/packages/tao-theme-20181020.1726.tar b/packages/tao-theme-20190204.1104.tar similarity index 97% rename from packages/tao-theme-20181020.1726.tar rename to packages/tao-theme-20190204.1104.tar index 784fd36..ef10b91 100644 Binary files a/packages/tao-theme-20181020.1726.tar and b/packages/tao-theme-20190204.1104.tar differ diff --git a/packages/tide-20181025.1201.tar b/packages/tide-20190706.2322.tar similarity index 81% rename from packages/tide-20181025.1201.tar rename to packages/tide-20190706.2322.tar index 1bdbdf3..d3f5bf7 100644 Binary files a/packages/tide-20181025.1201.tar and b/packages/tide-20190706.2322.tar differ diff --git a/packages/toc-org-20181108.1621.el b/packages/toc-org-20190603.803.el similarity index 98% rename from packages/toc-org-20181108.1621.el rename to packages/toc-org-20190603.803.el index 8fee054..1c0a43c 100644 --- a/packages/toc-org-20181108.1621.el +++ b/packages/toc-org-20190603.803.el @@ -4,7 +4,7 @@ ;; Author: Sergei Nosov ;; Version: 1.0 -;; Package-Version: 20181108.1621 +;; Package-Version: 20190603.803 ;; Keywords: org-mode org-toc toc-org org toc table of contents ;; URL: https://github.com/snosov1/toc-org @@ -128,7 +128,10 @@ auxiliary text." (setq custom-keywords (append custom-keywords (split-string (match-string 2) "[ \f\t\n\r\v|]+" t)))) (if custom-keywords (setq toc-org-states-regexp - (concat "^*+\s+\\(" (mapconcat 'identity custom-keywords "\s+\\|") "\s+\\)")) + (concat "^*+\s+\\(" + (mapconcat (lambda (x) (replace-regexp-in-string "(.+?)" "" x)) + custom-keywords "\s+\\|") + "\s+\\)")) (setq toc-org-states-regexp "^*+\s+\\(TODO\s+\\|DONE\s+\\)")) ;; keep only lines starting with *s diff --git a/packages/transient-20190812.1336.tar b/packages/transient-20190812.1336.tar new file mode 100644 index 0000000..a1c3cda Binary files /dev/null and b/packages/transient-20190812.1336.tar differ diff --git a/packages/transmission-20180728.1717.el b/packages/transmission-20190211.246.el similarity index 99% rename from packages/transmission-20180728.1717.el rename to packages/transmission-20190211.246.el index dfc2bd7..aa1123c 100644 --- a/packages/transmission-20180728.1717.el +++ b/packages/transmission-20190211.246.el @@ -1,10 +1,10 @@ ;;; transmission.el --- Interface to a Transmission session -*- lexical-binding: t -*- -;; Copyright (C) 2014-2018 Mark Oteiza +;; Copyright (C) 2014-2019 Mark Oteiza ;; Author: Mark Oteiza ;; Version: 0.12.1 -;; Package-Version: 20180728.1717 +;; Package-Version: 20190211.246 ;; Package-Requires: ((emacs "24.4") (let-alist "1.0.5")) ;; Keywords: comm, tools @@ -51,7 +51,7 @@ ;; line utility transmission-remote(1), the ncurses interface ;; transmission-remote-cli(1), and the rtorrent(1) client. These can ;; be found respectively at the following: -;; +;; ;; ;; @@ -2024,11 +2024,15 @@ is constructed from TEST, BODY and the `tabulated-list-id' tagged as `<>'." (define-transmission-predicate download>? > (cdr (assq 'rateToClient <>))) (define-transmission-predicate upload>? > (cdr (assq 'rateToPeer <>))) (define-transmission-predicate size>? > (cdr (assq 'length <>))) -(define-transmission-predicate eta>? > (cdr (assq 'eta <>))) (define-transmission-predicate size-when-done>? > (cdr (assq 'sizeWhenDone <>))) (define-transmission-predicate percent-done>? > (cdr (assq 'percentDone <>))) (define-transmission-predicate ratio>? > (cdr (assq 'uploadRatio <>))) +(define-transmission-predicate eta>=? >= + (let-alist <> + (if (>= .eta 0) .eta + (- 1.0 .percentDone)))) + (defvar transmission-peers-mode-map (let ((map (make-sparse-keymap))) (define-key map "i" 'transmission-info) @@ -2302,7 +2306,7 @@ Transmission." :group 'transmission (setq-local line-move-visual nil) (setq tabulated-list-format - [("ETA" 4 transmission-eta>? :right-align t) + [("ETA" 4 transmission-eta>=? :right-align t) ("Size" 9 transmission-size-when-done>? :right-align t :transmission-size t) ("Have" 4 transmission-percent-done>? :right-align t) diff --git a/packages/tree-mode-20151104.1331.el b/packages/tree-mode-20151104.1331.el new file mode 100644 index 0000000..0341b84 --- /dev/null +++ b/packages/tree-mode-20151104.1331.el @@ -0,0 +1,528 @@ +;;; tree-mode.el --- A mode to manage tree widgets +;; Copyright 2007 Ye Wenbin +;; +;; Author: wenbinye@163.com +;; Package-Version: 20151104.1331 +;; Package-X-Original-Version: 1.1.1.1 +;; Version: $Id: tree-mode.el,v 1.1.1.1 2007-03-13 13:16:10 ywb Exp $ +;; Keywords: help, convenience, widget +;; +;; This file is part of PDE (Perl Development Environment). +;; But it is useful for generic programming. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, 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, write to the Free Software +;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +;;; Dependencies: +;; no extra libraries is required + +;;; Installation: +;; Put this file into your load-path and the following into your ~/.emacs: +;; (require 'tree-mode) + +;;; Code: + +(require 'tree-widget) +(eval-when-compile + (require 'cl)) + +(defvar tree-mode-version "1.0") + +(defvar tree-mode-list nil) + +(defvar tree-mode-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map widget-keymap) + (define-key map " " 'scroll-up) + (define-key map "\C-?" 'scroll-down) + (define-key map "D" 'tree-mode-delete-tree) + (define-key map "p" 'tree-mode-previous-node) + (define-key map "n" 'tree-mode-next-node) + (define-key map "j" 'tree-mode-next-sib) + (define-key map "k" 'tree-mode-previous-sib) + (define-key map "u" 'tree-mode-goto-parent) + (define-key map "r" 'tree-mode-goto-root) + (define-key map "g" 'tree-mode-reflesh) + (define-key map "E" 'tree-mode-expand-level) + (define-key map "e" 'tree-mode-toggle-expand) + (define-key map "s" 'tree-mode-sort-by-tag) + (define-key map "/" 'tree-mode-keep-match) + (define-key map "!" 'tree-mode-collapse-other-except) + ;; (define-key map "\C-s" 'tree-mode-isearch-forward) + ;; (define-key map "\C-r" 'tree-mode-isearch-backward) + (dotimes (i 10) + (define-key map `[,(+ ?0 i)] 'digit-argument)) + map)) + +(defvar tree-mode-menu nil) +(unless tree-mode-menu + (easy-menu-define + tree-mode-menu tree-mode-map "Tree menu" + '("Tree" + ["Next tree node" tree-mode-next-node t] + ["Previous tree node" tree-mode-previous-node t] + ["Next sibling node" tree-mode-next-sib t] + ["Previous sibling node" tree-mode-previous-sib t] + ["Goto parent node" tree-mode-goto-parent t] + ["Goto root node" tree-mode-goto-root t] + "--" + ["Toggle Expand" tree-mode-toggle-expand t] + ["Expand to level 1" (lambda () (interactive) + (tree-mode-expand-level 1)) t] + ["Expand to level 2" (lambda () (interactive) + (tree-mode-expand-level 2)) t] + "--" + ["Collapse other tree" tree-mode-collapse-other-except t] + ["Sort by tag" tree-mode-sort-by-tag t] + ["Keep match" tree-mode-keep-match t]))) + +(defvar tree-mode-insert-tree-hook nil + "Hooks run after insert a tree into buffer. Each function is +passed the new tree created") + +(defvar tree-mode-delete-tree-hook nil + "Hooks run after delete a tree in the buffer. Each function is +passed the new tree created") + +(defun tree-mode-nearest-widget () + "Return widget at point or next nearest widget." + (or (widget-at) + (ignore-errors + (let ((pos (point))) + (widget-forward 1) + (and (< pos (point)) + (widget-at)))))) + +(defun tree-mode-scan-tree () + "Find all tree widget in current buffer." + (save-excursion + (goto-char (point-min)) + (setq tree-mode-list nil) + (let ((widget (tree-mode-nearest-widget)) + parent) + (while widget + (if (tree-widget-p (setq parent (widget-get widget :parent))) + (push parent tree-mode-list)) + (goto-char (widget-get (or parent widget) :to)) + (setq widget (tree-mode-nearest-widget))) + (setq tree-mode-list (nreverse tree-mode-list))))) + +;;;###autoload +(define-minor-mode tree-minor-mode + "More keybindings for tree-widget. + +\\{tree-mode-map}" + :lighter " Tree" + :keymap tree-mode-map + (when tree-minor-mode + (make-local-variable 'tree-mode-list) + (tree-mode-scan-tree))) + +(define-derived-mode tree-mode nil "Tree" + "A mode to manage many tree widgets" + (make-local-variable 'tree-mode-list) + (make-local-variable 'tree-mode-insert-tree-hook) + (make-local-variable 'tree-mode-delete-tree-hook) + (widget-setup)) + +;; put :button-icon in push-button to setup the node icon +(add-hook 'tree-widget-before-create-icon-functions + 'tree-mode-icon-create) +(defun tree-mode-icon-create (icon) + (let ((img (widget-get (widget-get icon :node) :button-icon))) + (if img (widget-put icon :glyph-name img)))) + +(defun tree-mode-insert (tree &optional before) + "Insert tree to buffer. +If BEFORE is non-nil and is a tree in current buffer, the new +TREE will insert at position of BEFORE." + (if (and before (memq before tree-mode-list)) + (goto-char (widget-get before :from)) + (goto-char (point-max))) + (setq tree (widget-create tree)) + (setq tree-mode-list (append tree-mode-list (list tree))) + (run-hook-with-args 'tree-mode-insert-tree-hook tree) + tree) + +(defun tree-mode-delete (tree) + "Delete tree in the buffer." + (setq tree-mode-list (delq tree tree-mode-list)) + (widget-delete tree) + (run-hook-with-args 'tree-mode-delete-tree-hook tree)) + +(defun tree-mode-tree-buffer (tree) + "Return the buffer where the TREE is inserted" + (marker-buffer (widget-get tree :from))) + +(defun tree-mode-kill-buffer (&rest ignore) + "If no tree in current buffer, kill this buffer." + (if (= (length tree-mode-list) 0) + (kill-buffer (current-buffer)))) + +;;{{{ Predicate and others +(defun tree-mode-root-treep (tree) + "Test if the TREE is root" + (and (tree-widget-p tree) + (null (widget-get tree :parent)))) + +(defun tree-mode-tree-linep () + "If there is tree-widget in current line, return t." + (let ((wid (tree-mode-icon-current-line))) + (and wid (not (tree-widget-leaf-node-icon-p wid))))) + +(defun tree-mode-root-linep () + "If the root tree node in current line, return t" + (let ((wid (tree-mode-icon-current-line))) + (and wid (not (tree-widget-leaf-node-icon-p wid)) + (null (widget-get (widget-get wid :parent) :parent))))) + +(defun tree-mode-icon-current-line () + "Return the icon widget in current line" + (save-excursion + (forward-line 0) + (tree-mode-nearest-widget))) + +(defun tree-mode-button-current-line () + "Return the push button in current line." + (save-excursion + (let ((pos (line-beginning-position)) + but) + (goto-char (line-end-position)) + (while (and (not but) (> (point) pos)) + (setq but (get-char-property (point) 'button)) + (backward-char 1)) + but))) + +(defun tree-mode-parent-current-line () + "If current line is root line, return the root tree, otherwise +return the parent tree" + (let ((wid (tree-mode-icon-current-line)) + parent) + (when wid + (if (tree-widget-leaf-node-icon-p wid) + (widget-get wid :parent) + (setq parent (widget-get (widget-get wid :parent) :parent)) + (or parent (widget-get wid :parent)))))) + +(defun tree-mode-widget-root (wid) + "Return tree root of the widget WID." + (let (parent) + (while (setq parent (widget-get wid :parent)) + (setq wid parent)) + wid)) + +(defun tree-mode-tree-ap (&optional pos) + "Return the root tree at point" + (save-excursion + (if pos (goto-char pos)) + (ignore-errors + (tree-mode-widget-root (tree-mode-icon-current-line))))) +;;}}} + +(defun tree-mode-opened-tree (tree) + "Find all opened tree. +Return the tag list with the same depth." + (if (widget-get tree :open) + (cons (widget-get (tree-widget-node tree) :tag) + (delq nil + (mapcar (lambda (child) + (and (tree-widget-p child) + (tree-mode-opened-tree child))) + (widget-get tree :children)))))) + +(defun tree-mode-open-tree (tree path) + "Open tree using tag list given by `tree-mode-opened-tree'." + (when path + (if (not (widget-get tree :open)) + (widget-apply-action tree)) + (setq path (cdr path)) + (and path + (mapc (lambda (child) + (and (tree-widget-p child) + (let* ((tag (widget-get (tree-widget-node child) :tag)) + (subpath (assoc tag path))) + (if subpath + (tree-mode-open-tree child subpath))))) + (widget-get tree :children))))) + +(defun tree-mode-reflesh-tree (tree) + "Redraw TREE. +If tree has attribute :dynargs, generate new :args from that function. +Otherwise use :old-args which saved by `tree-mode-backup-args'." + (let ((path (tree-mode-opened-tree tree))) + (if (widget-get tree :dynargs) + (widget-put tree :args nil) + (if (widget-get tree :old-args) + (widget-put tree :args (widget-get tree :old-args)))) + (widget-value-set tree (widget-value tree)) + (tree-mode-open-tree tree path))) + +(defun tree-mode-reflesh-parent (widget &rest ignore) + "Put this function to :notify property of tree-widget node." + (tree-mode-reflesh-tree (widget-get widget :parent))) + +;;{{{ Movement commands +(defun tree-mode-next-node (arg) + "Move to next node." + (interactive "p") + (widget-forward (* arg 2))) + +(defun tree-mode-previous-node (arg) + (interactive "p") + (tree-mode-next-node (- arg))) + +(defun tree-mode-next-sib (arg) + "Move to next sibling node." + (interactive "p") + (let (me siblings sib others out-range) + (if (tree-mode-root-linep) + (setq me (tree-mode-tree-ap) + siblings tree-mode-list) + (let ((parent (tree-mode-parent-current-line))) + (setq me (tree-mode-button-current-line)) + (if (tree-mode-tree-linep) + (setq me (widget-get me :parent))) + (setq siblings (widget-get parent :children)))) + (setq others (member me siblings)) + (if (> arg 0) + (setq sib + (if (>= arg (length others)) + (progn + (setq out-range t) + (car (last others))) + (nth arg others))) + (setq sib (- (length siblings) + (length others) + (- arg)) + out-range (< sib 0)) + (setq sib (nth (max 0 sib) siblings))) + (goto-char (widget-get sib :from)) + (if out-range + (message "No %s sibling more!" (if (< arg 0) "previous" "next"))))) + +(defun tree-mode-previous-sib (arg) + "Move to previous sibling node." + (interactive "p") + (tree-mode-next-sib (- arg))) + +(defun tree-mode-goto-root () + "Move to root node" + (interactive) + (let ((root (tree-mode-tree-ap))) + (if root + (goto-char (widget-get root :from)) + (message "No Root!")))) + +(defun tree-mode-goto-parent (arg) + "Move to parent node." + (interactive "p") + (let ((parent (tree-mode-parent-current-line))) + (setq arg (1- arg)) + (if parent + (progn + (goto-char (widget-get parent :from)) + (while (and (> arg 0) + (setq parent (widget-get parent :parent)) + (goto-char (widget-get parent :from)) + (setq arg (1- arg))))) + (message "No parent!")))) + +(defun tree-mode-find-node (tree path) + "Find node by path. +Return a cons cell (NODE . REST). Check the rest to find if the node +is node of the full path. +PATH is a list of node tag to search from root. +Note if the tree is not opened, It will open some node when need. +`set-buffer' to tree buffer before call this function." + (when (and (tree-widget-p tree) path) + (let ((children (cdr (widget-get tree :children))) ; car is root node + ;; if last node, both push-button and tree-widget will check + (predicate (if (= (length path) 1) + 'widget-type 'tree-widget-p)) + node found) + (while (and (not found) children) + (setq node (car children)) + (if (and (funcall predicate node) + (string= (tree-mode-node-tag node) (car path))) + (progn + (when (cdr path) + ;; if tree is not open, open it + (if (and (tree-widget-p node) + (not (widget-get node :open))) + (widget-apply-action node)) + (setq found (tree-mode-find-node (car children) (cdr path)))) + (or found + (setq found (cons (car children) (cdr path))))) + (setq children (cdr children)))) + found))) +;;}}} + +;;{{{ Expand or collapse +(defun tree-mode-collapse-other-except () + "Collapse other trees. If the tree at point is contract, expand it." + (interactive) + (let ((me (tree-mode-icon-current-line))) + (if (tree-widget-leaf-node-icon-p me) + (message "Not a tree under point!") + (setq me (widget-get me :parent)) + (unless (widget-get me :open) + (widget-apply-action me)) + (mapc (lambda (tree) + (if (widget-get tree :open) + (widget-apply-action tree))) + (remq me (if (tree-mode-root-treep me) + tree-mode-list + (widget-get (widget-get me :parent) + :children))))))) + +(defun tree-mode-collapse-children (tree) + "Collapse child node" + (mapc (lambda (child) + (if (widget-get child :open) + (widget-apply-action child))) + (widget-get tree :children))) + +(defun tree-mode-expand-children (tree) + "Expand child node" + (mapc (lambda (child) + (if (and (tree-widget-p child) + (not (widget-get child :open))) + (widget-apply-action child))) + (widget-get tree :children))) + +(defun tree-mode-toggle-expand-node (&rest ignore) + "Put it to :notify of tree widget node." + (tree-mode-toggle-expand)) + +(defun tree-mode-toggle-expand (&optional arg) + (interactive "P") + (let ((me (tree-mode-icon-current-line)) + expandp open) + (if (tree-widget-leaf-node-icon-p me) + (message "Not a tree under point!") + (setq me (widget-get me :parent)) + (setq expandp (widget-get me :open)) + (setq open (if (null arg) + (not expandp) + (> (prefix-numeric-value arg) 0))) + (unless (eq open expandp) + (widget-apply-action me))))) + +(defun tree-mode-expand-level (level) + "Expand tree to LEVEL. With prefix argument 0 or negative, will +expand all leaves of the tree." + (interactive "p") + (let ((me (tree-mode-icon-current-line))) + (if (tree-widget-leaf-node-icon-p me) + (message "Not a tree under point!") + (setq me (widget-get me :parent)) + (tree-mode-expand-level-1 me (1- level))))) + +(defun tree-mode-expand-level-1 (tree level) + (when (tree-widget-p tree) + (if (not (widget-get tree :open)) + (widget-apply-action tree)) + (if (= level 0) + (tree-mode-collapse-children tree) + (mapc (lambda (child) + (tree-mode-expand-level-1 child (1- level))) + (widget-get tree :children))))) +;;}}} + +(defun tree-mode-node-tag (node) + "Return tag of push-button or tree-widget" + (or (widget-get node :tag) + (widget-get (widget-get node :node) :tag))) + +;;{{{ Commands about tree nodes +(defun tree-mode-backup-args (widget) + "Save :args of tree-widget if need." + (unless (and (widget-get widget :dynargs) + (null (widget-get widget :old-args))) + ;; if widget don't have a dynamic args function + ;; restore args to old-args for recover + (widget-put widget :old-args (copy-sequence (widget-get widget :args))))) + +(defun tree-mode-filter-children (widget filter) + "Remove children nodes when call FILTER with the node return true." + (tree-mode-backup-args widget) + (widget-put widget :args + (delq nil (mapcar (lambda (child) + (if (funcall filter child) + child)) + (widget-get widget :args)))) + (widget-value-set widget (widget-value widget))) + +(defun tree-mode-sort-by-nchild (wid1 wid2) + "Sort node by which node has children" + (widget-get wid1 :children)) + +(defun tree-mode-sort-children (widget sorter) + "Sort children nodes by SORTER." + (tree-mode-backup-args widget) + (widget-put widget :args + (sort (copy-sequence (widget-get widget :args)) sorter)) + (widget-value-set widget (widget-value widget))) + +(defun tree-mode-sort-by-tag (arg) + "Sort children node by tag." + (interactive "P") + (let ((tree (tree-mode-parent-current-line))) + (if tree + (tree-mode-sort-children tree + (lambda (w1 w2) + (or (tree-mode-sort-by-nchild w1 w2) + (string< (tree-mode-node-tag w1) + (tree-mode-node-tag w2))))) + (message "No tree at point!")))) + +(defun tree-mode-delete-match (regexp) + "Remove node which tag match REGEXP." + (interactive "sDelete node match: ") + (let ((tree (tree-mode-parent-current-line))) + (if tree + (tree-mode-filter-children + tree + (lambda (child) (not (string-match regexp (tree-mode-node-tag child))))) + (message "No tree at point!")))) + +(defun tree-mode-keep-match (regexp) + "Keep node which tag match REGEXP" + (interactive "sKeep node match: ") + (let ((tree (tree-mode-parent-current-line))) + (if tree + (tree-mode-filter-children + tree + (lambda (child) (string-match regexp (tree-mode-node-tag child)))) + (message "No tree at point!")))) + +(defun tree-mode-reflesh () + "Reflesh parent tree." + (interactive) + (let ((tree (tree-mode-parent-current-line))) + (if tree + (tree-mode-reflesh-tree tree) + (message "No tree at point!")))) + +(defun tree-mode-delete-tree () + "Delete a tree from buffer." + (interactive) + (if (tree-mode-root-linep) + (if (yes-or-no-p "Delete current tree? ") + (tree-mode-delete (tree-mode-tree-ap))) + (message "No tree at point!"))) +;;}}} + +(provide 'tree-mode) +;;; tree-mode.el ends here diff --git a/packages/treemacs-20181117.1604.tar b/packages/treemacs-20190814.459.tar similarity index 60% rename from packages/treemacs-20181117.1604.tar rename to packages/treemacs-20190814.459.tar index 1017dee..c2626cc 100644 Binary files a/packages/treemacs-20181117.1604.tar and b/packages/treemacs-20190814.459.tar differ diff --git a/packages/treemacs-evil-20180803.1017.el b/packages/treemacs-evil-20190619.1516.el similarity index 73% rename from packages/treemacs-evil-20180803.1017.el rename to packages/treemacs-evil-20190619.1516.el index 60921e2..a6b5830 100644 --- a/packages/treemacs-evil-20180803.1017.el +++ b/packages/treemacs-evil-20190619.1516.el @@ -1,10 +1,10 @@ ;;; treemacs-evil.el --- Evil mode integration for treemacs -*- lexical-binding: t -*- -;; Copyright (C) 2018 Alexander Miller +;; Copyright (C) 2019 Alexander Miller ;; Author: Alexander Miller -;; Package-Requires: ((evil "1.2.12") (treemacs "0")) -;; Package-Version: 20180803.1017 +;; Package-Requires: ((evil "1.2.12") (treemacs "0.0")) +;; Package-Version: 20190619.1516 ;; Package-X-Original-Version: 0 ;; Homepage: https://github.com/Alexander-Miller/treemacs @@ -44,6 +44,23 @@ (with-current-buffer it (evil-treemacs-state)))) +(defun treemacs--evil-window-move-compatibility-advice (orig-fun &rest args) + "Close Treemacs while moving windows around. +Then call ORIG-FUN with its ARGS and reopen treemacs if it was open before." + (let* ((treemacs-window (treemacs-get-local-window)) + (is-active (and treemacs-window (window-live-p treemacs-window)))) + (when is-active (treemacs)) + (apply orig-fun args) + (when is-active + (save-selected-window + (treemacs))))) + +(dolist (func '(evil-window-move-far-left + evil-window-move-far-right + evil-window-move-very-top + evil-window-move-very-bottom)) + (advice-add func :around #'treemacs--evil-window-move-compatibility-advice)) + (advice-add 'treemacs-leftclick-action :after #'treemacs--turn-off-visual-state-after-click) (advice-add 'treemacs-doubleclick-action :after #'treemacs--turn-off-visual-state-after-click) @@ -63,11 +80,14 @@ (define-key evil-treemacs-state-map (kbd "b") #'treemacs-add-bookmark) (define-key evil-treemacs-state-map (kbd "?") #'treemacs-helpful-hydra) (define-key evil-treemacs-state-map (kbd "RET") #'treemacs-RET-action) +(define-key evil-treemacs-state-map (kbd "H") #'treemacs-collapse-parent-node) (evil-define-key 'treemacs treemacs-mode-map (kbd "yr") #'treemacs-copy-project-root) (evil-define-key 'treemacs treemacs-mode-map (kbd "yy") #'treemacs-copy-path-at-point) +(evil-define-key 'treemacs treemacs-mode-map (kbd "yf") #'treemacs-copy-file) (evil-define-key 'treemacs treemacs-mode-map (kbd "gr") #'treemacs-refresh) -(evil-define-key 'treemacs treemacs-mode-map [down-mouse-1] #'ignore) +(evil-define-key 'treemacs treemacs-mode-map [down-mouse-1] #'treemacs-leftclick-action) +(evil-define-key 'treemacs treemacs-mode-map [drag-mouse-1] #'treemacs-dragleftclick-action) (evil-define-key 'treemacs treemacs-mode-map (kbd "h") #'treemacs-root-up) (evil-define-key 'treemacs treemacs-mode-map (kbd "l") #'treemacs-root-down) diff --git a/packages/treemacs-projectile-20181029.624.el b/packages/treemacs-projectile-20181029.624.el deleted file mode 100644 index 5cad78c..0000000 --- a/packages/treemacs-projectile-20181029.624.el +++ /dev/null @@ -1,58 +0,0 @@ -;;; treemacs-projectile.el --- Projectile integration for treemacs -*- lexical-binding: t -*- - -;; Copyright (C) 2018 Alexander Miller - -;; Author: Alexander Miller -;; Package-Requires: ((projectile "0.14.0") (treemacs "0")) -;; Package-Version: 20181029.624 -;; Package-X-Original-Version: 0 -;; Homepage: https://github.com/Alexander-Miller/treemacs - -;; 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 . - -;;; Commentary: -;;; Projectile integration for treemacs - -;;; Code: - -(require 'treemacs) -(require 'projectile) - -;;;###autoload -(defun treemacs-projectile () - "Add one of `projectile-known-projects' to the treemacs workspace." - (interactive) - (if (and (bound-and-true-p projectile-known-projects) - (listp projectile-known-projects) - projectile-known-projects) - (-let [projects (--reject (treemacs-is-path it :in-workspace (treemacs-current-workspace)) - (-map #'treemacs--unslash projectile-known-projects))] - (treemacs--init (completing-read "Project: " projects))) - (treemacs-pulse-on-failure "It looks like projectile does not know any projects."))) - -(define-key treemacs-mode-map (kbd "C-p p") #'treemacs-projectile) - -(defun treemacs--read-first-project-path () - "Overwrites the original definition from `treemacs-impl'. -This version will read a directory based on the current project root instead of -the current dir." - (when (treemacs-workspace->is-empty?) - (read-directory-name "Project root: " - (condition-case _ - (projectile-project-root) - (error nil))))) - -(provide 'treemacs-projectile) - -;;; treemacs-projectile.el ends here diff --git a/packages/treemacs-projectile-20190619.1516.el b/packages/treemacs-projectile-20190619.1516.el new file mode 100644 index 0000000..ee88373 --- /dev/null +++ b/packages/treemacs-projectile-20190619.1516.el @@ -0,0 +1,82 @@ +;;; treemacs-projectile.el --- Projectile integration for treemacs -*- lexical-binding: t -*- + +;; Copyright (C) 2019 Alexander Miller + +;; Author: Alexander Miller +;; Package-Requires: ((projectile "0.14.0") (treemacs "0.0")) +;; Package-Version: 20190619.1516 +;; Package-X-Original-Version: 0 +;; Homepage: https://github.com/Alexander-Miller/treemacs + +;; 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 . + +;;; Commentary: +;;; Projectile integration for treemacs + +;;; Code: + +(require 'treemacs) +(require 'projectile) + +;;;###autoload +(defun treemacs-projectile (&optional arg) + "Add one of `projectile-known-projects' to the treemacs workspace. +With a prefix ARG was for the name of the project instead of using the name of +the project's root directory." + (interactive) + (if (and (bound-and-true-p projectile-known-projects) + (listp projectile-known-projects) + projectile-known-projects) + (let* ((projects (--reject (treemacs-is-path (treemacs--canonical-path it) :in-workspace (treemacs-current-workspace)) + (-map #'treemacs--unslash projectile-known-projects))) + (path (completing-read "Project: " projects)) + (name (unless arg (treemacs--filename path)))) + (if (treemacs-workspace->is-empty?) + (treemacs--init path name) + (save-selected-window + (treemacs-select-window) + ;; not casing the full error list since some are excluded + (pcase (treemacs-do-add-project-to-workspace path name) + (`(success ,project) + (treemacs-pulse-on-success "Added project %s to the workspace." + (propertize (treemacs-project->name project) 'face 'font-lock-type-face))) + (`(duplicate-name ,duplicate) + (goto-char (treemacs-project->position duplicate)) + (treemacs-pulse-on-failure "A project with the name %s already exists." + (propertize (treemacs-project->name duplicate) 'face 'font-lock-type-face))))))) + (treemacs-pulse-on-failure "It looks like projectile does not know any projects."))) + +(define-key treemacs-project-map (kbd "p") #'treemacs-projectile) + +(defun treemacs--read-first-project-path () + "Overwrites the original definition from `treemacs-core-utils'. +This version will read a directory based on the current project root instead of +the current dir." + (when (treemacs-workspace->is-empty?) + (file-truename + (read-directory-name "Project root: " + (condition-case _ + (projectile-project-root) + (error nil)))))) + +(defun treemacs--projectile-current-user-project-function () + "Get the current projectile project root." + (declare (side-effect-free t)) + (-some-> (projectile-project-root) (file-truename) (treemacs--canonical-path))) + +(add-to-list 'treemacs--find-user-project-functions #'treemacs--projectile-current-user-project-function) + +(provide 'treemacs-projectile) + +;;; treemacs-projectile.el ends here diff --git a/packages/tuareg-20180918.1913.tar b/packages/tuareg-20190805.958.tar similarity index 72% rename from packages/tuareg-20180918.1913.tar rename to packages/tuareg-20190805.958.tar index 1188df4..ada8a92 100644 Binary files a/packages/tuareg-20180918.1913.tar and b/packages/tuareg-20190805.958.tar differ diff --git a/packages/twittering-mode-20180917.328.el b/packages/twittering-mode-20181121.1402.el similarity index 99% rename from packages/twittering-mode-20180917.328.el rename to packages/twittering-mode-20181121.1402.el index 6ebcb45..aa90cda 100644 --- a/packages/twittering-mode-20180917.328.el +++ b/packages/twittering-mode-20181121.1402.el @@ -12,8 +12,8 @@ ;; Xavier Maillard ;; Created: Sep 4, 2007 ;; Version: HEAD -;; Package-Version: 20180917.328 -;; Identity: $Id: 18628baf608b54e6d5a74c4970fa16f312695032 $ +;; Package-Version: 20181121.1402 +;; Identity: $Id: fb19946d706684ccd33bcd810e98638d7374964c $ ;; Keywords: twitter web ;; URL: http://twmode.sf.net/ @@ -96,7 +96,7 @@ :group 'hypermedia) (defconst twittering-mode-version "HEAD") -(defconst twittering-mode-identity "$Id: 18628baf608b54e6d5a74c4970fa16f312695032 $") +(defconst twittering-mode-identity "$Id: fb19946d706684ccd33bcd810e98638d7374964c $") (defvar twittering-api-host "api.twitter.com") (defvar twittering-api-search-host "search.twitter.com") (defvar twittering-web-host "twitter.com") @@ -5550,7 +5550,7 @@ The file is specified by `twittering-user-id-db-file'." ((or (equal generator-version emacs-version) (y-or-n-p (format "%s is generated by Emacs %s! Continue?" - filename version))) + filename generator-version))) (mapc (lambda (entry) (let ((id (car entry)) (properties (cdr entry))) diff --git a/packages/typescript-mode-20181018.553.tar b/packages/typescript-mode-20190710.2011.tar similarity index 98% rename from packages/typescript-mode-20181018.553.tar rename to packages/typescript-mode-20190710.2011.tar index d00242b..4190ce4 100644 Binary files a/packages/typescript-mode-20181018.553.tar and b/packages/typescript-mode-20190710.2011.tar differ diff --git a/packages/typit-20180317.807.tar b/packages/typit-20190713.1336.tar similarity index 98% rename from packages/typit-20180317.807.tar rename to packages/typit-20190713.1336.tar index b208ebc..c421d02 100644 Binary files a/packages/typit-20180317.807.tar and b/packages/typit-20190713.1336.tar differ diff --git a/packages/ucs-utils-20150826.1414.tar b/packages/ucs-utils-20150826.1414.tar index 3e70741..524f5a8 100644 Binary files a/packages/ucs-utils-20150826.1414.tar and b/packages/ucs-utils-20150826.1414.tar differ diff --git a/packages/use-package-20181110.1758.tar b/packages/use-package-20190716.1829.tar similarity index 97% rename from packages/use-package-20181110.1758.tar rename to packages/use-package-20190716.1829.tar index 271c6af..6fc84ab 100644 Binary files a/packages/use-package-20181110.1758.tar and b/packages/use-package-20190716.1829.tar differ diff --git a/packages/utop-20181010.2155.el b/packages/utop-20190715.1836.el similarity index 99% rename from packages/utop-20181010.2155.el rename to packages/utop-20190715.1836.el index 9d444db..2ec83e0 100644 --- a/packages/utop-20181010.2155.el +++ b/packages/utop-20190715.1836.el @@ -3,7 +3,7 @@ ;; Copyright: (c) 2011, Jeremie Dimino ;; Author: Jeremie Dimino ;; URL: https://github.com/diml/utop -;; Package-Version: 20181010.2155 +;; Package-Version: 20190715.1836 ;; Licence: BSD3 ;; Version: 1.11 ;; Package-Requires: ((emacs "24")) @@ -212,11 +212,6 @@ to add the newline character if it is not accepted).") "List of packages to load when visiting OCaml buffer. Useful as file variable.")) -(make-variable-buffer-local - (defvar utop-ocaml-preprocessor nil - "Name of preprocesor. Currently supported camlp4o, camlp4r. -Useful as file variable.")) - (defvar utop-next-phrase-beginning 'utop-compat-next-phrase-beginning "The function used to find the beginning of the next phrase.") @@ -1029,10 +1024,6 @@ defaults to 0." (defun utop-hack-local-variables () "Perform actions defined by local variables" - (when utop-ocaml-preprocessor - (with-current-buffer (utop)) - (utop-eval-string (format "#%s" utop-ocaml-preprocessor)) - (message (format "uTop: %s OCaml preprocessor loaded" utop-ocaml-preprocessor))) (utop-query-load-package-list)) ;; +-----------------------------------------------------------------+ diff --git a/packages/vagrant-tramp-20160427.2332.tar b/packages/vagrant-tramp-20190816.1846.tar similarity index 91% rename from packages/vagrant-tramp-20160427.2332.tar rename to packages/vagrant-tramp-20190816.1846.tar index 51d9792..0dbfdb7 100644 Binary files a/packages/vagrant-tramp-20160427.2332.tar and b/packages/vagrant-tramp-20190816.1846.tar differ diff --git a/packages/vala-snippets-20150429.352.tar b/packages/vala-snippets-20150429.352.tar index 3a6afcc..bce02f2 100644 Binary files a/packages/vala-snippets-20150429.352.tar and b/packages/vala-snippets-20150429.352.tar differ diff --git a/packages/visual-fill-column-20190422.2154.el b/packages/visual-fill-column-20190422.2154.el new file mode 100644 index 0000000..2420f04 --- /dev/null +++ b/packages/visual-fill-column-20190422.2154.el @@ -0,0 +1,227 @@ +;;; visual-fill-column.el --- fill-column for visual-line-mode -*- lexical-binding: t -*- + +;; Copyright (C) 2015-2019 Joost Kremers +;; Copyright (C) 2016 Martin Rudalics +;; All rights reserved. + +;; Author: Joost Kremers +;; Maintainer: Joost Kremers +;; Created: 2015 +;; Version: 1.9 +;; Package-Version: 20190422.2154 +;; Package-Requires: ((emacs "24.3")) + +;; This file is NOT part of GNU Emacs. + +;; visual-fill-column 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. + +;; visual-fill-column is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; `visual-fill-column-mode' is a small Emacs minor mode that mimics the effect of `fill-column' +;; in `visual-line-mode'. Instead of wrapping lines at the window edge, which +;; is the standard behaviour of `visual-line-mode', it wraps lines at +;; `fill-column'. If `fill-column' is too large for the window, the text is +;; wrapped at the window edge. + +;;; Code: + +(defgroup visual-fill-column nil "Wrap lines according to `fill-column' in `visual-line-mode'." + :group 'wp + :prefix "visual-fill-column-") + +(defcustom visual-fill-column-width nil + "Width of the text area. +By default, the global value of `fill-column' is used, but if +this option is set to a value, it is used instead." + :group 'visual-fill-column + :type '(choice (const :tag "Use `fill-column'" :value nil) + (integer :tag "Specify width" :value 70))) +(make-variable-buffer-local 'visual-fill-column-width) +(put 'visual-fill-column-width 'safe-local-variable 'numberp) + +(defcustom visual-fill-column-fringes-outside-margins t + "Put the fringes outside the margins." + :group 'visual-fill-column + :type '(choice (const :tag "Put fringes outside the margins" t) + (const :tag "Keep the fringes inside the margins" nil))) +(make-variable-buffer-local 'visual-fill-column-fringes-outside-margins) +(put 'visual-fill-column-fringes-outside-margins 'safe-local-variable 'symbolp) + +(defcustom visual-fill-column-center-text nil + "If set, center the text area in the window." + :group 'visual-fill-column + :type '(choice (const :tag "Display text area at window margin" nil) + (const :tag "Center text area" t))) +(make-variable-buffer-local 'visual-fill-column-center-text) +(put 'visual-fill-column-center-text 'safe-local-variable 'symbolp) + +;;;###autoload +(define-minor-mode visual-fill-column-mode + "Wrap lines according to `fill-column' in `visual-line-mode'." + :init-value nil :lighter nil :global nil + :keymap + (let ((map (make-sparse-keymap))) + (when (bound-and-true-p mouse-wheel-mode) + (progn + (define-key map (vector 'left-margin mouse-wheel-down-event) 'mwheel-scroll) + (define-key map (vector 'left-margin mouse-wheel-up-event) 'mwheel-scroll) + (define-key map (vector 'right-margin mouse-wheel-down-event) 'mwheel-scroll) + (define-key map (vector 'right-margin mouse-wheel-up-event) 'mwheel-scroll)) + map)) + (if visual-fill-column-mode + (visual-fill-column-mode--enable) + (visual-fill-column-mode--disable))) + +;;;###autoload +(define-globalized-minor-mode global-visual-fill-column-mode visual-fill-column-mode turn-on-visual-fill-column-mode + :require 'visual-fill-column-mode + :group 'visual-fill-column) + +(defun turn-on-visual-fill-column-mode () + "Turn on `visual-fill-column-mode'. +Note that `visual-fill-column-mode' is only turned on in buffers +in which Visual Line mode is active as well, and only in buffers +that actually visit a file." + (when (and visual-line-mode + buffer-file-name) + (visual-fill-column-mode 1))) + +(defun visual-fill-column-mode--enable () + "Set up `visual-fill-column-mode' for the current buffer." + (add-hook 'window-configuration-change-hook #'visual-fill-column--adjust-window 'append 'local) + (if (>= emacs-major-version 26) + (add-hook 'window-size-change-functions #'visual-fill-column--adjust-frame 'append)) + (visual-fill-column--adjust-window)) + +(defun visual-fill-column-mode--disable () + "Disable `visual-fill-column-mode' for the current buffer." + (remove-hook 'window-configuration-change-hook #'visual-fill-column--adjust-window 'local) + (set-window-fringes (get-buffer-window (current-buffer)) nil) + (set-window-margins (get-buffer-window (current-buffer)) nil)) + +(defun visual-fill-column-split-window (&optional window size side pixelwise) + "Split WINDOW, unsetting its margins first. +SIZE, SIDE, and PIXELWISE are passed on to `split-window'. This +function is for use in the window parameter `split-window'." + (let ((horizontal (memq side '(t left right))) + margins new) + (when horizontal + ;; Reset margins. + (setq margins (window-margins window)) + (set-window-margins window nil)) + ;; Now try to split the window. + (set-window-parameter window 'split-window nil) + (unwind-protect + (setq new (split-window window size side pixelwise)) + (set-window-parameter window 'split-window #'visual-fill-column-split-window) + ;; Restore old margins if we failed. + (when (and horizontal (not new)) + (set-window-margins window (car margins) (cdr margins)))))) + +;;;###autoload +(defun visual-fill-column-split-window-sensibly (&optional window) + "Split WINDOW sensibly, unsetting its margins first. +This function unsets the window margins and calls +`split-window-sensibly'. + +By default, `split-window-sensibly' does not split a window +vertically if it has wide margins, even if there is enough space +for a vertical split. This function can be used as the value of +`split-window-preferred-function' to enable vertically splitting +windows with wide margins." + (let ((margins (window-margins window)) + new) + ;; unset the margins and try to split the window + (when (buffer-local-value 'visual-fill-column-mode (window-buffer window)) + (set-window-margins window nil)) + (unwind-protect + (setq new (split-window-sensibly window)) + (when (not new) + (set-window-margins window (car margins) (cdr margins)))))) + +(defun visual-fill-column--adjust-window () + "Adjust the window margins and fringes." + ;; Only run when we're really looking at a buffer that has v-f-c-mode enabled. See #22. + (when (buffer-local-value 'visual-fill-column-mode (window-buffer (selected-window))) + (set-window-fringes (get-buffer-window (current-buffer)) nil nil visual-fill-column-fringes-outside-margins) + (if (>= emacs-major-version 25) + (set-window-parameter (get-buffer-window (current-buffer)) 'split-window #'visual-fill-column-split-window)) + (visual-fill-column--set-margins))) + +(defun visual-fill-column--adjust-frame (frame) + "Adjust the windows of FRAME." + (mapc (lambda (w) + (with-selected-window w + (visual-fill-column--adjust-window))) + (window-list frame :never))) + +(defun visual-fill-column-adjust (&optional _inc) + "Adjust the window margins and fringes. +This function is for use as advice to `text-scale-adjust'. It +calls `visual-fill-column--adjust-window', but only if +`visual-fill-column' is active." + (if visual-fill-column-mode + (visual-fill-column--adjust-window))) + +(defun visual-fill-column--window-max-text-width (&optional window) + "Return the maximum possible text width of WINDOW. +The maximum possible text width is the width of the current text +area plus the margins, but excluding the fringes, scroll bar and +right divider. WINDOW defaults to the selected window. The +return value is scaled to account for `text-scale-mode-amount' +and `text-scale-mode-step'." + (or window (setq window (get-buffer-window (current-buffer)))) + (let* ((margins (window-margins window)) + (buffer (window-buffer window)) + (scale (if (and (boundp 'text-scale-mode-step) + (boundp 'text-scale-mode-amount)) + (with-current-buffer buffer + (expt text-scale-mode-step + text-scale-mode-amount)) + 1.0))) + (truncate (/ (+ (window-width window) + (or (car margins) 0) + (or (cdr margins) 0) + (or (and (boundp 'display-line-numbers-width) + (numberp display-line-numbers-width) + (- display-line-numbers-width)) + 0)) + (float scale))))) + +(defun visual-fill-column--set-margins () + "Set window margins for the current window." + ;; calculate left & right margins + (let* ((window (get-buffer-window (current-buffer))) + (total-width (visual-fill-column--window-max-text-width window)) + (width (or visual-fill-column-width + fill-column)) + (margins (if (< (- total-width width) 0) ; margins must be >= 0 + 0 + (- total-width width))) + (left (if visual-fill-column-center-text + (/ margins 2) + 0)) + (right (- margins left))) + + ;; put an explicitly R2L buffer on the right side of the window + (when (and (eq bidi-paragraph-direction 'right-to-left) + (= left 0)) + (setq left right) + (setq right 0)) + + (set-window-margins window left right))) + +(provide 'visual-fill-column) + +;;; visual-fill-column.el ends here diff --git a/packages/web-completion-data-20160318.848.tar b/packages/web-completion-data-20160318.848.tar index 2000eda..8dc1ab4 100644 Binary files a/packages/web-completion-data-20160318.848.tar and b/packages/web-completion-data-20160318.848.tar differ diff --git a/packages/web-mode-20181104.2004.el b/packages/web-mode-20190625.1951.el similarity index 97% rename from packages/web-mode-20181104.2004.el rename to packages/web-mode-20190625.1951.el index 2fd1fb9..bf2d921 100644 --- a/packages/web-mode-20181104.2004.el +++ b/packages/web-mode-20190625.1951.el @@ -1,10 +1,10 @@ ;;; web-mode.el --- major mode for editing web templates ;;; -*- coding: utf-8; lexical-binding: t; -*- -;; Copyright 2011-2018 François-Xavier Bois +;; Copyright 2011-2019 François-Xavier Bois -;; Version: 16.0.16 -;; Package-Version: 20181104.2004 +;; Version: 16.0.24 +;; Package-Version: 20190625.1951 ;; Author: François-Xavier Bois ;; Maintainer: François-Xavier Bois ;; Package-Requires: ((emacs "23.1")) @@ -25,7 +25,7 @@ ;;---- CONSTS ------------------------------------------------------------------ -(defconst web-mode-version "16.0.16" +(defconst web-mode-version "16.0.24" "Web Mode version.") ;;---- GROUPS ------------------------------------------------------------------ @@ -569,21 +569,31 @@ See web-mode-block-face." "Face for css comments." :group 'web-mode-faces) +(defface web-mode-annotation-face + '((t :inherit web-mode-comment-face)) + "Face for code annotations." + :group 'web-mode-faces) + (defface web-mode-annotation-tag-face - '((t :inherit web-mode-comment-face :underline t)) + '((t :inherit web-mode-annotation-face :underline t)) "Face for @tags in code annotations." :group 'web-mode-faces) (defface web-mode-annotation-type-face - '((t :inherit web-mode-comment-face :weight bold)) + '((t :inherit web-mode-annotation-face :weight bold)) "Face for types in code annotations." :group 'web-mode-faces) (defface web-mode-annotation-value-face - '((t :inherit web-mode-comment-face :slant italic)) + '((t :inherit web-mode-annotation-face :slant italic)) "Face for values in code annotations." :group 'web-mode-faces) +(defface web-mode-annotation-html-face + '((t :inherit web-mode-annotation-face :slant italic)) + "Face for HTML tags in code annotations." + :group 'web-mode-faces) + (defface web-mode-constant-face '((t :inherit font-lock-constant-face)) "Face for language constants." @@ -811,6 +821,7 @@ Must be used in conjunction with web-mode-enable-block-face." (defvar web-mode-engines '(("angular" . ("angularjs")) ("archibus" . ()) + ("artanis" . ()) ("asp" . ()) ("aspx" . ()) ("blade" . ("laravel")) @@ -888,6 +899,7 @@ Must be used in conjunction with web-mode-enable-block-face." (defvar web-mode-engine-file-regexps '(("angular" . "\\.component.html\\'") + ("artanis" . "\\.tpl\\'") ("asp" . "\\.asp\\'") ("aspx" . "\\.as[cp]x\\'") ("archibus" . "\\.axvw\\'") @@ -898,7 +910,7 @@ Must be used in conjunction with web-mode-enable-block-face." ("ctemplate" . "\\.\\(chtml\\|mustache\\)\\'") ("django" . "\\.\\(djhtml\\|tmpl\\|dtl\\|liquid\\|j2\\|njk\\)\\'") ("dust" . "\\.dust\\'") - ("elixir" . "\\.eex\\'") + ("elixir" . "\\.l?eex\\'") ("ejs" . "\\.ejs\\'") ("erb" . "\\.\\(erb\\|rhtml\\|erb\\.html\\)\\'") ("freemarker" . "\\.ftl\\'") @@ -1074,6 +1086,12 @@ Must be used in conjunction with web-mode-enable-block-face." (defvar web-mode-engines-auto-pairs '(("angular" . (("{{ " . " }}"))) + ("artanis" . (("<% " . " %>") + ("<%=" . " | %>") + ("<@css" . " | %>") + ("<@icon" . " | %>") + ("<@include" . " | %>") + ("<@js" . " | %>"))) ("asp" . (("<% " . " %>"))) ("aspx" . (("<% " . " %>") ("<%=" . "%>") @@ -1095,6 +1113,7 @@ Must be used in conjunction with web-mode-enable-block-face." ("{~{" . " | }}") ("{{~" . "{ | }}}") ("{{!" . "-- | --}}") + ("{{^" . "}}") ("{{/" . "}}") ("{{#" . "}}"))) ("django" . (("{{ " . " }}") @@ -1163,7 +1182,16 @@ Must be used in conjunction with web-mode-enable-block-face." )) (defvar web-mode-engines-snippets - '(("ejs" . (("for" . "<% for (|) { %>\n\n<% } %>") + '(("artanis" . (("if" . "<% (if (|) %>\n\n<% ) %>") + ("when" . "<% (when (|) %>\n\n<% ) %>") + ("unless" . "<% (unless (|) %>\n\n<% ) %>") + ("cond" . "<% (cond %>\n<% [(|) %>\n\n<% ] %>\n<% [else %>\n\n<% ] %>\n<% ) %>") + ("let" . "<% (let ([|]) %>\n\n<% ) %>") + ("let*" . "<% (let* ([|]) %>\n\n<% ) %>") + ("do" . "<% (do ([|]) %>\n<% [()] %>\n\n<% ) %>") + ("for-each" . "<% (for-each %>\n|\n\n<% ) %>") + ("case" . "<% (case | %>\n<% [() %>\n\n<% ] %>\n<% [() %>\n\n<% ] %>\n<% ) %>"))) + ("ejs" . (("for" . "<% for (|) { %>\n\n<% } %>") ("if" . "<% if (|) { %>\n\n<% } %>"))) ("erb" . (("each" . "<% |.each do %>\n\n<% end %>") ("if" . "<% if | %>\n\n<% end %>") @@ -1195,6 +1223,7 @@ Must be used in conjunction with web-mode-enable-block-face." (defvar web-mode-engine-token-regexps (list + '("artanis" . "\"\\|#|\\|;") '("asp" . "//\\|/\\*\\|\"\\|'") '("ejs" . "//\\|/\\*\\|\"\\|'") '("erb" . "\"\\|'\\|#\\|<<[-]?['\"]?\\([[:alnum:]_]+\\)['\"]?") @@ -1210,6 +1239,7 @@ Must be used in conjunction with web-mode-enable-block-face." (defvar web-mode-engine-open-delimiter-regexps (list '("angular" . "{{") + '("artanis" . "<%\\|<@\\(css\\|icon\\|include\\|js\\)") '("asp" . "<%\\|") '(0 'web-mode-keyword-face)) + (cons (concat "\\_<\\(" web-mode-artanis-constants "\\)\\_>") '(0 'web-mode-constant-face)) + '("(define[*]? (\\([[:alnum:]-:_!#$%^&*=+/?<>.]+\\)" 1 'web-mode-function-name-face) + '("\\(#:[[:alnum:]-:_!#$%^&*=+/?<>.]+\\)" 1 'web-mode-builtin-face) + )) + (defvar web-mode-php-font-lock-keywords (list (cons (concat "\\_<\\(" web-mode-php-keywords "\\)\\_>") '(0 'web-mode-keyword-face)) @@ -2189,6 +2257,7 @@ shouldn't be moved back.)") (defvar web-mode-engines-font-lock-keywords '(("angular" . web-mode-angular-font-lock-keywords) + ("artanis" . web-mode-artanis-font-lock-keywords) ("blade" . web-mode-blade-font-lock-keywords) ("cl-emb" . web-mode-cl-emb-font-lock-keywords) ("closure" . web-mode-closure-font-lock-keywords) @@ -2217,6 +2286,11 @@ shouldn't be moved back.)") ) "Engines font-lock keywords") +(defvar web-mode-prettify-symbols-alist + '(("=>" . 8658) + (">=" . 8805) + ("<=" . 8804))) + (defvar web-mode-before-auto-complete-hooks nil "List of functions to run before triggering the auto-complete library. @@ -2307,6 +2381,7 @@ another auto-completion with different ac-sources (e.g. ac-php)") (define-key map [menu-bar wm elt elt-inn] '(menu-item "Content (select)" web-mode-element-content-select)) (define-key map [menu-bar wm elt elt-clo] '(menu-item "Close" web-mode-element-close)) (define-key map [menu-bar wm elt elt-ins] '(menu-item "Insert" web-mode-element-insert)) + (define-key map [menu-bar wm elt elt-ins] '(menu-item "Word to tag" web-mode-element-insert-at-point)) (define-key map [menu-bar wm elt elt-dup] '(menu-item "Clone" web-mode-element-clone)) (define-key map [menu-bar wm elt elt-cfo] '(menu-item "Children fold" web-mode-element-children-fold-or-unfold)) (define-key map [menu-bar wm elt elt-chi] '(menu-item "Child" web-mode-element-child)) @@ -2356,6 +2431,7 @@ another auto-completion with different ac-sources (e.g. ac-php)") (define-key map (kbd "C-c C-e e") 'web-mode-element-end) (define-key map (kbd "C-c C-e f") 'web-mode-element-children-fold-or-unfold) (define-key map (kbd "C-c C-e i") 'web-mode-element-insert) + (define-key map (kbd "C-c C-e I") 'web-mode-element-insert-at-point) (define-key map (kbd "C-c C-e k") 'web-mode-element-kill) (define-key map (kbd "C-c C-e m") 'web-mode-element-mute-blanks) (define-key map (kbd "C-c C-e n") 'web-mode-element-next) @@ -2535,7 +2611,8 @@ another auto-completion with different ac-sources (e.g. ac-php)") indent-line-function 'web-mode-indent-line parse-sexp-lookup-properties t yank-excluded-properties t - uncomment-region-function 'web-mode-comment-or-uncomment-region) + uncomment-region-function 'web-mode-comment-or-uncomment-region + prettify-symbols-alist web-mode-prettify-symbols-alist) (substitute-key-definition 'indent-new-comment-line 'web-mode-comment-indent-new-line @@ -2758,6 +2835,23 @@ another auto-completion with different ac-sources (e.g. ac-php)") ) ) ;cl-emb + ((string= web-mode-engine "artanis") + (cond + ((string= tagopen "<%;") + (setq closing-string "%>")) + ((string= tagopen "<%#|") + (setq closing-string "|#%>")) + ((string= sub2 "<@") + (setq closing-string "%>" + delim-open "<@\\(css\\|icon\\|include\\|js\\)" + delim-close "%>")) + ((string= sub2 "<%") + (setq closing-string "%>" + delim-open "<%[=]?" + delim-close "%>")) + ) + ) ;artanis + ((string= web-mode-engine "elixir") (cond ((member (char-after) '(?\#)) @@ -3390,7 +3484,7 @@ another auto-completion with different ac-sources (e.g. ac-php)") (forward-char)) (cond ((member (char-after) '(?\{)) - (search-forward "}")) + (search-forward "}" nil t)) ((looking-at-p "def \\|define ") (search-forward ")" (line-end-position) t)) (t @@ -3480,7 +3574,7 @@ another auto-completion with different ac-sources (e.g. ac-php)") "Set text-property 'block-token to 'delimiter-(beg|end) on block delimiters (e.g. )" ;;(message "reg-beg(%S) reg-end(%S) delim-open(%S) delim-close(%S)" reg-beg reg-end delim-open delim-close) (when (member web-mode-engine - '("asp" "aspx" "cl-emb" "clip" "closure" "ctemplate" "django" "dust" + '("artanis" "asp" "aspx" "cl-emb" "clip" "closure" "ctemplate" "django" "dust" "elixir" "ejs" "erb" "freemarker" "go" "hero" "jsp" "lsp" "mako" "mason" "mojolicious" "smarty" "template-toolkit" "web2py" "xoops")) (save-excursion @@ -3628,6 +3722,17 @@ another auto-completion with different ac-sources (e.g. ac-php)") ) ) ;cl-emb + ((string= web-mode-engine "artanis") + (cond + ((string= sub3 "<%;") + (setq token-type 'comment)) + ((string= sub3 "<%#|") + (setq token-type 'comment)) + (t + (setq regexp "\"")) + ) + ) ;artanis + ((string= web-mode-engine "elixir") (cond ((string= sub3 "<%#") @@ -4233,8 +4338,12 @@ another auto-completion with different ac-sources (e.g. ac-php)") ((web-mode-block-starts-with "section\(\s*\\(['\"]\\).*\\1\s*,\s*\\(['\"]\\).*\\2\s*\)" reg-beg) ) + ((web-mode-block-starts-with "case\\|break" reg-beg) + (setq type (if (eq (aref (match-string-no-properties 0) 0) ?b) 'close 'open)) + (setq controls (append controls (list (cons type "case")))) + ) ((web-mode-block-starts-with - "\\(?:end\\)?\\(component\\|foreach\\|forelse\\|for\\|if\\|section\\|slot\\|unless\\|while\\)" + (concat "\\(?:end\\)?\\(" web-mode-blade-control-blocks-regexp "\\)") reg-beg) (setq control (match-string-no-properties 1) type (if (eq (aref (match-string-no-properties 0) 0) ?e) 'close 'open)) @@ -4549,7 +4658,7 @@ another auto-completion with different ac-sources (e.g. ac-php)") ) ;cond ) ;let ) ;script - ((string= tname "template") + ((and (string= tname "template") (string-match-p " lang" (buffer-substring-no-properties tbeg tend))) (let (template) (setq template (buffer-substring-no-properties tbeg tend) part-close-tag "") @@ -5775,12 +5884,13 @@ another auto-completion with different ac-sources (e.g. ac-php)") (defun web-mode-buffer-highlight () (interactive) (cond - ((fboundp 'font-lock-flush) + ((and (fboundp 'font-lock-flush) global-font-lock-mode) (font-lock-flush) (font-lock-ensure)) (t ;emacs 24 ;;(font-lock-fontify-buffer) - (font-lock-fontify-region (point-min) (point-max))) + (and global-font-lock-mode + (font-lock-fontify-region (point-min) (point-max)))) ) ;cond ) @@ -6426,7 +6536,7 @@ another auto-completion with different ac-sources (e.g. ac-php)") (font-lock-keywords-only t) (font-lock-extend-region-functions nil)) ;; (message "%S" keywords) - (when (listp font-lock-keywords) + (when (and (listp font-lock-keywords) global-font-lock-mode) (font-lock-fontify-region beg end) ) ) @@ -6519,6 +6629,11 @@ another auto-completion with different ac-sources (e.g. ac-php)") ;;(message "beg=%S end=%S" beg end) (goto-char beg) (when (looking-at-p "/\\*\\*") + (while (re-search-forward "\\(.+\\)" end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-annotation-face)) + (goto-char beg) (while (re-search-forward "[ ]+\\({[^}]+}\\)" end t) (font-lock-prepend-text-property (match-beginning 1) (match-end 1) 'font-lock-face @@ -6528,6 +6643,32 @@ another auto-completion with different ac-sources (e.g. ac-php)") (font-lock-prepend-text-property (match-beginning 1) (match-end 1) 'font-lock-face 'web-mode-annotation-tag-face)) + (goto-char beg) + (while (re-search-forward "}[[:blank:]]+\\([[:graph:]]+\\)" end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-annotation-value-face)) + (goto-char beg) + (while (re-search-forward "@see[[:blank:]]+\\([[:graph:]]+\\)" end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-annotation-value-face)) + (goto-char beg) + (while (re-search-forward "{\\(@\\(?:link\\|code\\)\\)\\s-+\\([^}\n]+\\)\\(#.+\\)?}" end t) + (font-lock-prepend-text-property (match-beginning 2) (match-end 2) + 'font-lock-face + 'web-mode-annotation-value-face)) + (goto-char beg) + (while (re-search-forward "\\(\\)" end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-annotation-html-face) + (font-lock-prepend-text-property (match-beginning 2) (match-end 2) + 'font-lock-face + 'web-mode-annotation-html-face) + (font-lock-prepend-text-property (match-beginning 3) (match-end 3) + 'font-lock-face + 'web-mode-annotation-html-face)) ) ;when )) @@ -6953,6 +7094,11 @@ another auto-completion with different ac-sources (e.g. ac-php)") (cond ((null ctx) (web-mode-delete-tag-overlays)) + ((eq (get-text-property (caar ctx) 'tag-type) 'void) ;; #1046 + (web-mode-make-tag-overlays) + (setq len (length (get-text-property (caar ctx) 'tag-name))) + (move-overlay web-mode-overlay-tag-start (+ (caar ctx) 1) (+ (caar ctx) 1 len)) + ) (t (web-mode-make-tag-overlays) (setq len (length (get-text-property (caar ctx) 'tag-name))) @@ -7180,9 +7326,9 @@ another auto-completion with different ac-sources (e.g. ac-php)") (cond ((and (not (looking-at-p "[ ]*$")) (looking-back "^[[:space:]]*{" (point-min))) - (setq reg-col (+ (current-indentation) 1 + (setq reg-col (+ (current-indentation) ;; #1027 (cond - ((looking-at "[ ]+") (length (match-string-no-properties 0))) + ((looking-at "[ ]+") (1+ (length (match-string-no-properties 0)))) (t 0)) )) ) @@ -7197,8 +7343,12 @@ another auto-completion with different ac-sources (e.g. ac-php)") ;; (looking-at-p "{[ ]*")) ;; (setq reg-col (current-indentation)) ;; ) + ((get-text-property (1- (point)) 'tag-beg) + ;;(message "point=%S" (point)) + (setq reg-col (current-indentation)) + ) (t - ;;(message "%S : %S %S" (point) (current-indentation) web-mode-code-indent-offset) + (message "%S : %S %S" (point) (current-indentation) web-mode-code-indent-offset) ;;(setq reg-col (+ (current-indentation) web-mode-code-indent-offset web-mode-jsx-expression-padding))) (setq reg-col (+ (current-indentation) web-mode-code-indent-offset))) ) @@ -7417,7 +7567,7 @@ another auto-completion with different ac-sources (e.g. ac-php)") (let ((offset nil) (char nil) (debug nil) - (inhibit-modification-hooks t) + (inhibit-modification-hooks nil) (adjust t)) (save-excursion @@ -7492,7 +7642,8 @@ another auto-completion with different ac-sources (e.g. ac-php)") ) ((and is-js (web-mode-is-html-string pos)) - (setq offset (web-mode-html-indentation pos)) + (when debug (message "I128(%S) html string" pos)) + (setq offset (web-mode-token-html-indentation pos)) ) (t (setq offset nil)) @@ -7561,6 +7712,9 @@ another auto-completion with different ac-sources (e.g. ac-php)") (setq offset (+ (current-indentation) web-mode-markup-indent-offset))) (t (setq offset (current-indentation)) + (if (and (string= web-mode-engine "blade") + (string-match-p "@break" curr-line)) + (setq offset (+ (current-indentation) offset))) ) ) ;cond ) @@ -7605,7 +7759,6 @@ another auto-completion with different ac-sources (e.g. ac-php)") (not (string-match-p "^/?>" curr-line)) ;;(progn (message "%S" pos) t) ) - ;;(message "la") (cond ((eq (logand (get-text-property (point) 'tag-attr-beg) 8) 8) (setq offset nil)) @@ -7623,7 +7776,8 @@ another auto-completion with different ac-sources (e.g. ac-php)") ((not (web-mode-tag-beginning)) ) ((string-match-p "^/?>" curr-line) - (setq offset (current-column))) + (setq offset (web-mode-column-at-pos (web-mode-tag-beginning-position pos))) + ) (web-mode-attr-indent-offset (setq offset (+ (current-column) web-mode-attr-indent-offset))) ((looking-at-p (concat web-mode-start-tag-regexp "[ ]*\n")) @@ -7654,33 +7808,6 @@ another auto-completion with different ac-sources (e.g. ac-php)") (setq offset (web-mode-indentation-at-pos parent-tag-pos)) )))) ; when let save-excursion when - ;; (when (and nil web-mode-enable-optional-tags) - ;; (save-excursion - ;; (let (prev-tag-pos next-tag-pos prev-tag next-tag) - ;; (if (get-text-property pos 'tag-type) - ;; (setq next-tag-pos pos) - ;; (setq next-tag-pos (web-mode-tag-next-position pos))) - ;; (setq prev-tag-pos (web-mode-tag-previous-position pos)) - ;; (message "ptp=%S ntp=%S" prev-tag-pos next-tag-pos) - ;; (when (and prev-tag-pos next-tag-pos - ;; (eq (get-text-property prev-tag-pos 'tag-type) 'start) - ;; (eq (get-text-property next-tag-pos 'tag-type) 'start)) - ;; (setq prev-tag (get-text-property prev-tag-pos 'tag-name) - ;; next-tag (get-text-property next-tag-pos 'tag-name)) - ;; ;;(message "%S %S" prev-tag next-tag) - ;; (when (or (and (string= prev-tag "p") (member next-tag '("p" "address", "article", "aside", "blockquote", "div", "dl", "fieldset", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "main", "nav", "ol", "p", "pre", "section", "table", "ul"))) - ;; (and (string= prev-tag "li") (member next-tag '("li"))) - ;; (and (string= prev-tag "dt") (member next-tag '("dt" "dd"))) - ;; (and (string= prev-tag "td") (member next-tag '("td" "th"))) - ;; (and (string= prev-tag "th") (member next-tag '("td" "th"))) - ;; ) - ;; (when debug (message "I205(%S) optional-tag" pos)) - ;; (setq offset (web-mode-indentation-at-pos prev-tag-pos))) - ;; ) ;when - ;; )) ;save-excursion let - ;; ) ;when web-mode-enable-optional-tags - - (when (string= web-mode-engine "closure") (save-excursion (when (and (re-search-backward "{/?switch" nil t) @@ -7733,7 +7860,7 @@ another auto-completion with different ac-sources (e.g. ac-php)") curr-indentation reg-beg))) - ((member language '("lsp" "cl-emb")) + ((member language '("lsp" "cl-emb" "artanis")) (when debug (message "I240(%S) lsp" pos)) (setq offset (web-mode-lisp-indentation pos ctx))) @@ -7922,6 +8049,7 @@ another auto-completion with different ac-sources (e.g. ac-php)") (not (and (eq prev-char ?\:) (string-match-p "^\\(case\\|default\\)" prev-line))) ) + ;;(message "prev=%S" prev-line) (when debug (message "I350(%S) multiline statement" pos)) (let (is-ternary) (setq is-ternary (or (string-match-p "[?:]$" prev-line) @@ -8158,24 +8286,30 @@ another auto-completion with different ac-sources (e.g. ac-php)") (if (>= value 1) (current-indentation) nil) ))) -(defun web-mode-html-indentation (pos) +(defun web-mode-token-html-indentation (pos) (save-excursion - (let (beg (continue t) end level map offset regexp tag val void) + (let (beg (continue t) end level map offset regexp tag val void (css-beg 0)) (goto-char pos) - ;;(message "%S" pos) + ;;(message "pos=%S" pos) (setq beg (web-mode-part-token-beginning-position pos)) + (save-excursion + (when (and (> (- pos beg) 5) + (re-search-backward " css-beg 0) + ;;(message "CSS") + (cond + ((member (char-after) '(?\) ?\} ?\])) + (web-mode-go (web-mode-token-opening-paren-position pos (+ css-beg 8) "")) + (setq offset (current-indentation)) + ) + ((setq level (web-mode-bracket-level pos (+ css-beg 8))) + (setq offset (+ level web-mode-css-indent-offset)) + ) + (t + (setq offset (+ (web-mode-indentation-at-pos css-beg) web-mode-style-padding)) + ) ;t + ) + ) ((looking-at "[a-zA-Z-]+[ ]?=") (re-search-backward "<[a-zA-Z]+[ ]*" beg t) (setq offset (+ (current-column) (length (match-string-no-properties 0)))) @@ -8196,7 +8345,7 @@ another auto-completion with different ac-sources (e.g. ac-php)") (setq offset (current-column)) ) (t - (setq regexp "")) + ) + (mark-active + (setq tag-name (buffer-substring (region-beginning) (region-end))) + (delete-region (region-beginning) (region-end)) + (insert (concat "<" tag-name ">" "")) + (web-mode-sb "" "")) + (web-mode-sb ""))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "artanis")) + (setq content (concat "<%; " sel " %>"))) ((and (= web-mode-comment-style 2) (string= web-mode-engine "aspx")) (setq content (concat "<%-- " sel " --%>"))) ((and (= web-mode-comment-style 2) (string= web-mode-engine "smarty")) @@ -10062,6 +10241,12 @@ Prompt user if TAG-NAME isn't provided." end (web-mode-block-end-position pos)) (web-mode-insert-text-at-pos "#" (+ beg 2)))) +(defun web-mode-comment-artanis-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos ";" (+ beg 2)))) + (defun web-mode-comment-django-block (pos) (let (beg end) (setq beg (web-mode-block-beginning-position pos) @@ -10200,6 +10385,22 @@ Prompt user if TAG-NAME isn't provided." ) ) +(defun web-mode-uncomment-artanis-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (cond + ((string= (buffer-substring-no-properties beg (+ beg 4)) "<%;=") + (web-mode-remove-text-at-pos 1 (+ beg 2))) + ((string-match-p "<[%[:alpha:]]" (buffer-substring-no-properties (+ beg 2) (- end 2))) + (web-mode-remove-text-at-pos 2 (1- end)) + (web-mode-remove-text-at-pos 3 beg)) + (t + (web-mode-remove-text-at-pos 1 (+ beg 2))) + ) ;cond + ) + ) + (defun web-mode-uncomment-ejs-block (pos) (let (beg end) (setq beg (web-mode-block-beginning-position pos) @@ -10341,6 +10542,11 @@ Prompt user if TAG-NAME isn't provided." (indent-region beg end) )) +(defun web-mode-column-at-pos (pos) + (save-excursion + (goto-char pos) + (current-column))) + (defun web-mode-indentation-at-pos (pos) (save-excursion (goto-char pos) @@ -10795,7 +11001,7 @@ Prompt user if TAG-NAME isn't provided." (when (member this-command '(yank)) (setq web-mode-fontification-off nil) - (when (and web-mode-scan-beg web-mode-scan-end) + (when (and web-mode-scan-beg web-mode-scan-end global-font-lock-mode) (save-excursion (font-lock-fontify-region web-mode-scan-beg web-mode-scan-end)) (when web-mode-enable-auto-indentation @@ -11252,6 +11458,7 @@ Prompt user if TAG-NAME isn't provided." ((string= web-mode-engine "lsp") "<% ) %>") ((string= web-mode-engine "erb") "<% } %>") ((string= web-mode-engine "erb") "<% end %>") + ((string= web-mode-engine "artanis") "<% ) %>") ((string= web-mode-engine "hero") "<% } %>") ((string= web-mode-engine "go") "{{end}}") ((string= web-mode-engine "velocity") "#end") @@ -11917,9 +12124,13 @@ Prompt user if TAG-NAME isn't provided." (setq pos (1- pos)) ) ((and (> ori pos) (member char '(?\( ?\= ?\[ ?\? ?\: ?\; ?\, ?\`))) - (setq continue nil) - (web-mode-looking-at ".[ \t\n]*" pos) - (setq pos (+ pos (length (match-string-no-properties 0)))) + (if (and (eq char ?\:) ; #1024 + (web-mode-looking-at ":" pos)) + (setq pos (1- pos)) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))) + continue nil) + ) ) ((web-mode-looking-at "\\(return\\|echo\\|include\\|print\\)[ \n]" pos) (setq pos (+ pos (length (match-string-no-properties 0))) diff --git a/packages/websocket-20180423.16.el b/packages/websocket-20190621.54.el similarity index 92% rename from packages/websocket-20180423.16.el rename to packages/websocket-20190621.54.el index ccc7d8a..47a5928 100644 --- a/packages/websocket-20180423.16.el +++ b/packages/websocket-20190621.54.el @@ -4,8 +4,8 @@ ;; Author: Andrew Hyatt ;; Keywords: Communication, Websocket, Server -;; Package-Version: 20180423.16 -;; Version: 1.9 +;; Package-Version: 20190621.54 +;; Version: 1.11.1 ;; Package-Requires: ((cl-lib "0.5")) ;; ;; This program is free software; you can redistribute it and/or @@ -47,6 +47,7 @@ (require 'bindat) (require 'url-parse) (require 'url-cookie) +(require 'seq) (eval-when-compile (require 'cl-lib)) ;;; Code: @@ -100,7 +101,7 @@ same for the protocols." accept-string (inflight-input nil)) -(defvar websocket-version "1.9" +(defvar websocket-version "1.11.1" "Version numbers of this version of websocket.el.") (defvar websocket-debug nil @@ -195,15 +196,15 @@ power of 2, up to 8. We support getting frames up to 536870911 bytes (2^29 - 1), approximately 537M long." (if (= n 8) - (let* ((32-bit-parts - (bindat-get-field (bindat-unpack '((:val vec 2 u32)) s) :val)) - (cval - (logior (lsh (aref 32-bit-parts 0) 32) (aref 32-bit-parts 1)))) - (if (and (= (aref 32-bit-parts 0) 0) - (= (lsh (aref 32-bit-parts 1) -29) 0)) - cval - (signal 'websocket-unparseable-frame - "Frame value found too large to parse!"))) + (let* ((32-bit-parts + (bindat-get-field (bindat-unpack '((:val vec 2 u32)) s) :val)) + (cval + (logior (lsh (aref 32-bit-parts 0) 32) (aref 32-bit-parts 1)))) + (if (and (= (aref 32-bit-parts 0) 0) + (= (lsh (aref 32-bit-parts 1) -29) 0)) + cval + (signal 'websocket-unparseable-frame + (list "Frame value found too large to parse!")))) ;; n is not 8 (bindat-get-field (condition-case _ @@ -218,7 +219,7 @@ approximately 537M long." "websocket-get-bytes: Unknown N: %S" n))))) s) (args-out-of-range (signal 'websocket-unparseable-frame - (format "Frame unexpectedly shortly: %s" s)))) + (list (format "Frame unexpectedly short: %s" s))))) :val))) (defun websocket-to-bytes (val nbytes) @@ -239,7 +240,7 @@ approximately 537M long." ;; This is just VAL on systems that don't have >= 32 bits. (low-32bits (- val (lsh hi-32bits 32)))) (when (or (> hi-32bits 0) (> (lsh low-32bits -29) 0)) - (signal 'websocket-frame-too-large val)) + (signal 'websocket-frame-too-large (list val))) (bindat-pack `((:val vec 2 u32)) `((:val . [,hi-32bits ,low-32bits]))))) (bindat-pack @@ -253,7 +254,7 @@ approximately 537M long." (defun websocket-get-opcode (s) "Retrieve the opcode from first byte of string S." (websocket-ensure-length s 1) - (let ((opcode (logand #xf (websocket-get-bytes s 1)))) + (let ((opcode (logand #xf (aref s 0)))) (cond ((= opcode 0) 'continuation) ((= opcode 1) 'text) ((= opcode 2) 'binary) @@ -266,7 +267,7 @@ approximately 537M long." We start at position 0, and return a cons of the payload length and how many bytes were consumed from the string." (websocket-ensure-length s 1) - (let* ((initial-val (logand 127 (websocket-get-bytes s 1)))) + (let* ((initial-val (logand 127 (aref s 0)))) (cond ((= initial-val 127) (websocket-ensure-length s 9) (cons (websocket-get-bytes (substring s 1) 8) 9)) @@ -285,17 +286,13 @@ many bytes were consumed from the string." (defun websocket-mask (key data) "Using string KEY, mask string DATA according to the RFC. This is used to both mask and unmask data." - ;; If we don't make the string unibyte here, a string of bytes that should be - ;; interpreted as a unibyte string will instead be interpreted as a multibyte - ;; string of the same length (for example, 6 multibyte chars for 你好 instead - ;; of the correct 6 unibyte chars, which would convert into 2 multibyte - ;; chars). - (apply - #'unibyte-string - (cl-loop for b across data - for i from 0 to (length data) - collect - (logxor (websocket-get-bytes (substring key (mod i 4)) 1) b)))) + ;; Returning the string as unibyte is important here. Because we set the + ;; string byte by byte, this results in a unibyte string. + (cl-loop + with result = (make-string (length data) ?x) + for i from 0 below (length data) + do (setf (seq-elt result i) (logxor (aref key (mod i 4)) (seq-elt data i))) + finally return result)) (defun websocket-ensure-length (s n) "Ensure the string S has at most N bytes. @@ -352,13 +349,13 @@ the frame finishes. If the frame is not completed, return NIL." (catch 'websocket-incomplete-frame (websocket-ensure-length s 1) (let* ((opcode (websocket-get-opcode s)) - (fin (logand 128 (websocket-get-bytes s 1))) + (fin (logand 128 (aref s 0))) (payloadp (memq opcode '(continuation text binary ping pong))) (payload-len (when payloadp (websocket-get-payload-len (substring s 1)))) (maskp (and payloadp - (= 128 (logand 128 (websocket-get-bytes (substring s 1) 1))))) + (= 128 (logand 128 (aref s 1))))) (payload-start (when payloadp (+ (if maskp 5 1) (cdr payload-len)))) (payload-end (when payloadp (+ payload-start (car payload-len)))) (unmasked-payload (when payloadp @@ -461,10 +458,10 @@ The only acceptable one to websocket is responce code 101. A t value will be returned on success, and an error thrown if not." (unless (string-match "^HTTP/1.1 \\([[:digit:]]+\\)" output) - (signal 'websocket-invalid-header "Invalid HTTP status line")) + (signal 'websocket-invalid-header (list "Invalid HTTP status line"))) (unless (equal "101" (match-string 1 output)) (signal 'websocket-received-error-http-response - (string-to-number (match-string 1 output)))) + (list (string-to-number (match-string 1 output))))) t) (defun websocket-parse-repeated-field (output field) @@ -556,21 +553,19 @@ The frame may be too large for this buid of Emacs, in which case size of the frame which was too large to process. This also has the `websocket-error' condition." (unless (websocket-check frame) - (signal 'websocket-illegal-frame frame)) + (signal 'websocket-illegal-frame (list frame))) (websocket-debug websocket "Sending frame, opcode: %s payload: %s" (websocket-frame-opcode frame) (websocket-frame-payload frame)) (websocket-ensure-connected websocket) (unless (websocket-openp websocket) - (signal 'websocket-closed frame)) + (signal 'websocket-closed (list frame))) (process-send-string (websocket-conn websocket) ;; We mask only when we're a client, following the spec. (websocket-encode-frame frame (not (websocket-server-p websocket))))) (defun websocket-openp (websocket) - ;; FIXME: "open and either connecting or open"? I don't understand. --Stef - "Check WEBSOCKET and return non-nil if it is open, and either -connecting or open." + "Check WEBSOCKET and return non-nil if the connection is open." (and websocket (not (eq 'close (websocket-ready-state websocket))) (member (process-status (websocket-conn websocket)) '(open run)))) @@ -606,9 +601,9 @@ connecting or open." ;;;;;;;;;;;;;;;;;;;;;; (cl-defun websocket-open (url &key protocols extensions (on-open 'identity) - (on-message (lambda (_w _f))) (on-close 'identity) - (on-error 'websocket-default-error-handler) - (nowait nil) (custom-header-alist nil)) + (on-message (lambda (_w _f))) (on-close 'identity) + (on-error 'websocket-default-error-handler) + (nowait nil) (custom-header-alist nil)) "Open a websocket connection to URL, returning the `websocket' struct. The PROTOCOL argument is optional, and setting it will declare to the server that this client supports the protocols in the list @@ -699,14 +694,14 @@ to the websocket protocol. (if (eq type 'tls) 443 80) (url-port url-struct))) (host (url-host url-struct))) - (if (eq type 'plain) - (make-network-process :name name :buffer nil :host host - :service port :nowait nowait) - (condition-case-unless-debug nil - (open-network-stream name nil host port :type type :nowait nowait) - (wrong-number-of-arguments - (signal 'websocket-wss-needs-emacs-24 "wss"))))) - (signal 'websocket-unsupported-protocol (url-type url-struct)))) + (if (eq type 'plain) + (make-network-process :name name :buffer nil :host host + :service port :nowait nowait) + (condition-case-unless-debug nil + (open-network-stream name nil host port :type type :nowait nowait) + (wrong-number-of-arguments + (signal 'websocket-wss-needs-emacs-24 (list "wss")))))) + (signal 'websocket-unsupported-protocol (list (url-type url-struct))))) (websocket (websocket-inner-create :conn conn :url url @@ -789,7 +784,8 @@ connection is invalid, the connection will be closed." (websocket-process-headers (websocket-url websocket) text)) (error (websocket-close websocket) - (signal (car err) (cdr err)))) + (funcall (websocket-on-error websocket) + websocket 'on-open err))) (setf (websocket-ready-state websocket) 'open) (websocket-try-callback 'websocket-on-open 'on-open websocket)) (setf (websocket-inflight-input websocket) text))) @@ -807,16 +803,16 @@ of populating the list of server extensions to WEBSOCKET." (websocket-debug websocket "Checking for accept header: %s" accept-string) (unless (string-match (regexp-quote accept-string) output) (signal 'websocket-invalid-header - "Incorrect handshake from websocket: is this really a websocket connection?"))) + (list "Incorrect handshake from websocket: is this really a websocket connection?")))) (let ((case-fold-search t)) (websocket-debug websocket "Checking for upgrade header") (unless (string-match "\r\nUpgrade: websocket\r\n" output) (signal 'websocket-invalid-header - "No 'Upgrade: websocket' header found")) + (list "No 'Upgrade: websocket' header found"))) (websocket-debug websocket "Checking for connection header") (unless (string-match "\r\nConnection: upgrade\r\n" output) (signal 'websocket-invalid-header - "No 'Connection: upgrade' header found")) + (list "No 'Connection: upgrade' header found"))) (when (websocket-protocols websocket) (dolist (protocol (websocket-protocols websocket)) (websocket-debug websocket "Checking for protocol match: %s" @@ -827,7 +823,7 @@ of populating the list of server extensions to WEBSOCKET." output) (list protocol) (signal 'websocket-invalid-header - "Incorrect or missing protocol returned by the server.")))) + (list "Incorrect or missing protocol returned by the server."))))) (setf (websocket-negotiated-protocols websocket) protocols)))) (let* ((extensions (websocket-parse-repeated-field output @@ -840,8 +836,8 @@ of populating the list of server extensions to WEBSOCKET." (push x extra-extensions)))) (when extra-extensions (signal 'websocket-invalid-header - (format "Non-requested extensions returned by server: %S" - extra-extensions))) + (list (format "Non-requested extensions returned by server: %S" + extra-extensions)))) (setf (websocket-negotiated-extensions websocket) extensions))) t) @@ -914,13 +910,13 @@ connection, which should be kept in order to pass to (process-put client :websocket ws) (set-process-coding-system client 'binary 'binary) (set-process-sentinel client - (lambda (process change) - (let ((websocket (process-get process :websocket))) - (websocket-debug websocket "State change to %s" change) - (when (and - (member (process-status process) '(closed failed exit signal)) - (not (eq 'closed (websocket-ready-state websocket)))) - (websocket-try-callback 'websocket-on-close 'on-close websocket))))))) + (lambda (process change) + (let ((websocket (process-get process :websocket))) + (websocket-debug websocket "State change to %s" change) + (when (and + (member (process-status process) '(closed failed exit signal)) + (not (eq 'closed (websocket-ready-state websocket)))) + (websocket-try-callback 'websocket-on-close 'on-close websocket))))))) (defun websocket-create-headers (url key protocol extensions custom-headers-alist) "Create connections headers for the given URL, KEY, PROTOCOL, and EXTENSIONS. diff --git a/packages/wgrep-20180711.626.el b/packages/wgrep-20181229.40.el similarity index 77% rename from packages/wgrep-20180711.626.el rename to packages/wgrep-20181229.40.el index e41b32d..1d12dd3 100644 --- a/packages/wgrep-20180711.626.el +++ b/packages/wgrep-20181229.40.el @@ -2,10 +2,10 @@ ;; Author: Masahiro Hayashi ;; Keywords: grep edit extensions -;; Package-Version: 20180711.626 +;; Package-Version: 20181229.40 ;; URL: http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep.el -;; Emacs: GNU Emacs 22 or later -;; Version: 2.2.0 +;; Emacs: GNU Emacs 25 or later +;; Version: 2.3.0 ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as @@ -27,46 +27,46 @@ ;; wgrep allows you to edit a grep buffer and apply those changes to ;; the file buffer. -;;; Install: +;; ## Install: ;; Put this file into load-path'ed directory, and byte compile it if ;; desired. And put the following expression into your ~/.emacs. ;; ;; (require 'wgrep) -;;; Usage: +;; ## Usage: -;; You can edit the text in the *grep* buffer after typing C-c C-p. +;; You can edit the text in the *grep* buffer after typing `C-c C-p` . ;; After that the changed text is highlighted. ;; The following keybindings are defined: -;; C-c C-e : Apply the changes to file buffers. -;; C-c C-u : All changes are unmarked and ignored. -;; C-c C-d : Mark as delete to current line (including newline). -;; C-c C-r : Remove the changes in the region (these changes are not -;; applied to the files. Of course, the remaining -;; changes can still be applied to the files.) -;; C-c C-p : Toggle read-only area. -;; C-c C-k : Discard all changes and exit. -;; C-x C-q : Exit wgrep mode. +;; * `C-c C-e`: Apply the changes to file buffers. +;; * `C-c C-u`: All changes are unmarked and ignored. +;; * `C-c C-d`: Mark as delete to current line (including newline). +;; * `C-c C-r`: Remove the changes in the region (these changes are not +;; applied to the files. Of course, the remaining +;; changes can still be applied to the files.) +;; * `C-c C-p`: Toggle read-only area. +;; * `C-c C-k`: Discard all changes and exit. +;; * `C-x C-q`: Exit wgrep mode. ;; * To save all buffers that wgrep has changed, run ;; -;; M-x wgrep-save-all-buffers +;; M-x wgrep-save-all-buffers ;; * To save buffer automatically when `wgrep-finish-edit'. ;; -;; (setq wgrep-auto-save-buffer t) +;; (setq wgrep-auto-save-buffer t) ;; * You can change the default key binding to switch to wgrep. ;; -;; (setq wgrep-enable-key "r") +;; (setq wgrep-enable-key "r") ;; * To apply all changes wheather or not buffer is read-only. ;; -;; (setq wgrep-change-readonly-file t) +;; (setq wgrep-change-readonly-file t) -;;; History: +;; ## History: ;; This program is a forked version. the original version can be downloaded from ;; http://www.bookshelf.jp/elc/grep-edit.el @@ -94,6 +94,14 @@ :prefix "wgrep-" :group 'grep) +;;; +;;; Variable / Constant +;;; + +;; +;; Customize +;; + (defcustom wgrep-change-readonly-file nil "Non-nil means to enable change read-only files." :group 'wgrep @@ -106,73 +114,23 @@ Key to enable `wgrep-mode'." :type 'string) (defcustom wgrep-auto-save-buffer nil - "Non-nil means do `save-buffer' automatically while `wgrep-finish-edit'." + "Non-nil means do `basic-save-buffer' automatically while `wgrep-finish-edit'." :group 'wgrep :type 'boolean) +(defcustom wgrep-too-many-file-length 10 + "Number to detect as too many files." + :group 'wgrep + :type 'number) + (defvar wgrep-setup-hook nil "Hooks to run when setting up wgrep.") -(defface wgrep-face - '((((class color) - (background dark)) - (:background "SlateGray1" :foreground "Black")) - (((class color) - (background light)) - (:background "ForestGreen" :foreground "white")) - (t - ())) - "*Face used for the changed text in the grep buffer." - :group 'wgrep) - -(defface wgrep-delete-face - '((((class color) - (background dark)) - (:background "SlateGray1" :foreground "pink")) - (((class color) - (background light)) - (:background "ForestGreen" :foreground "pink")) - (t - ())) - "*Face used for the deleted whole line in the grep buffer." - :group 'wgrep) - -(defface wgrep-file-face - '((((class color) - (background dark)) - (:background "gray30" :foreground "white")) - (((class color) - (background light)) - (:background "ForestGreen" :foreground "white")) - (t - ())) - "*Face used for the changed text in the file buffer." - :group 'wgrep) - -(defface wgrep-reject-face - '((((class color) - (background dark)) - (:foreground "HotPink" :weight bold)) - (((class color) - (background light)) - (:foreground "Red" :weight bold)) - (t - ())) - "*Face used for the line in the grep buffer that can not be applied to -a file." - :group 'wgrep) +(defvar wgrep-mode-map nil) -(defface wgrep-done-face - '((((class color) - (background dark)) - (:foreground "LightSkyBlue")) - (((class color) - (background light)) - (:foreground "Blue")) - (t - ())) - "*Face used for the line in the grep buffer that can be applied to a file." - :group 'wgrep) +;; +;; Internal variable +;; (defvar wgrep-readonly-state nil) (make-variable-buffer-local 'wgrep-readonly-state) @@ -186,12 +144,21 @@ a file." (defvar wgrep-original-mode-map nil) (make-variable-buffer-local 'wgrep-original-mode-map) +(defvar wgrep-inhibit-modification-hook nil) + +(defvar wgrep-auto-apply-disk nil + "Internal use `wgrep-auto-save-buffer' or too many file is editing.") + +(defvar wgrep-acceptable-modes nil) +(make-obsolete 'wgrep-acceptable-modes nil "2.1.1") + ;; Suppress elint warning ;; GNU Emacs have this variable at least version 21 or later (defvar auto-coding-regexp-alist) -(defvar wgrep-acceptable-modes nil) -(make-obsolete 'wgrep-acceptable-modes nil "2.1.1") +;; +;; Constant +;; ;; These regexp come from `grep-regexp-alist' at grep.el (eval-and-compile @@ -215,157 +182,95 @@ a file." wgrep-colon-file-separator-header-regexp "\\)"))) +;; +;; Error +;; + +(define-error 'wgrep-error "wgrep error") + +;; +;; Overridable functions / regexp +;; + (defvar wgrep-line-file-regexp wgrep-default-line-header-regexp "Regexp that match to line header of grep result. That capture 1: filename 3: line-number End of this match equals start of file contents. ") -(defvar wgrep-results-parser 'wgrep-parse-command-results) -(defvar wgrep-header/footer-parser 'wgrep-prepare-header/footer) - -(defvar wgrep-inhibit-modification-hook nil) -(defvar wgrep-mode-map nil) -(unless wgrep-mode-map - (let ((map (make-sparse-keymap))) +(defvar wgrep-results-parser 'wgrep-parse-command-results + "This function parse line oriented command output and set following properties. +`wgrep-line-filename', `wgrep-line-number', `wgrep-ignore' and +`wgrep-construct-filename-property' function construct the property name with +`wgrep-line-filename' and the value is same. This property is used for searching + correct point of filename. +Not like `wgrep-header/footer-parser' should not set `read-only' property.") - (define-key map "\C-c\C-c" 'wgrep-finish-edit) - (define-key map "\C-c\C-d" 'wgrep-mark-deletion) - (define-key map "\C-c\C-e" 'wgrep-finish-edit) - (define-key map "\C-c\C-p" 'wgrep-toggle-readonly-area) - (define-key map "\C-c\C-r" 'wgrep-remove-change) - (define-key map "\C-x\C-s" 'wgrep-finish-edit) - (define-key map "\C-c\C-u" 'wgrep-remove-all-change) - (define-key map "\C-c\C-[" 'wgrep-remove-all-change) - (define-key map "\C-c\C-k" 'wgrep-abort-changes) - (define-key map "\C-x\C-q" 'wgrep-exit) +(defvar wgrep-header/footer-parser 'wgrep-prepare-header/footer + "This function should set text properties `read-only' and `wgrep-header' to +non editable region.") - (setq wgrep-mode-map map))) +;;; +;;; Basic utilities +;;; -;;;###autoload -(defun wgrep-setup () - "Setup wgrep preparation." - (cond - ((and (boundp 'grep-use-null-filename-separator) - grep-use-null-filename-separator - ;; FIXME: command may contain "--null" text in search text - ;; (e.g. grep -nH -e "searching --null argument") - ;; `grep-use-null-filename-separator' is non-nil - ;; enough to reduce that confusion. - (let ((command (car-safe compilation-arguments))) - (and (stringp command) - (string-match "[\s\t]--null[\s\t]" command)))) - (set (make-local-variable 'wgrep-line-file-regexp) - wgrep-null-file-separator-header-regexp)) - (t - (set (make-local-variable 'wgrep-line-file-regexp) - wgrep-colon-file-separator-header-regexp))) - (wgrep-setup-internal)) +;; +;; misc +;; -(defun wgrep-setup-internal () - (setq wgrep-original-mode-map (current-local-map)) - (define-key wgrep-original-mode-map - wgrep-enable-key 'wgrep-change-to-wgrep-mode) - ;; delete previous wgrep overlays - (wgrep-cleanup-overlays (point-min) (point-max)) - (remove-hook 'post-command-hook 'wgrep-maybe-echo-error-at-point t) - (run-hooks 'wgrep-setup-hook)) +;;Hack function +(defun wgrep-string-replace-bom (string cs) + (let ((regexp (car (rassq (coding-system-base cs) auto-coding-regexp-alist))) + ;;TODO check ack-grep + ;; FIXME: `find-operation-coding-system' is not exactly correct. + ;; However almost case is ok like this bom function. + ;; e.g. (let ((default-process-coding-system 'some-coding)) + ;; (call-interactively 'grep)) + (grep-cs (or (find-operation-coding-system 'call-process grep-program) + (terminal-coding-system))) + str) + (if (and regexp + (setq str (encode-coding-string string grep-cs)) + (string-match regexp str)) + (decode-coding-string (substring str (match-end 0)) cs) + string))) -(defun wgrep-maybe-echo-error-at-point () - (when (null (current-message)) - (let ((ov (catch 'found - (dolist (o (overlays-in - (line-beginning-position) (line-end-position))) - (when (overlay-get o 'wgrep-reject-message) - (throw 'found o)))))) - (when ov - (let (message-log-max) - (message "%s" (overlay-get ov 'wgrep-reject-message))))))) +(defun wgrep-delete-whole-line () + (delete-region (point-at-bol) (point-at-bol 2))) -(defun wgrep-set-readonly-area (state) - (let ((inhibit-read-only t) - (wgrep-inhibit-modification-hook t) - pos start end) - (save-excursion - ;; set readonly grep result filename - (setq pos (point-min)) - (while (setq start (next-single-property-change - pos 'wgrep-line-filename)) - (setq end (next-single-property-change - start 'wgrep-line-filename)) - (put-text-property start end 'read-only state) - (put-text-property (1- end) end 'rear-nonsticky t) - ;; set readonly all newline at end of grep line - (when (eq (char-before start) ?\n) - (put-text-property (1- start) start 'read-only state)) - (setq pos end)) - (setq pos (point-min)) - (while (setq start (next-single-property-change - pos 'wgrep-ignore)) - (setq end (next-single-property-change - start 'wgrep-ignore)) - (put-text-property start end 'read-only state) - ;; set readonly all newline at end of grep line - (when (eq (char-before start) ?\n) - (put-text-property (1- start) start 'read-only state)) - (setq pos end)) - ;; set readonly last of grep line - (let ((footer (or (next-single-property-change (point-min) 'wgrep-footer) - ;; to consider empty footer. - (point-max)))) - (when (eq (char-before footer) ?\n) - (put-text-property (1- footer) footer 'read-only state)))) - (setq wgrep-readonly-state state))) +(defun wgrep-goto-line (line) + (goto-char (point-min)) + (forward-line (1- line))) -(defun wgrep-after-change-function (beg end leng-before) - (cond - (wgrep-inhibit-modification-hook nil) - ((= (point-min) (point-max)) - ;; cleanup when first executing - (wgrep-cleanup-overlays (point-min) (point-max))) - (t - (wgrep-put-change-face beg end)))) +(defun wgrep-process-exited-p () + (let ((proc (get-buffer-process (current-buffer)))) + (or (null proc) + (eq (process-status proc) 'exit)))) -(put 'wgrep-error 'error-conditions '(wgrep-error error)) -(put 'wgrep-error 'error-message "wgrep error") +;; +;; error +;; -(defun wgrep-get-file-buffer (file) +(defun wgrep-check-file (file) (unless (file-exists-p file) (signal 'wgrep-error (list "File does not exist."))) (unless (file-writable-p file) - (signal 'wgrep-error (list "File is not writable."))) - (or (get-file-buffer file) - (find-file-noselect file))) - -(defun wgrep-check-buffer () - "Check the file's status. If it is possible to change the file, return t" - (when (and (not wgrep-change-readonly-file) - buffer-read-only) - (signal 'wgrep-error - (list (format "Buffer \"%s\" is read-only." (buffer-name)))))) + (signal 'wgrep-error (list "File is not writable.")))) -(defun wgrep-display-physical-data () - (cond - ;; `funcall' is a trick to suppress the elint warnings. - ((derived-mode-p 'image-mode) - ;; toggle to raw data if buffer has image. - (when (image-get-display-property) - (image-mode-as-text))) - (t nil))) +;; +;; overlay +;; -(defun wgrep-let-destructive-overlay (ov) - (dolist (prop '(modification-hooks insert-in-front-hooks insert-behind-hooks)) - (overlay-put - ov prop - `((lambda (ov after-p &rest ignore) - (when after-p - (delete-overlay ov))))))) +(defun wgrep-cleanup-overlays (beg end) + (dolist (ov (overlays-in beg end)) + (when (overlay-get ov 'wgrep) + (delete-overlay ov)))) -(defun wgrep-after-save-hook () - (remove-hook 'after-save-hook 'wgrep-after-save-hook t) - (dolist (ov (wgrep-file-overlays)) - (delete-overlay ov))) +(defun wgrep-make-overlay (beg end) + (let ((o (make-overlay beg end nil nil t))) + (overlay-put o 'wgrep t) + o)) (defun wgrep-file-overlays () (save-restriction @@ -376,140 +281,62 @@ End of this match equals start of file contents. (setq res (cons ov res)))) (nreverse res)))) -(defun wgrep-replace-to-new-line (new-text) - ;; delete grep extracted region (restricted to a line) - (delete-region (line-beginning-position) (line-end-position)) - (let ((beg (point)) - end) - (insert new-text) - (let* ((end (point)) - ;; hilight the changed line - (ov (wgrep-put-overlay-to-file-buffer beg end))) - ;; make overlay volatile. - (wgrep-let-destructive-overlay ov)))) +(defun wgrep-edit-field-overlays () + (let (res) + (dolist (ov (overlays-in (point-min) (point-max))) + (when (overlay-get ov 'wgrep-changed) + (setq res (cons ov res)))) + (sort res (lambda (x y) (< (overlay-start x) (overlay-start y)))))) -(defun wgrep-flush-whole-line () - (wgrep-put-overlay-to-file-buffer - (line-beginning-position) (line-end-position)) - (wgrep-delete-whole-line)) - -;;Hack function -(defun wgrep-string-replace-bom (string cs) - (let ((regexp (car (rassq (coding-system-base cs) auto-coding-regexp-alist))) - ;;TODO check ack-grep - ;; FIXME: `find-operation-coding-system' is not exactly correct. - ;; However almost case is ok like this bom function. - ;; e.g. (let ((default-process-coding-system 'some-coding)) - ;; (call-interactively 'grep)) - (grep-cs (or (find-operation-coding-system 'call-process grep-program) - (terminal-coding-system))) - str) - (if (and regexp - (setq str (encode-coding-string string grep-cs)) - (string-match regexp str)) - (decode-coding-string (substring str (match-end 0)) cs) - string))) - -(defun wgrep-put-overlay-to-file-buffer (beg end) - "*Highlight the changes in the file" - (let ((ov - (catch 'done - (dolist (o (overlays-in beg end)) - (when (overlay-get o 'wgrep) - (move-overlay o beg end) - (throw 'done o))) - (wgrep-make-overlay beg end)))) - (overlay-put ov 'face 'wgrep-file-face) - (overlay-put ov 'priority 0) - (add-hook 'after-save-hook 'wgrep-after-save-hook nil t) - ov)) +;;; +;;; grep result handler +;;; -(defun wgrep-put-done-result (ov) - (wgrep-set-result ov 'wgrep-done-face)) +(defun wgrep-construct-filename-property (filename) + (intern (format "wgrep-fn-%s" filename))) -(defun wgrep-put-reject-result (ov error-data) - (let ((message (mapconcat (lambda (x) (format "%s" x)) error-data " "))) - (wgrep-set-result ov 'wgrep-reject-face message))) +(defun wgrep-goto-grep-line (file number) + (let ((first (point)) + (fprop (wgrep-construct-filename-property file)) + fn next) + (catch 'found + ;; FIXME + ;; In a huge buffer, `next-single-property-change' loop make + ;; slow down the program. + ;; 1. sketchy move by filename (wgrep-fn-* property). + ;; 2. search filename and line-number in text property. + ;; 3. return to 1. while search is done or EOB. -(defun wgrep-set-result (ov face &optional message) - (overlay-put ov 'face face) - (overlay-put ov 'priority 1) - (overlay-put ov 'wgrep-reject-message message)) + (goto-char (point-min)) -(defun wgrep-edit-overlays () - (let (res) - (dolist (ov (overlays-in (point-min) (point-max))) - (when (overlay-get ov 'wgrep-changed) - (setq res (cons ov res)))) - (nreverse res))) + (while (setq next (next-single-property-change (point) fprop)) + (goto-char next) + (while (and (not (eobp)) + (or (null (setq fn (get-text-property + (point-at-bol) + 'wgrep-line-filename))) + (string= fn file))) + (when fn + (let ((num (get-text-property (point) 'wgrep-line-number)) + (start (next-single-property-change (point) 'wgrep-line-number))) + (when (eq number num) + (goto-char start) + (throw 'found t)))) + (forward-line 1))) + (goto-char first) + nil))) -(defun wgrep-put-change-face (beg end) - (save-excursion - ;; `looking-at' may destroy match data while replace by regexp. - (save-match-data - (let ((ov (wgrep-editing-overlay beg end))) - ;; delete overlay if text is same as old value. - (cond - ;; not a valid point - ((null ov)) - ((string= (overlay-get ov 'wgrep-old-text) - (overlay-get ov 'wgrep-edit-text)) - ;; back to unchanged - (delete-overlay ov)) - (t - (overlay-put ov 'face 'wgrep-face))))))) +(defun wgrep-get-old-text (file number) + (when (and wgrep-sibling-buffer + (buffer-live-p wgrep-sibling-buffer)) + (with-current-buffer wgrep-sibling-buffer + (when (wgrep-goto-grep-line file number) + (buffer-substring-no-properties + (point) (point-at-eol)))))) -;; get overlay BEG and END is passed by `after-change-functions' -(defun wgrep-editing-overlay (&optional start end) - (let ((beg (or start (line-beginning-position))) - (fin (or end (line-end-position))) - ov bol eol - ;; beginning/end of grep - bog eog) - (goto-char beg) - (setq bol (line-beginning-position)) - (goto-char fin) - (setq eol (line-end-position)) - (catch 'done - (dolist (o (overlays-in bol eol)) - ;; find overlay that have changed by user. - (when (overlay-get o 'wgrep-changed) - (setq ov o) - (throw 'done o)))) - (if ov - (setq bog (min beg (overlay-start ov)) - eog (max (overlay-end ov) fin)) - (setq bog bol - eog eol)) - (goto-char bog) - (cond - ;; When handling whole line, BOL equal beginning of edit. - ((and (null ov) start (= bog start))) - ((get-text-property (point) 'wgrep-line-filename) - (let* ((header-end - (next-single-property-change (point) 'wgrep-line-filename nil eol)) - (filename (get-text-property (point) 'wgrep-line-filename)) - (linum (get-text-property (point) 'wgrep-line-number)) - (value (buffer-substring-no-properties header-end eog)) - contents-begin) - (goto-char header-end) - (setq contents-begin (point-marker)) - ;; create editing overlay - (cond - ((null ov) - (let ((old (wgrep-get-old-text filename linum))) - (setq ov (wgrep-make-overlay bog eog)) - (overlay-put ov 'wgrep-contents-begin contents-begin) - (overlay-put ov 'wgrep-filename filename) - (overlay-put ov 'wgrep-linum linum) - (overlay-put ov 'wgrep-changed t) - (overlay-put ov 'priority 0) - (overlay-put ov 'evaporate t) - (overlay-put ov 'wgrep-old-text old))) - (t - (move-overlay ov bog eog))) - (overlay-put ov 'wgrep-edit-text value)))) - ov)) +;;; +;;; Prepare and parse grep <-> wgrep +;;; (defun wgrep-to-original-mode () (kill-local-variable 'query-replace-skip-read-only) @@ -521,145 +348,80 @@ End of this match equals start of file contents. (setq buffer-undo-list nil) (setq buffer-read-only t)) -(defun wgrep-finish-edit () - "Apply changes to file buffers. -These changes are not immediately saved to disk unless -`wgrep-auto-save-buffer' is non-nil." - (interactive) - (let ((all-tran (wgrep-compute-transaction)) - done) - (dolist (buf-tran all-tran) - (let ((commited (wgrep-commit-buffer (car buf-tran) (cdr buf-tran)))) - (setq done (append done commited)))) - (wgrep-cleanup-temp-buffer) - (wgrep-to-original-mode) - (let ((msg (format "(%d changed)" (length done))) - (ovs (wgrep-edit-overlays))) - (cond - ((null ovs) - (if (= (length done) 0) - (message "(No changes to be performed)") - (message "Successfully finished. %s" msg))) - ((= (length ovs) 1) - (message "There is an unapplied change. %s" msg)) - (t - (message "There are %d unapplied changes. %s" - (length ovs) msg)))))) - -(defun wgrep-exit () - "Return to original mode." - (interactive) - (if (and (buffer-modified-p) - (y-or-n-p (format "Buffer %s modified; save changes? " - (current-buffer)))) - (wgrep-finish-edit) - (wgrep-abort-changes))) - -(defun wgrep-abort-changes () - "Discard all changes and return to original mode." - (interactive) - (wgrep-cleanup-overlays (point-min) (point-max)) - (wgrep-restore-from-temp-buffer) - (wgrep-to-original-mode) - (message "Changes discarded")) - -(defun wgrep-remove-change (beg end) - "Remove changes in the region between BEG and END." - (interactive "r") - (wgrep-cleanup-overlays beg end) - (setq mark-active nil)) - -(defun wgrep-remove-all-change () - "Remove changes in the whole buffer." - (interactive) - (wgrep-cleanup-overlays (point-min) (point-max))) - -(defun wgrep-toggle-readonly-area () - "Toggle read-only area to remove a whole line. - -See the following example: you obviously don't want to edit the first line. -If grep matches a lot of lines, it's hard to edit the grep buffer. -After toggling to editable, you can call -`delete-matching-lines', `delete-non-matching-lines'. - -Example: ----------------------------------------------- -./.svn/text-base/some.el.svn-base:87:(hoge) -./some.el:87:(hoge) ----------------------------------------------- -" - (interactive) - (let ((modified (buffer-modified-p)) - (read-only (not wgrep-readonly-state))) - (wgrep-set-readonly-area read-only) - (wgrep-set-header/footer-read-only read-only) - (set-buffer-modified-p modified) - (if wgrep-readonly-state - (message "Removing the whole line is now disabled.") - (message "Removing the whole line is now enabled.")))) - -(defun wgrep-change-to-wgrep-mode () - "Change to wgrep mode. - -When the *grep* buffer is huge, this might freeze your Emacs -for several minutes. -" - (interactive) - (unless (wgrep-process-exited-p) - (error "Active process working")) - (wgrep-prepare-to-edit) - (wgrep-set-readonly-area t) - (set (make-local-variable 'query-replace-skip-read-only) t) - (add-hook 'after-change-functions 'wgrep-after-change-function nil t) - (add-hook 'post-command-hook 'wgrep-maybe-echo-error-at-point nil t) - (use-local-map wgrep-mode-map) - (buffer-disable-undo) - (wgrep-clone-to-temp-buffer) - (setq buffer-read-only nil) - (buffer-enable-undo) - ;; restore modified status - (set-buffer-modified-p (wgrep-edit-overlays)) - (setq buffer-undo-list nil) - (message "%s" (substitute-command-keys - "Press \\[wgrep-finish-edit] when finished \ -or \\[wgrep-abort-changes] to abort changes."))) +(defun wgrep-goto-first-found () + (let ((header (previous-single-property-change (point-max) 'wgrep-header))) + (cond + (header + (goto-char header) + header) + (t + (goto-char (point-min)) + (point))))) -(defun wgrep-save-all-buffers () - "Save the buffers that wgrep changed." - (interactive) - (let ((count 0)) - (dolist (b (buffer-list)) - (with-current-buffer b - (let ((ovs (wgrep-file-overlays))) - (when (and ovs (buffer-modified-p)) - (basic-save-buffer) - (setq count (1+ count)))))) +(defun wgrep-goto-end-of-found () + (let ((footer (next-single-property-change (point-min) 'wgrep-footer))) (cond - ((= count 0) - (message "No buffer has been saved.")) - ((= count 1) - (message "Buffer has been saved.")) + (footer + (goto-char footer) + footer) (t - (message "%d buffers have been saved." count))))) + (goto-char (point-max)) + (point-max))))) -(defun wgrep-mark-deletion () - "Mark as delete to current line. -This change will be applied when \\[wgrep-finish-edit]." - (interactive) - (save-excursion - (let ((ov (wgrep-editing-overlay))) - (unless ov - (error "Not a grep result")) - (condition-case nil - (progn - (overlay-put ov 'wgrep-edit-text nil) - (let ((wgrep-inhibit-modification-hook t) - (begin (overlay-get ov 'wgrep-contents-begin)) - (end (overlay-end ov))) - (delete-region begin end) - (overlay-put ov 'face 'wgrep-delete-face))) - (error - (delete-overlay ov)))))) +(defun wgrep-cleanup-temp-buffer () + "Cleanup temp buffer in *grep* buffer." + (let ((origin-buffer (current-buffer))) + (dolist (buf (buffer-list)) + (with-current-buffer buf + (when (eq origin-buffer wgrep-sibling-buffer) + (kill-buffer buf))))) + (setq wgrep-sibling-buffer nil)) + +(defun wgrep-clone-to-temp-buffer () + (wgrep-cleanup-temp-buffer) + (let ((grepbuf (current-buffer)) + (tmpbuf (generate-new-buffer " *wgrep temp* "))) + (setq wgrep-sibling-buffer tmpbuf) + (add-hook 'kill-buffer-hook 'wgrep-cleanup-temp-buffer nil t) + (append-to-buffer tmpbuf (point-min) (point-max)) + (with-current-buffer tmpbuf + (setq wgrep-sibling-buffer grepbuf)) + tmpbuf)) + +(defun wgrep-set-readonly-area (state) + (let ((inhibit-read-only t) + (wgrep-inhibit-modification-hook t) + pos start end) + (save-excursion + ;; set readonly grep result filename + (setq pos (point-min)) + (while (setq start (next-single-property-change + pos 'wgrep-line-filename)) + (setq end (next-single-property-change + start 'wgrep-line-filename)) + (put-text-property start end 'read-only state) + (put-text-property (1- end) end 'rear-nonsticky t) + ;; set readonly all newline at end of grep line + (when (eq (char-before start) ?\n) + (put-text-property (1- start) start 'read-only state)) + (setq pos end)) + (setq pos (point-min)) + (while (setq start (next-single-property-change + pos 'wgrep-ignore)) + (setq end (next-single-property-change + start 'wgrep-ignore)) + (put-text-property start end 'read-only state) + ;; set readonly all newline at end of grep line + (when (eq (char-before start) ?\n) + (put-text-property (1- start) start 'read-only state)) + (setq pos end)) + ;; set readonly last of grep line + (let ((footer (or (next-single-property-change (point-min) 'wgrep-footer) + ;; to consider empty footer. + (point-max)))) + (when (eq (char-before footer) ?\n) + (put-text-property (1- footer) footer 'read-only state)))) + (setq wgrep-readonly-state state))) (defun wgrep-prepare-context () (save-restriction @@ -669,6 +431,28 @@ This change will be applied when \\[wgrep-finish-edit]." (goto-char (point-min)) (funcall wgrep-results-parser)))) +;; -A -B -C output may be misunderstood and set read-only. +;; Context match break font-lock if context have at least two `:'. +;; e.g. +;; filename-1-2010-01-01 23:59:99 +;; filename:2:hoge +;; filename-3-20:10:25 +(defun wgrep-prepare-context-while (filename line direction fprop flen) + (let* ((next (+ direction line)) + (fregexp (regexp-quote filename))) + (forward-line direction) + (while (looking-at (format "^%s[-\0]%d-" fregexp next)) + (let ((start (match-beginning 0)) + (end (match-end 0)) + (bol (point-at-bol)) + (eol (point-at-eol))) + (put-text-property start end 'wgrep-line-filename filename) + (put-text-property start end 'wgrep-line-number next) + (put-text-property start (+ start flen) fprop filename) + (remove-text-properties bol eol '(wgrep-ignore)) + (forward-line direction) + (setq next (+ direction next)))))) + (defun wgrep-parse-command-results () (let ((cache (make-hash-table))) (while (not (eobp)) @@ -705,66 +489,43 @@ This change will be applied when \\[wgrep-finish-edit]." (t ;; Add property but this may be removed by `wgrep-prepare-context-while' (put-text-property - (line-beginning-position) (line-end-position) + (point-at-bol) (point-at-eol) 'wgrep-ignore t))) (forward-line 1)))) -(defun wgrep-delete-whole-line () - (delete-region (line-beginning-position) (line-beginning-position 2))) - -(defun wgrep-goto-first-found () - (let ((header (previous-single-property-change (point-max) 'wgrep-header))) - (cond - (header - (goto-char header) - header) - (t - (goto-char (point-min)) - (point))))) - -(defun wgrep-goto-end-of-found () - (let ((footer (next-single-property-change (point-min) 'wgrep-footer))) - (cond - (footer - (goto-char footer) - footer) - (t - (goto-char (point-max)) - (point-max))))) - -(defun wgrep-goto-line (line) - (goto-char (point-min)) - (forward-line (1- line))) - -;; -A -B -C output may be misunderstood and set read-only. -;; Context match break font-lock if context have at least two `:'. -;; e.g. -;; filename-1-2010-01-01 23:59:99 -;; filename:2:hoge -;; filename-3-20:10:25 -(defun wgrep-prepare-context-while (filename line direction fprop flen) - (let* ((next (+ direction line)) - (fregexp (regexp-quote filename))) - (forward-line direction) - (while (looking-at (format "^%s[-\0]%d-" fregexp next)) - (let ((start (match-beginning 0)) - (end (match-end 0)) - (bol (line-beginning-position)) - (eol (line-end-position))) - (put-text-property start end 'wgrep-line-filename filename) - (put-text-property start end 'wgrep-line-number next) - (put-text-property start (+ start flen) fprop filename) - (remove-text-properties bol eol '(wgrep-ignore)) - (forward-line direction) - (setq next (+ direction next)))))) - -(defun wgrep-construct-filename-property (filename) - (intern (format "wgrep-fn-%s" filename))) +(defun wgrep-current-file-and-linum () + (save-excursion + (forward-line 0) + (let ((fn (get-text-property (point) 'wgrep-line-filename)) + (linum (get-text-property (point) 'wgrep-line-number))) + (when (and fn linum) + (list fn linum))))) -(defun wgrep-process-exited-p () - (let ((proc (get-buffer-process (current-buffer)))) - (or (null proc) - (eq (process-status proc) 'exit)))) +(defun wgrep-restore-from-temp-buffer () + (cond + ((and wgrep-sibling-buffer + (buffer-live-p wgrep-sibling-buffer)) + (let ((grepbuf (current-buffer)) + (tmpbuf wgrep-sibling-buffer) + (header (wgrep-current-file-and-linum)) + (savedc (current-column)) + (savedp (point)) + (inhibit-read-only t) + (wgrep-inhibit-modification-hook t) + buffer-read-only) + (erase-buffer) + (with-current-buffer tmpbuf + (append-to-buffer grepbuf (point-min) (point-max))) + (goto-char (point-min)) + ;; restore previous cursor + (or (and header + (apply 'wgrep-goto-grep-line header) + (move-to-column savedc)) + (goto-char (min (point-max) savedp))) + (wgrep-cleanup-temp-buffer))) + (t + ;; non fatal error + (message "Error! Saved buffer is unavailable.")))) (defun wgrep-prepare-to-edit () (unless wgrep-prepared @@ -808,212 +569,301 @@ This change will be applied when \\[wgrep-finish-edit]." (when footer-beg (put-text-property footer-beg (point-max) 'read-only state))))) -(defun wgrep-cleanup-overlays (beg end) - (dolist (ov (overlays-in beg end)) - (when (overlay-get ov 'wgrep) - (delete-overlay ov)))) - -(defun wgrep-make-overlay (beg end) - (let ((o (make-overlay beg end nil nil t))) - (overlay-put o 'wgrep t) - o)) +;;; +;;; Editing handlers +;;; -(defun wgrep-clone-to-temp-buffer () - (wgrep-cleanup-temp-buffer) - (let ((grepbuf (current-buffer)) - (tmpbuf (generate-new-buffer " *wgrep temp* "))) - (setq wgrep-sibling-buffer tmpbuf) - (add-hook 'kill-buffer-hook 'wgrep-cleanup-temp-buffer nil t) - (append-to-buffer tmpbuf (point-min) (point-max)) - (with-current-buffer tmpbuf - (setq wgrep-sibling-buffer grepbuf)) - tmpbuf)) +;; get overlay BEG and END is passed by `after-change-functions' +(defun wgrep-editing-overlay (&optional start end) + (let ((beg (or start (point-at-bol))) + (fin (or end (point-at-eol))) + ov bol eol + ;; beginning/end of grep + bog eog) + (goto-char beg) + (setq bol (point-at-bol)) + (goto-char fin) + (setq eol (point-at-eol)) + (catch 'done + (dolist (o (overlays-in bol eol)) + ;; find overlay that have changed by user. + (when (overlay-get o 'wgrep-changed) + (setq ov o) + (throw 'done o)))) + (if ov + (setq bog (min beg (overlay-start ov)) + eog (max (overlay-end ov) fin)) + (setq bog bol + eog eol)) + (goto-char bog) + (cond + ;; When handling whole line, BOL equal beginning of edit. + ((and (null ov) start (= bog start))) + ((get-text-property (point) 'wgrep-line-filename) + (let* ((header-end + (next-single-property-change (point) 'wgrep-line-filename nil eol)) + (filename (get-text-property (point) 'wgrep-line-filename)) + (linum (get-text-property (point) 'wgrep-line-number)) + (value (buffer-substring-no-properties header-end eog)) + contents-begin) + (goto-char header-end) + (setq contents-begin (point-marker)) + ;; create editing overlay + (cond + ((null ov) + (let ((old (wgrep-get-old-text filename linum))) + (setq ov (wgrep-make-overlay bog eog)) + (overlay-put ov 'wgrep-contents-begin contents-begin) + (overlay-put ov 'wgrep-filename filename) + (overlay-put ov 'wgrep-linum linum) + (overlay-put ov 'wgrep-changed t) + (overlay-put ov 'priority 0) + (overlay-put ov 'evaporate t) + (overlay-put ov 'wgrep-old-text old))) + (t + (move-overlay ov bog eog))) + (overlay-put ov 'wgrep-edit-text value)))) + ov)) -(defun wgrep-restore-from-temp-buffer () +(defun wgrep-after-change-function (beg end leng-before) (cond - ((and wgrep-sibling-buffer - (buffer-live-p wgrep-sibling-buffer)) - (let ((grepbuf (current-buffer)) - (tmpbuf wgrep-sibling-buffer) - (header (wgrep-current-file-and-linum)) - (savedc (current-column)) - (savedp (point)) - (inhibit-read-only t) - (wgrep-inhibit-modification-hook t) - buffer-read-only) - (erase-buffer) - (with-current-buffer tmpbuf - (append-to-buffer grepbuf (point-min) (point-max))) - (goto-char (point-min)) - ;; restore previous cursor - (or (and header - (apply 'wgrep-goto-grep-line header) - (move-to-column savedc)) - (goto-char (min (point-max) savedp))) - (wgrep-cleanup-temp-buffer))) + (wgrep-inhibit-modification-hook nil) + ((= (point-min) (point-max)) + ;; cleanup when first executing + (wgrep-cleanup-overlays (point-min) (point-max))) (t - ;; non fatal error - (message "Error! Saved buffer is unavailable.")))) - -(defun wgrep-cleanup-temp-buffer () - "Cleanup temp buffer in *grep* buffer." - (let ((origin-buffer (current-buffer))) - (dolist (buf (buffer-list)) - (with-current-buffer buf - (when (eq origin-buffer wgrep-sibling-buffer) - (kill-buffer buf))))) - (setq wgrep-sibling-buffer nil)) + (wgrep-put-change-face beg end)))) -(defun wgrep-current-file-and-linum () +(defun wgrep-put-change-face (beg end) (save-excursion - (forward-line 0) - (let ((fn (get-text-property (point) 'wgrep-line-filename)) - (linum (get-text-property (point) 'wgrep-line-number))) - (when (and fn linum) - (list fn linum))))) + ;; `looking-at' may destroy match data while replace by regexp. + (save-match-data + (let ((ov (wgrep-editing-overlay beg end))) + ;; delete overlay if text is same as old value. + (cond + ;; not a valid point + ((null ov)) + ((string= (overlay-get ov 'wgrep-old-text) + (overlay-get ov 'wgrep-edit-text)) + ;; back to unchanged + (delete-overlay ov)) + (t + (overlay-put ov 'face 'wgrep-face))))))) -(defun wgrep-get-old-text (file number) - (when (and wgrep-sibling-buffer - (buffer-live-p wgrep-sibling-buffer)) - (with-current-buffer wgrep-sibling-buffer - (when (wgrep-goto-grep-line file number) - (buffer-substring-no-properties - (point) (line-end-position)))))) +;;; +;;; Save grep buffer to file buffer/disk +;;; -(defun wgrep-goto-grep-line (file number) - (let ((first (point)) - (fprop (wgrep-construct-filename-property file)) - fn next) - (catch 'found - ;; FIXME - ;; In a huge buffer, `next-single-property-change' loop make - ;; slow down the program. - ;; 1. sketchy move by filename (wgrep-fn-* property). - ;; 2. search filename and line-number in text property. - ;; 3. return to 1. while search is done or EOB. +(defun wgrep-display-physical-data () + (cond + ;; `funcall' is a trick to suppress the elint warnings. + ((derived-mode-p 'image-mode) + ;; toggle to raw data if buffer has image. + (when (image-get-display-property) + (image-mode-as-text))) + (t nil))) - (goto-char (point-min)) +(defun wgrep-set-result (ov face &optional message) + (overlay-put ov 'face face) + (overlay-put ov 'priority 1) + (overlay-put ov 'wgrep-reject-message message)) - (while (setq next (next-single-property-change (point) fprop)) - (goto-char next) - (while (and (not (eobp)) - (or (null (setq fn (get-text-property - (line-beginning-position) - 'wgrep-line-filename))) - (string= fn file))) - (when fn - (let ((num (get-text-property (point) 'wgrep-line-number)) - (start (next-single-property-change (point) 'wgrep-line-number))) - (when (eq number num) - (goto-char start) - (throw 'found t)))) - (forward-line 1))) - (goto-char first) - nil))) +(defun wgrep-put-done-result (ov) + (wgrep-set-result ov 'wgrep-done-face)) + +(defun wgrep-put-reject-result (ov error-data) + (let ((message (mapconcat (lambda (x) (format "%s" x)) error-data " "))) + (wgrep-set-result ov 'wgrep-reject-face message))) + +(defun wgrep-put-reject-result-all (editor error-data) + (dolist (edit (cdr editor)) + (let ((result (nth 3 edit))) + (wgrep-put-reject-result result error-data)))) + +(defun wgrep-after-save-hook () + (remove-hook 'after-save-hook 'wgrep-after-save-hook t) + (dolist (ov (wgrep-file-overlays)) + (delete-overlay ov))) + +(defun wgrep-put-overlay-to-file-buffer (beg end) + "*Highlight the changes in the file" + (let ((ov + (catch 'done + (dolist (o (overlays-in beg end)) + (when (overlay-get o 'wgrep) + (move-overlay o beg end) + (throw 'done o))) + (wgrep-make-overlay beg end)))) + (overlay-put ov 'face 'wgrep-file-face) + (overlay-put ov 'priority 0) + (add-hook 'after-save-hook 'wgrep-after-save-hook nil t) + ov)) + +(defun wgrep-let-destructive-overlay (ov) + (dolist (prop '(modification-hooks insert-in-front-hooks insert-behind-hooks)) + (overlay-put + ov prop + `((lambda (ov after-p &rest ignore) + (when after-p + (delete-overlay ov))))))) -;; return alist like following -;; key ::= buffer -;; value ::= linum old-text new-text result-overlay edit-overlay -(defun wgrep-transaction-editing-list () +(defun wgrep-replace-to-new-line (new-text) + ;; delete grep extracted region (restricted to a line) + (delete-region (point-at-bol) (point-at-eol)) + (let ((beg (point)) + end) + (insert new-text) + (let* ((end (point)) + ;; hilight the changed line + (ov (wgrep-put-overlay-to-file-buffer beg end))) + ;; make overlay volatile. + (wgrep-let-destructive-overlay ov)))) + +(defun wgrep-flush-whole-line () + (wgrep-put-overlay-to-file-buffer + (point-at-bol) (point-at-eol)) + (wgrep-delete-whole-line)) + +;; EDITOR ::= FILE (absolute-path) . EDITS +;; EDITS ::= EDIT [...] +;; EDIT ::= linum-or-marker old-text new-text result-overlay edit-field-overlay +(defun wgrep-gather-editor () (let (res) - (dolist (ov (wgrep-edit-overlays)) - (goto-char (overlay-start ov)) + (dolist (edit-field (wgrep-edit-field-overlays)) + (goto-char (overlay-start edit-field)) (forward-line 0) (cond ;; ignore removed line or removed overlay - ((eq (overlay-start ov) (overlay-end ov))) + ((eq (overlay-start edit-field) (overlay-end edit-field))) ((get-text-property (point) 'wgrep-line-filename) (let* ((name (get-text-property (point) 'wgrep-line-filename)) (linum (get-text-property (point) 'wgrep-line-number)) (start (next-single-property-change - (point) 'wgrep-line-filename nil (line-end-position))) + (point) 'wgrep-line-filename nil (point-at-eol))) (file (expand-file-name name default-directory)) (file-error nil) - (buffer (condition-case err - (wgrep-get-file-buffer file) - (wgrep-error - (setq file-error (cdr err)) - nil))) - (old (overlay-get ov 'wgrep-old-text)) - (new (overlay-get ov 'wgrep-edit-text)) + (old (overlay-get edit-field 'wgrep-old-text)) + (new (overlay-get edit-field 'wgrep-edit-text)) result) ;; wgrep-result overlay show the commiting of this editing (catch 'done - (dolist (o (overlays-in (overlay-start ov) (overlay-end ov))) + (dolist (o (overlays-in (overlay-start edit-field) (overlay-end edit-field))) (when (overlay-get o 'wgrep-result) ;; get existing overlay (setq result o) (throw 'done t))) ;; create overlay to show result of committing - (setq result (wgrep-make-overlay start (overlay-end ov))) + (setq result (wgrep-make-overlay start (overlay-end edit-field))) (overlay-put result 'wgrep-result t)) - (if file-error - (wgrep-put-reject-result result file-error) - (setq res - (cons - (list buffer linum old new result ov) - res))))))) + (setq res + (cons + (list file (list linum old new result edit-field)) + res)))))) (nreverse res))) (defun wgrep-compute-transaction () - (let ((edit-list (wgrep-transaction-editing-list)) - ;; key ::= buffer - ;; value ::= edit [edit ...] - ;; edit ::= linum old-text new-text result-overlay edit-overlay - all-tran) - (dolist (x edit-list) - (let* ((buffer (car x)) - (edit (cdr x)) - (pair (assq buffer all-tran))) - (unless pair - (setq pair (cons buffer nil)) - (setq all-tran (cons pair all-tran))) + (let ((editors (wgrep-gather-editor)) + editor-group tran) + (dolist (editor editors) + (let* ((file (car editor)) + (edits (cdr editor)) + (editor-cache (assoc file editor-group))) + (unless editor-cache + (setq editor-cache (cons file nil)) + (setq editor-group (cons editor-cache editor-group))) ;; construct with current settings - (setcdr pair (cons edit (cdr pair))))) - ;; Convert linum to marker. - ;; When new text contains newline destroy linum access. - (dolist (buffer-tran all-tran) - (let ((buffer (car buffer-tran)) - (edit-tran (cdr buffer-tran))) + (setcdr editor-cache (append (cdr editor-cache) edits)))) + (setq editor-group (nreverse editor-group)) + + ;; Check file accessibility + (dolist (editor editor-group) + (let ((file (car editor))) + (condition-case err + (progn + (wgrep-check-file file) + (setq tran (cons editor tran))) + (wgrep-error + (wgrep-put-reject-result-all editor (cdr err)))))) + + (nreverse tran))) + +(defun wgrep-compute-linum-to-marker (edits) + ;; Convert linum to marker. + ;; When new text contains newline destroy linum access. + (dolist (edit edits) + (let ((linum (car edit))) + ;; get a marker + (wgrep-goto-line linum) + (setcar edit (point-marker))))) + +(defun wgrep-commit-edits (editor) + (let ((file (car editor)) + (edits (cdr editor))) + (wgrep-compute-linum-to-marker edits) + (let ((done 0) + (first-result nil) + (inhibit-read-only wgrep-change-readonly-file)) + (dolist (edit edits) + (let ((marker (nth 0 edit)) + (old (nth 1 edit)) + (new (nth 2 edit)) + (result-ov (nth 3 edit)) + (edit-ov (nth 4 edit))) + (condition-case err + (progn + (unless first-result + (setq first-result result-ov)) + (wgrep-apply-change marker old new) + (wgrep-put-done-result result-ov) + (delete-overlay edit-ov) + (setq done (1+ done))) + (error + (wgrep-put-reject-result result-ov (cdr err)))))) + (cond + ((or (not wgrep-auto-apply-disk) + (= done 0))) + (buffer-file-name + (basic-save-buffer)) + (t + (let ((coding-system-for-write buffer-file-coding-system)) + (write-region (point-min) (point-max) file nil 'no-msg)))) + (list done first-result)))) + +(defun wgrep-commit-file (editor) + ;; Apply EDITOR to file/buffer. See `wgrep-compute-transaction'. + ;; Return succeeded count and first result overlay in *grep* buffer. + (let* ((file (car editor)) + (edits (cdr editor)) + (open-buffer (get-file-buffer file)) + (buffer + (cond + (open-buffer open-buffer) + (wgrep-auto-apply-disk + (let ((buf (generate-new-buffer "*TMP *"))) + (with-current-buffer buf + ;; To detect coding-system and set `buffer-file-coding-system'. + (insert-file-contents file)) + buf)) + (t + (find-file-noselect file))))) + (unwind-protect (with-current-buffer buffer (save-restriction (widen) - (dolist (edit edit-tran) - (let ((linum (car edit))) - ;; get a marker - (wgrep-goto-line linum) - (setcar edit (point-marker)))))))) - all-tran)) - -(defun wgrep-commit-buffer (buffer tran) - ;; Apply TRAN to BUFFER. - ;; See `wgrep-compute-transaction' - (with-current-buffer buffer - (save-restriction - (widen) - (wgrep-display-physical-data) - (let ((inhibit-read-only wgrep-change-readonly-file) - done) - (dolist (info tran) - (let ((marker (nth 0 info)) - (old (nth 1 info)) - (new (nth 2 info)) - (result (nth 3 info)) - (ov (nth 4 info))) - (condition-case err - (progn - ;; check the buffer while each of overlays - ;; to set a result message. - (wgrep-check-buffer) - (wgrep-apply-change marker old new) - (wgrep-put-done-result result) - (delete-overlay ov) - (setq done (cons ov done))) - (error - (wgrep-put-reject-result result (cdr err)))))) - (when (and wgrep-auto-save-buffer done) - (basic-save-buffer)) - (nreverse done))))) + (wgrep-display-physical-data) + + (cond + ((and (not wgrep-change-readonly-file) + buffer-read-only) + (wgrep-put-reject-result-all + editor + (list (format "Buffer \"%s\" is read-only." (buffer-name)))) + (list 0 nil)) + (t + (wgrep-commit-edits editor))))) + (when wgrep-auto-apply-disk + (when (null open-buffer) + (kill-buffer buffer)))))) (defun wgrep-apply-change (marker old new) "The changes in the *grep* buffer are applied to the file. @@ -1030,7 +880,7 @@ NEW may be nil this means deleting whole line." ;; Check buffer line was modified after execute grep. (unless (string= old (buffer-substring-no-properties - (line-beginning-position) (line-end-position))) + (point-at-bol) (point-at-eol))) (signal 'wgrep-error (list "Buffer was changed after grep."))) (cond (new @@ -1039,6 +889,297 @@ NEW may be nil this means deleting whole line." ;; new nil means flush whole line. (wgrep-flush-whole-line))))) +;;; +;;; UI +;;; + +(defface wgrep-face + '((((class color) + (background dark)) + (:background "SlateGray1" :foreground "Black")) + (((class color) + (background light)) + (:background "ForestGreen" :foreground "white")) + (t + ())) + "*Face used for the changed text in the grep buffer." + :group 'wgrep) + +(defface wgrep-delete-face + '((((class color) + (background dark)) + (:background "SlateGray1" :foreground "pink")) + (((class color) + (background light)) + (:background "ForestGreen" :foreground "pink")) + (t + ())) + "*Face used for the deleted whole line in the grep buffer." + :group 'wgrep) + +(defface wgrep-file-face + '((((class color) + (background dark)) + (:background "gray30" :foreground "white")) + (((class color) + (background light)) + (:background "ForestGreen" :foreground "white")) + (t + ())) + "*Face used for the changed text in the file buffer." + :group 'wgrep) + +(defface wgrep-reject-face + '((((class color) + (background dark)) + (:foreground "HotPink" :weight bold)) + (((class color) + (background light)) + (:foreground "Red" :weight bold)) + (t + ())) + "*Face used for the line in the grep buffer that can not be applied to +a file." + :group 'wgrep) + +(defface wgrep-done-face + '((((class color) + (background dark)) + (:foreground "LightSkyBlue")) + (((class color) + (background light)) + (:foreground "Blue")) + (t + ())) + "*Face used for the line in the grep buffer that can be applied to a file." + :group 'wgrep) + +(defun wgrep-maybe-echo-error-at-point () + (when (null (current-message)) + (let ((ov (catch 'found + (dolist (o (overlays-in + (point-at-bol) (point-at-eol))) + (when (overlay-get o 'wgrep-reject-message) + (throw 'found o)))))) + (when ov + (let (message-log-max) + (message "%s" (overlay-get ov 'wgrep-reject-message))))))) + +;;; +;;; Commands +;;; + +(defun wgrep-finish-edit () + "Apply changes to file buffers. +These changes are not immediately saved to disk unless +`wgrep-auto-save-buffer' is non-nil." + (interactive) + (let* ((tran (wgrep-compute-transaction)) + (all-length (length tran)) + (wgrep-auto-apply-disk nil) + (done 0)) + (cond + (wgrep-auto-save-buffer + (setq wgrep-auto-apply-disk t)) + ((> all-length wgrep-too-many-file-length) + (when (y-or-n-p (eval-when-compile + (concat + "Edited files are too many." + " Apply the changes to disk with non-confirmation?"))) + (setq wgrep-auto-apply-disk t)))) + (while tran + (let* ((editor (car tran)) + (commited (wgrep-commit-file editor)) + (count (nth 0 commited)) + (result (nth 1 commited))) + (when result + (goto-char (overlay-start result)) + (forward-line 0)) + (setq done (+ done count)) + (setq tran (cdr tran)) + (let (message-log-max) + (message "Writing %d files, %d files are left..." + all-length (length tran))) + (redisplay t))) + (wgrep-cleanup-temp-buffer) + (wgrep-to-original-mode) + (let ((msg (format "(%d changed)" done)) + (ovs (wgrep-edit-field-overlays))) + (cond + ((null ovs) + (if (= done 0) + (message "(No changes to be performed)") + (message "Successfully finished. %s" msg))) + ((= (length ovs) 1) + (message "There is an unapplied change. %s" msg)) + (t + (message "There are %d unapplied changes. %s" + (length ovs) msg)))))) + +(defun wgrep-exit () + "Return to original mode." + (interactive) + (if (and (buffer-modified-p) + (y-or-n-p (format "Buffer %s modified; save changes? " + (current-buffer)))) + (wgrep-finish-edit) + (wgrep-abort-changes))) + +(defun wgrep-abort-changes () + "Discard all changes and return to original mode." + (interactive) + (wgrep-cleanup-overlays (point-min) (point-max)) + (wgrep-restore-from-temp-buffer) + (wgrep-to-original-mode) + (message "Changes discarded")) + +(defun wgrep-remove-change (beg end) + "Remove changes in the region between BEG and END." + (interactive "r") + (wgrep-cleanup-overlays beg end) + (setq mark-active nil)) + +(defun wgrep-remove-all-change () + "Remove changes in the whole buffer." + (interactive) + (wgrep-cleanup-overlays (point-min) (point-max))) + +(defun wgrep-toggle-readonly-area () + "Toggle read-only area to remove a whole line. + +See the following example: you obviously don't want to edit the first line. +If grep matches a lot of lines, it's hard to edit the grep buffer. +After toggling to editable, you can call +`delete-matching-lines', `delete-non-matching-lines'. + +Example: +---------------------------------------------- +./.svn/text-base/some.el.svn-base:87:(hoge) +./some.el:87:(hoge) +---------------------------------------------- +" + (interactive) + (let ((modified (buffer-modified-p)) + (read-only (not wgrep-readonly-state))) + (wgrep-set-readonly-area read-only) + (wgrep-set-header/footer-read-only read-only) + (set-buffer-modified-p modified) + (if wgrep-readonly-state + (message "Removing the whole line is now disabled.") + (message "Removing the whole line is now enabled.")))) + +(defun wgrep-change-to-wgrep-mode () + "Change to wgrep mode. + +When the *grep* buffer is huge, this might freeze your Emacs +for several minutes. +" + (interactive) + (unless (wgrep-process-exited-p) + (error "Active process working")) + (wgrep-prepare-to-edit) + (wgrep-set-readonly-area t) + (set (make-local-variable 'query-replace-skip-read-only) t) + (add-hook 'after-change-functions 'wgrep-after-change-function nil t) + (add-hook 'post-command-hook 'wgrep-maybe-echo-error-at-point nil t) + (use-local-map wgrep-mode-map) + (buffer-disable-undo) + (wgrep-clone-to-temp-buffer) + (setq buffer-read-only nil) + (buffer-enable-undo) + ;; restore modified status + (set-buffer-modified-p (wgrep-edit-field-overlays)) + (setq buffer-undo-list nil) + (message "%s" (substitute-command-keys + "Press \\[wgrep-finish-edit] when finished \ +or \\[wgrep-abort-changes] to abort changes."))) + +(defun wgrep-save-all-buffers () + "Save the buffers that wgrep changed." + (interactive) + (let ((count 0)) + (dolist (b (buffer-list)) + (with-current-buffer b + (let ((ovs (wgrep-file-overlays))) + (when (and ovs (buffer-modified-p)) + (basic-save-buffer) + (setq count (1+ count)))))) + (cond + ((= count 0) + (message "No buffer has been saved.")) + ((= count 1) + (message "Buffer has been saved.")) + (t + (message "%d buffers have been saved." count))))) + +(defun wgrep-mark-deletion () + "Mark as delete to current line. +This change will be applied when \\[wgrep-finish-edit]." + (interactive) + (save-excursion + (let ((ov (wgrep-editing-overlay))) + (unless ov + (error "Not a grep result")) + (condition-case nil + (progn + (overlay-put ov 'wgrep-edit-text nil) + (let ((wgrep-inhibit-modification-hook t) + (begin (overlay-get ov 'wgrep-contents-begin)) + (end (overlay-end ov))) + (delete-region begin end) + (overlay-put ov 'face 'wgrep-delete-face))) + (error + (delete-overlay ov)))))) + +(unless wgrep-mode-map + (let ((map (make-sparse-keymap))) + + (define-key map "\C-c\C-c" 'wgrep-finish-edit) + (define-key map "\C-c\C-d" 'wgrep-mark-deletion) + (define-key map "\C-c\C-e" 'wgrep-finish-edit) + (define-key map "\C-c\C-p" 'wgrep-toggle-readonly-area) + (define-key map "\C-c\C-r" 'wgrep-remove-change) + (define-key map "\C-x\C-s" 'wgrep-finish-edit) + (define-key map "\C-c\C-u" 'wgrep-remove-all-change) + (define-key map "\C-c\C-[" 'wgrep-remove-all-change) + (define-key map "\C-c\C-k" 'wgrep-abort-changes) + (define-key map "\C-x\C-q" 'wgrep-exit) + + (setq wgrep-mode-map map))) + +;;; +;;; Entry point +;;; + +(defun wgrep-setup-internal () + (setq wgrep-original-mode-map (current-local-map)) + (define-key wgrep-original-mode-map + wgrep-enable-key 'wgrep-change-to-wgrep-mode) + ;; delete previous wgrep overlays + (wgrep-cleanup-overlays (point-min) (point-max)) + (remove-hook 'post-command-hook 'wgrep-maybe-echo-error-at-point t) + (run-hooks 'wgrep-setup-hook)) + +;;;###autoload +(defun wgrep-setup () + "Setup wgrep preparation." + (cond + ((and (boundp 'grep-use-null-filename-separator) + grep-use-null-filename-separator + ;; FIXME: command may contain "--null" text in search text + ;; (e.g. grep -nH -e "searching --null argument") + ;; `grep-use-null-filename-separator' is non-nil + ;; enough to reduce that confusion. + (let ((command (car-safe compilation-arguments))) + (and (stringp command) + (string-match "[\s\t]--null[\s\t]" command)))) + (set (make-local-variable 'wgrep-line-file-regexp) + wgrep-null-file-separator-header-regexp)) + (t + (set (make-local-variable 'wgrep-line-file-regexp) + wgrep-colon-file-separator-header-regexp))) + (wgrep-setup-internal)) + ;;; ;;; activate/deactivate marmalade install or github install. ;;; diff --git a/packages/which-key-20181114.1432.el b/packages/which-key-20190802.240.el similarity index 92% rename from packages/which-key-20181114.1432.el rename to packages/which-key-20190802.240.el index 503151c..1060e6a 100644 --- a/packages/which-key-20181114.1432.el +++ b/packages/which-key-20190802.240.el @@ -5,8 +5,8 @@ ;; Author: Justin Burkett ;; Maintainer: Justin Burkett ;; URL: https://github.com/justbur/emacs-which-key -;; Package-Version: 20181114.1432 -;; Version: 3.3.0 +;; Package-Version: 20190802.240 +;; Version: 3.3.2 ;; Keywords: ;; Package-Requires: ((emacs "24.4")) @@ -57,8 +57,11 @@ :prefix "which-key-") (defcustom which-key-idle-delay 1.0 - "Delay (in seconds) for which-key buffer to popup. A value of zero -might lead to issues, so a non-zero value is recommended + "Delay (in seconds) for which-key buffer to popup. This + variable should be set before activating `which-key-mode'. + +A value of zero might lead to issues, so a non-zero value is +recommended (see https://github.com/justbur/emacs-which-key/issues/134)." :group 'which-key :type 'float) @@ -410,6 +413,21 @@ prefixes in `which-key-paging-prefixes'" :group 'which-key :type 'boolean) +(defcustom which-key-show-early-on-C-h nil + "Show the which-key buffer before if C-h is pressed in the +middle of a prefix before the which-key buffer would normally be +triggered through the idle delay. If combined with the following +settings, which-key will effectively only show when triggered +\"manually\" using C-h. + +\(setq `which-key-idle-delay' 10000) +\(setq `which-key-idle-secondary-delay' 0.05) + +Note that `which-key-idle-delay' should be set before turning on +`which-key-mode'. " + :group 'which-key + :type 'boolean) + (defcustom which-key-is-verbose nil "Whether to warn about potential mistakes in configuration." :group 'which-key @@ -443,6 +461,7 @@ prefixes in `which-key-paging-prefixes'" "Keymap for C-h commands.") (defvar which-key--paging-functions '(which-key-C-h-dispatch + which-key-manual-update which-key-turn-page which-key-show-next-page-cycle which-key-show-next-page-no-cycle @@ -451,6 +470,9 @@ prefixes in `which-key-paging-prefixes'" which-key-undo-key which-key-undo)) +(defvar which-key-persistent-popup nil + "Whether or not to disable `which-key--hide-popup'.") + (defcustom which-key-hide-alt-key-translations t "Hide key translations using Alt key if non nil. These translations are not relevant most of the times since a lot @@ -641,12 +663,13 @@ used.") (defvar which-key--automatic-display nil "Internal: Non-nil if popup was triggered with automatic update.") +(defvar which-key--debug-buffer-name nil + "If non-nil, use this buffer for debug messages.") (defvar which-key--multiple-locations nil) (defvar which-key--inhibit-next-operator-popup nil) (defvar which-key--prior-show-keymap-args nil) (defvar which-key--previous-frame-size nil) (defvar which-key--prefix-title-alist nil) -(defvar which-key--debug nil) (defvar which-key--evil-keys-regexp (eval-when-compile (regexp-opt '("-state")))) (defvar which-key--ignore-non-evil-keys-regexp @@ -702,6 +725,14 @@ update.") (when which-key--pages-obj (which-key--pages-prefix which-key--pages-obj))) +(defmacro which-key--debug-message (&rest msg) + `(when which-key--debug-buffer-name + (let ((buf (get-buffer-create which-key--debug-buffer-name)) + (fmt-msg (format ,@msg))) + (with-current-buffer buf + (goto-char (point-max)) + (insert "\n" fmt-msg "\n"))))) + ;;; Third-party library support ;;;; Evil @@ -776,7 +807,8 @@ problems at github. If DISABLE is non-nil disable support." (which-key--setup-echo-keystrokes)) (unless (member prefix-help-command which-key--paging-functions) (setq which-key--prefix-help-cmd-backup prefix-help-command)) - (when which-key-use-C-h-commands + (when (or which-key-use-C-h-commands + which-key-show-early-on-C-h) (setq prefix-help-command #'which-key-C-h-dispatch)) (when which-key-show-remaining-keys (add-hook 'pre-command-hook #'which-key--lighter-restore)) @@ -1069,13 +1101,13 @@ total height." (defun which-key--hide-popup () "This function is called to hide the which-key buffer." - (unless (member real-this-command which-key--paging-functions) + (unless (or which-key-persistent-popup + (member real-this-command which-key--paging-functions)) (setq which-key--last-try-2-loc nil) (setq which-key--pages-obj nil) (setq which-key--automatic-display nil) (setq which-key--prior-show-keymap-args nil) - (when (and which-key-idle-secondary-delay - which-key--secondary-timer-active) + (when (and which-key-idle-secondary-delay which-key--secondary-timer-active) (which-key--start-timer)) (which-key--lighter-restore) (cl-case which-key-popup-type @@ -1402,29 +1434,19 @@ local bindings coming first. Within these categories order using (defsubst which-key--butlast-string (str) (mapconcat #'identity (butlast (split-string str)) " ")) -(defun which-key--get-replacements (key-binding &optional use-major-mode) - (let ((alist (or (and use-major-mode - (cdr-safe - (assq major-mode which-key-replacement-alist))) - which-key-replacement-alist)) - res case-fold-search) - (catch 'res - (dolist (replacement alist) - ;; these are mode specific ones to ignore. The mode specific case is - ;; handled in the selection of alist - (unless (symbolp (car replacement)) - (let ((key-regexp (caar replacement)) - (binding-regexp (cdar replacement))) - (when (and (or (null key-regexp) - (string-match-p key-regexp - (car key-binding))) - (or (null binding-regexp) - (string-match-p binding-regexp - (cdr key-binding)))) - (push replacement res) - (when (not which-key-allow-multiple-replacements) - (throw 'res res))))))) - (nreverse res))) +(defun which-key--match-replacement (key-binding replacement) + ;; these are mode specific ones to ignore. The mode specific case is + ;; handled in the selection of alist + (when (and (consp key-binding) (not (symbolp (car replacement)))) + (let ((key-regexp (caar replacement)) + (binding-regexp (cdar replacement)) + case-fold-search) + (and (or (null key-regexp) + (string-match-p key-regexp + (car key-binding))) + (or (null binding-regexp) + (string-match-p binding-regexp + (cdr key-binding))))))) (defun which-key--get-pseudo-binding (key-binding &optional prefix) (let* ((pseudo-binding @@ -1445,30 +1467,35 @@ local bindings coming first. Within these categories order using "Use `which-key--replacement-alist' to maybe replace KEY-BINDING. KEY-BINDING is a cons cell of the form \(KEY . BINDING\) each of which are strings. KEY is of the form produced by `key-binding'." - (let* ((pseudo-binding (which-key--get-pseudo-binding key-binding prefix))) + (let* ((pseudo-binding (which-key--get-pseudo-binding key-binding prefix)) + one-match) (if pseudo-binding pseudo-binding - (let* ((mode-res (which-key--get-replacements key-binding t)) - (all-repls (or mode-res - (which-key--get-replacements key-binding)))) + (let* ((all-repls + (append (cdr-safe (assq major-mode which-key-replacement-alist)) + which-key-replacement-alist))) (dolist (repl all-repls key-binding) - (setq key-binding - (cond ((or (not (consp repl)) (null (cdr repl))) - key-binding) - ((functionp (cdr repl)) - (funcall (cdr repl) key-binding)) - ((consp (cdr repl)) - (cons - (cond ((and (caar repl) (cadr repl)) - (replace-regexp-in-string - (caar repl) (cadr repl) (car key-binding) t)) - ((cadr repl) (cadr repl)) - (t (car key-binding))) - (cond ((and (cdar repl) (cddr repl)) - (replace-regexp-in-string - (cdar repl) (cddr repl) (cdr key-binding) t)) - ((cddr repl) (cddr repl)) - (t (cdr key-binding)))))))))))) + (when (and (or which-key-allow-multiple-replacements + (not one-match)) + (which-key--match-replacement key-binding repl)) + (setq one-match t) + (setq key-binding + (cond ((or (not (consp repl)) (null (cdr repl))) + key-binding) + ((functionp (cdr repl)) + (funcall (cdr repl) key-binding)) + ((consp (cdr repl)) + (cons + (cond ((and (caar repl) (cadr repl)) + (replace-regexp-in-string + (caar repl) (cadr repl) (car key-binding) t)) + ((cadr repl) (cadr repl)) + (t (car key-binding))) + (cond ((and (cdar repl) (cddr repl)) + (replace-regexp-in-string + (cdar repl) (cddr repl) (cdr key-binding) t)) + ((cddr repl) (cddr repl)) + (t (cdr key-binding))))))))))))) (defsubst which-key--current-key-list (&optional key-str) (append (listify-key-sequence (which-key--current-prefix)) @@ -1735,6 +1762,7 @@ ones. PREFIX is for internal use and should not be used." ((eq 'lambda (car-safe def)) "lambda") ((eq 'menu-item (car-safe def)) "menu-item") ((stringp def) def) + ((vectorp def) (key-description def)) (t "unknown"))) bindings :test (lambda (a b) (string= (car a) (car b))))))))) keymap) @@ -1925,7 +1953,7 @@ as well as metadata." (push page-width page-widths)) (make-which-key--pages :pages (nreverse pages) - :height avl-lines + :height (if (> n-pages 1) avl-lines (min avl-lines n-keys)) :widths (nreverse page-widths) :keys/page (reverse keys/page) :page-nums (number-sequence 1 n-pages) @@ -1987,6 +2015,12 @@ is the width of the live window." (or prefix-title (which-key--maybe-get-prefix-title (key-description prefix-keys)))) + (which-key--debug-message "Frame height: %s +Minibuffer height: %s +Max dimensions: (%s,%s) +Available for bindings: (%s,%s) +Actual lines: %s" (frame-height) (window-text-height (minibuffer-window)) +max-lines max-width avl-lines avl-width (which-key--pages-height result)) result))) (defun which-key--lighter-status () @@ -2266,6 +2300,21 @@ current evil state. " "Major-mode bindings") (message "which-key: No map named %s" map-sym)))) +;;;###autoload +(defun which-key-dump-bindings (prefix buffer-name) + "Dump bindings from PREFIX into buffer named BUFFER-NAME. + +PREFIX should be a string suitable for `kbd'." + (interactive "sPrefix: \nB") + (let* ((buffer (get-buffer-create buffer-name)) + (keys (which-key--get-bindings (kbd prefix)))) + (with-current-buffer buffer + (point-max) + (save-excursion + (dolist (key keys) + (insert (apply #'format "%s%s%s\n" key))))) + (switch-to-buffer-other-window buffer))) + ;;;###autoload (defun which-key-undo-key (&optional _) "Undo last keypress and force which-key update." @@ -2313,40 +2362,52 @@ current evil state. " `which-key-C-h-map'. This command is always accessible (from any prefix) if `which-key-use-C-h-commands' is non nil." (interactive) - (if (not (which-key--popup-showing-p)) - (which-key-show-standard-help) - (let* ((prefix-keys (which-key--current-key-string)) - (full-prefix (which-key--full-prefix prefix-keys current-prefix-arg t)) - (prompt (concat (when (string-equal prefix-keys "") - (which-key--propertize - (concat " " - (which-key--pages-prefix-title - which-key--pages-obj)) - 'face 'which-key-note-face)) - full-prefix - (which-key--propertize - (substitute-command-keys - (concat - " \\" - " \\[which-key-show-next-page-cycle]" - which-key-separator "next-page," - " \\[which-key-show-previous-page-cycle]" - which-key-separator "previous-page," - " \\[which-key-undo-key]" - which-key-separator "undo-key," - " \\[which-key-toggle-docstrings]" - which-key-separator "toggle-docstrings," - " \\[which-key-show-standard-help]" - which-key-separator "help," - " \\[which-key-abort]" - which-key-separator "abort" - " 1..9" - which-key-separator "digit-arg")) - 'face 'which-key-note-face))) - (key (string (read-key prompt))) - (cmd (lookup-key which-key-C-h-map key)) - (which-key-inhibit t)) - (if cmd (funcall cmd key) (which-key-turn-page 0))))) + (cond ((and (not (which-key--popup-showing-p)) + which-key-show-early-on-C-h) + (let* ((current-prefix + (butlast + (listify-key-sequence (which-key--this-command-keys))))) + (which-key-reload-key-sequence current-prefix) + (if which-key-idle-secondary-delay + (which-key--start-timer which-key-idle-secondary-delay t) + (which-key--start-timer 0.05 t)))) + ((not (which-key--popup-showing-p)) + (which-key-show-standard-help)) + (t + (if (not (which-key--popup-showing-p)) + (which-key-show-standard-help) + (let* ((prefix-keys (which-key--current-key-string)) + (full-prefix (which-key--full-prefix prefix-keys current-prefix-arg t)) + (prompt (concat (when (string-equal prefix-keys "") + (which-key--propertize + (concat " " + (which-key--pages-prefix-title + which-key--pages-obj)) + 'face 'which-key-note-face)) + full-prefix + (which-key--propertize + (substitute-command-keys + (concat + " \\" + " \\[which-key-show-next-page-cycle]" + which-key-separator "next-page," + " \\[which-key-show-previous-page-cycle]" + which-key-separator "previous-page," + " \\[which-key-undo-key]" + which-key-separator "undo-key," + " \\[which-key-toggle-docstrings]" + which-key-separator "toggle-docstrings," + " \\[which-key-show-standard-help]" + which-key-separator "help," + " \\[which-key-abort]" + which-key-separator "abort" + " 1..9" + which-key-separator "digit-arg")) + 'face 'which-key-note-face))) + (key (string (read-key prompt))) + (cmd (lookup-key which-key-C-h-map key)) + (which-key-inhibit t)) + (if cmd (funcall cmd key) (which-key-turn-page 0))))))) ;;; Update @@ -2398,12 +2459,16 @@ Only if no bindings fit fallback to LOC2." 'which-key-keymap-history))) ;;;###autoload -(defun which-key-show-keymap (keymap) +(defun which-key-show-keymap (keymap &optional no-paging) "Show the top-level bindings in KEYMAP using which-key. KEYMAP -is selected interactively from all available keymaps." +is selected interactively from all available keymaps. + +If NO-PAGING is non-nil, which-key will not intercept subsequent +keypresses for the paging functionality." (interactive (list (which-key--read-keymap))) (which-key--show-keymap (symbol-name keymap) - (symbol-value keymap))) + (symbol-value keymap) + nil nil no-paging)) ;;;###autoload (defun which-key-show-full-keymap (keymap) @@ -2433,7 +2498,8 @@ is selected interactively by mode in `minor-mode-map-alist'." (which-key--show-keymap (symbol-name mode-sym) (cdr (assq mode-sym minor-mode-map-alist))))) -(defun which-key--show-keymap (keymap-name keymap &optional prior-args all) +(defun which-key--show-keymap + (keymap-name keymap &optional prior-args all no-paging) (when prior-args (push prior-args which-key--prior-show-keymap-args)) (let ((bindings (which-key--get-bindings nil keymap nil all))) (if (= (length bindings) 0) @@ -2446,15 +2512,16 @@ is selected interactively by mode in `minor-mode-map-alist'." (t (setq which-key--pages-obj (which-key--create-pages bindings nil keymap-name)) (which-key--show-page))) - (let* ((key (key-description (list (read-key)))) - (next-def (lookup-key keymap (kbd key)))) - (cond ((and which-key-use-C-h-commands (string= "C-h" key)) - (which-key-C-h-dispatch)) - ((keymapp next-def) - (which-key--hide-popup-ignore-command) - (which-key--show-keymap (concat keymap-name " " key) next-def - (cons keymap-name keymap))) - (t (which-key--hide-popup))))))) + (unless no-paging + (let* ((key (key-description (list (read-key)))) + (next-def (lookup-key keymap (kbd key)))) + (cond ((and which-key-use-C-h-commands (string= "C-h" key)) + (which-key-C-h-dispatch)) + ((keymapp next-def) + (which-key--hide-popup-ignore-command) + (which-key--show-keymap (concat keymap-name " " key) next-def + (cons keymap-name keymap))) + (t (which-key--hide-popup)))))))) (defun which-key--evil-operator-filter (binding) (let ((def (intern (cdr binding)))) @@ -2501,7 +2568,7 @@ is selected interactively by mode in `minor-mode-map-alist'." (&optional prefix-keys from-keymap filter prefix-title) "Fill `which-key--buffer' with key descriptions and reformat. Finally, show the buffer." - (let ((start-time (when which-key--debug (current-time))) + (let ((start-time (current-time)) (formatted-keys (which-key--get-bindings prefix-keys from-keymap filter)) (prefix-desc (key-description prefix-keys))) @@ -2516,9 +2583,9 @@ Finally, show the buffer." (which-key--create-pages formatted-keys prefix-keys prefix-title)) (which-key--show-page))) - (when which-key--debug - (message "On prefix \"%s\" which-key took %.0f ms." prefix-desc - (* 1000 (float-time (time-since start-time))))))) + (which-key--debug-message + "On prefix \"%s\" which-key took %.0f ms." prefix-desc + (* 1000 (float-time (time-since start-time)))))) (defun which-key--this-command-keys () "Version of `this-single-command-keys' corrected for key-chords and god-mode." @@ -2632,7 +2699,11 @@ Finally, show the buffer." (not (equal (which-key--current-prefix) (which-key--this-command-keys))))) (cancel-timer which-key--paging-timer) - (which-key--start-timer)))))) + (if which-key-idle-secondary-delay + ;; we haven't executed a command yet so the secandary + ;; timer is more relevant here + (which-key--start-timer which-key-idle-secondary-delay t) + (which-key--start-timer))))))) (provide 'which-key) ;;; which-key.el ends here diff --git a/packages/window-purpose-20180926.1047.tar b/packages/window-purpose-20190628.1827.tar similarity index 91% rename from packages/window-purpose-20180926.1047.tar rename to packages/window-purpose-20190628.1827.tar index c626c06..ec7843a 100644 Binary files a/packages/window-purpose-20180926.1047.tar and b/packages/window-purpose-20190628.1827.tar differ diff --git a/packages/winum-20181107.47.el b/packages/winum-20181119.1705.el similarity index 98% rename from packages/winum-20181107.47.el rename to packages/winum-20181119.1705.el index 7277511..f3b50ec 100644 --- a/packages/winum-20181107.47.el +++ b/packages/winum-20181119.1705.el @@ -17,8 +17,8 @@ ;; along with this program. If not, see . ;; ;; Author: Thomas de Beauchêne -;; Version: 2.0.0 -;; Package-Version: 20181107.47 +;; Version: 2.1.0 +;; Package-Version: 20181119.1705 ;; Keywords: convenience, frames, windows, multi-screen ;; URL: http://github.com/deb0ch/winum.el ;; Created: 2016 @@ -144,6 +144,13 @@ numbers in the mode-line." :group 'winum :type 'integer) +(defcustom winum-format " %s " + "Format string defining how the window number looks like in the mode-line. +This string is passed to the `format' function along with the +result of `winum-get-number-string'." + :group 'winum + :type 'string) + (defcustom winum-ignored-buffers '(" *which-key*") "List of buffers to ignore when assigning numbers." :group 'winum @@ -209,6 +216,10 @@ To get a number given a window, use the `cdr' of a value. Such a structure allows for per-frame bidirectional fast access.") +(defvar winum--mode-line-segment + '(:eval (format winum-format (winum-get-number-string))) + "What is pushed into `mode-line-format' when setting it up automatically.") + (defvar winum--last-used-scope winum-scope "Tracks the last used `winum-scope'. Needed to detect scope changes at runtime.") @@ -405,8 +416,6 @@ WINDOW: if specified, the window of which we want to know the number. (remove-hook 'window-configuration-change-hook 'winum--update) (setq winum--frames-table nil)) -(defvar winum--mode-line-segment '(:eval (winum-get-number-string))) - (defun winum--install-mode-line (&optional position) "Install the window number from `winum-mode' to the mode-line. POSITION: position in the mode-line." diff --git a/packages/with-editor-20181113.1845.tar b/packages/with-editor-20190715.2007.tar similarity index 95% rename from packages/with-editor-20181113.1845.tar rename to packages/with-editor-20190715.2007.tar index 7daac84..4dde000 100644 Binary files a/packages/with-editor-20181113.1845.tar and b/packages/with-editor-20190715.2007.tar differ diff --git a/packages/writeroom-mode-20190406.2135.tar b/packages/writeroom-mode-20190406.2135.tar new file mode 100644 index 0000000..01ccb98 Binary files /dev/null and b/packages/writeroom-mode-20190406.2135.tar differ diff --git a/packages/xcscope-20180426.712.el b/packages/xcscope-20190723.629.el similarity index 99% rename from packages/xcscope-20180426.712.el rename to packages/xcscope-20190723.629.el index 971b485..f7f89c6 100644 --- a/packages/xcscope-20180426.712.el +++ b/packages/xcscope-20190723.629.el @@ -10,7 +10,7 @@ ;; Maintainer: Dima Kogan ;; Keywords: languages c ;; Homepage: https://github.com/dkogan/xcscope.el -;; Package-Version: 20180426.712 +;; Package-Version: 20190723.629 ;; Package-X-Original-Version: 1.0 ;; This file is not part of GNU Emacs. @@ -2145,6 +2145,18 @@ concatenation of ARGS is returned" dir ) + +(defun cscope--expand-file-name-with-absolute-remote (file) + "Returns an expanded filename, with the remote prefix. +This is just like `expand-file-name', but will always contain the +remote prefix if `default-directory' has one. `expand-file-name' +will not do this if FILE is an absolute (but local) path" + (let ((file-expanded (expand-file-name file))) + (if (file-remote-p file-expanded) + file-expanded + (concat (or (file-remote-p default-directory) "") + file-expanded)))) + (defun cscope-construct-custom-options-list () "Returns a list of cscope options defined by the cscope-option-* variables" @@ -2362,7 +2374,7 @@ using the mouse." str)) (cscope-insert-with-text-properties str - (expand-file-name file)) + (cscope--expand-file-name-with-absolute-remote file)) (insert "\n"))) (if cscope-first-match-point @@ -2375,7 +2387,7 @@ using the mouse." (cscope-make-entry-line function-name line-number line) - (expand-file-name file) + (cscope--expand-file-name-with-absolute-remote file) line-number line) (insert "\n") diff --git a/packages/xterm-color-20180202.2318.el b/packages/xterm-color-20180202.2318.el deleted file mode 100644 index ac79ff6..0000000 --- a/packages/xterm-color-20180202.2318.el +++ /dev/null @@ -1,699 +0,0 @@ -;;; xterm-color.el --- ANSI & XTERM 256 color support -*- lexical-binding: t -*- -;; -;; Copyright (C) 2010-2018 xristos@sdf.lonestar.org -;; All rights reserved -;; -;; Version: 1.7 - 2018-2-2 -;; Package-Version: 20180202.2318 -;; Author: xristos@sdf.lonestar.org -;; URL: https://github.com/atomontage/xterm-color -;; Package-Requires: ((cl-lib "0.5")) -;; Keywords: faces -;; -;; Redistribution and use in source and binary forms, with or without -;; modification, are permitted provided that the following conditions -;; are met: -;; -;; * Redistributions of source code must retain the above copyright -;; notice, this list of conditions and the following disclaimer. -;; -;; * Redistributions in binary form must reproduce the above -;; copyright notice, this list of conditions and the following -;; disclaimer in the documentation and/or other materials -;; provided with the distribution. -;; -;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED -;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -;;; Commentary: -;; -;; Translates ANSI control sequences into text properties. -;; -;; * Regular ANSI colors -;; -;; * XTERM 256 colors -;; -;; * Works with compilation-mode -;; -;; * Works with eshell -;; -;; * More accurate than ansi-color.el -;; -;; * Should perform much better than ansi-color.el -;; -;;; Usage: -;; -;; Call xterm-color-filter to propertize strings that you can then insert into -;; a buffer. All state is kept in buffer-local variables which means that -;; control sequences can span xterm-color-filter call boundaries. -;; -;; Example: -;; -;; (xterm-color-filter "[0;1;3;4") -;; (xterm-color-filter ";35") -;; (xterm-color-filter ";mThis is only a test") -;; (xterm-color-filter "") -;; -;; -;; You may also use xterm-color-colorize-buffer, interactively or from elisp, -;; to colorize an entire buffer. -;; -;; -;; * You can replace ansi-color.el with xterm-color for all comint buffers, -;; but this may create problems with modes that propertize strings -;; and feed them through comint-preoutput-filter-functions since xterm-color-filter -;; will strip all text properties. -;; -;; The recommended configuration is to remove ansi-color-process-output from -;; comint-output-filter-functions and add xterm-color-filter as the *first* -;; hook in the buffer-local comint-preoutput-filter-functions for any comint-based -;; mode that you would like it to affect (e.g. shell-mode). -;; -;; An example configuration for shell-mode (M-x shell) is shown below: -;; -;; (setq comint-output-filter-functions -;; (remove 'ansi-color-process-output comint-output-filter-functions)) -;; -;; (add-hook 'shell-mode-hook -;; (lambda () (add-hook 'comint-preoutput-filter-functions 'xterm-color-filter nil t))) -;; -;; Also set TERM accordingly (xterm-256color) -;; -;; * You can also use it with eshell (and thus get color output from system ls): -;; -;; (require 'eshell) -;; -;; (add-hook 'eshell-before-prompt-hook -;; (lambda () -;; (setq xterm-color-preserve-properties t))) -;; -;; (add-to-list 'eshell-preoutput-filter-functions 'xterm-color-filter) -;; (setq eshell-output-filter-functions (remove 'eshell-handle-ansi-color eshell-output-filter-functions)) -;; -;; Don't forget to setenv TERM xterm-256color -;; -;; -;; * Compilation buffers -;; -;; -;; You may use `compilation-shell-minor-mode' with shell-mode buffers -;; and the configuration previously described. -;; -;; For standalone compilation-mode buffers, you may use the following -;; configuration: -;; -;; (setq compilation-environment '("TERM=xterm-256color")) -;; -;; (add-hook 'compilation-start-hook -;; (lambda (proc) -;; ;; We need to differentiate between compilation-mode buffers -;; ;; and running as part of comint (which at this point we assume -;; ;; has been configured separately for xterm-color) -;; (when (eq (process-filter proc) 'compilation-filter) -;; ;; This is a process associated with a compilation-mode buffer. -;; ;; We may call `xterm-color-filter' before its own filter function. -;; (set-process-filter -;; proc -;; (lambda (proc string) -;; (funcall 'compilation-filter proc (xterm-color-filter string))))))) -;; -;; -;;; Test: -;; -;; M-x xterm-color-test -;; -;; For shell or eshell: -;; -;; M-x shell || M-x eshell -;; -;; perl tests/xterm-colortest && perl tests/256colors2.pl -;; -;; -;;; Code: - -(require 'cl-lib) - -(defgroup xterm-color nil - "Translates ANSI control sequences to text properties." - :prefix "xterm-color-" - :group 'processes) - -;; -;; CUSTOM -;; - -(defcustom xterm-color-debug nil - "Print ANSI state machine debug information in *Messages* if T." - :type 'boolean - :group 'xterm-color) - -(defcustom xterm-color-names - ["#192033" ; black - "#A93F43" ; red - "#59963A" ; green - "#BE8A2D" ; yellow - "#4068A3" ; blue - "#7F60A7" ; magenta - "#4E9B9B" ; cyan - "#7E8A90"] ; white - "The default colors to use as regular ANSI colors." - :type '(vector string string string string string string string string) - :group 'xterm-color) - -(defcustom xterm-color-names-bright - ["#666666" ; black - "#EC6261" ; red - "#ADCF44" ; green - "#F0C649" ; yellow - "#63B4F6" ; blue - "#CB77F9" ; magenta - "#86D7DB" ; cyan - "#D3D2D1"] ; white - "The default colors to use as bright ANSI colors." - :type '(vector string string string string string string string string) - :group 'xterm-color) - -;; -;; Buffer locals, used by state machine -;; - -(defvar xterm-color--current nil - "Hash table with current ANSI color.") - -(make-variable-buffer-local 'xterm-color--current) - -(defvar xterm-color-preserve-properties nil - "If T, preserve existing text properties on input about to be filtered. -This should be NIL most of the time as it can mess up the internal state -machine if it encounters ANSI data with text properties applied. It is -really meant for and works fine with eshell.") - -(make-variable-buffer-local 'xterm-color-preserve-properties) - -(defvar xterm-color-ignore-movement nil - "If T, ignore CSI sequences that move the cursor.") - -(make-variable-buffer-local 'xterm-color-ignore-movement) - -(defvar xterm-color--char-buffer "" - "Buffer with characters that the current ANSI color applies to. -In order to avoid having per-character text properties, we grow this -buffer dynamically until we encounter an ANSI reset sequence. - -Once that happens, we generate a single text property for the entire string.") - -(make-variable-buffer-local 'xterm-color--char-buffer) - -(defvar xterm-color--CSI-buffer "" - "Buffer with current ANSI CSI sequence bytes.") - -(make-variable-buffer-local 'xterm-color--CSI-buffer) - -(defvar xterm-color--osc-buffer "" - "Buffer with current ANSI OSC sequence bytes.") - -(make-variable-buffer-local 'xterm-color--osc-buffer) - -(defvar xterm-color--state :char - "The current state of the ANSI sequence state machine.") - -(make-variable-buffer-local 'xterm-color--state) - -(defvar xterm-color--attributes 0) - -(make-variable-buffer-local 'xterm-color--attributes) - - -(defconst +xterm-color--bright+ 1) -(defconst +xterm-color--italic+ 2) -(defconst +xterm-color--underline+ 4) -(defconst +xterm-color--strike+ 8) -(defconst +xterm-color--negative+ 16) -(defconst +xterm-color--frame+ 32) -(defconst +xterm-color--overline+ 64) - -;; -;; Functions -;; - -(cl-defun xterm-color--string-properties (string) - (cl-loop - with res = '() - with pos = 0 - do - (let ((next-pos (next-property-change pos string))) - (if next-pos - (progn - (push (list pos (text-properties-at pos string) (substring string pos next-pos)) res) - (setq pos next-pos)) - (push (list pos (text-properties-at pos string) (substring string pos)) res) - (cl-return-from xterm-color--string-properties (nreverse res)))))) - -(defun xterm-color--message (format-string &rest args) - "Call `message' with FORMAT-STRING and ARGS if `xterm-color-debug' is T." - (when xterm-color-debug - (let ((message-truncate-lines t)) - (apply 'message format-string args) - (message nil)))) - -(defun xterm-color--dispatch-SGR (elems) - (cl-loop - for elem = (cl-first elems) - while elem do - (cond - ;; Reset - ((= 0 elem) - (clrhash xterm-color--current) - (setq xterm-color--attributes 0) - (setq elems (cdr elems))) - ;; ANSI FG color - ((and (>= elem 30) - (<= elem 37)) - (setf (gethash 'foreground-color xterm-color--current) - (- elem 30)) - (setq elems (cdr elems))) - ;; ANSI BG color - ((and (>= elem 40) - (<= elem 47)) - (setf (gethash 'background-color xterm-color--current) - (- elem 40)) - (setq elems (cdr elems))) - ;; XTERM 256 FG color - ((= 38 elem) - (setf (gethash 'foreground-color xterm-color--current) - (xterm-color-256 (cl-third elems))) - (setq elems (cl-cdddr elems))) - ;; XTERM 256 BG color - ((= 48 elem) - (setf (gethash 'background-color xterm-color--current) - (xterm-color-256 (cl-third elems))) - (setq elems (cl-cdddr elems))) - ;; Reset to default FG color - ((= 39 elem) - (remhash 'foreground-color xterm-color--current) - (setq elems (cdr elems))) - ;; Reset to default BG color - ((= 49 elem) - (remhash 'background-color xterm-color--current) - (setq elems (cdr elems))) - ;; Bright color - ((= 1 elem) - (setq xterm-color--attributes - (logior xterm-color--attributes - +xterm-color--bright+)) - (setq elems (cdr elems))) - ;; Faint color, emulated as normal intensity - ((= 2 elem) - (setq xterm-color--attributes - (logand xterm-color--attributes - (lognot +xterm-color--bright+))) - (setq elems (cdr elems))) - ;; Italic - ((= 3 elem) - (setq xterm-color--attributes - (logior xterm-color--attributes - +xterm-color--italic+)) - (setq elems (cdr elems))) - ;; Underline - ((= 4 elem) - (setq xterm-color--attributes - (logior xterm-color--attributes - +xterm-color--underline+)) - (setq elems (cdr elems))) - ;; Negative - ((= 7 elem) - (setq xterm-color--attributes - (logior xterm-color--attributes - +xterm-color--negative+)) - (setq elems (cdr elems))) - ;; Strike through - ((= 9 elem) - (setq xterm-color--attributes - (logior xterm-color--attributes - +xterm-color--strike+)) - (setq elems (cdr elems))) - ;; Normal intensity - ((= 22 elem) - (setq xterm-color--attributes - (logand xterm-color--attributes - (lognot +xterm-color--bright+))) - (setq elems (cdr elems))) - ;; No italic - ((= 23 elem) - (setq xterm-color--attributes - (logand xterm-color--attributes - (lognot +xterm-color--italic+))) - (setq elems (cdr elems))) - ;; No underline - ((= 24 elem) - (setq xterm-color--attributes - (logand xterm-color--attributes - (lognot +xterm-color--underline+))) - (setq elems (cdr elems))) - ;; No negative - ((= 27 elem) - (setq xterm-color--attributes - (logand xterm-color--attributes - (lognot +xterm-color--negative+))) - (setq elems (cdr elems))) - ;; No strike through - ((= 29 elem) - (setq xterm-color--attributes - (logand xterm-color--attributes - (lognot +xterm-color--strike+))) - (setq elems (cdr elems))) - ;; Frame - ((= 51 elem) - (setq xterm-color--attributes - (logior xterm-color--attributes - +xterm-color--frame+)) - (setq elems (cdr elems))) - ;; Overline - ((= 53 elem) - (setq xterm-color--attributes - (logior xterm-color--attributes - +xterm-color--overline+)) - (setq elems (cdr elems))) - ;; No frame - ((= 54 elem) - (setq xterm-color--attributes - (logand xterm-color--attributes - (lognot +xterm-color--frame+))) - (setq elems (cdr elems))) - ;; No overline - ((= 55 elem) - (setq xterm-color--attributes - (logand xterm-color--attributes - (lognot +xterm-color--overline+))) - (setq elems (cdr elems))) - ;; AIXTERM hi-intensity FG color - ((and (>= elem 90) - (<= elem 97)) - (setf (gethash 'foreground-color xterm-color--current) - (- elem 90)) - (setq xterm-color--attributes - (logior xterm-color--attributes - +xterm-color--bright+)) - (setq elems (cdr elems))) - ;; Fallback - (t (xterm-color--message "xterm-color: not implemented SGR attribute %s" elem) - (setq elems (cdr elems)))))) - - -(defun xterm-color--dispatch-CSI (csi) - (let* ((len (1- (length csi))) - (term (aref csi len))) - (cl-macrolet ((maybe-ignore-CSI - (&rest body) - `(if xterm-color-ignore-movement - (xterm-color--message "xterm-color: ignoring %s CSI since xterm-color-ignore-movement is set" csi) - ,@body))) - (cond ((= ?m term) - ;; SGR - (if (= len 0) - (xterm-color--dispatch-SGR '(0)) - (let ((len (1- len))) ; Don't need the ?m character - (subst-char-in-string 59 ? csi t) - (xterm-color--dispatch-SGR - ;; The following is somewhat faster than - ;; (mapcar 'string-to-number (split-string csi)) - (cl-loop with idx = 0 - while (<= idx len) - for (num . end) = (read-from-string csi idx (1+ len)) - do (progn (cl-assert (integerp num)) - (setf idx end)) - collect num))))) - ((= ?J term) - ;; Clear screen - (xterm-color--message "xterm-color: %s CSI not implemented (clear screen)" csi)) - ((= ?C term) - (maybe-ignore-CSI - (let ((num (string-to-number (substring csi 0 len)))) - (setq xterm-color--char-buffer - (concat xterm-color--char-buffer - (make-string num 32)))))) - (t - (xterm-color--message "xterm-color: %s CSI not implemented" csi)))))) - - -(defun xterm-color-256 (color) - (cond ((and (>= color 232) - (<= color 255)) - ;; Grayscale - (let ((val (+ 8 (* (- color 232) 10)))) - (format "#%02x%02x%02x" - val val val))) - ((<= color 7) - ;; Normal ANSI color - (aref xterm-color-names color)) - ((and (>= color 8) - (<= color 15)) - ;; Bright ANSI color - (aref xterm-color-names-bright (- color 8))) - (t (let* ((color-table [0 #x5f #x87 #xaf #xd7 #xff]) - (color (- color 16)) - (red (/ color 36)) - (color (mod color 36)) - (green (/ color 6)) - (color (mod color 6)) - (blue color)) - ;; XTERM 256 color - (format "#%02x%02x%02x" - (aref color-table red) - (aref color-table green) - (aref color-table blue)))))) - -(defun xterm-color--make-property () - (let ((ret nil) - (fg (gethash 'foreground-color xterm-color--current)) - (bg (gethash 'background-color xterm-color--current))) - (cl-macrolet ((is-set? (attrib) `(> (logand ,attrib xterm-color--attributes) 0))) - (when (is-set? +xterm-color--italic+) - (push `(:slant italic) ret)) - (when (is-set? +xterm-color--underline+) - (push `(:underline t) ret)) - (when (is-set? +xterm-color--strike+) - (push `(:strike-through t) ret)) - (when (is-set? +xterm-color--negative+) - (push `(:inverse-video t) ret)) - (when (is-set? +xterm-color--overline+) - (push `(:overline t) ret)) - (when (is-set? +xterm-color--frame+) - (push `(:box t) ret)) - (when fg - (push `(:foreground ,(if (stringp fg) - fg - (if (is-set? +xterm-color--bright+) - (aref xterm-color-names-bright fg) - (aref xterm-color-names fg)))) - ret)) - (when bg - (push `(:background ,(if (stringp bg) bg (aref xterm-color-names bg))) - ret))) - ret)) - -(defun xterm-color-filter-real (string) - "Translate ANSI color sequences in STRING into text properties. -Returns new STRING with text properties applied. - -This function strips text properties that may be present in STRING." - ;; It is *a lot* faster to keep track of propertized strings in a list - ;; and mapconcat at the end, than using a temporary buffer to insert them. - (let ((result nil)) - (cl-macrolet ((output (x) `(push ,x result)) - (update (x place) `(setq ,place (concat ,place (string ,x)))) - (new-state (state) `(setq xterm-color--state ,state)) - (has-color? () `(or (> (hash-table-count xterm-color--current) 0) - (not (= xterm-color--attributes 0)))) - (maybe-fontify () - `(when (> (length xterm-color--char-buffer) 0) - (if (has-color?) - (output (propertize xterm-color--char-buffer 'xterm-color t - (if font-lock-mode 'font-lock-face 'face) (xterm-color--make-property))) - (output xterm-color--char-buffer)) - (setq xterm-color--char-buffer "")))) - (cl-loop for char across string do - (cl-case xterm-color--state - (:char - (cond - ((= char 27) ; ESC - (maybe-fontify) - (new-state :ansi-esc)) - (t - (if (has-color?) - (update char xterm-color--char-buffer) - (output (string char)))))) - (:ansi-esc - (cond ((= char ?\[) - (new-state :ansi-csi)) - ((= char ?\]) - (new-state :ansi-osc)) - (t - (update char xterm-color--char-buffer) - (new-state :char)))) - (:ansi-csi - (update char xterm-color--CSI-buffer) - (when (and (>= char #x40) - (<= char #x7e)) - ;; Dispatch - (xterm-color--dispatch-CSI xterm-color--CSI-buffer) - (setq xterm-color--CSI-buffer "") - (new-state :char))) - (:ansi-osc - ;; Read entire sequence - (update char xterm-color--osc-buffer) - (cond ((= char 7) - ;; BEL - ;(xterm-color--dispatch-osc xterm-color--osc-buffer) - (setq xterm-color--osc-buffer "") - (new-state :char)) - ((= char 27) - ;; ESC - (new-state :ansi-osc-esc)))) - (:ansi-osc-esc - (update char xterm-color--osc-buffer) - (cond ((= char ?\\) - ;(xterm-color--dispatch-osc xterm-color--osc-buffer) - (setq xterm-color--osc-buffer "") - (new-state :char)) - (t (new-state :ansi-osc)))))) - (when (eq xterm-color--state :char) (maybe-fontify))) - (mapconcat 'identity (nreverse result) ""))) - - -;;;###autoload -(defun xterm-color-filter (string) - "Translate ANSI color sequences in STRING into text properties. -Returns new STRING with text properties applied. - -This function will check if `xterm-color-preserve-properties' is -set to T and only call `xterm-color-filter-real' on substrings -that do not have text properties applied (passing through the rest -unmodified). Preserving properties in this fashion is really a hack -and not very robust as there may be situations where text properties -are applied on ANSI data, which will mess up the state machine. -It works fine with and is really meant for eshell though. - -This can be inserted into `comint-preoutput-filter-functions'." - (when (null xterm-color--current) - (setq xterm-color--current (make-hash-table))) - (if (not xterm-color-preserve-properties) - (xterm-color-filter-real string) - (cl-loop with res = nil - for (_ props substring) in (xterm-color--string-properties string) do - (push (if props substring (xterm-color-filter-real substring)) - res) - finally return (mapconcat 'identity (nreverse res) "")))) - -;; This will be removed in 2.0, it's here so as not to break existing configs -;; for 1.0 -> 1.6 transition. -(defalias 'xterm-color-unfontify-region 'font-lock-default-unfontify-region) - -;; -;; Interactive -;; - -;;;###autoload -(cl-defun xterm-color-colorize-buffer () - "Apply `xterm-color-filter' to current buffer, and replace its contents." - (interactive) - (let ((read-only-p buffer-read-only)) - (when read-only-p - (unless (y-or-n-p "Buffer is read only, continue colorizing? ") - (cl-return-from xterm-color-colorize-buffer)) - (read-only-mode -1)) - (insert (xterm-color-filter (delete-and-extract-region (point-min) (point-max)))) - (goto-char (point-min)) - (when read-only-p (read-only-mode 1)))) - - -;; -;; Tests -;; - -(let ((test-attributes - '((1 . "bright") - (51 . "frame") - (3 . "italic") - (4 . "underline") - (7 . "negative") - (9 . "strike through") - (53 . "overline")))) - - (defun xterm-color--test-ansi () - ;; System colors - (insert "* ANSI system colors\n\n") - (cl-loop for color from 40 to 47 do - (insert (xterm-color-filter (format "[0;%sm " color))) - finally (insert (xterm-color-filter "\n\n"))) - - ;; Attributes (no color) - (insert "* ANSI attributes (default colors)\n\n") - (cl-loop for (attrib . name) in test-attributes do - (insert (xterm-color-filter (format "[0;%smThis is only a test!\t --[ %s ]\n" attrib name))) - finally (insert "\n")) - - ;; Attributes (blue fg) - (insert "* ANSI attributes (blue foreground)\n\n") - (cl-loop for (attrib . name) in test-attributes do - (insert (xterm-color-filter (format "[0;34;%smThis is only a test!\t --[ %s ]\n" attrib name))) - finally (insert "\n")) - - ;; Attributes (blue bg) - (insert "* ANSI attributes (blue background)\n\n") - (cl-loop for (attrib . name) in test-attributes do - (insert (xterm-color-filter (format "[0;44;%smThis is only a test!\t --[ %s ]\n" attrib name))) - finally (insert "\n")))) - -(defun xterm-color--test-xterm () - ;; Normal ANSI colors mapped to XTERM - (insert "* ANSI colors mapped to XTERM\n\n") - (cl-loop for color from 0 to 7 do - (insert (xterm-color-filter (format "[48;5;%sm " color))) - finally (insert (xterm-color-filter "\n\n"))) - - ;; Bright ANSI colors mapped to XTERM - (insert "* ANSI bright colors mapped to XTERM\n\n") - (cl-loop for color from 8 to 15 do - (insert (xterm-color-filter (format "[48;5;%sm " color))) - finally (insert (xterm-color-filter "\n\n"))) - - ;; XTERM 256 color cubes - (insert "* XTERM 256 color cubes\n\n") - (cl-loop for green from 0 to 5 do - (cl-loop for red from 0 to 5 do - (cl-loop for blue from 0 to 5 - for color = (+ 16 (* 36 red) (* green 6) blue) do - (insert (xterm-color-filter (format "[48;5;%sm " color)))) - (insert (xterm-color-filter " "))) - (insert "\n")) - (insert "\n") - - (insert "* XTERM color grayscale ramp\n\n") - (cl-loop for color from 232 to 255 do - (insert (xterm-color-filter (format "[48;5;%sm " color))) - finally (insert (xterm-color-filter "\n\n")))) - -;;;###autoload -(defun xterm-color-test () - "Create and display a new buffer that contains ANSI control sequences." - (interactive) - (let* ((name (generate-new-buffer-name "xterm-color-test")) - (buf (get-buffer-create name))) - (switch-to-buffer buf)) - (xterm-color--test-ansi) - (xterm-color--test-xterm) - (setq buffer-read-only t)) - - -(provide 'xterm-color) -;;; xterm-color.el ends here diff --git a/packages/xterm-color-20190816.941.el b/packages/xterm-color-20190816.941.el new file mode 100644 index 0000000..1c88e49 --- /dev/null +++ b/packages/xterm-color-20190816.941.el @@ -0,0 +1,871 @@ +;;; xterm-color.el --- ANSI & XTERM 256 color support -*- lexical-binding: t -*- + +;; Copyright (C) 2010-2019 xristos@sdf.lonestar.org +;; All rights reserved + +;; Version: 1.9 - 2019-08-15 +;; Package-Version: 20190816.941 +;; Author: xristos +;; URL: https://github.com/atomontage/xterm-color +;; Package-Requires: ((cl-lib "0.5")) +;; Keywords: faces + +;; Redistribution and use in source and binary forms, with or without +;; modification, are permitted provided that the following conditions +;; are met: +;; +;; * Redistributions of source code must retain the above copyright +;; notice, this list of conditions and the following disclaimer. +;; +;; * Redistributions in binary form must reproduce the above +;; copyright notice, this list of conditions and the following +;; disclaimer in the documentation and/or other materials +;; provided with the distribution. +;; +;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED +;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +;;; Commentary: +;; +;; Translate ANSI control sequences into text properties. +;; +;; * Regular ANSI colors +;; +;; * XTERM 256 colors +;; +;; * AIXTERM bright foreground color +;; +;; * AIXTERM bright background color (since 1.8) +;; +;; * Use bold for bright (since 1.8) +;; +;; * Works with compilation-mode +;; +;; * Works with eshell +;; +;; * More accurate than ansi-color.el +;; +;; * Should perform much better than ansi-color.el +;; +;;; Usage: +;; +;; Interactively or from Emacs Lisp call xterm-color-colorize-buffer +;; to colorize an entire buffer. +;; +;; In Emacs Lisp, call xterm-color-filter to propertize strings that you can +;; then insert into a buffer. All state is kept in buffer-local variables +;; which means that control sequences can span xterm-color-filter call boundaries. +;; +;; You may customize `xterm-color-debug' (default NIL, if T you will get warnings +;; in *Messages* when unsupported escape sequences are encountered), +;; `xterm-color-use-bold-for-bright' (default NIL), `xterm-color-names', +;; `xterm-color-names-bright'. Additionally, you may set `xterm-color-preserve-properties' +;; to T (default NIL, should be set to T if using xterm-color with eshell, see below). +;; +;; A buffer-local face attribute cache is used since 1.8 to improve performance. +;; This means that if you change `xterm-color-names' or `xterm-color-names-bright' +;; or `xterm-color-use-bold-for-bright' at runtime and want the changes to take +;; effect in a pre-existing buffer with activated xterm-color, you will need to +;; run `xterm-color-clear-cache' in relevant buffer. +;; +;; Example: +;; +;; (let ((buffer (generate-new-buffer "*xterm-color-test*"))) +;; (with-current-buffer buffer +;; (insert (xterm-color-filter "\x1b[0;1;3;4")) +;; (insert (xterm-color-filter ";35")) +;; (insert (xterm-color-filter ";51mThis is only a test")) +;; (insert (xterm-color-filter "\x1b[0m"))) +;; (switch-to-buffer buffer)) +;; +;; +;; * You can replace ansi-color.el with xterm-color for all comint buffers, +;; but this may create problems with modes that propertize strings +;; and feed them through comint-preoutput-filter-functions since xterm-color-filter +;; will strip all text properties. +;; +;; The recommended configuration is to remove ansi-color-process-output from +;; comint-output-filter-functions and add xterm-color-filter as the *first* +;; hook in the *buffer-local* comint-preoutput-filter-functions for any comint-based +;; mode that you would like it to affect (e.g. shell-mode). +;; +;; Additionally, it is recommended to disable font-locking for shell-mode buffers since +;; it seems to interact badly with comint and drastically affect performance +;; (https://github.com/atomontage/xterm-color/issues/28). +;; +;; Font locking in shell-mode buffers is superfluous since xterm-color.el will handle +;; faces fine by itself. +;; +;; An example configuration for shell-mode (M-x shell) is shown below: +;; +;; (setq comint-output-filter-functions +;; (remove 'ansi-color-process-output comint-output-filter-functions)) +;; +;; (add-hook 'shell-mode-hook +;; (lambda () +;; ;; Disable font-locking in this buffer to improve performance +;; (font-lock-mode -1) +;; ;; Prevent font-locking from being re-enabled in this buffer +;; (make-local-variable 'font-lock-function) +;; (setq font-lock-function (lambda (_) nil)) +;; (add-hook 'comint-preoutput-filter-functions 'xterm-color-filter nil t))) +;; +;; Also set TERM accordingly (xterm-256color) in the shell itself. +;; +;; * You can also use it with eshell (and thus get color output from system ls): +;; +;; (require 'eshell) ; or use with-eval-after-load +;; +;; (add-hook 'eshell-before-prompt-hook +;; (lambda () +;; (setq xterm-color-preserve-properties t))) +;; +;; (add-to-list 'eshell-preoutput-filter-functions 'xterm-color-filter) +;; (setq eshell-output-filter-functions (remove 'eshell-handle-ansi-color eshell-output-filter-functions)) +;; (setenv "TERM" "xterm-256color") +;; +;; * Compilation buffers +;; +;; Using `compilation-shell-minor-mode' with shell-mode buffers that have xterm-color +;; enabled is NOT recommended, as `compilation-shell-minor-mode' depends on font-locking +;; and the latter introduces severe performance degradation. If you still want to use it, +;; omit the statements that disable font-locking in the previously given shell-mode +;; example configuration. +;; +;; For standalone compilation-mode buffers, you may use the following configuration: +;; +;; (setq compilation-environment '("TERM=xterm-256color")) +;; +;; (defun my/advice-compilation-filter (f proc string) +;; (funcall f proc (xterm-color-filter string))) +;; +;; (advice-add 'compilation-filter :around #'my/advice-compilation-filter) +;; +;;; Notes: +;; +;; Unsupported SGR attributes: 5 (slow blink), 6 (rapid blink), 8 (conceal), +;; 10 (primary font), 11-19 (alternative font), 20 (fraktur), 21 (double underline), +;; 25 (blink off), 29 (reveal), 52 (encircled), 60-65 (ideogram) +;; +;; Most of these can not be mapped to Emacs face properties. The rest may be +;; supported in a future release. +;; +;; Supported SGR attributes: Look at `xterm-color--dispatch-SGR'. +;; SGR attribute 1 is rendered as bright unless `xterm-color-use-bold-for-bright' +;; is T which will, if current Emacs font has a bold variant, switch to bold. +;; SGR attributes 38 and 48 are only supported in their 256 color variants, +;; not full RGB. + +;;; Test: +;; +;; M-x xterm-color-test +;; +;; For shell or eshell: +;; +;; M-x shell || M-x eshell +;; +;; perl tests/xterm-colortest && perl tests/256colors2.pl +;; +;; Comparison with ansi-color.el: +;; +;; M-x xterm-color-test-raw then M-x xterm-color-colorize-buffer +;; +;; and contrast with +;; +;; M-x xterm-color-test-raw then M-: (ansi-color-apply-on-region (point-min) (point-max)) + +;;; Code: + +(require 'cl-lib) + +(defgroup xterm-color nil + "Translate ANSI control sequences to text properties." + :prefix "xterm-color-" + :group 'processes) + + +;;; +;;; CUSTOM +;;; + + +(defcustom xterm-color-debug nil + "Print ANSI state machine debug information in *Messages* if not NIL." + :type 'boolean + :group 'xterm-color) + +(defcustom xterm-color-use-bold-for-bright nil + "Render bright foreground attribute as bold." + :type 'boolean + :group 'xterm-color) + +(defcustom xterm-color-names + ["#192033" ; black + "#A93F43" ; red + "#59963A" ; green + "#BE8A2D" ; yellow + "#4068A3" ; blue + "#7F60A7" ; magenta + "#4E9B9B" ; cyan + "#7E8A90"] ; white + "The default colors to use as regular ANSI colors." + :type '(vector string string string string string string string string) + :group 'xterm-color) + +(defcustom xterm-color-names-bright + ["#666666" ; black + "#EC6261" ; red + "#ADCF44" ; green + "#F0C649" ; yellow + "#63B4F6" ; blue + "#CB77F9" ; magenta + "#86D7DB" ; cyan + "#D3D2D1"] ; white + "The default colors to use as bright ANSI colors." + :type '(vector string string string string string string string string) + :group 'xterm-color) + + +;;; +;;; Buffer locals, used by state machine +;;; + + +(defvar xterm-color-preserve-properties nil + "If T, preserve existing text properties on input about to be filtered. +This should be NIL most of the time as it can mess up the internal state +machine if it encounters ANSI data with text properties applied. It is +really meant for and works fine with eshell.") + +(make-variable-buffer-local 'xterm-color-preserve-properties) + +(defvar xterm-color--current-fg nil) + +(make-variable-buffer-local 'xterm-color--current-fg) + +(defvar xterm-color--current-bg nil) + +(make-variable-buffer-local 'xterm-color--current-bg) + +(defvar xterm-color--char-list nil + "List with characters that the current ANSI color applies to. +All characters are stored in reverse, LIFO, order.") + +(make-variable-buffer-local 'xterm-color--char-list) + +(defvar xterm-color--CSI-list nil + "List with current ANSI CSI sequence bytes (characters). +All characters are stored in reverse, LIFO, order.") + +(make-variable-buffer-local 'xterm-color--CSI-list) + +(defvar xterm-color--state :char + "The current state of the ANSI sequence state machine.") + +(make-variable-buffer-local 'xterm-color--state) + +(defvar xterm-color--attributes 0 + "Bitvector that keeps track of bright, italic, underline, strike-through, +inverse-color, frame, overline SGR state machine bits.") + +(make-variable-buffer-local 'xterm-color--attributes) + +(defvar xterm-color--face-cache nil + "Cache for auto-generated face attributes.") + +(make-variable-buffer-local 'xterm-color--face-cache) + + +;;; +;;; Constants +;;; + + +(defconst +xterm-color--table-256+ [0 #x5f #x87 #xaf #xd7 #xff]) + + +;;; +;;; Internal API +;;; + + +(cl-defun xterm-color--string-properties (string) + (cl-loop + with pos = 0 and result do + (let ((next-pos (next-property-change pos string))) + (if next-pos + (progn + (push (list pos (text-properties-at pos string) (substring string pos next-pos)) result) + (setq pos next-pos)) + (push (list pos (text-properties-at pos string) (substring string pos)) result) + (cl-return-from xterm-color--string-properties (nreverse result)))))) + +(defun xterm-color--message (format-string &rest args) + "Call `message' with FORMAT-STRING and ARGS if `xterm-color-debug' is not NIL." + (when xterm-color-debug + (let ((message-truncate-lines t)) + (apply 'message format-string args) + (message nil)))) + + +;;; +;;; SGR state machine +;;; + + +(cl-defmacro xterm-color--with-SGR-constants (&body body) + (declare (indent defun)) + `(cl-symbol-macrolet + ((+bright+ 1) + (+italic+ 2) + (+underline+ 4) + (+strike-through+ 8) + (+negative+ 16) + (+frame+ 32) + (+overline+ 64)) + ,@body)) + +(cl-defmacro xterm-color--create-SGR-table ((attrib SGR-list) &body body) + "Create an iteration/dispatch table based on provided rules that match SGR attributes. +For each attribute in SGR-LIST, check to see if it matches a rule in BODY. If so, +evaluate the rule body. + +ATTRIB should be a symbol that will be bound to SGR-LIST attributes in BODY. +SGR-LIST should be a list of SGR attributes (integers) in LIFO order. +BODY should contain rules with each rule being a list of form: + + (:match (condition &optional skip) rule-body-form..) + +CONDITION should be a Lisp form which will be evaluated as part of a COND +condition clause. If it is an atom, it will be rewritten to (= CONDITION ATTRIB). +Otherwise it will be used as is. As per COND statement, if CONDITION evaluates +to T, rule body forms will be evaluated as part of the body of the COND clause. +If SKIP is given, it should be a function that will be used to iterate over SGR-LIST, +by returning a list that the next iteration will use as SGR-LIST. If not given, CDR will +be used, meaning the iteration will go down the SGR-LIST one element at a time. By +using other functions, it is possible to skip elements." + (declare (indent defun)) + `(xterm-color--with-SGR-constants + (cl-macrolet + ;; The following macros can be used in the match rule bodies + ((set-a! (attr &key clear) + (if clear + `(setq xterm-color--attributes + (logand xterm-color--attributes + (logand #xff (lognot ,attr)))) + `(setq xterm-color--attributes + (logior xterm-color--attributes ,attr)))) + (set-f! (fg-color) `(setq xterm-color--current-fg ,fg-color)) + (set-b! (bg-color) `(setq xterm-color--current-bg ,bg-color)) + (reset! () `(setq xterm-color--current-fg nil + xterm-color--current-bg nil + xterm-color--attributes 0))) + (cl-loop + for ,attrib = (cl-first ,SGR-list) + while ,SGR-list do + (cond + ,@(cl-loop + for skip = nil + for (tag (c . rest) . rule-body) in body + when (not (eq tag :match)) do + (error "Rule (%s (%s..)..) does not start with :match" tag c) + when rest do + (setq skip (car rest)) + (and (cdr rest) (error "Rule (%s (%s..)..) has malformed arguments: %s" tag c rest)) + ;; Condition part of the COND clause + collect `(,(if (atom c) `(= ,c ,attrib) c) + ;; Body of the COND clause + ,@rule-body + ;; Last expression of the body of the COND clause + ;; that determines how many SGR attributes will be + ;; skipped. If a skip argument is provided to the + ;; match rule, it will be funcalled with SGR-list + ;; as the argument. Otherwise CDR will be used which + ;; will skip to the next SGR attribute. + (setq ,SGR-list ,(if skip + `(funcall ,skip ,SGR-list) + `(cdr ,SGR-list))))) + (t (xterm-color--message "xterm-color: not implemented SGR attribute %s" ,attrib) + (setq ,SGR-list (cdr ,SGR-list)))))))) + + +(defsubst xterm-color--dispatch-SGR (SGR-list) + "Update state machine based on SGR-LIST which should be a list of SGR attributes (integers)." + (xterm-color--create-SGR-table (elem SGR-list) + (:match (0) (reset!)) ; RESET everything + (:match ((<= 30 elem 37)) (set-f! (- elem 30))) ; ANSI FG color + (:match ((<= 40 elem 47)) (set-b! (- elem 40))) ; ANSI BG color + (:match (39) (set-f! nil)) ; RESET FG color (switch to default) + (:match (49) (set-b! nil)) ; RESET BG color (switch to default) + (:match (1) (set-a! +bright+)) + (:match (2) (set-a! +bright+ :clear t)) + (:match (3) (set-a! +italic+)) + (:match (4) (set-a! +underline+)) + (:match (7) (set-a! +negative+)) + (:match (9) (set-a! +strike-through+)) + (:match (22) (set-a! +bright+ :clear t)) + (:match (23) (set-a! +italic+ :clear t)) + (:match (24) (set-a! +underline+ :clear t)) + (:match (27) (set-a! +negative+ :clear t)) + (:match (29) (set-a! +strike-through+ :clear t)) + (:match (38 'cl-cdddr) ; XTERM 256 FG color + (set-f! (cl-third SGR-list))) + (:match (48 'cl-cdddr) ; XTERM 256 BG color + (set-b! (cl-third SGR-list))) + (:match (51) (set-a! +frame+)) + (:match (53) (set-a! +overline+)) + (:match (54) (set-a! +frame+)) + (:match (55) (set-a! +overline+)) + (:match ((<= 90 elem 97)) ; AIXTERM hi-intensity FG + ;; Rather than setting the bright attribute, which would be a bug, + ;; rescale the color to fall within the range 8-15 which + ;; xterm-color-256 will map to xterm-color-names-bright. + (set-f! (- elem 82))) + ;; Same for BG, rescale to 8-15 + (:match ((<= 100 elem 107)) (set-b! (- elem 92))))) ; AIXTERM hi-intensity BG + +(defsubst xterm-color--SGR-attributes (list) + "Convert LIFO list of SGR characters to FIFO list of SGR attributes (integers). +Returns FIFO list of SGR attributes. + +Characters should be in the ASCII set 0-9 (decimal 48 to 57) and are converted +to integer digits by subtracting 48 from each character. E.g. Character 48 will +be converted to integer digit 0, character 49 to integer digit 1 and so on. +Character 59 (;) is not converted but signifies that all accumulated integer +digits should be reversed and combined into a single integer (SGR attribute). + +Examples: + +Given (48) return (0) +Given (59) return (0) +Given (48 49 50) return (210) +Given (48 49 50 59 50 50 59 48 49) return (10 22 210)" + (cl-loop + with mul = 1 and num = 0 and ret + for c = (car list) while c do + (if (/= 59 c) + (let ((e (- c 48))) + (unless (<= 0 e 9) (error "Invalid SGR attribute: %s" e)) + (cl-incf num (* mul e)) + (setq mul (* mul 10))) + (push num ret) + (setq num 0 mul 1)) + (setq list (cdr list)) + finally return (push num ret))) + + +;;; +;;; CSI state machine +;;; + + +(defsubst xterm-color--dispatch-CSI () + "Update state machine based on CSI parameters collected so far. +The parameters are taken from `xterm-color--CSI-list' which stores them +in LIFO order." + (let* ((csi xterm-color--CSI-list) + (term (car csi)) ; final parameter, terminator + (params (cdr csi))) ; rest of parameters, LIFO order + (setq xterm-color--CSI-list nil) + (cond ((= ?m term) + ;; SGR + (xterm-color--dispatch-SGR + (if (null params) + '(0) + (xterm-color--SGR-attributes params)))) + (t + (xterm-color--message "xterm-color: %s CSI not implemented" csi))))) + +(defmacro xterm-color--with-ANSI-macro-helpers (&rest body) + (declare (indent defun)) + `(xterm-color--with-SGR-constants + (cl-macrolet + ((out! (x) `(push ,x result)) + (push-char! (c) `(push ,c xterm-color--char-list)) + (push-csi! (c) `(push ,c xterm-color--CSI-list)) + + (state! (s) `(setq state ,s)) + (color? () `(or xterm-color--current-fg + xterm-color--current-bg + (/= xterm-color--attributes 0))) + (has? (attrib) `(/= (logand ,attrib xterm-color--attributes) 0)) + (face-cache-get () `(gethash (logior (ash xterm-color--attributes 16) + (ash (or xterm-color--current-bg 0) 8) + (or xterm-color--current-fg 0)) + xterm-color--face-cache)) + (face! (k v) `(setq plistf (plist-put plistf ,k ,v))) + (make-face () `(or (face-cache-get) + (let (plistf) + (when (has? +italic+) (face! :slant 'italic)) + (when (has? +underline+) (face! :underline t)) + (when (has? +strike-through+) (face! :strike-through t)) + (when (has? +negative+) (face! :inverse-video t)) + (when (has? +overline+) (face! :overline t)) + (when (has? +frame+) (face! :box t)) + (if xterm-color--current-fg + (if (and xterm-color-use-bold-for-bright + (or (has? +bright+) + (<= 8 xterm-color--current-fg 15))) + (progn (face! :weight 'bold) + (face! :foreground + (xterm-color-256 (if (<= 8 xterm-color--current-fg) + (- xterm-color--current-fg 8) + xterm-color--current-fg)))) + (face! :foreground + (xterm-color-256 + (if (and (<= xterm-color--current-fg 7) + (has? +bright+)) + (+ xterm-color--current-fg 8) + xterm-color--current-fg)))) + (when (and xterm-color-use-bold-for-bright + (has? +bright+)) + (face! :weight 'bold))) + (when xterm-color--current-bg + (face! :background (xterm-color-256 xterm-color--current-bg))) + (setf (face-cache-get) plistf)))) + (maybe-fontify () '(when xterm-color--char-list + (let ((s (concat (nreverse xterm-color--char-list)))) + (when (color?) + (add-text-properties + 0 (length s) + (list 'xterm-color t (if font-lock-mode 'font-lock-face 'face) (make-face)) + s)) + (out! s)) + (setq xterm-color--char-list nil)))) + ,@body))) + + +;;; +;;; Exports +;;; + + +;;;###autoload +(defun xterm-color-filter-strip (string) + "Translate ANSI color sequences in STRING into text properties. +Return new STRING with text properties applied. + +This function strips text properties that may be present in STRING." + (or xterm-color--face-cache + (setq xterm-color--face-cache (make-hash-table :weakness 'value))) + (xterm-color--with-ANSI-macro-helpers + (cl-loop + with state = xterm-color--state and result + for char across string do + (cl-case state + (:char + (cond + ((= char 27) ; ESC + (maybe-fontify) + (state! :ansi-esc)) + (t + (if (color?) + (push-char! char) + (out! (string char)))))) + (:ansi-esc + (cond ((= char ?\[) + (state! :ansi-csi)) + ((= char ?\]) + (state! :ansi-osc)) + (t + (push-char! char) + (state! :char)))) + (:ansi-csi + (push-csi! char) + (when (and (>= char #x40) + (<= char #x7e)) + (xterm-color--dispatch-CSI) + (state! :char))) + (:ansi-osc + ;; OSC sequences are skipped + (cond ((= char 7) + (state! :char)) + ((= char 27) + ;; ESC + (state! :ansi-osc-esc)))) + (:ansi-osc-esc + (cond ((= char ?\\) + (state! :char)) + (t (state! :ansi-osc))))) + finally return + (progn (when (eq state :char) (maybe-fontify)) + (setq xterm-color--state state) + (mapconcat 'identity (nreverse result) ""))))) + +;;;###autoload +(defun xterm-color-filter (string) + "Translate ANSI color sequences in STRING into text properties. +Return new STRING with text properties applied. + +This function will check if `xterm-color-preserve-properties' is +set to T and only call `xterm-color-filter-strip' on substrings +that do not have text properties applied (passing through the rest +unmodified). Preserving properties in this fashion is really a hack +and not very robust as there may be situations where text properties +are applied on ANSI data, which will mess up the state machine. +It works fine with and is really meant for eshell though. + +This can be inserted into `comint-preoutput-filter-functions'." + (if (not xterm-color-preserve-properties) + (xterm-color-filter-strip string) + (cl-loop + with result + for (_ props substring) in (xterm-color--string-properties string) do + (push (if props substring (xterm-color-filter-strip substring)) + result) + finally return (mapconcat 'identity (nreverse result) "")))) + +;;;###autoload +(defun xterm-color-256 (color) + (cond ((and (>= color 232) + (<= color 255)) + ;; Grayscale + (let ((val (+ 8 (* (- color 232) 10)))) + (format "#%02x%02x%02x" val val val))) + ((<= color 7) + ;; Normal ANSI color + (aref xterm-color-names color)) + ((and (>= color 8) + (<= color 15)) + ;; Bright ANSI color + (aref xterm-color-names-bright (- color 8))) + (t (let* ((color (- color 16)) + (red (/ color 36)) + (color (mod color 36)) + (green (/ color 6)) + (color (mod color 6)) + (blue color)) + ;; XTERM 256 color + (format "#%02x%02x%02x" + (aref +xterm-color--table-256+ red) + (aref +xterm-color--table-256+ green) + (aref +xterm-color--table-256+ blue)))))) + + +;;; +;;; Interactive +;;; + + +;;;###autoload +(cl-defun xterm-color-colorize-buffer () + "Apply `xterm-color-filter' to current buffer, and replace its contents." + (interactive) + (let ((read-only-p buffer-read-only)) + (when read-only-p + (unless (y-or-n-p "Buffer is read only, continue colorizing? ") + (cl-return-from xterm-color-colorize-buffer)) + (read-only-mode -1)) + (insert (xterm-color-filter (delete-and-extract-region (point-min) (point-max)))) + (goto-char (point-min)) + (when read-only-p (read-only-mode 1)))) + +;;;###autoload +(defun xterm-color-clear-cache () + "Clear xterm color face attribute cache. +You may want to call this if you change `xterm-color-names' or +`xterm-color-names-bright' at runtime and you want to see the changes +take place in a pre-existing buffer that has had xterm-color initialized. + +Since the cache is buffer-local and created on-demand when needed, this has no +effect when called from a buffer that does not have a cache." + (interactive) + (and xterm-color--face-cache + (clrhash xterm-color--face-cache) + (message "Cleared xterm-color face attribute cache"))) + + +;;; +;;; Tests +;;; + + +(defmacro xterm-color--bench (path &optional repetitions) + `(benchmark-run-compiled ,repetitions + (with-temp-buffer + (insert-file-contents-literally ,path) + (xterm-color-colorize-buffer)))) + +(defvar xterm-color--test-do-filter t) + +(cl-defmacro xterm-color--with-tests (&body body) + `(cl-labels ((ansi-filter (msg &rest args) + (insert + (if xterm-color--test-do-filter + (xterm-color-filter + (apply 'format msg args)) + (apply 'format msg args)))) + (test (name &rest attribs) + (ansi-filter "\x1b[0;%smThis is only a test!\x1b[0m\t --[ %s ]\n" + (mapconcat 'identity attribs ";") + name))) + ,@body)) + +(defun xterm-color--test-ansi () + (xterm-color--with-tests + (let ((test-attributes + '(("1" . "bright") + ("51" . "frame") + ("3" . "italic") + ("4" . "underline") + ("7" . "negative") + ("9" . "strike through") + ("53" . "overline") + ("1;51" . "bright + frame") + ("1;3" . "bright + italic") + ("1;4" . "bright + underline") + ("1;7" . "bright + negative") + ("1;9" . "bright + strike through") + ("1;53" . "bright + overline")))) + + ;; Attributes (no color) + (insert "* ANSI attributes (default colors)\n") + + (if xterm-color-use-bold-for-bright + (insert " Expect: Bold instead of bright, if current Emacs font has bold variant") + (insert " Expect: Bright not to be rendered since no foreground color is set")) + (insert "\n\n") + + (cl-loop for (attrib . name) in test-attributes + do (test name attrib) + finally (insert "\n")) + + (insert "* ANSI attributes (blue foreground)\n") + + (if xterm-color-use-bold-for-bright + (insert " Expect: Bold instead of bright, if current Emacs font has bold variant") + (insert " Expect: Bright rendered as bright color")) + (insert "\n\n") + + (cl-loop for (attrib . name) in test-attributes + do (test name "34" attrib) + finally (insert "\n")) + + (insert "* ANSI attributes (blue background)\n") + + (if xterm-color-use-bold-for-bright + (insert " Expect: Bold instead of bright, if current Emacs font has bold variant") + (insert " Expect: Bright not to be rendered since no foreground color is set")) + (insert "\n\n") + + (cl-loop for (attrib . name) in test-attributes + do (test name "44" attrib) + finally (insert "\n")) + + (insert "* ANSI attributes (AIXTERM blue foreground)\n") + + (if xterm-color-use-bold-for-bright + (insert " Expect: Bold instead of bright, if current Emacs font has bold variant") + (insert " Expect: Bright color everywhere due to AIXTERM")) + (insert "\n\n") + + (cl-loop for (attrib . name) in test-attributes + do (test name "94" attrib) + finally (insert "\n")) + + (insert "* ANSI attributes (AIXTERM red background)\n") + (insert " Expect: Bright background color due to AIXTERM\n") + (if xterm-color-use-bold-for-bright + (insert " Expect: Bold instead of bright for foreground, if current Emacs font has bold variant\n\n") + (insert "\n")) + + (cl-loop for (attrib . name) in test-attributes + do (test name "101" attrib) + finally (insert "\n")) + + (insert "* Various\n") + (if xterm-color-use-bold-for-bright + (progn + (insert " Expect: Bold instead of bright, if current Emacs font has bold variant\n") + (insert " Otherwise bright rendered as normal intensity\n\n")) + (insert "\n")) + + (ansi-filter "Default \x1b[34;1mBright blue\x1b[39m Reset-fg-color \x1b[34mBlue (should be bright)\x1b[0m\t --[ Resetting FG color should not affect other SGR bits ]\n") + (ansi-filter "Default \x1b[94mBright blue\x1b[34m Switch-to-blue (should be normal intensity)\x1b[0m\t --[ AIXTERM bright color should not set bright SGR bit ]\n") + (insert "\n")))) + +(defun xterm-color--test-xterm () + (xterm-color--with-tests + ;; System colors + (cl-loop for color from 40 to 47 + do (ansi-filter "\x1b[0;%sm " color) + finally (ansi-filter "\x1b[0m * ANSI system colors\n")) + + ;; Normal ANSI colors mapped to XTERM + (cl-loop for color from 0 to 7 + do (ansi-filter "\x1b[48;5;%sm " color) + finally (ansi-filter "\x1b[0m * ANSI colors mapped to XTERM\n")) + + ;; Bright ANSI colors mapped to XTERM + (cl-loop for color from 8 to 15 + do (ansi-filter "\x1b[48;5;%sm " color) + finally (ansi-filter "\x1b[0m * ANSI bright colors mapped to XTERM\n\n")) + + ;; XTERM 256 color cubes + (insert "* XTERM 256 color cubes\n\n") + + (cl-loop for green from 0 to 5 do + (cl-loop for red from 0 to 5 do + (cl-loop for blue from 0 to 5 + for color = (+ 16 (* 36 red) (* green 6) blue) + do (ansi-filter "\x1b[48;5;%sm \x1b[0m" color)) + (ansi-filter "\x1b[0m ")) + (insert "\n")) + + (insert "\n") + (insert "* XTERM color grayscale ramp\n\n") + + (cl-loop for color from 232 to 255 + do (ansi-filter "\x1b[48;5;%sm " color) + finally (ansi-filter "\x1b[0m\n\n")))) + +;;;###autoload +(defun xterm-color-test () + "Create/display and render a new buffer that contains ANSI control sequences." + (interactive) + (let* ((name (generate-new-buffer-name "*xterm-color-test*")) + (buf (get-buffer-create name))) + (switch-to-buffer buf)) + + (xterm-color--test-xterm) + + (let ((xterm-color-use-bold-for-bright nil)) + (xterm-color--test-ansi)) + (xterm-color-clear-cache) + + (insert "; Temporarily setting `xterm-color-use-bold-for-bright' to T\n") + (insert "; Current Emacs font needs to have a bold variant\n\n") + + (let ((xterm-color-use-bold-for-bright t)) + (xterm-color--test-ansi)) + + (setq buffer-read-only t) + (goto-char (point-min))) + +;;;###autoload +(defun xterm-color-test-raw () + "Create and display a new buffer that contains ANSI SGR control sequences. +The ANSI sequences will not be processed. One can use a different Emacs +package (e.g. ansi-color.el) to do so. In that way it is easy to compare +xterm-color.el with libraries that offer similar functionality." + (interactive) + (let* ((name (generate-new-buffer-name "*xterm-color-test-raw*")) + (buf (get-buffer-create name))) + (switch-to-buffer buf)) + + (let (xterm-color--test-do-filter) + (xterm-color--test-xterm) + (xterm-color--test-ansi)) + (goto-char (point-min))) + +(provide 'xterm-color) +;;; xterm-color.el ends here diff --git a/packages/yaml-mode-20180409.607.el b/packages/yaml-mode-20190625.1740.el similarity index 99% rename from packages/yaml-mode-20180409.607.el rename to packages/yaml-mode-20190625.1740.el index 455fa26..6ec99cc 100644 --- a/packages/yaml-mode-20180409.607.el +++ b/packages/yaml-mode-20190625.1740.el @@ -6,9 +6,9 @@ ;; Marshall T. Vandegrift ;; Maintainer: Vasilij Schneidermann ;; Package-Requires: ((emacs "24.1")) -;; Package-Version: 20180409.607 +;; Package-Version: 20190625.1740 ;; Keywords: data yaml -;; Version: 0.0.13 +;; Version: 0.0.14 ;; This file is not part of Emacs @@ -118,7 +118,7 @@ that key is pressed to begin a block literal." ;; Constants -(defconst yaml-mode-version "0.0.13" "Version of `yaml-mode'.") +(defconst yaml-mode-version "0.0.14" "Version of `yaml-mode'.") (defconst yaml-blank-line-re "^ *$" "Regexp matching a line containing only (valid) whitespace.") diff --git a/packages/yang-mode-20190507.724.el b/packages/yang-mode-20190507.724.el new file mode 100644 index 0000000..33e61c5 --- /dev/null +++ b/packages/yang-mode-20190507.724.el @@ -0,0 +1,400 @@ +;;; yang-mode.el --- major mode for editing YANG files + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2 of the License, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;; Author: Martin Bjorklund +;; Version: 0.9.9 +;; Package-Version: 20190507.724 + +;;; Commentary: + +;; Note: The interface used in this file requires CC Mode 5.30 or +;; later. + +;; History: +;; 0.9.9 - 2019-05-07 +;; added support for YANG multiline string literals; contributed +;; by Tripp Lilley +;; 0.9.8 - 2018-03-06 +;; yet another autoload fix; contributed by Christian Hopps +;; 0.9.7 - 2017-03-23 +;; one more autoload fix +;; 0.9.6 - 2017-03-21 +;; autoload fix, tested with use-package +;; 0.9.5 - 2017-02-13 +;; autoload fix +;; 0.9.4 - 2016-12-20 +;; derive from prog-mode if available, otherwise nil +;; use proper syntax-table +;; 0.9.3 - 2016-12-13 +;; derive from nil +;; 0.9.2 - 2016-12-13 +;; derive mode from prog-mode in order to get correct hook behavior +;; 0.9.1 - 2016-12-12 +;; use define-derived-mode +;; yang-fill-paragraph now works in Emacs 23 +;; 0.9 - 2016-12-09 +;; workaround Emacs bug #18845 (for 24.4+) +;; 00.8 - 2016-10-27 +;; rfc7950 compliant +;; added yang-fill-paragraph for better string fill +;; 00.7 - 2016-03-15 +;; draft-ietf-netmod-rfc6020bis-11 compliant +;; added support for new 1.1 keywords +;; 00.6 - 2012-02-01 +;; removed unused defcustom yang-font-lock-extra-types +;; made emacs24 to give a warning +;; 00.5 - 2010-10-07 +;; rfc6020 compliant +;; classify all keywords as decl-start gives better indentation +;; 00.4 - 2010-04-30 +;; draft-ietf-netmod-yang-12 compliant, +;; added instructions for Emacs 23 +;; 00.3 - 2009-12-19 +;; draft-ietf-netmod-yang-09 compliant, +;; 00.2 - 2008-11-04 +;; draft-ietf-netmod-yang-02 compliant. +;; 00.1 - 2007-11-14 +;; Initial version, draft-bjorklund-netconf-yang-00 compliant. + +;; Useful tips: +;; +;; If you're using use-package, put this in your .emacs: +;; (use-package yang-mode +;; :ensure t) +;; +;; Otherwise, put this in your .emacs: +;; (require 'yang-mode) +;; +;; For use with Emacs 23, put this in your .emacs: +;; (autoload 'yang-mode "yang-mode" "Major mode for editing YANG modules." +;; t) +;; (add-to-list 'auto-mode-alist '("\\.yang$" . yang-mode)) +;; +;; Some users have reported other errors with Emacs 23, and have found +;; that removing the byte-compiled cc-mode.elc file fixes these problems. +;; (e.g. /usr/share/emacs/23.1/lisp/progmodes/cc-mode.elc) +;; +;; +;; For editing somewhat larger YANG modules, add this to your .emacs +;; (setq blink-matching-paren-distance nil) +;; +;; Common YANG layout: +;; (defun my-yang-mode-hook () +;; "Configuration for YANG Mode. Add this to `yang-mode-hook'." +;; (if window-system +;; (progn +;; (c-set-style "BSD") +;; (setq indent-tabs-mode nil) +;; (setq c-basic-offset 2) +;; (setq font-lock-maximum-decoration t) +;; (font-lock-mode t)))) +;; +;; (add-hook 'yang-mode-hook 'my-yang-mode-hook) +;; +;; Using the outline minor mode for YANG is very useful to get a +;; good overview of the structure of a module. +;; +;; Put this in your .emacs: +;; +;; (defun show-onelevel () +;; "show entry and children in outline mode" +;; (interactive) +;; (show-entry) +;; (show-children)) +;; +;; (defun my-outline-bindings () +;; "sets shortcut bindings for outline minor mode" +;; (interactive) +;; (local-set-key [?\C-,] 'hide-body) +;; (local-set-key [?\C-.] 'show-all) +;; (local-set-key [C-up] 'outline-previous-visible-heading) +;; (local-set-key [C-down] 'outline-next-visible-heading) +;; (local-set-key [C-left] 'hide-subtree) +;; (local-set-key [C-right] 'show-onelevel) +;; (local-set-key [M-up] 'outline-backward-same-level) +;; (local-set-key [M-down] 'outline-forward-same-level) +;; (local-set-key [M-left] 'hide-subtree) +;; (local-set-key [M-right] 'show-subtree)) +;; +;; (add-hook +;; 'outline-minor-mode-hook +;; 'my-outline-bindings) +;; +;; (defconst sort-of-yang-identifier-regexp "[-a-zA-Z0-9_\\.:]*") +;; +;; (add-hook +;; 'yang-mode-hook +;; '(lambda () +;; (outline-minor-mode) +;; (setq outline-regexp +;; (concat "^ *" sort-of-yang-identifier-regexp " *" +;; sort-of-yang-identifier-regexp +;; " *{")))) + +;;; Code: + +(require 'cc-mode) + +;; These are only required at compile time to get the sources for the +;; language constants. (The cc-fonts require and the font-lock +;; related constants could additionally be put inside an +;; (eval-after-load "font-lock" ...) but then some trickery is +;; necessary to get them compiled.) +(eval-when-compile + (require 'cc-langs) + (require 'cc-fonts)) + +(eval-and-compile + ;; Make our mode known to the language constant system. Use Java + ;; mode as the fallback for the constants we don't change here. + ;; This needs to be done also at compile time since the language + ;; constants are evaluated then. + (c-add-language 'yang-mode 'java-mode) + + ;; compatibility with emacs < 24 + (defalias 'yang-mode-prog-mode + (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode)) + ) + + +;; Work around Emacs bug #18845, cc-mode expects cl to be loaded +(eval-and-compile + (if (and (= emacs-major-version 24) (>= emacs-minor-version 4)) + (require 'cl))) + +;; YANG has no primitive types in the C/Java sense. +(c-lang-defconst c-primitive-type-kwds + yang '()) + +(c-lang-defconst c-modifier-kwds + yang '()) + +(c-lang-defconst c-multiline-string-start-char + yang t) + +(c-lang-defconst c-label-kwds + yang '()) + +(c-lang-defconst c-before-label-kwds + yang '()) + +(c-lang-defconst c-class-decl-kwds + yang '()) + +(c-lang-defconst c-decl-start-kwds + yang '( + "action" + "anydata" + "anyxml" + "argument" + "augment" + "base" + "belongs-to" + "bit" + "case" + "choice" + "config" + "contact" + "container" + "default" + "description" + "deviate" + "deviation" + "enum" + "error-app-tag" + "error-message" + "extension" + "feature" + "fraction-digits" + "grouping" + "identity" + "if-feature" + "import" + "include" + "input" + "key" + "leaf" + "leaf-list" + "length" + "list" + "mandatory" + "max-elements" + "min-elements" + "modifier" + "module" + "must" + "namespace" + "notification" + "ordered-by" + "organization" + "output" + "path" + "pattern" + "position" + "prefix" + "presence" + "range" + "reference" + "refine" + "require-instance" + "revision" + "revision-date" + "rpc" + "status" + "submodule" + "type" + "typedef" + "unique" + "units" + "uses" + "value" + "when" + "yang-version" + "yin-element" + )) + +;; No cpp in this language. (The definitions for the extra keywords +;; above are enough to incorporate them into the fontification regexps +;; for types and keywords, so no additional font-lock patterns are +;; required.) +(c-lang-defconst c-cpp-matchers + yang + ;; There are some other things in `c-cpp-matchers' besides the + ;; preprocessor support, so include it. + (c-lang-const c-cpp-matchers)) + +;; '-' is part of an identifier in YANG +;; FIXME: how do I make '.' part of the identifier? +(c-lang-defconst c-identifier-syntax-modifications + yang (append '((?- . "w") (?: . "w")) + (c-lang-const c-identifier-syntax-modifications))) + +(c-lang-defconst c-symbol-chars + yang (concat c-alnum ":_-")) + +;; YANG does not have labels +(c-lang-defconst c-recognize-colon-labels + yang nil) + +(defconst yang-font-lock-keywords-1 (c-lang-const c-matchers-1 yang) + "Minimal highlighting for YANG mode.") + +(defconst yang-font-lock-keywords-2 (c-lang-const c-matchers-2 yang) + "Fast normal highlighting for YANG mode.") + +(defconst yang-font-lock-keywords-3 (c-lang-const c-matchers-3 yang) + "Accurate normal highlighting for YANG mode.") + +(defvar yang-font-lock-keywords yang-font-lock-keywords-3 + "Default expressions to highlight in YANG mode.") + +(defvar yang-mode-syntax-table nil + "Syntax table used in `yang-mode' buffers.") +(or yang-mode-syntax-table + (setq yang-mode-syntax-table + (funcall (c-lang-const c-make-mode-syntax-table yang)))) + +(defvar yang-mode-map (let ((map (c-make-inherited-keymap))) + ;; Add bindings which are only useful for YANG + map) + "Keymap used in `yang-mode' buffers.") + +(easy-menu-define yang-menu yang-mode-map "YANG Mode Commands" + ;; Can use `yang' as the language for `c-mode-menu' + ;; since its definition covers any language. In + ;; this case the language is used to adapt to the + ;; nonexistence of a cpp pass and thus removing some + ;; irrelevant menu alternatives. + (cons "YANG" (c-lang-const c-mode-menu yang))) + +(defun yang-fill-paragraph (&optional arg) + "Like \\[c-fill-paragraph] but handles first line in strings properly. + + Optional prefix ARG means justify paragraph as well." + ;; c-fill-paragraph narrows the region to the contents of a string + ;; before filling, and this means that the start quote character + ;; will be in column 1 in the narrowed region. Thus the first line + ;; line will not be filled properly. + ;; This function handles this by temporarily inserting a newline + ;; followed by whitespaces to line up the first line before filling. + (interactive) + (save-excursion + (let ((limits (c-literal-limits)) + (tmppoint nil) + (col nil)) + (if (eq (c-literal-type limits) 'string) + (let ((curpoint (point))) + (backward-paragraph) + (if (< (point) (car limits)) + ;; do this in the first paragraph of a string + (let ((first-char (+ 1 (car limits)))) + (goto-char first-char) + (beginning-of-line) + (setq col (- first-char (point))) + (goto-char first-char) + (setq tmppoint (point)) + (insert-char ?\n 1) + (insert-char ?\s col)) + (goto-char curpoint)))) + (c-fill-paragraph arg) + (if tmppoint + (progn + (goto-char tmppoint) + (delete-char (+ 1 col)))))) + ;; Always return t. This has the effect that if filling isn't done + ;; above, it isn't done at all, and it's therefore effectively + ;; disabled in normal code. + t) + +;; It doesn't suffice to put `yang-fill-paragraph' on +;; `fill-paragraph-function' since `yang-fill-paragraph' must be called +;; before any fill prefix adaption is done. +(substitute-key-definition 'c-fill-paragraph 'yang-fill-paragraph + yang-mode-map c-mode-map) + +;;;###autoload +(define-derived-mode yang-mode yang-mode-prog-mode "YANG" + "Major mode for editing YANG modules. + +The hook `c-mode-common-hook' is run with no args at mode +initialization, then `yang-mode-hook'. + +Key bindings: +\\{yang-mode-map}" + :syntax-table yang-mode-syntax-table + (c-initialize-cc-mode t) + (c-init-language-vars yang-mode) + (c-common-init 'yang-mode) + + ;; Allow auto-fill in strings + (setq c-ignore-auto-fill '(cpp code)) + + ;; Install `yang-fill-paragraph' on `fill-paragraph-function' so + ;; that a direct call to `fill-paragraph' behaves better. + (make-local-variable fill-paragraph-function) + (setq fill-paragraph-function 'yang-fill-paragraph) + ;; we derive from prog-mode/nil rather than c-mode in order to not run + ;; c-mode-hooks; this means that we need to run c-mode-common-hook + ;; explicitly. + (c-run-mode-hooks 'c-mode-common-hook)) + +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.yang\\'" . yang-mode)) + +(provide 'yang-mode) + +;;; yang-mode.el ends here diff --git a/packages/yasnippet-20181015.1212.el b/packages/yasnippet-20190724.1204.el similarity index 92% rename from packages/yasnippet-20181015.1212.el rename to packages/yasnippet-20190724.1204.el index 58ff8fd..3ebdaba 100644 --- a/packages/yasnippet-20181015.1212.el +++ b/packages/yasnippet-20190724.1204.el @@ -1,12 +1,12 @@ -;;; yasnippet.el --- Yet another snippet extension for Emacs. +;;; yasnippet.el --- Yet another snippet extension for Emacs -;; Copyright (C) 2008-2018 Free Software Foundation, Inc. +;; Copyright (C) 2008-2019 Free Software Foundation, Inc. ;; Authors: pluskid , ;; João Távora , ;; Noam Postavsky ;; Maintainer: Noam Postavsky ;; Version: 0.13.0 -;; Package-Version: 20181015.1212 +;; Package-Version: 20190724.1204 ;; X-URL: http://github.com/joaotavora/yasnippet ;; Keywords: convenience, emulation ;; URL: http://github.com/joaotavora/yasnippet @@ -382,8 +382,7 @@ the trigger key itself." (defcustom yas-alias-to-yas/prefix-p t "If non-nil make aliases for the old style yas/ prefixed symbols. It must be set to nil before loading yasnippet to take effect." - :type 'boolean - :group 'yasnippet) + :type 'boolean) ;; Only two faces, and one of them shouldn't even be used... ;; @@ -414,15 +413,25 @@ This can be used as a key definition in keymaps to bind a key to `yas-clear-field' only when at the beginning of an unmodified snippet field.") -(defvar yas-keymap (let ((map (make-sparse-keymap))) - (define-key map [(tab)] 'yas-next-field-or-maybe-expand) - (define-key map (kbd "TAB") 'yas-next-field-or-maybe-expand) - (define-key map [(shift tab)] 'yas-prev-field) - (define-key map [backtab] 'yas-prev-field) - (define-key map (kbd "C-g") 'yas-abort-snippet) - (define-key map (kbd "C-d") yas-maybe-skip-and-clear-field) - (define-key map (kbd "DEL") yas-maybe-clear-field) - map) +(defun yas-filtered-definition (def) + "Return a condition key definition. +The condition will respect the value of `yas-keymap-disable-hook'." + `(menu-item "" ,def + :filter ,(lambda (cmd) (unless (run-hook-with-args-until-success + 'yas-keymap-disable-hook) + cmd)))) + +(defvar yas-keymap + (let ((map (make-sparse-keymap))) + (define-key map [(tab)] (yas-filtered-definition 'yas-next-field-or-maybe-expand)) + (define-key map (kbd "TAB") (yas-filtered-definition 'yas-next-field-or-maybe-expand)) + (define-key map [(shift tab)] (yas-filtered-definition 'yas-prev-field)) + (define-key map [backtab] (yas-filtered-definition 'yas-prev-field)) + (define-key map (kbd "C-g") (yas-filtered-definition 'yas-abort-snippet)) + ;; Yes, filters can be chained! + (define-key map (kbd "C-d") (yas-filtered-definition yas-maybe-skip-and-clear-field)) + (define-key map (kbd "DEL") (yas-filtered-definition yas-maybe-clear-field)) + map) "The active keymap while a snippet expansion is in progress.") (defvar yas-key-syntaxes (list #'yas-try-key-from-whitespace @@ -482,10 +491,8 @@ Attention: These hooks are not run when exiting nested/stacked snippet expansion "Hooks to run just before expanding a snippet.") (defconst yas-not-string-or-comment-condition - '(if (and (let ((ppss (syntax-ppss))) - (or (nth 3 ppss) (nth 4 ppss))) - (memq this-command '(yas-expand yas-expand-from-trigger-key - yas-expand-from-keymap))) + '(if (let ((ppss (syntax-ppss))) + (or (nth 3 ppss) (nth 4 ppss))) '(require-snippet-condition . force-in-comment) t) "Disables snippet expansion in strings and comments. @@ -548,12 +555,28 @@ conditions. (const :tag "Disable all snippet expansion" nil) sexp)) +(defcustom yas-keymap-disable-hook nil + "The `yas-keymap' bindings are disabled if any function in this list returns non-nil. +This is useful to control whether snippet navigation bindings +override bindings from other packages (e.g., `company-mode')." + :type 'hook) + (defcustom yas-overlay-priority 100 "Priority to use for yasnippets overlays. This is useful to control whether snippet navigation bindings -override bindings from other packages (e.g., `company-mode')." +override `keymap' overlay property bindings from other packages." :type 'integer) +(defcustom yas-inhibit-overlay-modification-protection nil + "If nil, changing text outside the active field aborts the snippet. +This protection is intended to prevent yasnippet from ending up +in an inconsistent state. However, some packages (e.g., the +company completion package) may trigger this protection when it +is not needed. In that case, setting this variable to non-nil +can be useful." + ;; See also `yas--on-protection-overlay-modification'. + :type 'boolean) + ;;; Internal variables @@ -767,12 +790,12 @@ expanded.") ["About" yas-about :help "Display some information about YASnippet"])) +(define-obsolete-variable-alias 'yas-extra-modes 'yas--extra-modes "0.9.1") (defvar yas--extra-modes nil "An internal list of modes for which to also lookup snippets. This variable probably makes more sense as buffer-local, so ensure your use `make-local-variable' when you set it.") -(define-obsolete-variable-alias 'yas-extra-modes 'yas--extra-modes "0.9.1") (defvar yas--tables (make-hash-table) "A hash table of mode symbols to `yas--table' objects.") @@ -919,9 +942,12 @@ activate snippets associated with that mode." (remove mode yas--extra-modes))) +(defun yas-temp-buffer-p (&optional buffer) + (eq (aref (buffer-name buffer) 0) ?\s)) + (define-obsolete-variable-alias 'yas-dont-activate 'yas-dont-activate-functions "0.9.2") -(defvar yas-dont-activate-functions (list #'minibufferp) +(defvar yas-dont-activate-functions (list #'minibufferp #'yas-temp-buffer-p) "Special hook to control which buffers `yas-global-mode' affects. Functions are called with no argument, and should return non-nil to prevent `yas-global-mode' from enabling yasnippet in this buffer. @@ -1666,10 +1692,8 @@ Here's a list of currently recognized directives: (let ((where (if (region-active-p) (cons (region-beginning) (region-end)) (cons (point) (point))))) - (yas-expand-snippet (yas--template-content yas--current-template) - (car where) - (cdr where) - (yas--template-expand-env yas--current-template))))))) + (yas-expand-snippet yas--current-template + (car where) (cdr where))))))) (defun yas--key-from-desc (text) "Return a yasnippet key from a description string TEXT." @@ -2346,6 +2370,10 @@ object satisfying `yas--field-p' to restrict the expansion to." (yas--fallback)))) (defun yas--maybe-expand-from-keymap-filter (cmd) + "Check whether a snippet may be expanded. +If there are expandable snippets, return CMD (this is useful for +conditional keybindings) or the list of expandable snippet +template objects if CMD is nil (this is useful as a more general predicate)." (let* ((yas--condition-cache-timestamp (current-time)) (vec (cl-subseq (this-command-keys-vector) (if current-prefix-arg @@ -2370,14 +2398,12 @@ object satisfying `yas--field-p' to restrict the expansion to." Prompt the user if TEMPLATES has more than one element, else expand immediately. Common gateway for `yas-expand-from-trigger-key' and `yas-expand-from-keymap'." - (let ((yas--current-template (or (and (cl-rest templates) ;; more than one - (yas--prompt-for-template (mapcar #'cdr templates))) - (cdar templates)))) + (let ((yas--current-template + (or (and (cl-rest templates) ;; more than one + (yas--prompt-for-template (mapcar #'cdr templates))) + (cdar templates)))) (when yas--current-template - (yas-expand-snippet (yas--template-content yas--current-template) - start - end - (yas--template-expand-env yas--current-template))))) + (yas-expand-snippet yas--current-template start end)))) ;; Apropos the trigger key and the fallback binding: ;; @@ -2522,10 +2548,7 @@ by condition." (cons (region-beginning) (region-end)) (cons (point) (point))))) (if yas--current-template - (yas-expand-snippet (yas--template-content yas--current-template) - (car where) - (cdr where) - (yas--template-expand-env yas--current-template)) + (yas-expand-snippet yas--current-template (car where) (cdr where)) (yas--message 1 "No snippets can be inserted here!")))) (defun yas-visit-snippet-file () @@ -2813,17 +2836,17 @@ DEBUG is for debugging the YASnippet engine itself." :name (nth 2 parsed) :expand-env (nth 5 parsed))))) (cond (yas--current-template - (let ((buffer-name (format "*testing snippet: %s*" (yas--template-name yas--current-template)))) + (let ((buffer-name + (format "*testing snippet: %s*" + (yas--template-name yas--current-template)))) (kill-buffer (get-buffer-create buffer-name)) (switch-to-buffer (get-buffer-create buffer-name)) (setq buffer-undo-list nil) (condition-case nil (funcall test-mode) (error nil)) (yas-minor-mode 1) (setq buffer-read-only nil) - (yas-expand-snippet (yas--template-content yas--current-template) - (point-min) - (point-max) - (yas--template-expand-env yas--current-template)) + (yas-expand-snippet yas--current-template + (point-min) (point-max)) (when (and debug (require 'yasnippet-debug nil t)) (yas-debug-snippets "*YASnippet trace*" 'snippet-navigation) @@ -3016,8 +3039,13 @@ snippet field. The arguments are the same as `completing-read'. (defun yas--auto-next () "Helper for `yas-auto-next'." - (remove-hook 'post-command-hook #'yas--auto-next t) - (yas-next-field)) + (cl-loop + do (progn (remove-hook 'post-command-hook #'yas--auto-next t) + (yas-next-field)) + ;; The transform in the next field may have requested auto-next as + ;; well. Call it ourselves, since the command loop itself won't + ;; recheck the value of post-command-hook while running it. + while (memq #'yas--auto-next post-command-hook))) (defmacro yas-auto-next (&rest body) "Automatically advance to next field after eval'ing BODY." @@ -3503,10 +3531,7 @@ This renders the snippet as ordinary text." (dolist (snippet snippets) (yas--snippet-map-markers (lambda (m) - (goto-char m) - (beginning-of-line) - (prog1 (cons (count-lines (point-min) (point)) - (yas--snapshot-marker-location m)) + (prog1 (cons m (yas--snapshot-line-location m)) (set-marker m nil))) snippet) (let ((ctrl-ov (yas--snapshot-overlay-line-location @@ -3514,23 +3539,27 @@ This renders the snippet as ordinary text." (push (list ctrl-ov dst-base-line snippet) to-move) (delete-overlay (car ctrl-ov)))) (with-current-buffer buf - (setq yas--snippets-to-move (nconc to-move yas--snippets-to-move)))))) + (cl-callf2 nconc to-move yas--snippets-to-move))))) (defun yas--on-buffer-kill () ;; Org mode uses temp buffers for fontification and "native tab", ;; move all the snippets to the original org-mode buffer when it's ;; killed. - (let ((org-marker nil)) + (let ((org-marker nil) + (org-buffer nil)) (when (and yas-minor-mode (or (bound-and-true-p org-edit-src-from-org-mode) (bound-and-true-p org-src--from-org-mode)) (markerp (setq org-marker (or (bound-and-true-p org-edit-src-beg-marker) - (bound-and-true-p org-src--beg-marker))))) + (bound-and-true-p org-src--beg-marker)))) + ;; If the org source buffer is killed before the temp + ;; fontification one, org-marker might point nowhere. + (setq org-buffer (marker-buffer org-marker))) (yas--prepare-snippets-for-move (point-min) (point-max) - (marker-buffer org-marker) org-marker)))) + org-buffer org-marker)))) (add-hook 'kill-buffer-hook #'yas--on-buffer-kill) @@ -3540,18 +3569,16 @@ This renders the snippet as ordinary text." for base-pos = (progn (goto-char (point-min)) (forward-line base-line) (point)) do (yas--snippet-map-markers - (lambda (l-m-r-w) - (goto-char base-pos) - (forward-line (nth 0 l-m-r-w)) - (save-restriction - (narrow-to-region (line-beginning-position) - (line-end-position)) - (yas--restore-marker-location (cdr l-m-r-w))) - (nth 1 l-m-r-w)) + (lambda (saved-location) + (let ((m (pop saved-location))) + (set-marker m (yas--goto-saved-line-location + base-pos saved-location)) + m)) snippet) (goto-char base-pos) - (yas--restore-overlay-location ctrl-ov) - (yas--maybe-move-to-active-field snippet)) + (yas--restore-overlay-line-location base-pos ctrl-ov) + (yas--maybe-move-to-active-field snippet) + (push snippet yas--active-snippets)) (setq yas--snippets-to-move nil)) (defun yas--safely-call-fun (fun) @@ -3756,13 +3783,49 @@ BEG, END and LENGTH like overlay modification hooks." (= beg (yas--field-start field)) ; Insertion at field start? (not (yas--field-modified-p field)))) + +(defun yas--merge-and-drop-dups (list1 list2 cmp key) + ;; `delete-consecutive-dups' + `cl-merge'. + (funcall (if (fboundp 'delete-consecutive-dups) + #'delete-consecutive-dups ; 24.4 + #'delete-dups) + (cl-merge 'list list1 list2 cmp :key key))) + +(defvar yas--before-change-modified-snippets nil) +(make-variable-buffer-local 'yas--before-change-modified-snippets) + +(defun yas--gather-active-snippets (overlay beg end then-delete) + ;; Add active snippets in BEG..END into an OVERLAY keyed entry of + ;; `yas--before-change-modified-snippets'. Return accumulated list. + ;; If THEN-DELETE is non-nil, delete the entry. + (let ((new (yas-active-snippets beg end)) + (old (assq overlay yas--before-change-modified-snippets))) + (prog1 (cond ((and new old) + (setf (cdr old) + (yas--merge-and-drop-dups + (cdr old) new + ;; Sort like `yas-active-snippets'. + #'>= #'yas--snippet-id))) + (new (unless then-delete + ;; Don't add new entry if we're about to + ;; remove it anyway. + (push (cons overlay new) + yas--before-change-modified-snippets)) + new) + (old (cdr old)) + (t nil)) + (when then-delete + (cl-callf2 delq old yas--before-change-modified-snippets))))) + +(defvar yas--todo-snippet-indent nil nil) +(make-variable-buffer-local 'yas--todo-snippet-indent) + (defun yas--on-field-overlay-modification (overlay after? beg end &optional length) "Clears the field and updates mirrors, conditionally. Only clears the field if it hasn't been modified and point is at field start. This hook does nothing if an undo is in progress." - (unless (or (not after?) - yas--inhibit-overlay-hooks + (unless (or yas--inhibit-overlay-hooks (not (overlayp yas--active-field-overlay)) ; Avoid Emacs bug #21824. ;; If a single change hits multiple overlays of the same ;; snippet, then we delete the snippet the first time, @@ -3775,28 +3838,52 @@ field start. This hook does nothing if an undo is in progress." (field (overlay-get overlay 'yas--field)) (snippet (overlay-get yas--active-field-overlay 'yas--snippet))) (if (yas--snippet-live-p snippet) - (save-match-data - (yas--letenv (yas--snippet-expand-env snippet) - (when (yas--skip-and-clear-field-p field beg end length) - ;; We delete text starting from the END of insertion. - (yas--skip-and-clear field end)) - (setf (yas--field-modified-p field) t) - ;; Adjust any pending active fields in case of stacked - ;; expansion. - (let ((pfield field) - (psnippets (yas-active-snippets beg end))) - (while (and pfield psnippets) - (let ((psnippet (pop psnippets))) - (cl-assert (memq pfield (yas--snippet-fields psnippet))) - (yas--advance-end-maybe pfield (overlay-end overlay)) - (setq pfield (yas--snippet-previous-active-field psnippet))))) - (save-excursion - (yas--field-update-display field)) - (yas--update-mirrors snippet))) + (if after? + (save-match-data + (yas--letenv (yas--snippet-expand-env snippet) + (when (yas--skip-and-clear-field-p field beg end length) + ;; We delete text starting from the END of insertion. + (yas--skip-and-clear field end)) + (setf (yas--field-modified-p field) t) + ;; Adjust any pending active fields in case of stacked + ;; expansion. + (let ((pfield field) + (psnippets (yas--gather-active-snippets + overlay beg end t))) + (while (and pfield psnippets) + (let ((psnippet (pop psnippets))) + (cl-assert (memq pfield (yas--snippet-fields psnippet))) + (yas--advance-end-maybe pfield (overlay-end overlay)) + (setq pfield (yas--snippet-previous-active-field psnippet))))) + ;; Update fields now, but delay auto indentation until + ;; post-command. We don't want to run indentation on + ;; the intermediate state where field text might be + ;; removed (and hence the field could be deleted along + ;; with leading indentation). + (let ((yas-indent-line nil)) + (save-excursion + (yas--field-update-display field)) + (yas--update-mirrors snippet)) + (unless (or (not (eq yas-indent-line 'auto)) + (memq snippet yas--todo-snippet-indent)) + (push snippet yas--todo-snippet-indent)))) + ;; Remember active snippets to use for after the change. + (yas--gather-active-snippets overlay beg end nil)) (lwarn '(yasnippet zombie) :warning "Killing zombie snippet!") (delete-overlay overlay))))) +(defun yas--do-todo-snippet-indent () + ;; Do pending indentation of snippet fields, called from + ;; `yas--post-command-handler'. + (when yas--todo-snippet-indent + (save-excursion + (cl-loop for snippet in yas--todo-snippet-indent + do (yas--indent-mirrors-of-snippet + snippet (yas--snippet-field-mirrors snippet))) + (setq yas--todo-snippet-indent nil)))) + (defun yas--auto-fill () + ;; Preserve snippet markers during auto-fill. (let* ((orig-point (point)) (end (progn (forward-paragraph) (point))) (beg (progn (backward-paragraph) (point))) @@ -3806,57 +3893,59 @@ field start. This hook does nothing if an undo is in progress." (dolist (snippet snippets) (dolist (m (yas--collect-snippet-markers snippet)) (when (and (<= beg m) (<= m end)) - (push (yas--snapshot-marker-location m beg end) remarkers))) + (push (cons m (yas--snapshot-location m beg end)) remarkers))) (push (yas--snapshot-overlay-location (yas--snippet-control-overlay snippet) beg end) reoverlays)) (goto-char orig-point) (let ((yas--inhibit-overlay-hooks t)) - (if (null yas--original-auto-fill-function) - ;; Try to get more info on #873/919. - (let ((yas--fill-fun-values `((t ,(default-value 'yas--original-auto-fill-function)))) - (fill-fun-values `((t ,(default-value 'auto-fill-function)))) - ;; Listing 2 buffers with the same value is enough - (print-length 3)) - (save-current-buffer - (dolist (buf (let ((bufs (buffer-list))) - ;; List the current buffer first. - (setq bufs (cons (current-buffer) - (remq (current-buffer) bufs))))) - (set-buffer buf) - (let* ((yf-cell (assq yas--original-auto-fill-function - yas--fill-fun-values)) - (af-cell (assq auto-fill-function fill-fun-values))) - (when (local-variable-p 'yas--original-auto-fill-function) - (if yf-cell (setcdr yf-cell (cons buf (cdr yf-cell))) - (push (list yas--original-auto-fill-function buf) yas--fill-fun-values))) - (when (local-variable-p 'auto-fill-function) - (if af-cell (setcdr af-cell (cons buf (cdr af-cell))) - (push (list auto-fill-function buf) fill-fun-values)))))) - (lwarn '(yasnippet auto-fill bug) :error - "`yas--original-auto-fill-function' unexpectedly nil in %S! Disabling auto-fill. + (if yas--original-auto-fill-function + (funcall yas--original-auto-fill-function) + ;; Shouldn't happen, gather more info about it (see #873/919). + (let ((yas--fill-fun-values `((t ,(default-value 'yas--original-auto-fill-function)))) + (fill-fun-values `((t ,(default-value 'auto-fill-function)))) + ;; Listing 2 buffers with the same value is enough + (print-length 3)) + (save-current-buffer + (dolist (buf (let ((bufs (buffer-list))) + ;; List the current buffer first. + (setq bufs (cons (current-buffer) + (remq (current-buffer) bufs))))) + (set-buffer buf) + (let* ((yf-cell (assq yas--original-auto-fill-function + yas--fill-fun-values)) + (af-cell (assq auto-fill-function fill-fun-values))) + (when (local-variable-p 'yas--original-auto-fill-function) + (if yf-cell (setcdr yf-cell (cons buf (cdr yf-cell))) + (push (list yas--original-auto-fill-function buf) yas--fill-fun-values))) + (when (local-variable-p 'auto-fill-function) + (if af-cell (setcdr af-cell (cons buf (cdr af-cell))) + (push (list auto-fill-function buf) fill-fun-values)))))) + (lwarn '(yasnippet auto-fill bug) :error + "`yas--original-auto-fill-function' unexpectedly nil in %S! Disabling auto-fill. %S `auto-fill-function': %S\n%s" - (current-buffer) yas--fill-fun-values fill-fun-values - (if (fboundp 'backtrace--print-frame) - (with-output-to-string - (mapc (lambda (frame) - (apply #'backtrace--print-frame frame)) - yas--watch-auto-fill-backtrace)) - "")) - ;; Try to avoid repeated triggering of this bug. - (auto-fill-mode -1) - ;; Don't pop up more than once in a session (still log though). - (defvar warning-suppress-types) ; `warnings' is autoloaded by `lwarn'. - (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))) - (funcall yas--original-auto-fill-function))) + (current-buffer) yas--fill-fun-values fill-fun-values + (if (fboundp 'backtrace--print-frame) + (with-output-to-string + (mapc (lambda (frame) + (apply #'backtrace--print-frame frame)) + yas--watch-auto-fill-backtrace)) + "")) + ;; Try to avoid repeated triggering of this bug. + (auto-fill-mode -1) + ;; Don't pop up more than once in a session (still log though). + (defvar warning-suppress-types) ; `warnings' is autoloaded by `lwarn'. + (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))))) (save-excursion (setq end (progn (forward-paragraph) (point))) (setq beg (progn (backward-paragraph) (point)))) (save-excursion (save-restriction (narrow-to-region beg end) - (mapc #'yas--restore-marker-location remarkers) + (dolist (remarker remarkers) + (set-marker (car remarker) + (yas--goto-saved-location (cdr remarker)))) (mapc #'yas--restore-overlay-location reoverlays)) (mapc (lambda (snippet) (yas--letenv (yas--snippet-expand-env snippet) @@ -3910,6 +3999,7 @@ Move the overlays, or create them if they do not exit." (defun yas--on-protection-overlay-modification (_overlay after? beg end &optional length) "Commit the snippet if the protection overlay is being killed." (unless (or yas--inhibit-overlay-hooks + yas-inhibit-overlay-modification-protection (not after?) (= length (- end beg)) ; deletion or insertion (yas--undo-in-progress)) @@ -4064,6 +4154,7 @@ After revival, push the `yas--take-care-of-redo' in the (when (yas--maybe-move-to-active-field snippet) (setf (yas--snippet-control-overlay snippet) (yas--make-control-overlay snippet beg end)) (overlay-put (yas--snippet-control-overlay snippet) 'yas--snippet snippet) + (push snippet yas--active-snippets) (when (listp buffer-undo-list) (push `(apply yas--take-care-of-redo ,snippet) buffer-undo-list)))) @@ -4335,35 +4426,54 @@ Meant to be called in a narrowed buffer, does various passes" ;; current paragraph instead of line. ;; ;; 2. Moving snippets from an `org-src' temp buffer into the main org -;; buffer, in this case we need to count the line offsets (because org -;; may add indentation on each line making character positions -;; unreliable). +;; buffer, in this case we need to count the relative line number +;; (because org may add indentation on each line making character +;; positions unreliable). +;; +;; Data formats: +;; (LOCATION) = (REGEXP WS-COUNT) +;; MARKER -> (MARKER . (LOCATION)) +;; OVERLAY -> (OVERLAY LOCATION-BEG LOCATION-END) +;; +;; For `org-src' temp buffer, add a line number to format: +;; (LINE-LOCATION) = (LINE . (LOCATION)) +;; MARKER@LINE -> (MARKER . (LINE-LOCATION)) +;; OVERLAY@LINE -> (OVERLAY LINE-LOCATION-BEG LINE-LOCATION-END) ;; ;; This is all best-effort heuristic stuff, but it should cover 99% of ;; use-cases. -(defun yas--snapshot-marker-location (marker &optional beg end) - "Returns info for restoring MARKER's location after indent. -The returned value is a list of the form (MARKER REGEXP WS-COUNT)." +(defun yas--snapshot-location (position &optional beg end) + "Returns info for restoring POSITIONS's location after indent. +The returned value is a list of the form (REGEXP WS-COUNT). +POSITION may be either a marker or just a buffer position. The +REGEXP matches text between BEG..END which default to the current +line if omitted." + (goto-char position) (unless beg (setq beg (line-beginning-position))) (unless end (setq end (line-end-position))) - (let ((before (split-string (buffer-substring-no-properties beg marker) + (let ((before (split-string (buffer-substring-no-properties beg position) "[[:space:]\n]+" t)) - (after (split-string (buffer-substring-no-properties marker end) + (after (split-string (buffer-substring-no-properties position end) "[[:space:]\n]+" t))) - (list marker - (concat "[[:space:]\n]*" + (list (concat "[[:space:]\n]*" (mapconcat (lambda (s) - (if (eq s marker) "\\(\\)" + (if (eq s position) "\\(\\)" (regexp-quote s))) - (nconc before (list marker) after) + (nconc before (list position) after) "[[:space:]\n]*")) - (progn (goto-char marker) - (skip-chars-forward "[:space:]\n" end) - (- (point) marker))))) + (progn (skip-chars-forward "[:space:]\n" end) + (- (point) position))))) + +(defun yas--snapshot-line-location (position &optional beg end) + "Like `yas--snapshot-location', but return also line number. +Returned format is (LINE REGEXP WS-COUNT)." + (goto-char position) + (cons (count-lines (point-min) (line-beginning-position)) + (yas--snapshot-location position beg end))) (defun yas--snapshot-overlay-location (overlay beg end) - "Like `yas--snapshot-marker-location' for overlays. + "Like `yas--snapshot-location' for overlays. The returned format is (OVERLAY (RE WS) (RE WS)). Either of the (RE WS) lists may be nil if the start or end, respectively, of the overlay is outside the range BEG .. END." @@ -4371,67 +4481,59 @@ of the overlay is outside the range BEG .. END." (oend (overlay-end overlay))) (list overlay (when (and (<= beg obeg) (< obeg end)) - (cdr (yas--snapshot-marker-location obeg beg end))) + (yas--snapshot-location obeg beg end)) (when (and (<= beg oend) (< oend end)) - (cdr (yas--snapshot-marker-location oend beg end)))))) + (yas--snapshot-location oend beg end))))) (defun yas--snapshot-overlay-line-location (overlay) "Return info for restoring OVERLAY's line based location. The returned format is (OVERLAY (LINE RE WS) (LINE RE WS))." - (let ((loc-beg (progn (goto-char (overlay-start overlay)) - (yas--snapshot-marker-location (point)))) - (loc-end (progn (goto-char (overlay-end overlay)) - (yas--snapshot-marker-location (point))))) - (setcar loc-beg (count-lines (point-min) (progn (goto-char (car loc-beg)) - (line-beginning-position)))) - (setcar loc-end (count-lines (point-min) (progn (goto-char (car loc-end)) - (line-beginning-position)))) - (list overlay loc-beg loc-end))) - -(defun yas--goto-saved-location (regexp ws-count) - "Move point to location saved by `yas--snapshot-marker-location'. -Buffer must be narrowed to BEG..END used to create the snapshot info." - (goto-char (point-min)) - (if (not (looking-at regexp)) - (lwarn '(yasnippet re-marker) :warning - "Couldn't find: %S" regexp) - (goto-char (match-beginning 1)) - (skip-chars-forward "[:space:]\n") - (skip-chars-backward "[:space:]\n" (- (point) ws-count)))) - -(defun yas--restore-marker-location (re-marker) - "Restores marker based on info from `yas--snapshot-marker-location'. + (list overlay + (yas--snapshot-line-location (overlay-start overlay)) + (yas--snapshot-line-location (overlay-end overlay)))) + +(defun yas--goto-saved-location (re-count) + "Move to and return point saved by `yas--snapshot-location'. Buffer must be narrowed to BEG..END used to create the snapshot info." - (apply #'yas--goto-saved-location (cdr re-marker)) - (set-marker (car re-marker) (point))) + (let ((regexp (pop re-count)) + (ws-count (pop re-count))) + (goto-char (point-min)) + (if (not (looking-at regexp)) + (lwarn '(yasnippet re-marker) :warning + "Couldn't find: %S" regexp) + (goto-char (match-beginning 1)) + (skip-chars-forward "[:space:]\n") + (skip-chars-backward "[:space:]\n" (- (point) ws-count))) + (point))) (defun yas--restore-overlay-location (ov-locations) - "Restores marker based on info from `yas--snapshot-marker-location'. + "Restores marker based on info from `yas--snapshot-overlay-location'. Buffer must be narrowed to BEG..END used to create the snapshot info." (cl-destructuring-bind (overlay loc-beg loc-end) ov-locations (move-overlay overlay (if (not loc-beg) (overlay-start overlay) - (apply #'yas--goto-saved-location loc-beg) - (point)) + (yas--goto-saved-location loc-beg)) (if (not loc-end) (overlay-end overlay) - (apply #'yas--goto-saved-location loc-end) - (point))))) - - -(defun yas--restore-overlay-line-location (ov-locations) - "Restores overlay based on info from `yas--snapshot-overlay-line-location'." + (yas--goto-saved-location loc-end))))) + +(defun yas--goto-saved-line-location (base-pos l-re-count) + "Move to and return point saved by `yas--snapshot-line-location'. +Additionally requires BASE-POS to tell where the line numbers are +relative to." + (goto-char base-pos) + (forward-line (pop l-re-count)) (save-restriction - (move-overlay (car ov-locations) - (save-excursion - (forward-line (car (nth 1 ov-locations))) - (narrow-to-region (line-beginning-position) (line-end-position)) - (apply #'yas--goto-saved-location (cdr (nth 1 ov-locations))) - (point)) - (save-excursion - (forward-line (car (nth 2 ov-locations))) - (narrow-to-region (line-beginning-position) (line-end-position)) - (apply #'yas--goto-saved-location (cdr (nth 2 ov-locations))) - (point))))) + (narrow-to-region (line-beginning-position) + (line-end-position)) + (yas--goto-saved-location l-re-count))) + +(defun yas--restore-overlay-line-location (base-pos ov-locations) + "Restores marker based on info from `yas--snapshot-overlay-line-location'." + (cl-destructuring-bind (overlay beg-l-r-w end-l-r-w) + ov-locations + (move-overlay overlay + (yas--goto-saved-line-location base-pos beg-l-r-w) + (yas--goto-saved-line-location base-pos end-l-r-w)))) (defun yas--indent-region (from to snippet) "Indent the lines between FROM and TO with `indent-according-to-mode'. @@ -4450,14 +4552,16 @@ The SNIPPET's markers are preserved." (let ((remarkers nil)) (dolist (m snippet-markers) (when (and (<= bol m) (<= m eol)) - (push (yas--snapshot-marker-location m bol eol) + (push (cons m (yas--snapshot-location m bol eol)) remarkers))) (unwind-protect (progn (back-to-indentation) (indent-according-to-mode)) (save-restriction (narrow-to-region bol (line-end-position)) - (mapc #'yas--restore-marker-location remarkers)))) + (dolist (remarker remarkers) + (set-marker (car remarker) + (yas--goto-saved-location (cdr remarker))))))) while (and (zerop (forward-line 1)) (< (point) to))))))) @@ -4585,7 +4689,10 @@ SAVED-QUOTES is the in format returned by `yas--save-backquotes'." (defun yas--scan-sexps (from count) (ignore-errors (save-match-data ; `scan-sexps' may modify match data. + ;; Parse using the syntax table corresponding to the yasnippet syntax. (with-syntax-table (standard-syntax-table) + ;; And ignore syntax-table properties that may have been placed by the + ;; major mode since these aren't related to the yasnippet syntax. (let ((parse-sexp-lookup-properties nil)) (scan-sexps from count)))))) @@ -4755,46 +4862,58 @@ When multiple expressions are found, only the last one counts." (parent 1) (t 0)))))) +(defun yas--snippet-field-mirrors (snippet) + ;; Make a list of (FIELD . MIRROR). + (cl-sort + (cl-mapcan (lambda (field) + (mapcar (lambda (mirror) + (cons field mirror)) + (yas--field-mirrors field))) + (yas--snippet-fields snippet)) + ;; Then sort this list so that entries with mirrors with + ;; parent fields appear before. This was important for + ;; fixing #290, and also handles the case where a mirror in + ;; a field causes another mirror to need reupdating. + #'> :key (lambda (fm) (yas--calculate-mirror-depth (cdr fm))))) + +(defun yas--indent-mirrors-of-snippet (snippet &optional f-ms) + ;; Indent mirrors of SNIPPET. F-MS is the return value of + ;; (yas--snippet-field-mirrors SNIPPET). + (when (eq yas-indent-line 'auto) + (let ((yas--inhibit-overlay-hooks t)) + (cl-loop for (beg . end) in + (cl-sort (mapcar (lambda (f-m) + (let ((mirror (cdr f-m))) + (cons (yas--mirror-start mirror) + (yas--mirror-end mirror)))) + (or f-ms + (yas--snippet-field-mirrors snippet))) + #'< :key #'car) + do (yas--indent-region beg end snippet))))) + (defun yas--update-mirrors (snippet) "Update all the mirrors of SNIPPET." (yas--save-restriction-and-widen (save-excursion - (cl-loop - for (field . mirror) - in (cl-sort - ;; Make a list of (FIELD . MIRROR). - (cl-mapcan (lambda (field) - (mapcar (lambda (mirror) - (cons field mirror)) - (yas--field-mirrors field))) - (yas--snippet-fields snippet)) - ;; Then sort this list so that entries with mirrors with - ;; parent fields appear before. This was important for - ;; fixing #290, and also handles the case where a mirror in - ;; a field causes another mirror to need reupdating. - #'> :key (lambda (fm) (yas--calculate-mirror-depth (cdr fm)))) - ;; Before updating a mirror with a parent-field, maybe advance - ;; its start (#290). - do (let ((parent-field (yas--mirror-parent-field mirror))) - (when parent-field - (yas--advance-start-maybe mirror (yas--fom-start parent-field)))) - ;; Update this mirror. - do (yas--mirror-update-display mirror field) - ;; Delay indenting until we're done all mirrors. We must do - ;; this to avoid losing whitespace between fields that are - ;; still empty (i.e., they will be non-empty after updating). - when (eq yas-indent-line 'auto) - collect (cons (yas--mirror-start mirror) (yas--mirror-end mirror)) - into indent-regions - ;; `yas--place-overlays' is needed since the active field and - ;; protected overlays might have been changed because of insertions - ;; in `yas--mirror-update-display'. - do (let ((active-field (yas--snippet-active-field snippet))) - (when active-field (yas--place-overlays snippet active-field))) - finally do - (let ((yas--inhibit-overlay-hooks t)) - (cl-loop for (beg . end) in (cl-sort indent-regions #'< :key #'car) - do (yas--indent-region beg end snippet))))))) + (let ((f-ms (yas--snippet-field-mirrors snippet))) + (cl-loop + for (field . mirror) in f-ms + ;; Before updating a mirror with a parent-field, maybe advance + ;; its start (#290). + do (let ((parent-field (yas--mirror-parent-field mirror))) + (when parent-field + (yas--advance-start-maybe mirror (yas--fom-start parent-field)))) + ;; Update this mirror. + do (yas--mirror-update-display mirror field) + ;; `yas--place-overlays' is needed since the active field and + ;; protected overlays might have been changed because of insertions + ;; in `yas--mirror-update-display'. + do (let ((active-field (yas--snippet-active-field snippet))) + (when active-field (yas--place-overlays snippet active-field)))) + ;; Delay indenting until we're done all mirrors. We must do + ;; this to avoid losing whitespace between fields that are + ;; still empty (i.e., they will be non-empty after updating). + (yas--indent-mirrors-of-snippet snippet f-ms))))) (defun yas--mirror-update-display (mirror field) "Update MIRROR according to FIELD (and mirror transform)." @@ -4852,6 +4971,7 @@ When multiple expressions are found, only the last one counts." ;; Don't pop up more than once in a session (still log though). (defvar warning-suppress-types) ; `warnings' is autoloaded by `lwarn'. (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))) + (yas--do-todo-snippet-indent) (condition-case err (progn (yas--finish-moving-snippets) (cond ((eq 'undo this-command) diff --git a/packages/yasnippet-snippets-20181107.2203.tar b/packages/yasnippet-snippets-20190821.901.tar similarity index 59% rename from packages/yasnippet-snippets-20181107.2203.tar rename to packages/yasnippet-snippets-20190821.901.tar index c3b9875..d8b0501 100644 Binary files a/packages/yasnippet-snippets-20181107.2203.tar and b/packages/yasnippet-snippets-20190821.901.tar differ diff --git a/packages/yatemplate-20180617.952.tar b/packages/yatemplate-20180617.952.tar index 86f8971..b350b24 100644 Binary files a/packages/yatemplate-20180617.952.tar and b/packages/yatemplate-20180617.952.tar differ diff --git a/packages/ycmd-20180724.1256.tar b/packages/ycmd-20190416.807.tar similarity index 98% rename from packages/ycmd-20180724.1256.tar rename to packages/ycmd-20190416.807.tar index 2641fbe..3ce16ea 100644 Binary files a/packages/ycmd-20180724.1256.tar and b/packages/ycmd-20190416.807.tar differ diff --git a/packages/zenburn-theme-20181014.1555.el b/packages/zenburn-theme-20190809.1324.el similarity index 93% rename from packages/zenburn-theme-20181014.1555.el rename to packages/zenburn-theme-20190809.1324.el index 7da640b..470640e 100644 --- a/packages/zenburn-theme-20181014.1555.el +++ b/packages/zenburn-theme-20190809.1324.el @@ -4,7 +4,7 @@ ;; Author: Bozhidar Batsov ;; URL: http://github.com/bbatsov/zenburn-emacs -;; Package-Version: 20181014.1555 +;; Package-Version: 20190809.1324 ;; Version: 2.7-snapshot ;; This program is free software; you can redistribute it and/or modify @@ -36,6 +36,7 @@ (defgroup zenburn-theme nil "Zenburn theme." + :group 'faces :prefix "zenburn-theme-" :link '(url-link :tag "GitHub" "http://github.com/bbatsov/zenburn-emacs") :tag "Zenburn theme") @@ -102,30 +103,33 @@ defining them in this alist." ;;; Color Palette (defvar zenburn-default-colors-alist - '(("zenburn-fg+1" . "#FFFFEF") + '(("zenburn-fg-1" . "#656555") + ("zenburn-fg-05" . "#989890") ("zenburn-fg" . "#DCDCCC") - ("zenburn-fg-1" . "#656555") + ("zenburn-fg+1" . "#FFFFEF") + ("zenburn-fg+2" . "#FFFFFD") ("zenburn-bg-2" . "#000000") ("zenburn-bg-1" . "#2B2B2B") + ("zenburn-bg-08" . "#303030") ("zenburn-bg-05" . "#383838") ("zenburn-bg" . "#3F3F3F") ("zenburn-bg+05" . "#494949") ("zenburn-bg+1" . "#4F4F4F") ("zenburn-bg+2" . "#5F5F5F") ("zenburn-bg+3" . "#6F6F6F") - ("zenburn-red+2" . "#ECB3B3") - ("zenburn-red+1" . "#DCA3A3") - ("zenburn-red" . "#CC9393") - ("zenburn-red-1" . "#BC8383") - ("zenburn-red-2" . "#AC7373") - ("zenburn-red-3" . "#9C6363") - ("zenburn-red-4" . "#8C5353") - ("zenburn-red-5" . "#7C4343") ("zenburn-red-6" . "#6C3333") + ("zenburn-red-5" . "#7C4343") + ("zenburn-red-4" . "#8C5353") + ("zenburn-red-3" . "#9C6363") + ("zenburn-red-2" . "#AC7373") + ("zenburn-red-1" . "#BC8383") + ("zenburn-red" . "#CC9393") + ("zenburn-red+1" . "#DCA3A3") + ("zenburn-red+2" . "#ECB3B3") ("zenburn-orange" . "#DFAF8F") - ("zenburn-yellow" . "#F0DFAF") - ("zenburn-yellow-1" . "#E0CF9F") ("zenburn-yellow-2" . "#D0BF8F") + ("zenburn-yellow-1" . "#E0CF9F") + ("zenburn-yellow" . "#F0DFAF") ("zenburn-green-5" . "#2F4F2F") ("zenburn-green-4" . "#3F5F3F") ("zenburn-green-3" . "#4F6F4F") @@ -204,6 +208,12 @@ Also bind `class' to ((class color) (min-colors 89))." `(compilation-mode-line-run ((t (:foreground ,zenburn-yellow :weight bold)))) ;;;;; completions `(completions-annotations ((t (:foreground ,zenburn-fg-1)))) +;;;;; customize + `(custom-variable-tag ((t (:foreground ,zenburn-blue :weight bold)))) + `(custom-group-tag ((t (:foreground ,zenburn-blue :weight bold :height 1.2)))) + `(custom-state ((t (:foreground ,zenburn-green+4)))) +;;;;; display-fill-column-indicator + `(fill-column-indicator ((,class :foreground ,zenburn-bg-05 :weight semilight))) ;;;;; eww '(eww-invalid-certificate ((t (:inherit error)))) '(eww-valid-certificate ((t (:inherit success)))) @@ -394,6 +404,15 @@ Also bind `class' to ((class color) (min-colors 89))." `(cfw:face-toolbar ((t (:background ,zenburn-blue-5)))) `(cfw:face-toolbar-button-off ((t (:underline nil :inherit link)))) `(cfw:face-toolbar-button-on ((t (:underline nil :inherit link-visited)))) +;;;;; centaur-tabs + `(centaur-tabs-default ((t (:background ,zenburn-bg :foreground ,zenburn-fg :box nil)))) + `(centaur-tabs-selected ((t (:background ,zenburn-bg :foreground ,zenburn-fg+2 :box nil)))) + `(centaur-tabs-unselected ((t (:background ,zenburn-bg-1 :foreground ,zenburn-fg-05 :box nil)))) + `(centaur-tabs-selected-modified ((t (:background ,zenburn-bg :foreground ,zenburn-orange :box nil)))) + `(centaur-tabs-unselected-modified ((t (:background ,zenburn-bg-1 :foreground ,zenburn-orange :box nil)))) + `(centaur-tabs-active-bar-face ((t (:background ,zenburn-yellow :box nil)))) + `(centaur-tabs-modified-marker-selected ((t (:inherit 'centaur-tabs-selected-modified :foreground ,zenburn-yellow :box nil)))) + `(centaur-tabs-modified-marker-unselected ((t (:inherit 'centaur-tabs-unselected-modified :foreground ,zenburn-yellow :box nil)))) ;;;;; cider `(cider-result-overlay-face ((t (:background unspecified)))) `(cider-enlightened-face ((t (:box (:color ,zenburn-orange :line-width -1))))) @@ -439,12 +458,13 @@ Also bind `class' to ((class color) (min-colors 89))." `(debbugs-gnu-stale ((t (:foreground ,zenburn-orange)))) `(debbugs-gnu-tagged ((t (:foreground ,zenburn-red)))) ;;;;; diff - `(diff-added ((t (:background ,zenburn-green-5 :foreground ,zenburn-green+2)))) + ;; Please read (info "(magit)Theming Faces") before changing this. + `(diff-added ((t (:background "#335533" :foreground ,zenburn-green)))) `(diff-changed ((t (:background "#555511" :foreground ,zenburn-yellow-1)))) - `(diff-removed ((t (:background ,zenburn-red-6 :foreground ,zenburn-red+1)))) - `(diff-refine-added ((t (:background ,zenburn-green-4 :foreground ,zenburn-green+3)))) + `(diff-removed ((t (:background "#553333" :foreground ,zenburn-red-2)))) + `(diff-refine-added ((t (:background "#338833" :foreground ,zenburn-green+4)))) `(diff-refine-changed ((t (:background "#888811" :foreground ,zenburn-yellow)))) - `(diff-refine-removed ((t (:background ,zenburn-red-5 :foreground ,zenburn-red+2)))) + `(diff-refine-removed ((t (:background "#883333" :foreground ,zenburn-red)))) `(diff-header ((,class (:background ,zenburn-bg+2)) (t (:background ,zenburn-fg :foreground ,zenburn-bg)))) `(diff-file-header @@ -507,23 +527,26 @@ Also bind `class' to ((class color) (min-colors 89))." `(diredfl-read-priv ((t (:foreground ,zenburn-green-1)))) `(diredfl-symlink ((t (:foreground ,zenburn-yellow)))) `(diredfl-write-priv ((t (:foreground ,zenburn-magenta)))) +;;;;; doom-modeline + `(doom-modeline-bar ((t (:background ,zenburn-yellow)))) + `(doom-modeline-inactive-bar ((t (:background nil)))) ;;;;; ediff - `(ediff-current-diff-A ((t (:inherit diff-removed)))) - `(ediff-current-diff-Ancestor ((t (:inherit ediff-current-diff-A)))) - `(ediff-current-diff-B ((t (:inherit diff-added)))) - `(ediff-current-diff-C ((t (:foreground ,zenburn-blue+2 :background ,zenburn-blue-5)))) + `(ediff-current-diff-A ((t (:foreground ,zenburn-fg :background ,zenburn-red-4)))) + `(ediff-current-diff-Ancestor ((t (:foreground ,zenburn-fg :background ,zenburn-red-4)))) + `(ediff-current-diff-B ((t (:foreground ,zenburn-fg :background ,zenburn-green-2)))) + `(ediff-current-diff-C ((t (:foreground ,zenburn-fg :background ,zenburn-blue-5)))) `(ediff-even-diff-A ((t (:background ,zenburn-bg+1)))) `(ediff-even-diff-Ancestor ((t (:background ,zenburn-bg+1)))) `(ediff-even-diff-B ((t (:background ,zenburn-bg+1)))) `(ediff-even-diff-C ((t (:background ,zenburn-bg+1)))) - `(ediff-fine-diff-A ((t (:inherit diff-refine-removed :weight bold)))) - `(ediff-fine-diff-Ancestor ((t (:inherit ediff-fine-diff-A)))) - `(ediff-fine-diff-B ((t (:inherit diff-refine-added :weight bold)))) - `(ediff-fine-diff-C ((t (:foreground ,zenburn-blue+3 :background ,zenburn-blue-4 :weight bold)))) + `(ediff-fine-diff-A ((t (:foreground ,zenburn-fg :background ,zenburn-red-2 :weight bold)))) + `(ediff-fine-diff-Ancestor ((t (:foreground ,zenburn-fg :background ,zenburn-red-2 weight bold)))) + `(ediff-fine-diff-B ((t (:foreground ,zenburn-fg :background ,zenburn-green :weight bold)))) + `(ediff-fine-diff-C ((t (:foreground ,zenburn-fg :background ,zenburn-blue-3 :weight bold )))) `(ediff-odd-diff-A ((t (:background ,zenburn-bg+2)))) - `(ediff-odd-diff-Ancestor ((t (:inherit ediff-odd-diff-A)))) - `(ediff-odd-diff-B ((t (:inherit ediff-odd-diff-A)))) - `(ediff-odd-diff-C ((t (:inherit ediff-odd-diff-A)))) + `(ediff-odd-diff-Ancestor ((t (:background ,zenburn-bg+2)))) + `(ediff-odd-diff-B ((t (:background ,zenburn-bg+2)))) + `(ediff-odd-diff-C ((t (:background ,zenburn-bg+2)))) ;;;;; egg `(egg-text-base ((t (:foreground ,zenburn-fg)))) `(egg-help-header-1 ((t (:foreground ,zenburn-yellow)))) @@ -785,6 +808,10 @@ Also bind `class' to ((class color) (min-colors 89))." `(helm-moccur-buffer ((t (:foreground ,zenburn-cyan :background ,zenburn-bg)))) `(helm-mu-contacts-address-face ((t (:foreground ,zenburn-fg-1 :background ,zenburn-bg)))) `(helm-mu-contacts-name-face ((t (:foreground ,zenburn-fg :background ,zenburn-bg)))) +;;;;; helm-lxc + `(helm-lxc-face-frozen ((t (:foreground ,zenburn-blue :background ,zenburn-bg)))) + `(helm-lxc-face-running ((t (:foreground ,zenburn-green :background ,zenburn-bg)))) + `(helm-lxc-face-stopped ((t (:foreground ,zenburn-red :background ,zenburn-bg)))) ;;;;; helm-swoop `(helm-swoop-target-line-face ((t (:foreground ,zenburn-fg :background ,zenburn-bg+1)))) `(helm-swoop-target-word-face ((t (:foreground ,zenburn-yellow :background ,zenburn-bg+2 :weight bold)))) @@ -938,19 +965,18 @@ Also bind `class' to ((class color) (min-colors 89))." ((t (:underline t)))) ;;;;; magit ;;;;;; headings and diffs + ;; Please read (info "(magit)Theming Faces") before changing this. `(magit-section-highlight ((t (:background ,zenburn-bg+05)))) `(magit-section-heading ((t (:foreground ,zenburn-yellow :weight bold)))) `(magit-section-heading-selection ((t (:foreground ,zenburn-orange :weight bold)))) - - `(magit-diff-added ((t (:inherit diff-added)))) - `(magit-diff-added-highlight ((t (:inherit diff-refine-added)))) - `(magit-diff-removed ((t (:inherit diff-removed)))) - `(magit-diff-removed-highlight ((t (:inherit diff-refine-removed)))) - `(magit-diff-file-heading ((t (:weight bold)))) - `(magit-diff-file-heading-highlight ((t (:background ,zenburn-bg+05 :weight bold)))) - `(magit-diff-file-heading-selection ((t (:background ,zenburn-bg+05 - :foreground ,zenburn-orange :weight bold)))) + `(magit-diff-file-heading-highlight ((t (:background ,zenburn-bg+05 :weight bold)))) + `(magit-diff-file-heading-selection ((t (:background ,zenburn-bg+05 :weight bold + :foreground ,zenburn-orange)))) + `(magit-diff-added ((t (:background ,zenburn-green-2)))) + `(magit-diff-added-highlight ((t (:background ,zenburn-green)))) + `(magit-diff-removed ((t (:background ,zenburn-red-4)))) + `(magit-diff-removed-highlight ((t (:background ,zenburn-red-3)))) `(magit-diff-hunk-heading ((t (:background ,zenburn-bg+1)))) `(magit-diff-hunk-heading-highlight ((t (:background ,zenburn-bg+2)))) `(magit-diff-hunk-heading-selection ((t (:background ,zenburn-bg+2 @@ -959,8 +985,8 @@ Also bind `class' to ((class color) (min-colors 89))." :foreground ,zenburn-bg+2)))) `(magit-diff-context-highlight ((t (:background ,zenburn-bg+05 :foreground "grey70")))) - `(magit-diffstat-added ((t (:foreground ,zenburn-green+4)))) - `(magit-diffstat-removed ((t (:foreground ,zenburn-red)))) + `(magit-diffstat-added ((t (:foreground ,zenburn-green+4)))) + `(magit-diffstat-removed ((t (:foreground ,zenburn-red)))) ;;;;;; popup `(magit-popup-heading ((t (:foreground ,zenburn-yellow :weight bold)))) `(magit-popup-key ((t (:foreground ,zenburn-green-2 :weight bold)))) @@ -1193,7 +1219,9 @@ Also bind `class' to ((class color) (min-colors 89))." `(org-ellipsis ((t (:foreground ,zenburn-yellow-1 :underline t)))) `(org-footnote ((t (:foreground ,zenburn-cyan :underline t)))) `(org-document-title ((t (:inherit ,z-variable-pitch :foreground ,zenburn-blue - :weight bold :height ,zenburn-height-plus-4)))) + :weight bold + ,@(when zenburn-scale-org-headlines + (list :height zenburn-height-plus-4)))))) `(org-document-info ((t (:foreground ,zenburn-blue)))) `(org-habit-ready-face ((t :background ,zenburn-green))) `(org-habit-alert-face ((t :background ,zenburn-yellow-1 :foreground ,zenburn-bg))) @@ -1386,6 +1414,11 @@ Also bind `class' to ((class color) (min-colors 89))." (t (:underline ,zenburn-green)))) `(slime-highlight-face ((t (:inherit highlight)))) +;;;;; solaire + `(solaire-default-face ((t (:inherit default :background ,zenburn-bg-08)))) + `(solaire-minibuffer-face ((t (:inherit default :background ,zenburn-bg-08)))) + `(solaire-hl-line-face ((t (:inherit hl-line :background ,zenburn-bg)))) + `(solaire-org-hide-face ((t (:inherit org-hide :background ,zenburn-bg-08)))) ;;;;; speedbar `(speedbar-button-face ((t (:foreground ,zenburn-green+2)))) `(speedbar-directory-face ((t (:foreground ,zenburn-cyan)))) @@ -1394,6 +1427,8 @@ Also bind `class' to ((class color) (min-colors 89))." `(speedbar-selected-face ((t (:foreground ,zenburn-red)))) `(speedbar-separator-face ((t (:foreground ,zenburn-bg :background ,zenburn-blue-1)))) `(speedbar-tag-face ((t (:foreground ,zenburn-yellow)))) +;;;;; swiper + `(swiper-line-face ((t (:underline t)))) ;;;;; sx `(sx-custom-button ((t (:background ,zenburn-fg :foreground ,zenburn-bg-1 @@ -1578,28 +1613,39 @@ Also bind `class' to ((class color) (min-colors 89))." (defvar zenburn-add-font-lock-keywords nil "Whether to add font-lock keywords for zenburn color names. + In buffers visiting library `zenburn-theme.el' the zenburn -specific keywords are always added. In all other Emacs-Lisp -buffers this variable controls whether this should be done. -This requires library `rainbow-mode'.") +specific keywords are always added, provided that library has +been loaded (because that is where the code that does it is +definded). If you visit this file and only enable the theme, +then you have to turn `rainbow-mode' off and on again for the +zenburn-specific font-lock keywords to be used. + +In all other Emacs-Lisp buffers this variable controls whether +this should be done. This requires library `rainbow-mode'.") (defvar zenburn-colors-font-lock-keywords nil) -;; (defadvice rainbow-turn-on (after zenburn activate) -;; "Maybe also add font-lock keywords for zenburn colors." -;; (when (and (derived-mode-p 'emacs-lisp-mode) -;; (or zenburn-add-font-lock-keywords -;; (equal (file-name-nondirectory (buffer-file-name)) -;; "zenburn-theme.el"))) -;; (unless zenburn-colors-font-lock-keywords -;; (setq zenburn-colors-font-lock-keywords -;; `((,(regexp-opt (mapcar 'car zenburn-colors-alist) 'words) -;; (0 (rainbow-colorize-by-assoc zenburn-colors-alist)))))) -;; (font-lock-add-keywords nil zenburn-colors-font-lock-keywords))) +(defun zenburn--rainbow-turn-on () + "Maybe also add font-lock keywords for zenburn colors." + (when (and (derived-mode-p 'emacs-lisp-mode) + (or zenburn-add-font-lock-keywords + (and (buffer-file-name) + (equal (file-name-nondirectory (buffer-file-name)) + "zenburn-theme.el")))) + (unless zenburn-colors-font-lock-keywords + (setq zenburn-colors-font-lock-keywords + `((,(regexp-opt (mapcar 'car zenburn-default-colors-alist) 'words) + (0 (rainbow-colorize-by-assoc zenburn-default-colors-alist)))))) + (font-lock-add-keywords nil zenburn-colors-font-lock-keywords 'end))) + +(defun zenburn--rainbow-turn-off () + "Also remove font-lock keywords for zenburn colors." + (font-lock-remove-keywords nil zenburn-colors-font-lock-keywords)) -;; (defadvice rainbow-turn-off (after zenburn activate) -;; "Also remove font-lock keywords for zenburn colors." -;; (font-lock-remove-keywords nil zenburn-colors-font-lock-keywords)) +(when (fboundp 'advice-add) + (advice-add 'rainbow-turn-on :after #'zenburn--rainbow-turn-on) + (advice-add 'rainbow-turn-off :after #'zenburn--rainbow-turn-off)) ;;; Footer diff --git a/packages/zig-mode-20190109.217.el b/packages/zig-mode-20190109.217.el new file mode 100644 index 0000000..804bf30 --- /dev/null +++ b/packages/zig-mode-20190109.217.el @@ -0,0 +1,323 @@ +;;; zig-mode.el --- A major mode for the Zig programming language -*- lexical-binding: t -*- + +;; Version: 0.0.8 +;; Package-Version: 20190109.217 +;; Author: Andrea Orru , Andrew Kelley +;; Keywords: zig, languages +;; Package-Requires: ((emacs "24")) +;; URL: https://github.com/zig-lang/zig-mode + +;; 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 file 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 . + +;;; Commentary: +;; + +;;; Code: + +(defun zig-re-word (inner) + "Construct a regular expression for the word INNER." + (concat "\\<" inner "\\>")) + +(defun zig-re-grab (inner) + "Construct a group regular expression for INNER." + (concat "\\(" inner "\\)")) + +(defconst zig-re-identifier "[[:word:]_][[:word:]_[:digit:]]*") +(defconst zig-re-type-annotation + (concat (zig-re-grab zig-re-identifier) + "[[:space:]]*:[[:space:]]*" + (zig-re-grab zig-re-identifier))) + +(defun zig-re-definition (dtype) + "Construct a regular expression for definitions of type DTYPE." + (concat (zig-re-word dtype) "[[:space:]]+" (zig-re-grab zig-re-identifier))) + +(defconst zig-mode-syntax-table + (let ((table (make-syntax-table))) + + ;; Operators + (dolist (i '(?+ ?- ?* ?/ ?% ?& ?| ?= ?! ?< ?>)) + (modify-syntax-entry i "." table)) + + ;; Strings + (modify-syntax-entry ?\' "\"" table) + (modify-syntax-entry ?\" "\"" table) + (modify-syntax-entry ?\\ "\\" table) + + ;; Comments + (modify-syntax-entry ?/ ". 12" table) + (modify-syntax-entry ?\n ">" table) + + table)) + +(defconst zig-keywords + '( + ;; Storage + "const" "var" "extern" "packed" "export" "pub" "noalias" "inline" + "comptime" "nakedcc" "stdcallcc" "volatile" "align" "linksection" + + ;; Structure + "struct" "enum" "union" + + ;; Statement + "break" "return" "continue" "asm" "defer" "errdefer" "unreachable" + "try" "catch" "async" "await" "suspend" "resume" "cancel" + + ;; Conditional + "if" "else" "switch" "and" "or" "orelse" + + ;; Repeat + "while" "for" + + ;; Other keywords + "fn" "use" "test")) + +(defconst zig-types + '( + ;; Integer types + "i2" "u2" "i3" "u3" "i4" "u4" "i5" "u5" "i6" "u6" "i7" "u7" "i8" "u8" + "i16" "u16" "i29" "u29" "i32" "u32" "i64" "u64" "i128" "u128" + "isize" "usize" + + ;; Floating types + "f16" "f32" "f64" "f128" + + ;; C types + "c_short" "c_ushort" "c_int" "c_uint" "c_long" "c_ulong" + "c_longlong" "c_ulonglong" "c_longdouble" "c_void" + + ;; Comptime types + "comptime_int" "comptime_float" + + ;; Other types + "bool" "void" "noreturn" "type" "error" "anyerror" "promise")) + +(defconst zig-constants + '( + ;; Boolean + "true" "false" + + ;; Other constants + "null" "undefined" "this")) + +(defconst zig-electric-indent-chars + '( ?\; ?, ?) ?] ?} )) + +(defgroup zig-mode nil + "Support for Zig code." + :link '(url-link "https://ziglang.org/") + :group 'languages) + +(defcustom zig-indent-offset 4 + "Indent Zig code by this number of spaces." + :type 'integer + :group 'zig-mode + :safe #'integerp) + +(defface zig-multiline-string-face + '((t :inherit font-lock-string-face)) + "Face for multiline string literals." + :group 'zig-mode) + +(defvar zig-font-lock-keywords + (append + `( + ;; Builtins (prefixed with @) + (,(concat "@" zig-re-identifier) . font-lock-builtin-face) + + ;; Keywords, constants and types + (,(regexp-opt zig-keywords 'symbols) . font-lock-keyword-face) + (,(regexp-opt zig-constants 'symbols) . font-lock-constant-face) + (,(regexp-opt zig-types 'symbols) . font-lock-type-face) + + ;; Type annotations (both variable and type) + (,zig-re-type-annotation 1 font-lock-variable-name-face) + (,zig-re-type-annotation 2 font-lock-type-face) + ) + + ;; Definitions + (mapcar #'(lambda (x) + (list (zig-re-definition (car x)) + 1 (cdr x))) + '(("const" . font-lock-variable-name-face) + ("var" . font-lock-variable-name-face) + ("fn" . font-lock-function-name-face))))) + +(defun zig-paren-nesting-level () (nth 0 (syntax-ppss))) +(defun zig-currently-in-str () (nth 3 (syntax-ppss))) +(defun zig-start-of-current-str-or-comment () (nth 8 (syntax-ppss))) + +(defun zig-skip-backwards-past-whitespace-and-comments () + (while (or + ;; If inside a comment, jump to start of comment. + (let ((start (zig-start-of-current-str-or-comment))) + (and start + (not (zig-currently-in-str)) + (goto-char start))) + ;; Skip backwards past whitespace and comment end delimiters. + (/= 0 (skip-syntax-backward " >"))))) + +(defun zig-mode-indent-line () + (interactive) + ;; First, calculate the column that this line should be indented to. + (let ((indent-col + (save-excursion + (back-to-indentation) + (let* (;; paren-level: How many sets of parens (or other delimiters) + ;; we're within, except that if this line closes the + ;; innermost set(s) (e.g. the line is just "}"), then we + ;; don't count those set(s). + (paren-level + (save-excursion + (while (looking-at "[]})]") (forward-char)) + (zig-paren-nesting-level))) + ;; prev-block-indent-col: If we're within delimiters, this is + ;; the column to which the start of that block is indented + ;; (if we're not, this is just zero). + (prev-block-indent-col + (if (<= paren-level 0) 0 + (save-excursion + (while (>= (zig-paren-nesting-level) paren-level) + (backward-up-list) + (back-to-indentation)) + (current-column)))) + ;; base-indent-col: The column to which a complete expression + ;; on this line should be indented. + (base-indent-col + (if (<= paren-level 0) + prev-block-indent-col + (or (save-excursion + (backward-up-list) + (forward-char) + (and (not (looking-at " *\\(//[^\n]*\\)?\n")) + (current-column))) + (+ prev-block-indent-col zig-indent-offset)))) + ;; is-expr-continutation: True if this line continues an + ;; expression from the previous line, false otherwise. + (is-expr-continutation + (and + (not (looking-at "[]});]")) + (save-excursion + (zig-skip-backwards-past-whitespace-and-comments) + (when (> (point) 1) + (backward-char) + (not (looking-at "[,;([{}]"))))))) + ;; Now we can calculate indent-col: + (if is-expr-continutation + (+ base-indent-col zig-indent-offset) + base-indent-col))))) + ;; If point is within the indentation whitespace, move it to the end of the + ;; new indentation whitespace (which is what the indent-line-to function + ;; always does). Otherwise, we don't want point to move, so we use a + ;; save-excursion. + (if (<= (current-column) (current-indentation)) + (indent-line-to indent-col) + (save-excursion (indent-line-to indent-col))))) + +(defun zig-syntax-propertize-to-newline-if-in-multiline-str (end) + ;; First, we need to check if we're in a multiline string literal; if we're + ;; not, do nothing. + (when (zig-currently-in-str) + (let ((start (zig-start-of-current-str-or-comment))) + (when (save-excursion + (goto-char start) + (looking-at "\\\\\\\\")) + ;; At this point, we've determined that we're within a multiline string + ;; literal. Let `stop' be the position of the closing newline, or + ;; `end', whichever comes first. + (let ((stop (if (save-excursion + (goto-char start) + (re-search-forward "\n" end t)) + (prog1 (match-end 0) + ;; We found the closing newline, so mark it as the + ;; end of this string literal. + (put-text-property (match-beginning 0) + (match-end 0) + 'syntax-table + (string-to-syntax "|"))) + end))) + ;; Zig multiline string literals don't support escapes, so mark all + ;; backslashes (up to `stop') as punctation instead of escapes. + (save-excursion + (goto-char (+ 2 start)) + (while (re-search-forward "\\\\" stop t) + (put-text-property (match-beginning 0) (match-end 0) + 'syntax-table (string-to-syntax ".")) + (goto-char (match-end 0)))) + ;; Move to the end of the string (or `end'), so that + ;; zig-syntax-propertize can pick up from there. + (goto-char stop)))))) + +(defun zig-syntax-propertize (start end) + (goto-char start) + (zig-syntax-propertize-to-newline-if-in-multiline-str end) + (funcall + (syntax-propertize-rules + ;; Multiline strings + ("\\(\\\\\\)\\\\" + (1 (prog1 "|" + (goto-char (match-end 0)) + (zig-syntax-propertize-to-newline-if-in-multiline-str end))))) + (point) end)) + +(defun zig-mode-syntactic-face-function (state) + (if (nth 3 state) + (save-excursion + (goto-char (nth 8 state)) + (if (looking-at "\\\\\\\\") + 'zig-multiline-string-face + 'font-lock-string-face)) + (save-excursion + (goto-char (nth 8 state)) + (if (looking-at "///[^/]") + 'font-lock-doc-face + 'font-lock-comment-face)))) + +;;; Imenu support +(defun zig-re-structure-def-imenu (stype) + "Construct a regular expression for strucutres definitions of type STYPE." + (concat (zig-re-word "const") "[[:space:]]+" + (zig-re-grab zig-re-identifier) + ".*" + (zig-re-word stype))) + +(defvar zig-imenu-generic-expression + (append (mapcar #'(lambda (x) + (list (capitalize x) (zig-re-structure-def-imenu x) 1)) + '("enum" "struct" "union")) + `(("Fn" ,(zig-re-definition "fn") 1)))) + +;;;###autoload +(define-derived-mode zig-mode prog-mode "Zig" + "A major mode for the Zig programming language." + (setq-local comment-start "// ") + (setq-local comment-end "") + (setq-local electric-indent-chars + (append zig-electric-indent-chars + (and (boundp 'electric-indent-chars) + electric-indent-chars))) + (setq-local indent-line-function 'zig-mode-indent-line) + (setq-local indent-tabs-mode nil) ; Zig forbids tab characters. + (setq-local syntax-propertize-function 'zig-syntax-propertize) + (setq-local imenu-generic-expression zig-imenu-generic-expression) + (setq font-lock-defaults '(zig-font-lock-keywords + nil nil nil nil + (font-lock-syntactic-face-function + . zig-mode-syntactic-face-function)))) + +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.zig\\'" . zig-mode)) + +(provide 'zig-mode) +;;; zig-mode.el ends here