commit fb3eb48c17afae2211bae65bcc41ea0bd8f96cf9 parent 157461b185a6d6ea7d51a99146e2b22677fd0111 Author: Vincent Demeester <vincent@sbr.pm> Date: Sat, 14 Mar 2020 14:52:45 +0100 Add 'tmp/emacs-config/' from commit '246a03f95eb1b1a073801e855ffcc01e08e20fb7' git-subtree-dir: tmp/emacs-config git-subtree-mainline: 157461b185a6d6ea7d51a99146e2b22677fd0111 git-subtree-split: 246a03f95eb1b1a073801e855ffcc01e08e20fb7 Diffstat:
227 files changed, 10043 insertions(+), 0 deletions(-)
diff --git a/tmp/emacs-config/.gitattributes b/tmp/emacs-config/.gitattributes @@ -0,0 +1,8 @@ +init.el linguist-generated=true +config.nix linguist-generated=true +default.nix linguist-generated=true +bootstrap.sh linguist-generated=true +update.sh linguist-generated=true +.gitattributes linguist-generated=true +.gitignore linguist-generated=true +*.png filter=lfs diff=lfs merge=lfs -text diff --git a/tmp/emacs-config/.gitignore b/tmp/emacs-config/.gitignore @@ -0,0 +1,34 @@ +flycheck_*.el +*.elc +*.pdf +*.html +*.log +*.aux +*.out +*.toc + +# nix stuff +result +result-* + +# misc +auto-save-list +var +tramp +elpa +custom.el + +%backup%~ +# wat? +history +projectile-bookmarks.eld + +# dap-mode +.dap-breakpoints +.extension + +# publishing +publish.el +sitemap.org + +# private diff --git a/tmp/emacs-config/.ignore b/tmp/emacs-config/.ignore @@ -0,0 +1,2 @@ +var +elpa diff --git a/tmp/emacs-config/COPYING b/tmp/emacs-config/COPYING @@ -0,0 +1,673 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + Copyright (C) 2013-2020 Vincent Demeester + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Vincent Demeester's Emacs configuration Copyright (C) 2013-2020 Vincent Demeester + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/tmp/emacs-config/Makefile b/tmp/emacs-config/Makefile @@ -0,0 +1,7 @@ +all: publish + +publish.el: publish.org + emacs --batch --eval "(require 'ob-tangle)" --eval '(org-babel-tangle-file "publish.org")' + +publish: publish.el + emacs -batch --load publish.el --eval '(clean-and-publish)' diff --git a/tmp/emacs-config/README.org b/tmp/emacs-config/README.org @@ -0,0 +1 @@ +index.org+ \ No newline at end of file diff --git a/tmp/emacs-config/config/00-clean.el b/tmp/emacs-config/config/00-clean.el @@ -0,0 +1,56 @@ +(use-package recentf + :config + (setq recentf-max-saved-items 200 + recentf-auto-cleanup 360 + recentf-show-file-shortcuts-flag nil) + (recentf-mode 1) + (add-to-list 'recentf-exclude "^/\\(?:ssh\\|su\\|sudo\\)?:") + ;; Magic advice to rename entries in recentf when moving files in + ;; dired. + (defun rjs/recentf-rename-notify (oldname newname &rest args) + (if (file-directory-p newname) + (rjs/recentf-rename-directory oldname newname) + (rjs/recentf-rename-file oldname newname))) + + (defun rjs/recentf-rename-file (oldname newname) + (setq recentf-list + (mapcar (lambda (name) + (if (string-equal name oldname) + newname + oldname)) + recentf-list)) + recentf-cleanup) + + (defun rjs/recentf-rename-directory (oldname newname) + ;; oldname, newname and all entries of recentf-list should already + ;; be absolute and normalised so I think this can just test whether + ;; oldname is a prefix of the element. + (setq recentf-list + (mapcar (lambda (name) + (if (string-prefix-p oldname name) + (concat newname (substring name (length oldname))) + name)) + recentf-list)) + recentf-cleanup) + + (advice-add 'dired-rename-file :after #'rjs/recentf-rename-notify)) + +(use-package no-littering ; Keep .emacs.d clean + :config + (require 'recentf) + (add-to-list 'recentf-exclude no-littering-var-directory) + (add-to-list 'recentf-exclude no-littering-etc-directory) + + ;; Move this in its own thing + (setq + create-lockfiles nil + delete-old-versions t + kept-new-versions 6 + kept-old-versions 2 + version-control t) + + (setq + backup-directory-alist + `((".*" . ,(no-littering-expand-var-file-name "backup/"))) + auto-save-file-name-transforms + `((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))) diff --git a/tmp/emacs-config/config/00-environments.el b/tmp/emacs-config/config/00-environments.el @@ -0,0 +1,13 @@ +(use-package exec-path-from-shell ; Set up environment variables + :if (display-graphic-p) + :unless (eq system-type 'windows-nt) + :config + (setq exec-path-from-shell-variables + '("PATH" ; Full path + "INFOPATH" ; Info directories + "GOPATH" ; Golang path + )) + (exec-path-from-shell-initialize)) + +(setenv "PAGER" "cat") +(setenv "TERM" "xterm-256color") diff --git a/tmp/emacs-config/config/01-server.el b/tmp/emacs-config/config/01-server.el @@ -0,0 +1,8 @@ +;;; 01-server.el --- -*- lexical-binding: t -*- + +;; UseServer +(use-package server + :config (or (server-running-p) (server-mode))) +;; -UseServer + +;;; 01-server.el ends here diff --git a/tmp/emacs-config/config/README.org b/tmp/emacs-config/config/README.org @@ -0,0 +1 @@ +This holds configuration files for different modes and languages diff --git a/tmp/emacs-config/config/setup-buffers.el b/tmp/emacs-config/config/setup-buffers.el @@ -0,0 +1,153 @@ +;;; -*- lexical-binding: t; -*- +;; Don't let the cursor go into minibuffer prompt +(let ((default (eval (car (get 'minibuffer-prompt-properties 'standard-value)))) + (dont-touch-prompt-prop '(cursor-intangible t))) + (setq minibuffer-prompt-properties + (append default dont-touch-prompt-prop)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)) + +;; Allow to read from minibuffer while in minibuffer. +(setq enable-recursive-minibuffers t) + +;; Show the minibuffer depth (when larger than 1) +(minibuffer-depth-indicate-mode 1) + +(use-package savehist ; Save minibuffer history + :init (savehist-mode t) + :custom + (history-length 1000) + (savehist-save-minibuffer-history t) + (savehist-autosave-interval 180) + :config + (savehist-mode 1)) + +(use-package emacs + :init + ;; Configure `display-buffer' behaviour for some special buffers + (setq display-buffer-alist + '(;; bottom side window + ("\\*e?shell.*" + (display-buffer-in-side-window) + (window-height . 0.25) + (side . bottom) + (slot . -1)) + ("\\*v?term.*" + (display-buffer-in-side-window) + (window-height . 0.25) + (side . bottom) + (slot . -1)) + ("\\*\\(Backtrace\\|Warnings\\|Compile-Log\\|[Hh]elp\\|Messages\\)\\*" + (display-buffer-in-side-window) + (window-height . 0.25) + (side . bottom) + (slot . 0)) + ("\\*\\(helpful\\).*" + (display-buffer-in-side-window) + (window-height . 0.25) + (side . bottom) + (slot . 0)) + ("\\*\\(compilation\\|go test\\).*" + (display-buffer-in-side-window) + (window-height . 0.25) + (side . bottom) + (slot . 0)) + ("\\*\\(ielm\\).*" + (display-buffer-in-side-window) + (window-height . 0.25) + (side . bottom) + (slot . 1)) + ;; right side window + ("\\*wclock*" + (display-buffer-in-side-window) + (window-width . 0.20) + (side . right) + (slot . -1)) + ("\\*undo-tree*" + (display-buffer-in-side-window) + (window-width . 0.20) + (side . right) + (slot . -1)) + ("\\*\\(Flycheck\\|Package-Lint\\).*" + (display-buffer-in-side-window) + (window-width . 0.20) + (side . right) + (slot . 0) + (window-parameters . ((no-other-window . t) + (mode-line-format . (" " + mode-line-buffer-identification))))) + ("\\*Faces\\*" + (display-buffer-in-side-window) + (window-width . 0.20) + (side . right) + (slot . 1) + (window-parameters . ((no-other-window . t) + (mode-line-format . (" " + mode-line-buffer-identification))))) + ("\\*Custom.*" + (display-buffer-in-side-window) + (window-width . 0.20) + (side . right) + (slot . 2)))) + (setq window-sides-vertical nil) + (setq window-combination-resize t) ; Size new windows proportionally + :bind (("C-x +" . balance-windows-area) + ("<f7>" . window-toggle-side-windows))) + +(use-package uniquify ; Unique buffer names + :custom + (uniquify-buffer-name-style 'post-forward) + (uniquify-separator ":") + (uniquify-ignore-buffers-re "^\\*") + (uniquify-after-kill-buffer-p t)) + +(use-package ibuf-ext ; Extensions for Ibuffer + :config + ;; Do not show empty groups + (setq ibuffer-show-empty-filter-groups nil)) + +(use-package ibuffer ; Buffer management + :custom + (ibuffer-expert t) + (ibuffer-filter-group-name-face 'font-lock-doc-face) + (ibuffer-default-sorting-mode 'filename/process) + (ibuffer-use-header-line t) + :bind (("C-x C-b" . ibuffer) + ([remap list-buffers] . ibuffer)) + :config + ;; Use human readable Size column instead of original one + (define-ibuffer-column size-h + (:name "Size" :inline t) + (cond + ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0))) + ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0))) + (t (format "%8d" (buffer-size))))) + + (setq ibuffer-formats + '((mark modified read-only " " + (name 18 18 :left :elide) + " " + (size-h 9 -1 :right) + " " + (mode 16 16 :left :elide) + " " + filename-and-process) + (mark modified read-only " " + (name 18 18 :left :elide) + " " + (size 9 -1 :right) + " " + (mode 16 16 :left :elide) + " " + (vc-status 16 16 :left) + " " + filename-and-process)))) + +(use-package ibuffer-vc ; Group buffers by VC project and status + :defer 2 + :init (add-hook 'ibuffer-hook + (lambda () + (ibuffer-vc-set-filter-groups-by-vc-root) + (unless (eq ibuffer-sorting-mode 'filename/process) + (ibuffer-do-sort-by-filename/process))))) + +(provide 'setup-buffers) diff --git a/tmp/emacs-config/config/setup-compile.el b/tmp/emacs-config/config/setup-compile.el @@ -0,0 +1,63 @@ +;;; -*- lexical-binding: t; -*- +(use-package compile + :defer 2 + :config + (progn + ;; http://stackoverflow.com/a/13408008/1219634 + (setq + compilation-scroll-output t + ;; I'm not scared of saving everything. + compilation-ask-about-save nil + ;; Automatically scroll and jump to the first error + compilation-scroll-output 'next-error + ;; compilation-scroll-output 'first-error + ;; compilation-auto-jump-to-first-error t + ;; Skip over warnings and info messages in compilation + compilation-skip-threshold 2 + ;; Don't freeze when process reads from stdin + compilation-disable-input t + ;; Show three lines of context around the current message + compilation-context-lines 3) + (require 'ansi-color) + (defun vde/colorize-compilation-buffer () + (unless (or (derived-mode-p 'grep-mode) ;Don't mess up colors in Grep/Ag results buffers + (derived-mode-p 'ag-mode)) + (ansi-color-apply-on-region compilation-filter-start (point)))) + (add-hook 'compilation-filter-hook #'vde/colorize-compilation-buffer) + + (defun vde/mark-compilation-window-as-dedicated () + "Setup the *compilation* window with custom settings." + (when (string-prefix-p "*compilation: " (buffer-name)) + (save-selected-window + (save-excursion + (let* ((w (get-buffer-window (buffer-name)))) + (when w + (select-window w) + (switch-to-buffer (buffer-name)) + (set-window-dedicated-p w t))))))) + (add-hook 'compilation-mode-hook 'vde/mark-compilation-window-as-dedicated))) + +(use-package flycheck + :if (not (eq system-type 'windows-nt)) + :defer 4 + :commands (flycheck-mode + flycheck-next-error + flycheck-previous-error) + :init + (dolist (where '((emacs-lisp-mode-hook . emacs-lisp-mode-map) + (haskell-mode-hook . haskell-mode-map) + (js2-mode-hook . js2-mode-map) + (go-mode-hook . go-mode-map) + (c-mode-common-hook . c-mode-base-map))) + (add-hook (car where) + `(lambda () + (bind-key "M-n" #'flycheck-next-error ,(cdr where)) + (bind-key "M-p" #'flycheck-previous-error ,(cdr where))) + t)) + :config + (add-hook 'prog-mode-hook 'flycheck-mode) + (defalias 'show-error-at-point-soon + 'flycheck-show-error-at-point) + (setq flycheck-idle-change-delay 1.2)) + +(provide 'setup-compile) diff --git a/tmp/emacs-config/config/setup-completion.el b/tmp/emacs-config/config/setup-completion.el @@ -0,0 +1,296 @@ +;;; -*- lexical-binding: t; -*- +(use-package ivy + :delight + :custom + (ivy-count-format "%d/%d ") + (ivy-height-alist '((t lambda (_caller) (/ (window-height) 4)))) + (ivy-use-virtual-buffers t) + (ivy-virtual-abbreviate 'full) ;Show the full virtual file paths + (ivy-wrap nil) + (ivy-re-builders-alist + '((counsel-M-x . ivy--regex-fuzzy) + (t . ivy--regex-plus))) + (ivy-display-style 'fancy) + (ivy-use-selectable-prompt t) + (ivy-fixed-height-minibuffer nil) + (ivy-extra-directories nil) ; Default value: ("../" "./") + :bind (("C-x b" . vde/switch-buffer) + ("C-x B" . ivy-switch-buffer) + ("M-u" . ivy-resume) ;Override the default binding for `upcase-word' + ("C-c C-w p" . ivy-push-view) ;Push window configuration to `ivy-views' + ("C-c C-w P" . ivy-pop-view) ;Remove window configuration from `ivy-views' + ("C-c C-w s" . ivy-switch-view) ; Switch window configuration to `ivy-views' + :map ivy-occur-mode-map + ("f" . forward-char) + ("b" . backward-char) + ("n" . ivy-occur-next-line) + ("p" . ivy-occur-previous-line) + ("<C-return>" . ivy-occur-press)) + :hook + (ivy-occur-mode . hl-line-mode) + :config + (ivy-set-occur 'ivy-switch-buffer 'ivy-switch-buffer-occur) + (ivy-set-occur 'swiper 'swiper-occur) + (ivy-set-occur 'swiper-isearch 'swiper-occur) + (ivy-mode 1) + (progn + (defun vde/switch-buffer (arg) + "Custom switch to buffer. +With universal argument ARG or when not in project, rely on +`ivy-switch-buffer'. +Otherwise, use `counsel-projectile-switch-project'." + (interactive "P") + (if (or arg + (not (projectile-project-p))) + (ivy-switch-buffer) + (counsel-projectile-switch-to-buffer))) + ;; Disable ido + (with-eval-after-load 'ido + (ido-mode -1) + ;; Enable ivy + (ivy-mode 1)) + )) + +(use-package counsel + :after ivy + :custom + (counsel-yank-pop-preselect-last t) + (counsel-yank-pop-separator "\nβββββββββ\n") + (counsel-describe-function-function 'helpful-function) + (counsel-describe-variable-function 'helpful-variable) + (counsel-find-file-at-point t) + (counsel-find-file-ignore-regexp + ;; Note that `ivy-extra-directories' should also not contain the "../" and + ;; "./" elements if you don't want to see those in the `counsel-find-file' + ;; completion list. + (concat + ;; file names beginning with # or . + "\\(?:\\`[#.]\\)" + ;; file names ending with # or ~ + "\\|\\(?:[#~]\\'\\)")) + :bind (("M-i" . counsel-semantic-or-imenu) + ("C-x C-r" . counsel-recentf) + ("C-M-y" . counsel-yank-pop) + ("C-h F" . counsel-faces) ;Overrides `Info-goto-emacs-command-node' + ("C-h S" . counsel-info-lookup-symbol) + ("C-c u" . counsel-unicode-char) + ("C-c C" . counsel-colors-emacs) ;Alternative to `list-colors-display' + ([remap execute-extended-command] . counsel-M-x) + ([remap bookmark-jump] . counsel-bookmark) ;Jump to book or set it if it doesn't exist, C-x r b + ([remap bookmark-set] . counsel-bookmark) ;C-x r m + ([remap find-file] . counsel-find-file) + ([remap describe-bindings] . counsel-descbinds) + ([remap finder-by-keyword] . counsel-package) ;C-h p + ([remap describe-variable] . counsel-describe-variable) + ([remap describe-function] . counsel-describe-function) + ("M-s r" . counsel-rg) + ("M-s g" . counsel-git-grep) + ("M-s z" . prot/counsel-fzf-rg-files) + :map ivy-minibuffer-map + ("C-r" . counsel-minibuffer-history) + ("C-SPC" . ivy-restrict-to-matches)) + :config + (progn + (ivy-set-actions + 'counsel-find-file + `(("x" + (lambda (x) (delete-file (expand-file-name x ivy--directory))) + ,(propertize "delete" 'face 'font-lock-warning-face)))) + + ;; counsel-rg + ;; Redefine `counsel-rg-base-command' with my required options, especially + ;; the `--follow' option to allow search through symbolic links (part of + ;; `modi/rg-arguments'). + (setq counsel-rg-base-command + (concat (mapconcat #'shell-quote-argument + (append '("rg") + vde/rg-arguments + '("--no-heading" ;No file names above matching content + )) + " ") + " %s" ;This MUST be %s, not %S + ;https://github.com/abo-abo/swiper/issues/427 + )))) + + +(use-package company + :commands global-company-mode + :init + (add-hook 'after-init-hook #'global-company-mode) + (setq + company-idle-delay 0.2 + company-selection-wrap-around t + company-minimum-prefix-length 2 + company-require-match nil + company-dabbrev-ignore-case nil + company-dabbrev-downcase nil + company-show-numbers t + company-tooltip-align-annotations t) + :config + (bind-keys :map company-active-map + ("C-d" . company-show-doc-buffer) + ("C-l" . company-show-location) + ("C-n" . company-select-next) + ("C-p" . company-select-previous) + ("C-t" . company-select-next) + ("C-s" . company-select-previous) + ("TAB" . company-complete)) + (setq company-backends + '(company-css + company-clang + company-capf + company-semantic + company-xcode + company-cmake + company-files + company-gtags + company-etags + company-keywords))) + +(use-package company-emoji + :ensure company + :config + (add-to-list 'company-backends 'company-emoji)) + +;;; Default rg arguments +;; https://github.com/BurntSushi/ripgrep +(defconst vde/rg-arguments + `("--no-ignore-vcs" ;Ignore files/dirs ONLY from `.ignore' + "--line-number" ;Line numbers + "--smart-case" + "--max-columns" "150" ;Emacs doesn't handle long line lengths very well + "--ignore-file" ,(expand-file-name ".ignore" (getenv "HOME"))) + "Default rg arguments used in the functions in `counsel' and `projectile' packages.") + + +(if *sys/full* + (progn + (use-package ivy-rich + :after ivy + :custom + (ivy-virtual-abbreviate 'full + ivy-rich-switch-buffer-align-virtual-buffer t + ivy-rich-path-style 'abbrev) + :config (ivy-rich-mode 1)) + + (use-package prescient + :custom + (prescient-history-length 50) + ;; (prescient-save-file "~/.emacs.d/prescient-items") + (prescient-filter-method '(fuzzy initialism regexp)) + :config + (prescient-persist-mode 1)) + + + (use-package ivy-prescient + :after (prescient ivy) + :custom + (ivy-prescient-sort-commands + '(:not swiper ivy-switch-buffer counsel-switch-buffer)) + (ivy-prescient-retain-classic-highlighting t) + (ivy-prescient-enable-filtering t) + (ivy-prescient-enable-sorting t) + :config + (defun prot/ivy-prescient-filters (str) + "Specify an exception for `prescient-filter-method'. + +This new rule can be used to tailor the results of individual +Ivy-powered commands, using `ivy-prescient-re-builder'." + (let ((prescient-filter-method '(literal regexp))) + (ivy-prescient-re-builder str))) + + (setq ivy-re-builders-alist + '((counsel-rg . prot/ivy-prescient-filters) + (counsel-grep . prot/ivy-prescient-filters) + (counsel-yank-pop . prot/ivy-prescient-filters) + (swiper . prot/ivy-prescient-filters) + (swiper-isearch . prot/ivy-prescient-filters) + (swiper-all . prot/ivy-prescient-filters) + (t . ivy-prescient-re-builder))) + (ivy-prescient-mode 1)) + + (use-package company-prescient + :ensure company + :after (company prescient) + :config + (company-prescient-mode 1)) + + (use-package lsp-mode + :commands (lsp lsp-deferred) + :config + (setq lsp-enable-file-watchers nil + lsp-gopls-staticcheck t + lsp-gopls-complete-unimported t + lsp-eldoc-render-all nil + lsp-enable-snippet nil + lsp-enable-links nil + lsp-enable-folding nil + lsp-enable-completion-at-point t + lsp-diagnostic-package :auto + lsp-restart 'auto-restart + lsp-auto-guess-root t + ;; @see https://github.com/emacs-lsp/lsp-mode/pull/1498 + ;; and read code related to auto configure + ;; require clients could be slow and that's only thing auto configure + ;; could do for me. Manual loading of client is faster. + lsp-auto-configure t + ; Use flycheck instead of flymake + lsp-prefer-flymake nil) + ;; don't ping LSP lanaguage server too frequently + (defvar lsp-on-touch-time 0) + (defadvice lsp-on-change (around lsp-on-change-hack activate) + ;; don't run `lsp-on-change' too frequently + (when (> (- (float-time (current-time)) + lsp-on-touch-time) 30) ;; 30 seconds + (setq lsp-on-touch-time (float-time (current-time))) + ad-do-it)) + :hook ((go-mode . lsp-deferred) + (python-mode . lsp-deferred))) + + (with-eval-after-load "company" + (use-package company-lsp + :after lsp-mode + :config + (push 'company-lsp company-backends))) + + (with-eval-after-load "projectile" + (defun my-set-projectile-root () + (when lsp--cur-workspace + (setq projectile-project-root (lsp--workspace-root lsp--cur-workspace)))) + (add-hook 'lsp-before-open-hook #'my-set-projectile-root)) + + (use-package dap-mode + :disabled + :after lsp-mode + :bind (:map dap-mode-map + ([f9] . dap-debug) + ;; ([f9] . dap-continue) + ;; ([S-f9] . dap-disconnect) + ;; ([f10] . dap-next) + ;; ([f11] . dap-step-in) + ;; ([S-f11] . dap-step-out) + ([C-f9] . dap-hide/show-ui)) + :hook (dap-stopped-hook . (lambda (arg) (call-interactively #'dap-hydra))) + :config + ;; FIXME: Create nice solution instead of a hack + (defvar dap-hide/show-ui-hidden? t) + (defun dap-hide/show-ui () + "Hide/show dap ui. FIXME" + (interactive) + (if dap-hide/show-ui-hidden? + (progn + (setq dap-hide/show-ui-hidden? nil) + (dap-ui-locals) + (dap-ui-repl)) + (dolist (buf '("*dap-ui-inspect*" "*dap-ui-locals*" "*dap-ui-repl*" "*dap-ui-sessions*")) + (when (get-buffer buf) + (kill-buffer buf))) + (setq dap-hide/show-ui-hidden? t))) + + (dap-mode) + (dap-ui-mode) + (dap-tooltip-mode)) + + )) + +(provide 'setup-completion) diff --git a/tmp/emacs-config/config/setup-dired.el b/tmp/emacs-config/config/setup-dired.el @@ -0,0 +1,153 @@ +;;; -*- lexical-binding: t; -*- +(use-package dired + :defer t + :custom + (dired-auto-revert-buffer t) + (dired-recursive-copies 'always) + (dired-recursive-deletes 'always) + (dired-isearch-filenames 'dwim) + (delete-by-moving-to-trash t) + (dired-listing-switches "-lFaGh1v --group-directories-first") + (dired-ls-F-marks-symlinks t) + (dired-dwim-target t) + :bind (("<C-return>" . vde/open-in-external-app) + ("C-c f g" . vde/dired-get-size) + ("C-c f f" . find-name-dired) + (:map dired-mode-map + ("M-p" . vde/dired-up) + ("^" . vde/dired-up) + ("<backspace>" . vde/dired-up) + ("M-n" . vde/dired-down) + ("RET" . find-file-reuse-dir-buffer) + ("!" . vde/sudired) + ("<prior>" . beginend-dired-mode-goto-beginning) + ("<next>" . beginend-dired-mode-goto-end))) + :config + (when (string= system-type "darwin") + (setq dired-use-ls-dired t + insert-directory-program "/usr/local/bin/gls")) + + ;; Enable dired-find-alternate-file + (put 'dired-find-alternate-file 'disabled nil) + + ;; Handle long file names + (add-hook 'dired-mode-hook #'toggle-truncate-lines) + + (defun vde/dired-up () + "Go to previous directory." + (interactive) + (find-alternate-file "..")) + + (defun vde/dired-down () + "Enter directory." + (interactive) + (dired-find-alternate-file)) + + (defun vde/open-in-external-app () + "Open the file(s) at point with an external application." + (interactive) + (let* ((file-list + (dired-get-marked-files))) + (mapc + (lambda (file-path) + (let ((process-connection-type nil)) + (start-process "" nil "xdg-open" file-path))) file-list))) + + (defun find-file-reuse-dir-buffer () + "Like `dired-find-file', but reuse Dired buffers." + (interactive) + (set-buffer-modified-p nil) + (let ((file (dired-get-file-for-visit))) + (if (file-directory-p file) + (find-alternate-file file) + (find-file file)))) + + (defun vde/sudired () + "Open directory with sudo in Dired." + (interactive) + (require 'tramp) + (let ((dir (expand-file-name default-directory))) + (if (string-match "^/sudo:" dir) + (user-error "Already in sudo") + (dired (concat "/sudo::" dir))))) + + (defun vde/dired-get-size () + "Quick and easy way to get file size in Dired." + (interactive) + (let ((files (dired-get-marked-files))) + (with-temp-buffer + (apply 'call-process "du" nil t nil "-sch" files) + (message + "Size of all marked files: %s" + (progn + (re-search-backward "\\(^[0-9.,]+[A-Za-z]+\\).*total$") + (match-string 1))))))) + +(use-package find-dired + :after dired + :custom + (find-ls-option ;; applies to `find-name-dired' + '("-ls" . "-AFhlv --group-directories-first")) + (find-name-arg "-iname")) + +(use-package dired-x ; Enable some nice Dired features + :bind ("C-x C-j" . dired-jump) + :custom + (dired-omit-verbose nil) + (dired-clean-confirm-killing-deleted-buffers nil) + :hook + (dired-mode . dired-omit-mode) + :config + (setq dired-omit-files (concat dired-omit-files "\\|^\\.+$\\|^\\..+$"))) + +(use-package dired-aux ; Other Dired customizations + :after dired + :config + (setq + ;; Ask for creation of missing directories when copying/moving + dired-create-destination-dirs 'ask + ;; Search only file names when point is on a file name + dired-isearch-filenames'dwim)) + +(use-package dired-collapse + :defer 1 + :commands (dired-collapse-mode) + :init + (add-hook 'dired-mode-hook #'dired-collapse-mode)) + +(use-package dired-quick-sort + :defer 1 + :after dired + :config + (dired-quick-sort-setup)) + +(use-package async) + +(use-package dired-async + :after (dired async) + :config + (dired-async-mode 1)) + +(use-package dired-narrow + :after dired + :custom + (dired-narrow-exit-when-one-left t) + (dired-narrow-enable-blinking t) + (dired-narrow-blink-time 0.3) + :bind (:map dired-mode-map + ("M-s n" . dired-narrow))) + +(use-package wdired + :after dired + :commands (wdired-mode + wdired-change-to-wdired-mode) + :custom + (wdired-allow-to-change-permissions t) + (wdired-create-parent-directories t)) + +(use-package dired-rsync + :ensure t + :bind (:map dired-mode-map + ("r" . dired-rsync))) + +(provide 'setup-dired) diff --git a/tmp/emacs-config/config/setup-docker.el b/tmp/emacs-config/config/setup-docker.el @@ -0,0 +1,28 @@ +;;; -*- lexical-binding: t; -*- +(use-package dockerfile-mode ; Edit docker's Dockerfiles + :unless *sys/full* + :mode ("Dockerfile\\'" . dockerfile-mode)) + +;; I have a bunch of different 'profiles' for kubernetes by different cluster so +;; i don't mess between things +;; This allow me to set the KUBECONFIG variable between those easily +;; TODO: add the current profile in modeline +(defun my-switch-kubeconfig-env (&optional kubeconfig) + "Set KUBECONFIG environment variable for the current session" + (interactive + (list + (completing-read + "Kubeconfig: " + (mapcar + (lambda (x) + (replace-regexp-in-string + "^config\." "" + (file-name-nondirectory(directory-file-name x)))) + (directory-files-recursively + (expand-file-name "~/.kube") "^config\.")) nil t ))) + (setq kubeconfig (expand-file-name (format "~/.kube/config.%s" kubeconfig))) + (if (file-exists-p kubeconfig) + (setenv "KUBECONFIG" kubeconfig) + (error "Cannot find kubeconfig: %s" kubeconfig))) + +(provide 'setup-docker) diff --git a/tmp/emacs-config/config/setup-editing.el b/tmp/emacs-config/config/setup-editing.el @@ -0,0 +1,258 @@ +;;; -*- lexical-binding: t; -*- +(setq enable-remote-dir-locals t) +(use-package aggressive-indent ; Automatically indent code + :bind ("C-c e i" . aggressive-indent-mode) + :hook ((lisp-mode . aggressive-indent-mode) + (emacs-lisp-mode . aggressive-indent-mode) + (clojure-mode . aggressive-indent-mode)) + :config + ;; Free C-c C-q, used in Org and in CIDER + (unbind-key "C-c C-q" aggressive-indent-mode-map)) + +(use-package undo-tree ; Show buffer changes as a tree + :defer 1 + :init (global-undo-tree-mode) + :config (setq undo-tree-visualizer-timestamps t + undo-tree-enable-undo-in-region t)) + +(use-package whitespace + :defer 1 + :hook ((prog-mode . whitespace-mode)) + :config + (setq whitespace-style '(face tabs spaces trailing space-before-tab newline indentation empty space-after-tab space-mark tab-mark newline-mark))) + +(use-package smartparens + :defer 1 + :init + (progn + (use-package smartparens-config) + (show-smartparens-global-mode 1)) + :config + (progn + (require 'smartparens-config) + (add-hook 'prog-mode-hook 'turn-on-smartparens-strict-mode) + (add-hook 'markdown-mode-hook 'turn-on-smartparens-strict-mode) + + (sp-local-pair 'minibuffer-inactive-mode "'" nil :actions nil) + (sp-local-pair 'web-mode "{%" "%}") + (sp-with-modes 'emacs-lisp-mode + ;; disable ', it's the quote character! + (sp-local-pair "'" nil :actions nil) + ;; also only use the pseudo-quote inside strings where it + ;; serves as hyperlink. + (sp-local-pair "`" "'" :when '(sp-in-string-p sp-in-comment-p))))) + +(use-package expand-region + :bind (("C-=" . er/expand-region) + ("C--". er/contract-region))) + +(use-package iedit + :defines hydra-iedit/body + :bind* (:map global-map + ("C-*" . iedit-mode) + :map iedit-mode-keymap + ("M-n" . iedit-next-occurence) + ("M-p" . iedit-prev-occurence)) + :config + (defhydra hydra-iedit (:color pink :columns 1) + "IEDIT" + ("C-*" iedit-mode "toggle") + ("C-p" iedit-prev-occurrence "prev") + ("C-n" iedit-next-occurrence "next") + ("C-g" iedit-quit "toggle" :color blue))) + +(use-package visual-regexp + :bind (("C-c r" . vr/replace) + ("C-c %" . vr/query-replace) + ("C-c m" . vr/mc-mark))) + +(use-package yasnippet + :after (company prog-mode) + :defer 5 + :bind (("C-c y d" . yas-load-directory) + ("C-c y i" . yas-insert-snippet) + ("C-c y f" . yas-visit-snippet-file) + ("C-c y n" . yas-new-snippet) + ("C-c y t" . yas-tryout-snippet) + ("C-c y l" . yas-describe-tables) + ("C-c y g" . yas-global-mode) + ("C-c y m" . yas-minor-mode) + ("C-c y a" . yas-reload-all) + ("C-c y x" . yas-expand)) + :bind (:map yas-keymap + ("C-i" . yas-next-field-or-maybe-expand)) + :mode ("/\\.emacs\\.d/etc/yasnippet/snippets/" . snippet-mode) + :hook (go-mode . yas-minor-mode) + :config + (yas-load-directory (concat user-emacs-directory "etc/yasnippet/snippets")) + (yas-global-mode 1) + :init + (add-hook 'term-mode-hook (lambda () (yas-minor-mode -1)))) + +(use-package hs-minor-mode + :hook ((prog-mode . hs-minor-mode))) + +(use-package easy-kill + :config + (global-set-key [remap kill-ring-save] 'easy-kill) + (global-set-key [remap mark-sexp] 'easy-mark)) + +(use-package define-word) + +(setq display-line-numbers-type 'relative) +(add-hook 'prog-mode-hook + 'display-line-numbers-mode) +(add-hook 'prog-mode-hook 'toggle-truncate-lines) + +(use-package newcomment + :custom + (comment-empty-lines t) + (comment-fill-column nil) + (comment-multi-line t) + (comment-style 'multi-line) + :config + (defun prot/comment-dwim (&optional arg) + "Alternative to `comment-dwim': offers a simple wrapper +around `comment-line' and `comment-dwim'. + +If the region is active, then toggle the comment status of the +region or, if the major mode defines as much, of all the lines +implied by the region boundaries. + +Else toggle the comment status of the line at point." + (interactive "*P") + (if (use-region-p) + (comment-dwim arg) + (save-excursion + (comment-line arg)))) + + :bind (("C-;" . prot/comment-dwim) + ("C-:" . comment-kill) + ("M-;" . comment-indent) + ("C-x C-;" . comment-box))) + +(use-package flyspell + :init + (setq flyspell-issue-message-flag nil) + (setq flyspell-issue-welcome-flag nil) + (setq ispell-program-name "hunspell") + (setq ispell-local-dictionary "en_GB") + (setq ispell-local-dictionary-alist + '(("en_GB" + "[[:alpha:]]" + "[^[:alpha:]]" + "[']" + nil + ("-d" "en_GB,fr_FR") + nil + utf-8))) + :config + (define-key flyspell-mode-map (kbd "C-;") nil) + :hook + (text-mode . turn-on-flyspell) + (prog-mode . turn-off-flyspell)) + +(use-package flyspell-correct-ivy + :after flyspell + :bind (:map flyspell-mode-map + ([remap flyspell-correct-word-before-point] . flyspell-correct-previous-word-generic))) + +(use-package electric + :custom + (electric-pair-inhibit-predicate 'electric-pair-default-inhibit) + (electric-pair-pairs '((8216 . 8217) + (8220 . 8221) + (171 . 187))) + (electric-pair-skip-self 'electric-pair-default-skip-self) + (electric-quote-context-sensitive t) + (electric-quote-paragraph t) + (electric-quote-string nil) + :config + (electric-indent-mode 1) + (electric-pair-mode 1) + (electric-quote-mode -1)) + +(use-package emacs + :init + (setq-default tab-always-indent 'complete) + (setq-default tab-width 4) + (setq-default indent-tabs-mode nil)) + +(use-package emacs + :hook (before-save . delete-trailing-whitespace)) + +(use-package delsel + :config + (delete-selection-mode 1)) + +(use-package emacs + :custom + (repeat-on-final-keystroke t) + (set-mark-command-repeat-pop t) + :bind ("M-z" . zap-up-to-char)) + +(use-package emacs + :config + (defun prot/new-line-below () + "Create a new line below the current one. Move the point to +the absolute beginning. Also see `prot/new-line-above'." + (interactive) + (end-of-line) + (newline)) + + (defun prot/new-line-above () + "Create a new line above the current one. Move the point to +the absolute beginning. Also see `prot/new-line-below'." + (interactive) + (beginning-of-line) + (newline) + (forward-line -1)) + + (defun prot/yank-replace-line-or-region () + "Replace the line at point with the contents of the last +stretch of killed text. If the region is active, operate over it +instead. This command can then be followed by the standard +`yank-pop' (default is bound to M-y)." + (interactive) + (if (use-region-p) + (progn + (delete-region (region-beginning) (region-end)) + (yank)) + (progn + (delete-region (point-at-bol) (point-at-eol)) + (yank)))) + + :bind (("C-S-SPC" . contrib/mark-whole-word) + ("<C-return>" . prot/new-line-below) + ("<C-S-return>" . prot/new-line-above) + ("M-SPC" . cycle-spacing) + ("M-o" . delete-blank-lines) + ("<f6>" . tear-off-window) + ("C-S-y" . prot/yank-replace-line-or-region))) + +(use-package crux + :commands (crux-transpose-windows + crux-duplicate-current-line-or-region + crux-rename-file-and-buffer + crux-open-with) + :bind (("C-c w S" . crux-transpose-windows) + ("C-c d" . crux-duplicate-current-line-or-region) + ("<C-f2>" . crux-rename-file-and-buffer) + :map dired-mode-map + ("<M-return>" . crux-open-with))) + +(use-package goto-last-change + :commands goto-last-change + :bind ("C-z" . goto-last-change)) + +(use-package pdf-tools + :pin manual + :mode ("\\.pdf\\'" . pdf-view-mode) + :config + (setq-default pdf-view-display-size 'fit-page) + (setq pdf-annot-activate-created-annotations t) + (setq pdf-view-midnight-colors '("#ffffff" . "#000000")) + (pdf-tools-install :no-query) + (require 'pdf-occur)) + +(provide 'setup-editing) diff --git a/tmp/emacs-config/config/setup-files.el b/tmp/emacs-config/config/setup-files.el @@ -0,0 +1,108 @@ +;;; -*- lexical-binding: t; -*- +(use-package files ; Core commands for files + :bind (("<f5>" . revert-buffer))) + +(use-package ripgrep + :defer 2) + +(setq view-read-only t) ; View read-only + +(use-package direnv + :custom + (direnv-always-show-summary t) + (direnv-show-paths-in-summary nil) + :config + (direnv-mode)) + +(use-package hardhat ; Protect user-writable files + :init (global-hardhat-mode)) + +(use-package image-file ; Visit images as images + :init (auto-image-file-mode)) + +(use-package markdown-mode ; Edit markdown files + :mode ("\\.md\\'" . markdown-mode) + :config + (setq markdown-fontify-code-blocks-natively t) + + ;; Don't change font in code blocks + (set-face-attribute 'markdown-code-face nil + :inherit nil) + + ;; Process Markdown with Pandoc, using a custom stylesheet for nice output + (let ((stylesheet (expand-file-name + (locate-user-emacs-file "etc/pandoc.css")))) + (setq markdown-command + (mapconcat #'shell-quote-argument + `("pandoc" "--toc" "--section-divs" + "--css" ,(concat "file://" stylesheet) + "--standalone" "-f" "markdown" "-t" "html5") + " "))) + (add-hook 'markdown-mode-hook #'auto-fill-mode)) + +(use-package highlight-indentation + :config + (set-face-background 'highlight-indentation-face "#e3e3d3") + (set-face-background 'highlight-indentation-current-column-face "#c3b3b3")) + +(use-package yaml-mode + :mode "\\.ya?ml\\'" + :hook ((yaml-mode . highlight-indentation-mode) + (yaml-mode . highlight-indentation-current-column-mode))) + +(use-package toml-mode + :mode "\\.to?ml\\'") + +;;;###autoload +(defun vde/delete-this-file () + "Delete the current file, and kill the buffer." + (interactive) + (or (buffer-file-name) (error "No file is currently being edited")) + (when (yes-or-no-p (format "Really delete '%s'?" + (file-name-nondirectory buffer-file-name))) + (delete-file (buffer-file-name)) + (kill-this-buffer))) + +;;;###autoload +(defun vde/rename-this-file-and-buffer (new-name) + "Renames both current buffer and file it's visiting to NEW-NAME." + (interactive "sNew name: ") + (let ((name (buffer-name)) + (filename (buffer-file-name))) + (unless filename + (error "Buffer '%s' is not visiting a file!" name)) + (if (get-buffer new-name) + (message "A buffer named '%s' already exists!" new-name) + (progn + (when (file-exists-p filename) + (rename-file filename new-name 1)) + (rename-buffer new-name) + (set-visited-file-name new-name))))) + +(bind-key "C-c f D" #'vde/delete-this-file) +(bind-key "C-c f R" #'vde/rename-this-file-and-buffer) + +;; Additional bindings for built-ins +(bind-key "C-c f v d" #'add-dir-local-variable) +(bind-key "C-c f v l" #'add-file-local-variable) +(bind-key "C-c f v p" #'add-file-local-variable-prop-line) + +(defun vde/reload-dir-locals-for-current-buffer () + "Reload dir locals for the current buffer." + (interactive) + (let ((enable-local-variables :all)) + (hack-dir-local-variables-non-file-buffer))) + +(defun vde/reload-dir-locals-for-all-buffers-in-this-directory () + "Reload dir-locals for all buffers in current buffer's `default-directory'." + (interactive) + (let ((dir default-directory)) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when (equal default-directory dir)) + (vde/reload-dir-locals-for-current-buffer))))) + +(bind-key "C-c f v r" #'vde/reload-dir-locals-for-current-buffer) +(bind-key "C-c f v r" #'vde/reload-dir-locals-for-all-buffers-in-this-directory) + +(provide 'setup-files) diff --git a/tmp/emacs-config/config/setup-go.el b/tmp/emacs-config/config/setup-go.el @@ -0,0 +1,47 @@ +;;; -*- lexical-binding: t; -*- +(use-package go-mode + :mode "\\.go$" + :interpreter "go" + :config + (use-package company-go + :config + (setq company-go-show-annotation t) + (push 'company-go company-backends)) + ;(setq gofmt-command "goimports") + (if (not (executable-find "goimports")) + (warn "go-mode: couldn't find goimports; no code formatting/fixed imports on save") + (add-hook 'before-save-hook 'gofmt-before-save)) + (if (not (string-match "go" compile-command)) ; set compile command default + (set (make-local-variable 'compile-command) + "go build -v && go test -v && go vet"))) + +(use-package lsp-go + :after (lsp-mode go-mode) + :config + ;;Set up before-save hooks to format buffer and add/delete imports. + ;;Make sure you don't have other gofmt/goimports hooks enabled. + (defun lsp-go-install-save-hooks () + ;; (add-hook 'before-save-hook #'lsp-format-buffer t t) + (add-hook 'before-save-hook #'lsp-organize-imports t t)) + (add-hook 'go-mode-hook #'lsp-go-install-save-hooks) + ) + +(use-package flycheck-golangci-lint + :hook (go-mode . flycheck-golangci-lint-setup) + :config (setq flycheck-golangci-lint-tests t)) + +(use-package dap-go + :disabled + :after dap-mode) + +(use-package gotest + :after go-mode) + +(use-package gotest-ui + :after (go-mode gotest) + :bind (:map go-mode-map + ("C-c t t" . gotest-ui-current-test) + ("C-c t f" . gotest-ui-current-file) + ("C-c t p" . gotest-ui-current-project))) + +(provide 'setup-go) diff --git a/tmp/emacs-config/config/setup-hydras.el b/tmp/emacs-config/config/setup-hydras.el @@ -0,0 +1,72 @@ +;;; -*- lexical-binding: t; -*- +(defhydra hydra-goto-line (goto-map "") + "goto-line" + ("g" goto-line "go") + ("m" set-mark-command "mark" :bind nil) + ("q" nil "quit")) + +(defhydra hydra-yank-pop () + "yank" + ("C-y" yank nil) + ("M-y" yank-pop nil) + ("y" (yank-pop 1) "next") + ("Y" (yank-pop -1) "prev")) ; or browse-kill-ring + +(defhydra hydra-zoom (global-map "<f2>") + "zoom" + ("g" text-scale-increase "in") + ("l" text-scale-decrease "out") + ("r" (text-scale-set 0) "reset") + ("0" (text-scale-set 0) :bind nil :exit t) + ("1" (text-scale-set 0) nil :bind nil :exit t)) + +;; Better shrink/enlarge windows +(defhydra hydra-resize (global-map "<f2>") + "resize windows" + ("<up>" enlarge-window "enlarge") + ("<down>" shrink-window "shrink") + ("<left>" shrink-window-horizontally "shrink horizontaly") + ("<right>" enlarge-window-horizontally "enlarge horizontaly")) + +(defvar hide-mode-line-mode nil) +(defvar whitespace-mode nil) +(defvar subword-mode nil) +(defhydra hydra-toggle (:color pink :hint nil) + " +_a_ abbrev-mode: %`abbrev-mode +_b_ subword-mode: %`subword-mode +_d_ debug-on-error: %`debug-on-error +_h_ hide-mode-line-mode %`hide-mode-line-mode +_f_ auto-fill-mode: %`auto-fill-function +_r_ readonly-mode: %`buffer-read-only +_t_ truncate-lines %`truncate-lines +_v_ visual-line-mode: %`visual-line-mode +_w_ whitespace-mode: %`whitespace-mode +_s_ smartparens-strict: %`smartparens-strict-mode +_V_ visible-mode: %`visible-mode +" + ("a" abbrev-mode nil) + ("b" subword-mode nil) + ("d" toggle-debug-on-error nil) + ("f" auto-fill-mode nil) + ("h" hide-mode-line-mode nil) + ("r" dired-toggle-read-only nil) + ("t" toggle-truncate-lines nil) + ("v" visual-line-mode nil) + ("V" visible-mode nil) + ("w" whitespace-mode nil) + ("s" smartparens-strict-mode nil) + ("q" nil "quit")) + +(global-set-key (kbd "C-c C-v") 'hydra-toggle/body) + +(defhydra hydra-marked-items (dired-mode-map "") + " +Number of marked items: %(length (dired-get-marked-files)) +" + ("m" dired-mark "mark")) + +(bind-key "M-y" #'hydra-yank-pop/yank-pop) +(bind-key "C-y" #'hydra-yank-pop/yank) + +(provide 'setup-hydras) diff --git a/tmp/emacs-config/config/setup-keybindings.el b/tmp/emacs-config/config/setup-keybindings.el @@ -0,0 +1,41 @@ +(use-package which-key + :init (which-key-mode) + :custom + (which-key-idle-delay 2) + (which-key-idle-secondary-delay 0.05) + (which-key-show-early-on-C-h t) + (which-key-sort-order 'which-key-prefix-then-key-order) + (which-key-popup-type 'side-window) + (which-key-show-prefix 'echo) + (which-key-max-display-columns 6) + (which-key-separator " β ") + :config + (add-to-list 'which-key-replacement-alist '(("TAB" . nil) . ("βΉ" . nil))) + (add-to-list 'which-key-replacement-alist '(("RET" . nil) . ("β" . nil))) + (add-to-list 'which-key-replacement-alist '(("DEL" . nil) . ("β€" . nil))) + (add-to-list 'which-key-replacement-alist '(("SPC" . nil) . ("β£" . nil)))) + +(use-package region-bindings-mode + :config + ;; Do not activate `region-bindings-mode' in Special modes like `dired' and + ;; `ibuffer'. Single-key bindings like 'm' are useful in those modes even + ;; when a region is selected. + (setq region-bindings-mode-disabled-modes '(dired-mode ibuffer-mode)) + + (region-bindings-mode-enable) + + (defun vde/disable-rbm-deactivate-mark () + "Disable `region-bindings-mode' and deactivate mark." + (interactive) + (region-bindings-mode -1) + (deactivate-mark) + (message "Mark deactivated")) + + (bind-keys + :map region-bindings-mode-map + ("<C-SPC>" . vde/disable-rbm-deactivate-mark))) + +;; Disable C-x C-n to avoid the disabled command buffer +(unbind-key "C-x C-n" global-map) + +(provide 'setup-keybindings) diff --git a/tmp/emacs-config/config/setup-mails.el b/tmp/emacs-config/config/setup-mails.el @@ -0,0 +1,244 @@ +;;; setup-mails.el --- -*- lexical-binding: t -*- + +;; AuthSource +(use-package auth-source + :config + (setq auth-sources '("~/.authinfo.gpg" "~/.authinfo")) + (setq user-full-name "Vincent Demeester") + (setq user-mail-address "vincent@sbr.pm")) +;; -AuthSource + +;; EPA +(use-package epa-file + :config + (setq epa-file-cache-passphrase-for-symmetric-encryption t) + :init + (epa-file-enable)) +;; -EPA + +;; GnusCfg +(use-package gnus + :config + (setq nnml-directory "~/desktop/gnus/mail") + (setq nnfolder-directory "~/desktop/gnus/archive") + (setq nndraft-directory "~/desktop/gnus/drafts") + (setq nnmh-directory "~/desktop/gnus/drafts") + (setq gnus-article-save-directory "~/desktop/gnus/news") + (setq gnus-home-directory "~/desktop/gnus") + (setq gnus-kill-files-directory "~/desktop/gnus/news") + (setq gnus-cache-directory "~/desktop/gnus/news/cache") + (setq gnus-startup-file "~/desktop/gnus/newsrc") + (setq mail-source-directory "~/desktop/gnus/mail") + (setq gnus-registry-cache-file "~/desktop/gnus/gnus.registry.eld") + (setq gnus-select-method '(nnnil)) + (setq nntp-authinfo-file "~/.authinfo.gpg") + (setq gnus-secondary-select-methods + '((nntp "news.gwene.org") + (nnimap "prv" + (nnimap-address "mail.gandi.net") + (nnimap-stream ssl) + (nnimap-authinfo-file "~/.authinfo.gpg")) + (nnimap "redhat" + (nnimap-address "imap.gmail.com") + (nnimap-stream ssl) + (nnimap-authinfo-file "~/.authinfo.gpg")) + (nnimap "vde" + (nnimap-address "imap.gmail.com") + (nnimap-stream ssl) + (nnimap-authinfo-file "~/.authinfo.gpg")) + )) + (setq gnus-parameters + '(("prv" + (posting-style + (address "vincent@demeester.fr") + (signature-file "~/desktop/documents/.prv.signature") + (gcc "nnimap+prv:Sent"))) + ("redhat" + (posting-style + (address "vdemeest@redhat.com") + (signature-file "~/desktop/documents/.redhat.signature"))) + ("nnimap+redhat:INBOX" + (display . all)) + ("vde" + (posting-style + (address "vinc.demeester.fr") + (signature-file "~/desktop/documents/.vde.signature"))) + ("nnimap+vde:INBOX" + (display . all)))) + (setq gnus-agent t) + (setq mail-user-agent 'gnus-user-agent) ; also works with `sendmail-user-agent' + (setq gnus-check-new-newsgroups 'ask-server) + (setq gnus-read-active-file 'some) + (setq gnus-use-dribble-file t) + (setq gnus-always-read-dribble-file t) + (setq gnus-novice-user nil) + (setq gnus-extra-headers + '(To Newsgroups X-GM-LABELS))) +;; -GnusCfg + +;; GnusMmlSec +(use-package mml-sec + :config + (setq mml-secure-openpgp-signers + '("8C4E8DDA04C18C6B503BD2DBB7E7CF1C634256FA"))) +;; -GnusMmlSec + +;; GnusAgent +(use-package gnus-agent + :after gnus + :config + (setq gnus-agent-article-alist-save-format 1) ; uncompressed + (setq gnus-agent-cache t) + (setq gnus-agent-confirmation-function 'y-or-n-p) + (setq gnus-agent-consider-all-articles nil) + (setq gnus-agent-directory "~/desktop/gnus/agent/") + (setq gnus-agent-enable-expiration 'ENABLE) + (setq gnus-agent-expire-all nil) + (setq gnus-agent-expire-days 30) + (setq gnus-agent-mark-unread-after-downloaded t) + (setq gnus-agent-queue-mail t) ; queue if unplugged + (setq gnus-agent-synchronize-flags nil)) +;; -GnusAgent + +;; GnusAsync +(use-package gnus-async + :after gnus + :config + (setq gnus-asynchronous t) + (setq gnus-use-article-prefetch 30)) +;; -GnusAsync + +;; GnusGroup +(use-package gnus-group + :after gnus + :config + (setq gnus-level-subscribed 6) + (setq gnus-level-unsubscribed 7) + (setq gnus-level-zombie 8) + (setq gnus-group-sort-function + '((gnus-group-sort-by-unread) + (gnus-group-sort-by-alphabet) + (gnus-group-sort-by-rank))) + (setq gnus-group-mode-line-format "Gnus: %%b") + :hook + (gnus-select-group-hook . gnus-group-set-timestamp) + :bind (:map gnus-agent-group-mode-map + ("M-n" . gnus-topic-goto-next-topic) + ("M-p" . gnus-topic-goto-previous-topic))) +;; -GnusGroup + +;; GnusTopic +(use-package gnus-topic + :after (gnus gnus-group) + :config + (setq gnus-topic-display-empty-topics t) + :hook + (gnus-group-mode . gnus-topic-mode)) +;; -GnusTopic + +;; GnusSummary +(use-package gnus-sum + :after (gnus gnus-group) + :demand + :config + (setq gnus-auto-select-first nil) + (setq gnus-summary-ignore-duplicates t) + (setq gnus-suppress-duplicates t) + (setq gnus-summary-goto-unread nil) + (setq gnus-summary-make-false-root 'adopt) + (setq gnus-summary-thread-gathering-function 'gnus-gather-threads-by-subject) + (setq gnus-thread-sort-functions + '((not gnus-thread-sort-by-number) + (not gnus-thread-sort-by-date))) + (setq gnus-subthread-sort-functions + 'gnus-thread-sort-by-date) + (setq gnus-thread-hide-subtree nil) + (setq gnus-thread-ignore-subject t) + (setq gnus-user-date-format-alist + '(((gnus-seconds-today) . "Today at %R") + ((+ 86400 (gnus-seconds-today)) . "Yesterday, %R") + (t . "%Y-%m-%d %R"))) + (setq gnus-summary-line-format "%U%R%z %-16,16&user-date; %4L:%-30,30f %B%S\n") + (setq gnus-summary-mode-line-format "Gnus: %p (%U)") + (setq gnus-sum-thread-tree-false-root "") + (setq gnus-sum-thread-tree-indent " ") + (setq gnus-sum-thread-tree-leaf-with-other "βββ€ ") + (setq gnus-sum-thread-tree-root "") + (setq gnus-sum-thread-tree-single-leaf "βββ€ ") + (setq gnus-sum-thread-tree-vertical "β") + :hook + (gnus-summary-exit-hook . gnus-topic-sort-groups-by-alphabet) + (gnus-summary-exit-hook . gnus-group-sort-groups-by-rank) + :bind (:map gnus-agent-summary-mode-map + ("<delete>" . gnus-summary-delete-article) + ("n" . gnus-summary-next-article) + ("p" . gnus-summary-prev-article) + ("N" . gnus-summary-next-unread-article) + ("P" . gnus-summary-prev-unread-article) + ("M-n" . gnus-summary-next-thread) + ("M-p" . gnus-summary-prev-thread) + ("C-M-n" . gnus-summary-next-group) + ("C-M-p" . gnus-summary-prev-group) + ("C-M-^" . gnus-summary-refer-thread))) +;; -GnusSummary + +;; GnusDired +(use-package gnus-dired + :after (gnus dired) + :hook (dired-mode . gnus-dired-mode)) +;; -GnusDired + + +;; SendmailCfg +(use-package smtpmail + :config + (setq message-send-mail-function 'message-send-mail-with-sendmail) + (setq sendmail-program "msmtp") + (setq message-sendmail-f-is-evil 't) + (setq message-sendmail-extra-arguments '("--read-envelope-from"))) + +(use-package sendmail + :defer t + :commands (mail-mode mail-text) + :defines (send-mail-function) + :config + (setq send-mail-function 'sendmail-send-it + sendmail-program "/home/vincent/bin/msmtp")) +;; -SendmailCfg + +;; MessageCfg +(use-package message + :commands (message-mode message-cite-original-without-signature) + :config + (setq mail-user-agent 'message-user-agent + message-wide-reply-confirm-recipients t + message-default-charset 'utf-8 + message-default-mail-headers "Cc: \nBcc: \n" + message-kill-buffer-on-exit t + message-generate-headers-first t) + (add-to-list 'mm-body-charset-encoding-alist '(utf-8 . base64)) + (add-hook 'message-mode-hook 'turn-on-auto-fill)) +;; -MessageCfg + +;; Notmuch +(if *sys/full* + (progn + (setenv "NOTMUCH_CONFIG" (expand-file-name ".config/notmuch/notmuchrc" (getenv "HOME"))) + (use-package notmuch + :defer t + :bind ("<f6>" . notmuch) + :config + (setq notmuch-search-oldest-first nil + mail-user-agent 'message-user-agent + notmuch-tree-show-out t) + (setq notmuch-saved-searches + '((:key "i" :name "inbox" :query "tag:Inbox") + (:key "r" :name "redhat inbox folder" :query "folder:redhat/Inbox") + (:key "p" :name "perso inbox folder" :query "folder:perso/Inbox") + (:key "u" :name "unread" :query "tag:unread") + (:key "F" :name "flagged" :query "tag:flagged") + (:key "S" :name "sent" :query "tag:Sent Mail")))))) +;; -Notmuch + +(provide 'setup-mails) +;;; setup-mails ends here diff --git a/tmp/emacs-config/config/setup-mouse.el b/tmp/emacs-config/config/setup-mouse.el @@ -0,0 +1,11 @@ +(use-package mouse + :config + (setq mouse-wheel-scroll-amount + '(1 + ((shift) . 5) + ((meta) . 0.5) + ((control) . text-scale))) + (setq make-pointer-invisible t + mouse-wheel-progressive-speed t + mouse-wheel-follow-mouse t) + :hook (after-init . mouse-wheel-mode)) diff --git a/tmp/emacs-config/config/setup-multiple-cursors.el b/tmp/emacs-config/config/setup-multiple-cursors.el @@ -0,0 +1,17 @@ +(use-package multiple-cursor + :bind (:map region-bindings-mode-map + ("a" . mc/mark-all-like-this) + ("p" . mc/mark-previous-like-this) + ("n" . mc/mark-next-like-this) + ("P" . mc/unmark-previous-like-this) + ("N" . mc/unmark-next-like-this) + ("[" . mc/cycle-backward) + ("]" . mc/cycle-forward) + ("m" . mc/mark-more-like-this-extended) + ("h" . mc-hide-unmatched-lines-mode) + ("\\" . mc/vertical-align-with-space) + ("#" . mc/insert-numbers) ; use num prefix to set the starting number + ("^" . mc/edit-beginnings-of-lines) + ("$" . mc/edit-ends-of-lines))) + +(provide 'setup-multiple-cursors) diff --git a/tmp/emacs-config/config/setup-navigating.el b/tmp/emacs-config/config/setup-navigating.el @@ -0,0 +1,35 @@ +(use-package avy ; Jump to characters in buffers + :bind (("C-c j" . avy-goto-word-1) + ("C-c n b" . avy-pop-mark) + ("C-c n j" . avy-goto-char-2) + ("C-c n t" . avy-goto-char-timer) + ("C-c n w" . avy-goto-word-1))) + +(use-package helpful + :unless noninteractive + :bind (("C-c h F" . helpful-function) + ("C-c h C" . helpful-command) + ("C-c h M" . helpful-macro) + ("C-c h L" . helpful-callable) + ("C-c h S" . helpful-at-point) + ("C-c h V" . helpful-variable))) +(use-package winner + :unless noninteractive + :defer 5 + :config + (winner-mode 1)) + +(use-package hideshow + :defer 5 + :bind (("C-c @ a" . hs-show-all) + ("C-c @ c" . hs-toggle-hiding) + ("C-c @ t" . hs-hide-all) + ("C-c @ d" . hs-hide-block) + ("C-c @ l" . hs-hide-level))) + +(use-package mwim + :bind (:map prog-mode-map + ("C-a" . mwim-beginning-of-code-or-line) + ("C-e" . mwim-end-of-code-or-line))) + +(provide 'setup-navigating) diff --git a/tmp/emacs-config/config/setup-nix.el b/tmp/emacs-config/config/setup-nix.el @@ -0,0 +1,13 @@ +;;; -*- lexical-binding: t; -*- +(use-package nix-mode + :mode ("\\.nix\\'" "\\.nix.in\\'")) + +(use-package nix-drv-mode + :ensure nix-mode + :mode "\\.drv\\'") + +(use-package nix-shell + :ensure nix-mode + :commands (nix-shell-unpack nix-shell-configure nix-shell-build)) + +(provide 'setup-nix) diff --git a/tmp/emacs-config/config/setup-org.el b/tmp/emacs-config/config/setup-org.el @@ -0,0 +1,561 @@ +;;; setup-org.el --- -*- lexical-binding: t -*- + +;; OrgConstants +(defconst org-directory "~/desktop/org/" "org-mode directory, where most of the org-mode file lives") +(defconst org-default-projects-dir (concat org-directory "projects") "Primary tasks directory.") +(defconst org-default-technical-dir (concat org-directory "technical") "Directory of shareable, technical notes.") +(defconst org-default-personal-dir (concat org-directory "personal") "Directory of un-shareable, personal notes.") +(defconst org-default-completed-dir (concat org-directory "archive/projects") "Directory of completed project files.") +(defconst org-default-inbox-file (concat org-directory "projects/inbox.org") "New stuff collected in this file.") +(defconst org-default-next-file (concat org-directory "projects/next.org") "Todo *next* collected in this file.") +(defconst org-default-incubate-file (concat org-directory "projects/incubate.org") "Ideas simmering on back burner.") +(defconst org-default-notes-file (concat org-directory "personal/notes.org") "Non-actionable, personal notes.") +(defconst org-default-journal-file (concat org-directory "personal/journal.org") "Journaling stuff.") +;; -OrgConstants + +;; OrgRegisters +(set-register ?i `(file . ,org-default-inbox-file)) +(set-register ?I `(file . ,org-default-incubate-file)) +(set-register ?N `(file . ,org-default-next-file)) +(set-register ?n `(file . ,org-default-notes-file)) +(set-register ?j `(file . ,org-default-journal-file)) +;; -OrgRegisters + +;; OrgMain +(use-package s) +(use-package org + :ensure org-plus-contrib ;; load from the package instead of internal + :mode (("\\.org$" . org-mode)) + :config + (setq org-agenda-files `(,org-default-projects-dir + ,user-emacs-directory + "~/.config/nixpkgs/" + "~/.emacs.d/") + org-agenda-file-regexp "^[a-zA-Z0-9-_]+.org$" + org-use-speed-commands t + org-special-ctrl-a/e t + org-special-ctrl-k t + org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "STARTED(s)" "|" "DONE(d!)" "CANCELED(c@/!)") + (sequence "WAITING(w@/!)" "SOMEDAY(s)" "|" "CANCELED(c@/!)") + (sequence "IDEA(i)" "|" "CANCELED(c@/!)")) + org-todo-state-tags-triggers '(("CANCELLED" ("CANCELLED" . t)) + ("WAITING" ("WAITING" . t)) + (done ("WAITING")) + ("TODO" ("WAITING") ("CANCELLED")) + ("NEXT" ("WAITING") ("CANCELLED")) + ("DONE" ("WAITING") ("CANCELLED"))) + org-use-tag-inheritance t + org-tag-alist '(("linux") ("nixos") ("emacs") ("org") + ("openshift") ("redhat") ("tektoncd") ("kubernetes") ("knative" ) ("docker") + ("docs") ("code") ("review") + (:startgroup . nil) + ("@home" . ?h) ("@work" . ?w) ("@errand" . ?e) ("@health" . ?l) + (:endgroup . nil) + (:startgroup . nil) + ("@link" . ?i) ("@read" . ?r) ("@project" . ?p) + (:endgroup . nil)) + org-log-done 'time + org-log-redeadline 'time + org-log-reschedule 'time + org-log-into-drawer t + org-enforce-todo-dependencies t + org-refile-targets (append '((org-default-inbox-file :level . 0)) + (->> + (directory-files org-default-projects-dir nil ".org") + (--remove (s-starts-with? "." it)) + (--map (format "%s/%s" org-default-projects-dir it)) + (--map `(,it :level . 1)))) + org-refile-use-outline-path 'file + org-refile-allow-creating-parent-nodes 'confirm + org-outline-path-complete-in-steps nil + org-columns-default-format "%80ITEM(Task) %TODO %3PRIORITY %10Effort(Effort){:} %10CLOCKSUM" + org-fontify-whole-heading-line t + org-pretty-entities t + org-ellipsis " ‡" + org-archive-location (concat org-default-completed-dir "/%s::datetree/") + org-use-property-inheritance t + org-global-properties (quote (("EFFORT_ALL" . "0:15 0:30 0:45 1:00 2:00 3:00 4:00 5:00 6:00 0:00") + ("STYLE_ALL" . "habit"))) + org-blank-before-new-entry '((heading . t) + (plain-list-item . nil)) + org-insert-heading-respect-content t + org-yank-adjusted-subtrees t + org-image-actual-width nil + org-startup-with-inline-images nil + org-list-demote-modify-bullet '(("+" . "-") ("-" . "+"))) + (setcar (nthcdr 4 org-emphasis-regexp-components) 10) + :bind (("C-c o l" . org-store-link) + ("C-c o r r" . org-refile)) + :hook (org-mode . vde/org-mode-hook)) +;; -OrgMain + +;; OrgHook +(defun vde/org-mode-hook () + "Org-mode hook" + (setq show-trailing-whitespace t) + (when (not (eq major-mode 'org-agenda-mode)) + (setq fill-column 90) + (auto-revert-mode) + (auto-fill-mode) + (org-indent-mode) + (add-hook 'after-save-hook #'save-and-update-includes nil 'make-it-local))) +;; -OrgHook + +;; OrgId +(use-package org-id + :after (org) + :config + (setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id) + (defun eos/org-custom-id-get (&optional pom create prefix) + "Get the CUSTOM_ID property of the entry at point-or-marker POM. + If POM is nil, refer to the entry at point. If the entry does + not have an CUSTOM_ID, the function returns nil. However, when + CREATE is non nil, create a CUSTOM_ID if none is present + already. PREFIX will be passed through to `org-id-new'. In any + case, the CUSTOM_ID of the entry is returned." + (interactive) + (org-with-point-at pom + (let ((id (org-entry-get nil "CUSTOM_ID"))) + (cond + ((and id (stringp id) (string-match "\\S-" id)) + id) + (create + (setq id (org-id-new (concat prefix "h"))) + (org-entry-put pom "CUSTOM_ID" id) + (org-id-add-location id (buffer-file-name (buffer-base-buffer))) + id))))) + + (defun eos/org-add-ids-to-headlines-in-file () + "Add CUSTOM_ID properties to all headlines in the + current file which do not already have one." + (interactive) + (org-map-entries (lambda () + (eos/org-custom-id-get (point) 'create))))) +;; -OrgId + +;; OrgCrypt +(use-package org-crypt + :after (org) + :config + (org-crypt-use-before-save-magic) + (setq org-tags-exclude-from-inheritance '("crypt"))) +;; -OrgCrypt + +;; OrgAgenda +(use-package org-agenda + :after (org) + :commands (org-agenda) + :config + (use-package org-super-agenda + :config (org-super-agenda-mode)) + (setq org-agenda-span 'day + org-agenda-start-on-weekday 1 + org-agenda-include-diary t + org-agenda-window-setup 'current-window + org-agenda-skip-scheduled-if-done nil + org-agenda-compact-blocks t + org-agenda-sticky t + org-super-agenda-header-separator "" + org-agenda-custom-commands + `(("n" "Personal agenda" + ((agenda "") + (tags-todo "+TODO=\"NEXT\"" + ((org-agenda-overriding-header "Next items"))) + (tags-todo "@work-goals" + ((org-agenda-skip-function '(org-agenda-skip-if nil '(scheduled deadline))) + (org-agenda-overriding-header "Work"))) + (tags-todo "@home-goals" + ((org-agenda-skip-function '(org-agenda-skip-if nil '(scheduled deadline))) + (org-agenda-overriding-header "Home")))) + ((org-super-agenda-groups + '((:name "Important" :priority "A") + (:name "Done" :log closed) + (:name "Scheduled" :time-grid t) + (:name "Work" :tag "@work") + (:name "Perso" :tag "@home") + (:habit t)))) + (org-agenda-list)))) + :commands (org-agenda) + :bind (("C-c o a" . org-agenda) + ("<f12>" . org-agenda) + ("C-c o r a" . org-agenda-refile))) +;; -OrgAgenda + +;; OrgGcal +(use-package org-gcal + :after (org) + :commands (org-gcal-fetch) + :config + (require 'netrc) + + (defun get-authinfo (host port) + (let* ((netrc (netrc-parse (expand-file-name "~/.authinfo.gpg"))) + (hostentry (netrc-machine netrc host port port))) + (when hostentry (netrc-get hostentry "password")))) + + (setq org-gcal-client-id "959564825992-kvc7ofe9640cpc8ibgjqqgpi15e89nkn.apps.googleusercontent.com" + org-gcal-client-secret (get-authinfo "gcal.api" "9999") + org-gcal-file-alist '(("vdemeest@redhat.com" . "~/desktop/org/projects/schedule.org")))) +;; -OrgGcal + +;; OrgHabit +(use-package org-habit + :after (org) + :config + (setq org-habit-show-habits-only-for-today nil + org-habit-graph-column 80)) +;; -OrgHabit + +;; OrgSrc +(use-package org-src + :after (org) + :config + (setq org-src-fontify-natively t + org-src-tab-acts-natively t + org-src-window-setup 'split-window-right + org-edit-src-content-indentation 0)) +;; -OrgSrc + +;; OrgCaptureStart +(use-package org-capture + :after org + :commands (org-capture) + :config + ;; -OrgCaptureStart + + ;; OrgCaptureOldTemplate + (add-to-list 'org-capture-templates + `("t" "Task Entry" entry + (file ,org-default-inbox-file) + "* %?\n:PROPERTIES:\n:CREATED:%U\n:END:\n\n%i\n\nFrom: %a" + :empty-lines 1)) + (add-to-list 'org-capture-templates + `("r" "PR Review" entry + (file ,org-default-inbox-file) + "* TODO review gh:%^{issue} :review:\n:PROPERTIES:\n:CREATED:%U\n:END:\n\n%i\n%?\nFrom: %a" + :empty-lines 1)) + (add-to-list 'org-capture-templates + `("l" "Link" entry + (file ,org-default-inbox-file) + "* %a\n%U\n%?\n%i" + :empty-lines 1)) + (add-to-list 'org-capture-templates + '("n" "Thought or Note" entry + (file org-default-notes-file) + "* %?\n\n %i\n\n See: %a" :empty-lines 1)) + ;; -OrgCaptureOldTemplate + + ;; OrgCaptureJournal + (add-to-list 'org-capture-templates + `("j" "Journal entry" entry + (file+datetree ,org-default-journal-file) + (file ,(concat user-emacs-directory "/etc/orgmode/journal.org")) + :empty-lines 1 :clock-in t :clock-resume t)) + ;; -OrgCaptureJournal + + ;; OrgCaptureWorklog + (add-to-list 'org-capture-templates + `("w" "Worklog (journal) entry" entry + (file+datetree ,org-default-journal-file) + (file ,(concat user-emacs-directory "/etc/orgmode/worklog.org")) + :unnarrowed t)) + ;; -OrgCaptureWorklog + + ;; OrgCaptureWeekly + (add-to-list 'org-capture-templates + `("e" "Weekly review" entry + (file+datetree,org-default-journal-file) + (file ,(concat user-emacs-directory "/etc/orgmode/weekly.org")) + :clock-in t :clock-resume t :unnarrowed t)) + ;; -OrgCaptureWeekly + + ;; OrgCaptureBlog + (add-to-list 'org-capture-templates + `("b" "Blog post")) + (add-to-list 'org-capture-templates + `("bp" "Blog post" entry + (file+headline "~/src/github.com/vdemeester/blog/content-org/posts.org" "Blog Ideas") + "* %?\n:PROPERTIES:\n:END:\n")) + (add-to-list 'org-capture-templates + `("bl" "Blog link post" entry + (file+olp "~/src/github.com/vdemeester/blog/content-org/links.org" "Link") + "* %a\n%?\n%i")) + ;; -OrgCaptureBlog + + ;; OrgCaptureEnd + :bind (("C-c o c" . org-capture))) +;; -OrgCaptureEnd + +;; OrgProtocol +(use-package org-protocol + :after org) +;; -OrgProtocol + +;; OrgClock +(use-package org-clock + :after org + :commands (org-clock-in org-clock-out org-clock-goto) + :config + ;; Setup hooks for clock persistance + (org-clock-persistence-insinuate) + (setq org-clock-clocked-in-display nil + ;; Show lot of clocking history so it's easy to pick items off the C-F11 list + org-clock-history-length 23 + ;; Change tasks to STARTED when clocking in + org-clock-in-switch-to-state 'vde/clock-in-to-started + ;; Clock out when moving task to a done state + org-clock-out-when-done t + ;; Save the running clock and all clock history when exiting Emacs, load it on startup + org-clock-persist t) + (use-package find-lisp) + (defun vde/is-project-p () + "Any task with a todo keyword subtask" + (save-restriction + (widen) + (let ((has-subtask) + (subtree-end (save-excursion (org-end-of-subtree t))) + (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1))) + (save-excursion + (forward-line 1) + (while (and (not has-subtask) + (< (point) subtree-end) + (re-search-forward "^\*+ " subtree-end t)) + (when (member (org-get-todo-state) org-todo-keywords-1) + (setq has-subtask t)))) + (and is-a-task has-subtask)))) + + (defun vde/is-project-subtree-p () + "Any task with a todo keyword that is in a project subtree. +Callers of this function already widen the buffer view." + (let ((task (save-excursion (org-back-to-heading 'invisible-ok) + (point)))) + (save-excursion + (vde/find-project-task) + (if (equal (point) task) + nil + t)))) + + (defun vde/find-project-task () + "Move point to the parent (project) task if any" + (save-restriction + (widen) + (let ((parent-task (save-excursion (org-back-to-heading 'invisible-ok) (point)))) + (while (org-up-heading-safe) + (when (member (nth 2 (org-heading-components)) org-todo-keywords-1) + (setq parent-task (point)))) + (goto-char parent-task) + parent-task))) + + (defun vde/is-task-p () + "Any task with a todo keyword and no subtask" + (save-restriction + (widen) + (let ((has-subtask) + (subtree-end (save-excursion (org-end-of-subtree t))) + (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1))) + (save-excursion + (forward-line 1) + (while (and (not has-subtask) + (< (point) subtree-end) + (re-search-forward "^\*+ " subtree-end t)) + (when (member (org-get-todo-state) org-todo-keywords-1) + (setq has-subtask t)))) + (and is-a-task (not has-subtask))))) + + (defun vde/is-subproject-p () + "Any task which is a subtask of another project" + (let ((is-subproject) + (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1))) + (save-excursion + (while (and (not is-subproject) (org-up-heading-safe)) + (when (member (nth 2 (org-heading-components)) org-todo-keywords-1) + (setq is-subproject t)))) + (and is-a-task is-subproject))) + + (defun vde/clock-in-to-started (kw) + "Switch a task from TODO to STARTED when clocking in. +Skips capture tasks, projects, and subprojects. +Switch projects and subprojects from STARTED back to TODO" + (when (not (and (boundp 'org-capture-mode) org-capture-mode)) + (cond + ((and (member (org-get-todo-state) (list "TODO")) + (vde/is-task-p)) + "STARTED") + ((and (member (org-get-todo-state) (list "STARTED")) + (vde/is-project-p)) + "TODO")))) + :bind (("<f11>" . org-clock-goto))) +;; -OrgClock + +;; OrgAttach +(use-package org-attach + :config + (setq org-link-abbrev-alist '(("att" . org-attach-expand-link)))) +;; -OrgAttach + +;; OrgLinks +;; my personal +(use-package ol-github + :after (org)) +(use-package ol-gitlab + :after (org)) +(use-package ol-ripgrep + :after (org)) +(use-package ol-grep + :after (org)) + +;; built-in org-mode +(use-package ol-eshell + :after (org)) +(use-package ol-git-link + :after (org)) +(use-package ol-gnus + :after (org)) +(use-package ol-irc + :after (org)) +(use-package ol-info + :after (org)) +(use-package ol-man + :after (org)) +(use-package ol-notmuch + :after (org)) +;; -OrgLinks + +;; OrgBabel +(use-package ob-async + :after (org)) + +(use-package ob-go + :after (org)) + +(use-package ob-http + :after (org)) +;; -OrgBabel + +;; OrgExportConstants +(defconst site-directory "~/desktop/sites/" "Website folder that holds exported orgmode files and more.") +(defconst org-default-publish-technical (concat site-directory "sbr.pm/technical") "Publish directory for the technical orgmode files.") +;; -OrgExportConstants + +;; OrgExportCfg +(use-package ox-publish + :after (org ox) + :config + (setq org-html-coding-system 'utf-8-unix)) +(use-package ox-slack + :after ox) +(use-package ox-hugo + :after ox + :commands (org-hugo-slug) + :config + (use-package ox-hugo-auto-export)) +;; -OrgExportCfg + +(use-package org + :defer t + :ensure org-plus-contrib + :config + + (defvar org-capture-templates (list)) + (setq org-protocol-default-template-key "l") + + ;; images + (setq org-image-actual-width nil + org-startup-with-inline-images nil) + + ;; Tasks (-> inbox) + + ;; Journal + + (setq org-ditaa-jar-path "/home/vincent/.nix-profile/lib/ditaa.jar") ;; FIXME(vdemeester) remove /home/vincent + ;; org-babel + (org-babel-do-load-languages + 'org-babel-load-languages + '((css . t) + (dot . t) + (ditaa . t) + (emacs-lisp . t) + (go . t) + (gnuplot . t) + (http . t) + (js . t) + ;;(ledger . t) + (latex . t) + (python . t) + (shell . t) + )) + + (add-to-list 'ispell-skip-region-alist '(":\\(PROPERTIES\\|LOGBOOK\\):" ":END:")) + (add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_SRC" "#\\+END_SRC")) + (add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_EXAMPLE" "#\\+END_EXAMPLE")) + + ;; org-links + ;; from http://endlessparentheses.com/use-org-mode-links-for-absolutely-anything.html + (org-link-set-parameters "tag" + :follow #'endless/follow-tag-link) + (defun endless/follow-tag-link (tag) + "Display a list of TODO headlines with tag TAG. +With prefix argument, also display headlines without a TODO keyword." + (org-tags-view (null current-prefix-arg) tag)) + + (org-link-set-parameters + "org" + :complete (lambda () (+org-link-read-file "org" org-directory)) + :follow (lambda (link) (find-file (expand-file-name link org-directory))) + :face (lambda (link) + (if (file-exists-p (expand-file-name link org-directory)) + 'org-link + 'error))) + (defun +org-link-read-file (key dir) + (let ((file (read-file-name (format "%s: " (capitalize key)) dir))) + (format "%s:%s" + key + (file-relative-name file dir)))) + ) + +(use-package smartparens-org + :after org-mode) + +(use-package org-capture-pop-frame) + +(use-package darkroom + :custom + (darkroom-text-scale-increase 2)) +(use-package org-tree-slide + :after (org darkroom) + :custom + (org-tree-slide-breadcrumbs nil) + (org-tree-slide-header nil) + (org-tree-slide-slide-in-effect nil) + (org-tree-slide-heading-emphasis nil) + (org-tree-slide-cursor-init t) + (org-tree-slide-modeline-display nil) + (org-tree-slide-skip-done nil) + (org-tree-slide-skip-comments t) + (org-tree-slide-fold-subtrees-skipped t) + (org-tree-slide-skip-outline-level 8) + (org-tree-slide-never-touch-face t) + :config + (defun prot/org-presentation () + "Specifies conditions that should apply locally upon +activation of `org-tree-slide-mode'." + (if (eq darkroom-tentative-mode nil) + (progn + (darkroom-tentative-mode 1) + (org-indent-mode 1) + (set-frame-font "Hack-14" t t) + (setq cursor-type '(bar . 1))) + (darkroom-tentative-mode -1) + (org-indent-mode -1) + (setq cursor-type 'box))) + :bind (("<f8>" . org-tree-slide-mode) + :map org-tree-slide-mode-map + ("<C-right>" . org-tree-slide-move-next-tree) + ("<C-left>" . org-tree-slide-move-previous-tree)) + :hook (org-tree-slide-mode . prot/org-presentation)) + +(use-package orgit + :after magit) + +(provide 'setup-org) +;;; setup-org.el ends here diff --git a/tmp/emacs-config/config/setup-projectile.el b/tmp/emacs-config/config/setup-projectile.el @@ -0,0 +1,29 @@ +;;; -*- lexical-binding: t; -*- +(use-package projectile ; Project management + :init (projectile-mode) + :bind-keymap ("C-c p" . projectile-command-map) + :config + ;; Remove dead projects when Emacs is idle + (run-with-idle-timer 10 nil #'projectile-cleanup-known-projects) + (setq + ;; Custom compilation buffer name function + compilation-buffer-name-function (lambda (mode) (concat "*" (downcase mode) ": " (projectile-project-name) "*")) + projectile-completion-system 'ivy + projectile-find-dir-includes-top-level t + projectile-switch-project-action #'projectile-commander + projectile-create-missing-test-files t + projectile-mode-line '(:eval (format " Proj[%s]" (projectile-project-name)))) + (def-projectile-commander-method ?s + "Open a *shell* buffer for the project" + (projectile-run-eshell)) + (def-projectile-commander-method ?c + "Run `compile' in the project" + (projectile-compile-project nil))) + +(use-package counsel-projectile ; Ivy integration for Projectile + :bind (:map projectile-command-map + ("p" . counsel-projectile-switch-project) + ("r" . counsel-projectile-rg)) + :init (counsel-projectile-mode)) + +(provide 'setup-projectile) diff --git a/tmp/emacs-config/config/setup-search.el b/tmp/emacs-config/config/setup-search.el @@ -0,0 +1,104 @@ +;;; -*- lexical-binding: t; -*- +;; Ignore directories during grep +(with-eval-after-load 'grep + '(progn + (add-to-list 'grep-find-ignored-directories "auto") + (add-to-list 'grep-find-ignored-directories "elpa"))) + +;; Truncate lines during grep +(add-hook 'grep-mode-hook #'toggle-truncate-lines) +(use-package isearch + :custom + (search-whitespace-regexp ".*?") + (isearch-lax-whitespace t) + (isearch-regexp-lax-whitespace nil) + :config + (defun prot/isearch-mark-and-exit () + "Marks the current search string. Can be used as a building +block for a more complex chain, such as to kill a region, or +place multiple cursors." + (interactive) + (push-mark isearch-other-end t 'activate) + (setq deactivate-mark nil) + (isearch-done)) + + (defun stribb/isearch-region (&optional not-regexp no-recursive-edit) + "If a region is active, make this the isearch default search +pattern." + (interactive "P\np") + (when (use-region-p) + (let ((search (buffer-substring-no-properties + (region-beginning) + (region-end)))) + (message "stribb/ir: %s %d %d" search (region-beginning) (region-end)) + (setq deactivate-mark t) + (isearch-yank-string search)))) + (advice-add 'isearch-forward-regexp :after 'stribb/isearch-region) + (advice-add 'isearch-forward :after 'stribb/isearch-region) + (advice-add 'isearch-backward-regexp :after 'stribb/isearch-region) + (advice-add 'isearch-backward :after 'stribb/isearch-region) + + (defun contrib/isearchp-remove-failed-part-or-last-char () + "Remove failed part of search string, or last char if successful. +Do nothing if search string is empty to start with." + (interactive) + (if (equal isearch-string "") + (isearch-update) + (if isearch-success + (isearch-delete-char) + (while (isearch-fail-pos) (isearch-pop-state))) + (isearch-update))) + + (defun contrib/isearch-done-opposite-end (&optional nopush edit) + "End current search in the opposite side of the match. +Particularly useful when the match does not fall within the +confines of word boundaries (e.g. multiple words)." + (interactive) + (funcall #'isearch-done nopush edit) + (when isearch-other-end (goto-char isearch-other-end))) + :bind (("M-s M-o" . multi-occur) + :map isearch-mode-map + ("C-SPC" . prot/isearch-mark-and-exit) + ("DEL" . contrib/isearchp-remove-failed-part-or-last-char) + ("<C-return>" . contrib/isearch-done-opposite-end))) + +(use-package anzu + :ensure t + :delight + :custom + (anzu-search-threshold 100) + (anzu-replace-threshold nil) + (anzu-deactivate-region nil) + (anzu-replace-to-string-separator "") + :config + (global-anzu-mode 1) + :bind (([remap isearch-query-replace] . anzu-isearch-query-replace) + ([remap isearch-query-replace-regexp] . anzu-isearch-query-replace-regexp)) + ([remap query-replace] . anzu-query-replace) + ([remap query-replace-regexp] . anzu-query-replace-regexp) + ("M-s %" . anzu-query-replace-at-cursor)) + +(use-package swiper + :after ivy + :custom + (swiper-action-recenter t) + (swiper-goto-start-of-match t) + (swiper-include-line-number-in-search t) + :bind (("C-S-s" . swiper) + ("M-s s" . swiper-multi) + ("M-s w" . swiper-thing-at-point) + :map swiper-map + ("M-y" . yank) + ("C-." . swiper-avy))) + +(use-package wgrep ; Editable grep buffer + :defer 2 + :custom + (wgrep-auto-save-buffer t) + (wgrep-change-readonly-file t)) + +(use-package visual-regexp ; Regexp replace with in-buffer display + :bind (("C-c s r" . vr/query-replace) + ("C-c s R" . vr/replace))) + +(provide 'setup-search) diff --git a/tmp/emacs-config/config/setup-shells.el b/tmp/emacs-config/config/setup-shells.el @@ -0,0 +1,250 @@ +;;; -*- lexical-binding: t; -*- +(use-package shell ; Specialized comint.el for running the shell + :custom + ;(ansi-color-for-comint-mode 'filter) + (explicit-shell-file-name "zsh") + (shell-file-name "zsh") + :bind (("<f1>" . shell) + (:map shell-mode-map + ("<tab>" . completion-at-point))) + :config + (unbind-key "C-c C-l" shell-mode-map) + (bind-key "C-c C-l" #'counsel-shell-history shell-mode-map)) + +(use-package eshell ; Emacs command shell + :bind* ("C-x m t" . eshell-here) + :config + (defun eshell-here () + "Open EShell in the directory associated with the current buffer's file. +The EShell is renamed to match that directory to make multiple windows easier." + (interactive) + (let* ((parent (if (buffer-file-name) + (file-name-directory (buffer-file-name)) + default-directory)) + (name (car (last (split-string parent "/" t))))) + (eshell "new") + (rename-buffer (concat "*eshell: " name "*")))) + + ;; Handy aliases + (defalias 'ff 'find-file) + + (defun eshell/d () + "Open a dired instance of the current working directory." + (dired ".")) + + (defun eshell/gs (&rest args) + (magit-status (pop args) nil) + (eshell/echo)) ; The echo command suppresses output + + (defun eshell/extract (file) + "One universal command to extract FILE (for bz2, gz, rar, etc.)" + (eshell-command-result (format "%s %s" (cond ((string-match-p ".*\.tar.bz2" file) + "tar xzf") + ((string-match-p ".*\.tar.gz" file) + "tar xzf") + ((string-match-p ".*\.bz2" file) + "bunzip2") + ((string-match-p ".*\.rar" file) + "unrar x") + ((string-match-p ".*\.gz" file) + "gunzip") + ((string-match-p ".*\.tar" file) + "tar xf") + ((string-match-p ".*\.tbz2" file) + "tar xjf") + ((string-match-p ".*\.tgz" file) + "tar xzf") + ((string-match-p ".*\.zip" file) + "unzip") + ((string-match-p ".*\.jar" file) + "unzip") + ((string-match-p ".*\.Z" file) + "uncompress") + (t + (error "Don't know how to extract %s" file))) + file))) + + (add-hook + 'eshell-mode-hook + (lambda () + (let ((ls (if (executable-find "exa") "exa" "ls"))) + (eshell/alias "ls" (concat ls " --color=always $*")) + (eshell/alias "ll" (concat ls " --color=always -l $*")) + (eshell/alias "l" (concat ls " --color=always -lah $*"))) + (eshell-smart-initialize) + (eshell-dirs-initialize) + (bind-keys :map eshell-mode-map + ("C-c C-l" . counsel-esh-history) + ([remap eshell-pcomplete] . completion-at-point)))) + + ;; Use system su/sudo + (with-eval-after-load "em-unix" + '(progn + (unintern 'eshell/su nil) + (unintern 'eshell/sudo nil))) + + (add-hook 'eshell-mode-hook #'with-editor-export-editor)) + +(use-package em-prompt ; EShell command prompts + :defer 2 + :config + (defun vde/eshell-quit-or-delete-char (arg) + "Use C-d to either delete forward char or exit EShell." + (interactive "p") + (if (and (eolp) (looking-back eshell-prompt-regexp nil nil)) + (progn + (eshell-life-is-too-much)) + (delete-char arg))) + + (add-hook 'eshell-mode-hook + (lambda () + (bind-key "C-d" + #'vde/eshell-quit-or-delete-char eshell-mode-map)))) + +(use-package esh-mode ; EShell UI customizations + :ensure eshell + :config (setq eshell-scroll-to-bottom-on-input 'all)) + +(use-package em-smart + :ensure eshell) +(use-package em-dirs + :ensure eshell) + +(use-package em-cmpl ; EShell TAB completion + :ensure eshell + :config + (add-hook 'eshell-mode-hook #'eshell-cmpl-initialize) + + (add-to-list 'eshell-command-completions-alist + '("gunzip" "gz\\'")) + (add-to-list 'eshell-command-completions-alist + '("tar" "\\(\\.tar|\\.tgz\\|\\.tar\\.gz\\)\\'"))) + +(use-package em-hist ; EShell History management + :ensure eshell + :config (setq eshell-hist-ignoredups t)) + +(use-package em-term ; Handle visual commands in EShell + :ensure eshell + :config + (add-to-list 'eshell-visual-commands "ssh") + (add-to-list 'eshell-visual-commands "htop") + (add-to-list 'eshell-visual-commands "top") + (add-to-list 'eshell-visual-commands "tail") + (add-to-list 'eshell-visual-commands "npm") + (add-to-list 'eshell-visual-commands "ncdu")) + +(use-package em-banner + :ensure eshell + :config + (setq eshell-banner-message " + Welcome to the Emacs + + _/ _/ _/ + _/_/ _/_/_/ _/_/_/ _/_/ _/ _/ + _/_/_/_/ _/_/ _/ _/ _/_/_/_/ _/ _/ + _/ _/_/ _/ _/ _/ _/ _/ + _/_/_/ _/_/_/ _/ _/ _/_/_/ _/ _/ + +")) + +(use-package fish-completion ; Add Fish completion to EShell + :defer 2 + :when (executable-find "fish") + :config (add-hook 'eshell-mode-hook #'fish-completion-mode)) + +(use-package eshell-prompt-extras + :defer 1 + :custom + (eshell-highlight-prompt nil) + (eshell-prompt-function 'vde-theme-lambda) + :config + (defun vde-kubernetes-current-context () + "Return the current context" + (if (not (string-empty-p (getenv "KUBECONFIG"))) + (epe-trim-newline (shell-command-to-string (concat + "env KUBECONFIG=" + (getenv "KUBECONFIG") + " kubectl config current-context"))) + (epe-trim-newline (shell-command-to-string "kubectl config current-context")))) + (defun vde-kubernetes-p () + "If you have kubectl install and a config set, +using either KUBECONFIG or ~/.kube/config" + (and (eshell-search-path "kubectl") + (not (string-empty-p (vde-kubernetes-current-context))) + (not (string-match-p "error: current-context is not set" (vde-kubernetes-current-context))))) + ;; From epe-theme-lambda + (defun vde-theme-lambda () + "A eshell-prompt lambda theme." + (setq eshell-prompt-regexp "^[^#\nΞ»]*[#Ξ»] ") + (concat + (when (epe-remote-p) + (epe-colorize-with-face + (concat (epe-remote-user) "@" (epe-remote-host) " ") + 'epe-remote-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)) + (let ((f (cond ((eq epe-path-style 'fish) 'epe-fish-path) + ((eq epe-path-style 'single) 'epe-abbrev-dir-name) + ((eq epe-path-style 'full) 'abbreviate-file-name)))) + (epe-colorize-with-face (funcall f (eshell/pwd)) 'epe-dir-face)) + (when (epe-git-p) + (concat + (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-face))) + (when (vde-kubernetes-p) + (concat (epe-colorize-with-face " (" 'epe-dir-face) + (epe-colorize-with-face (vde-kubernetes-current-context) 'epe-dir-face) + (epe-colorize-with-face ")" 'epe-dir-face))) + (epe-colorize-with-face " Ξ»" 'epe-symbol-face) + (epe-colorize-with-face (if (= (user-uid) 0) "#" "") 'epe-sudo-symbol-face) + " "))) + +(use-package esh-autosuggest + :defer 1 + :hook (eshell-mode . esh-autosuggest-mode)) + +(use-package xterm-color + :init + (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))) + (add-hook 'eshell-before-prompt-hook + (lambda () + (setenv "TERM" "xterm-256color") + (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)) + (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)))))))) + +;; for fish in ansi-term +(add-hook 'term-mode-hook 'toggle-truncate-lines) + +(provide 'setup-shells) diff --git a/tmp/emacs-config/config/setup-style.el b/tmp/emacs-config/config/setup-style.el @@ -0,0 +1,203 @@ +;;; -*- lexical-binding: t; -*- +;;; Β―\_(γ)_/Β― +;;; - Iosevka (https://github.com/be5invis/Iosevka) +;;; - Fira Sans (https://github.com/mozilla/Fira/) +(defconst font-height 130) +;; Middle/Near East: Χ©ΧΧΧ, Ψ§ΩΨ³ΩΩΨ§Ω ΨΉΩΩΩΩ +(when (member "Noto Sans Arabic" (font-family-list)) + (set-fontset-font t 'arabic "Noto Sans Arabic")) +(when (member "Noto Sans Hebrew" (font-family-list)) + (set-fontset-font t 'arabic "Noto Sans Hebrew")) + +;; Africa: α αα +(when (member "Noto Sans Ethiopic" (font-family-list)) + (set-fontset-font t 'ethiopic "Noto Sans Ethiopic")) + +(set-face-attribute 'default nil + :family "Ubuntu Mono" + :height font-height) +(set-face-attribute 'variable-pitch nil + :family "Ubuntu Sans" + :height font-height + :weight 'regular) + +;;; Utilities and key bindings +(defun mu-reset-fonts () + "Reset fonts to my preferences." + (interactive) + (set-face-attribute 'default nil + :family "Ubuntu Mono" + :height font-height) + (set-face-attribute 'variable-pitch nil + :family "Ubuntu Sans" + :height font-height + :weight 'regular)) + +(bind-key "C-c f r" #'mu-reset-fonts) + +;;; Interface +(use-package frame ; Frames + :bind ("C-c w f" . toggle-frame-fullscreen) + :init + ;; Kill `suspend-frame' + (unbind-key "C-x C-z") + :config (add-to-list 'initial-frame-alist '(fullscreen . maximized))) + +(use-package emacs + :custom + (use-file-dialog nil) + (use-dialog-box nil) + (echo-keystrokes 0.1) ; Faster echo keystrokes + (line-number-display-limit-width 10000) ;; Avoid showing ?? in the mode line when we have long lines. + (display-time-world-list '(("Europe/London" "London") + ("Europe/Paris" "Paris") + ("America/New_York" "Boston") + ("America/Los_Angeles" "San-Francisco") + ("Asia/Calcutta" "Bangalore") + ("Australia/Brisbane" "Brisbane"))) + :config + (line-number-mode 1) + (column-number-mode 1) + (global-hl-line-mode 1) + (global-unset-key (kbd "C-z")) + (global-unset-key (kbd "C-x C-z")) + (global-unset-key (kbd "C-h h"))) + +;;; Theme +(setq custom-safe-themes t) ; Treat themes as safe + +(use-package shortbrain-light-theme + :config + (load-theme 'shortbrain-light)) + +(use-package solaire-mode + :config + (setq solaire-mode-remap-modeline nil) + (add-hook 'after-change-major-mode-hook #'turn-on-solaire-mode) + (add-hook 'after-revert-hook #'turn-on-solaire-mode) + (add-hook 'minibuffer-setup-hook #'solaire-mode-in-minibuffer) + (add-hook 'ediff-prepare-buffer-hook #'solaire-mode) + (advice-add #'persp-load-state-from-file :after #'solaire-mode-restore-persp-mode-buffers)) + +;; Show buffer position percentage starting from top +(setq mode-line-percent-position '(-3 "%o")) +(defvar mu-eyebrowse-mode-line + '(:propertize + (:eval + (when (bound-and-true-p eyebrowse-mode) + (let* ((num (eyebrowse--get 'current-slot)) + (tag (when num + (nth 2 (assoc num (eyebrowse--get 'window-configs))))) + (str (concat + " " + (if (and tag (< 0 (length tag))) + tag + (when num (int-to-string num))) + " "))) + str))) + face (:background "#81a2be" :foreground "#373b41")) + "Mode line format for Eyebrowse.") + +(put 'mu-eyebrowse-mode-line 'risky-local-variable t) + +(setq-default mode-line-format + '("%e" + mu-eyebrowse-mode-line + mode-line-front-space + mode-line-mule-info + mode-line-client + mode-line-modified + mode-line-remote + mode-line-frame-identification + mode-line-buffer-identification " " mode-line-position + (vc-mode vc-mode) + (multiple-cursors-mode mc/mode-line) + " " mode-line-modes + mode-line-end-spaces)) + +(defmacro rename-modeline (package-name mode new-name) + "Rename PACKAGE-NAME with MODE into NEW-NAME in the mode line." + `(eval-after-load ,package-name + '(defadvice ,mode (after rename-modeline activate) + (setq mode-name ,new-name)))) + +(defun generic-term-init () + (visual-line-mode -1) + (setq-local global-hl-line-mode nil) + (setq-local scroll-margin 0)) + +(add-hook 'term-mode-hook #'generic-term-init) +(add-hook 'shell-mode-hook #'generic-term-init) +(add-hook 'eshell-mode-hook #'generic-term-init) + +(use-package moody + :config + (setq x-underline-at-descent-line t) + (moody-replace-mode-line-buffer-identification) + (moody-replace-vc-mode)) + +(use-package minions ; A minor-mode menu for the mode line + :init (minions-mode) + :config + (setq + minions-mode-line-lighter "Ξ»=" + minions-direct '(flycheck-mode))) + +(setq-default indicate-buffer-boundaries 'left) +(setq-default indicate-empty-lines +1) + +(use-package highlight + :ensure t + :pin melpa) + +(use-package highlight-numbers + :hook (prog-mode . highlight-numbers-mode)) + +(use-package symbol-overlay + :defer 4 + :bind + ("M-s h ." . symbol-overlay-put) + ("M-s h n" . symbol-overlay-jump-next) + ("M-s h p" . symbol-overlay-jump-prev) + :hook (prog-mode . symbol-overlay-mode) + :config + (setq symbol-overlay-idle-time 0.2)) + +(use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode)) + +(use-package rainbow-mode + :commands rainbow-mode + :hook (prog-mode . rainbow-mode)) + +(use-package visual-fill-column + :commands visual-fill-column-mode) + +(use-package hide-mode-line-mode + :commands hide-mode-line-mode) + +(defun set-light-theme () + "Set the light theme with some customization if needed." + (interactive) + (use-package shortbrain-light-theme + :config + (load-theme 'shortbrain-light t))) + +(defun set-dark-theme () + "Set the dark theme with some customization if needed." + (interactive) + (use-package shortbrain-theme + :config + (load-theme 'shortbrain t))) + +(defun theme-switcher () + (interactive) + (let ((current-hour (string-to-number (format-time-string "%H")))) + (if (and (> current-hour 6) (< current-hour 20)) + (set-light-theme) + (set-dark-theme)))) + +;; Run at every 3600 seconds, after 0s delay +;;Β (run-with-timer 0 3600 'theme-switcher) + +(provide 'setup-style) diff --git a/tmp/emacs-config/config/setup-vcs.el b/tmp/emacs-config/config/setup-vcs.el @@ -0,0 +1,123 @@ +;;; -*- lexical-binding: t; -*- +(use-package vc-hooks ; Simple version control + :bind (("S-<f5>" . vc-revert) + ("C-c v r" . vc-refresh-state)) + :config + ;; Always follow symlinks to files in VCS repos + (setq vc-follow-symlinks t)) + +(use-package magit ; The best Git client out there + :bind (("C-c v c" . magit-clone) + ("C-c v C" . magit-checkout) + ("C-c v d" . magit-dispatch-popup) + ("C-c v g" . magit-blame) + ("C-c v l" . magit-log-buffer-file) + ("C-c v p" . magit-pull) + ("C-c v v" . magit-status)) + :config + (setq + magit-save-repository-buffers 'dontask + magit-refs-show-commit-count 'all + magit-branch-prefer-remote-upstream '("master") + magit-display-buffer-function #'magit-display-buffer-traditional + magit-completing-read-function 'ivy-completing-read + ) + + (magit-define-popup-option 'magit-rebase-popup + ?S "Sign using gpg" "--gpg-sign=" #'magit-read-gpg-secret-key) + (magit-define-popup-switch 'magit-log-popup + ?m "Omit merge commits" "--no-merges") + + ;; Hide "Recent Commits" + (magit-add-section-hook 'magit-status-sections-hook + 'magit-insert-unpushed-to-upstream + 'magit-insert-unpushed-to-upstream-or-recent + 'replace) + + (use-package magit-files + :config + (global-magit-file-mode)) + + ;; Show refined hunks during diffs + (set-default 'magit-diff-refine-hunk t) + + (add-hook 'projectile-switch-project-hook + #'mu-magit-set-repo-dirs-from-projectile) + + ;; Refresh `magit-status' after saving a buffer + (add-hook 'after-save-hook #'magit-after-save-refresh-status) + + ;; Free C-c C-w for Eyebrowse + (unbind-key "C-c C-w" git-commit-mode-map) ) +(put 'magit-diff-edit-hunk-commit 'disabled nil) +(use-package magit-repos + :after magit + :commands magit-list-repositories + :config + (setq magit-repository-directories + '(("~/src" . 3)))) + +(use-package git-commit ; Git commit message mode + :defer 2 + :init (global-git-commit-mode) + :config + (setq git-commit-summary-max-length 50) + (setq git-commit-known-pseudo-headers + '("Signed-off-by" + "Acked-by" + "Modified-by" + "Cc" + "Suggested-by" + "Reported-by" + "Tested-by" + "Reviewed-by")) + (setq git-commit-style-convention-checks + '(non-empty-second-line + overlong-summary-line)) + (remove-hook 'git-commit-finish-query-functions + #'git-commit-check-style-conventions)) + +(use-package gitconfig-mode ; Git configuration mode + :defer 2) + +(use-package gitignore-mode ; .gitignore mode + :defer 2) + +(use-package gitattributes-mode ; Git attributes mode + :defer 2) + +(use-package dired-git-info + :bind (:map dired-mode-map + (")" . dired-git-info-mode)) + :defer 2) + +(use-package ediff + :config + (setq ediff-window-setup-function 'ediff-setup-windows-plain) + (setq ediff-split-window-function 'split-window-horizontally) + (setq ediff-diff-options "-w") + (add-hook 'ediff-after-quit-hook-internal 'winner-undo)) + +(defun git-blame-line () + "Runs `git blame` on the current line and + adds the commit id to the kill ring" + (interactive) + (let* ((line-number (save-excursion + (goto-char (point-at-bol)) + (+ 1 (count-lines 1 (point))))) + (line-arg (format "%d,%d" line-number line-number)) + (commit-buf (generate-new-buffer "*git-blame-line-commit*"))) + (call-process "git" nil commit-buf nil + "blame" (buffer-file-name) "-L" line-arg) + (let* ((commit-id (with-current-buffer commit-buf + (buffer-substring 1 9))) + (log-buf (generate-new-buffer "*git-blame-line-log*"))) + (kill-new commit-id) + (call-process "git" nil log-buf nil + "log" "-1" "--pretty=%h %an %s" commit-id) + (with-current-buffer log-buf + (message "Line %d: %s" line-number (buffer-string))) + (kill-buffer log-buf)) + (kill-buffer commit-buf))) + +(provide 'setup-vcs) diff --git a/tmp/emacs-config/config/setup-web.el b/tmp/emacs-config/config/setup-web.el @@ -0,0 +1,35 @@ +(if *sys/full* + (progn + (use-package web-mode + :mode + ("\\.html\\'" . web-mode) + ("\\.phtml\\'" . web-mode) + ("\\.[agj]sp\\'" . web-mode) + ("\\.as[cp]x\\'" . web-mode) + ("\\.erb\\'" . web-mode) + ("\\.mustache\\'" . web-mode) + ("\\.djhtml\\'" . web-mode) + ("\\.jsp\\'" . web-mode) + ("\\.eex\\'" . web-mode) + ("\\.tsx\\'" . web-mode) + :config + (setq web-mode-attr-indent-offset 2) + (setq web-mode-code-indent-offset 2) + (setq web-mode-css-indent-offset 2) + (setq web-mode-indent-style 2) + (setq web-mode-markup-indent-offset 2) + (setq web-mode-sql-indent-offset 2) + (eval-after-load 'smartparens + (lambda () + (setq web-mode-enable-auto-pairing nil) + (sp-with-modes '(web-mode) + (sp-local-pair "%" "%" + :unless '(sp-in-string-p) + :post-handlers '(((lambda (&rest _ignored) + (just-one-space) + (save-excursion (insert " "))) + "SPC" "=" "#"))) + (sp-local-tag "%" "<% " " %>") + (sp-local-tag "=" "<%= " " %>") + (sp-local-tag "#" "<%# " " %>"))))) + )) diff --git a/tmp/emacs-config/config/setup-windows.el b/tmp/emacs-config/config/setup-windows.el @@ -0,0 +1,67 @@ +;;; -*- lexical-binding: t; -*- + +;;;###autoload +(defun vde/window-split-toggle () + "Toggle between horizontal and vertical split with two windows." + (interactive) + (if (> (length (window-list)) 2) + (error "Can't toggle with more than 2 windows!") + (let ((func (if (window-full-height-p) + #'split-window-vertically + #'split-window-horizontally))) + (delete-other-windows) + (funcall func) + (save-selected-window + (other-window 1) + (switch-to-buffer (other-buffer)))))) + +(bind-key "C-c w t" #'vde/window-split-toggle) + +(defvar vde/saved-window-configuration nil) + +(defun vde/save-wins-then-call (func &optional args) + "Save current window configuration, then call FUNC optionally with ARGS." + (interactive) + (push (current-window-configuration) vde/saved-window-configuration) + (cond + ;; We have arguments for the function + ((bound-and-true-p args) (funcall func args)) + ;; The function expects exactly one argument, and we want it to be nil + ((equal args "nil") (funcall func nil)) + ;; The function does not expect arguments + (t (funcall func)))) + +(use-package eyebrowse ; Easy workspaces creation and switching + :init (eyebrowse-mode t) + :config + (setq + eyebrowse-mode-line-separator " " + eyebrowse-mode-line-style 'always + eyebrowse-new-workspace t + eyebrowse-wrap-around t)) + +(use-package ace-window ; Better movements between windows + :custom + (aw-keys '(?a ?u ?i ?e ?, ?c ?t ?r ?m)) + (aw-scope 'frame) + (aw-dispatch-always t) + (aw-dispatch-alist + '((?s aw-swap-window "Swap Windows") + (?2 aw-split-window-vert "Split Window Vertically") + (?3 aw-split-window-horz "Split Window Horizontally") + (?? aw-show-dispatch-help))) + (aw-minibuffer-flag t) + (aw-ignore-current nil) + (aw-display-mode-overlay t) + (aw-background t) + :bind (("C-x o" . ace-window) + ("C-c w w" . ace-window) + ("C-c w s" . ace-swap-window))) + +(use-package windmove + :bind (("M-<left>" . windmove-left) + ("M-<down>" . windmove-down) + ("M-<up>" . windmove-up) + ("M-<right>" . windmove-right))) + +(provide 'setup-windows) diff --git a/tmp/emacs-config/data/17/a3ed73-aaca-4a18-8ed1-3efe7bac855a/2020-02-29-14-41-59.png b/tmp/emacs-config/data/17/a3ed73-aaca-4a18-8ed1-3efe7bac855a/2020-02-29-14-41-59.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f96bb89ef7260c82a6283061a8e467125b94eb4ecb7320526e27c1525163b87e +size 63416 diff --git a/tmp/emacs-config/data/1f/74bbae-c4a1-4723-977e-e48900fcd1c7/2020-02-29-13-46-08.png b/tmp/emacs-config/data/1f/74bbae-c4a1-4723-977e-e48900fcd1c7/2020-02-29-13-46-08.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f85767c14dd416690fd03ef84d921f4fd929a657475e4f54a89b872cb2efcabd +size 97137 diff --git a/tmp/emacs-config/data/83/bc2073-0681-4fe9-bcf7-3070bd1ab695/2020-03-03-21-57-41.png b/tmp/emacs-config/data/83/bc2073-0681-4fe9-bcf7-3070bd1ab695/2020-03-03-21-57-41.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4e362cf1c5ed2b36c31d01cf604426d04c6b32bdee894e4171537994a81bb83 +size 187193 diff --git a/tmp/emacs-config/data/83/bc2073-0681-4fe9-bcf7-3070bd1ab695/2020-03-03-21-59-22.png b/tmp/emacs-config/data/83/bc2073-0681-4fe9-bcf7-3070bd1ab695/2020-03-03-21-59-22.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c002b6c041d7350bbe1e9a919b3ef2451f030739de70fb04f17d8c758ed48d80 +size 191294 diff --git a/tmp/emacs-config/early-init.el b/tmp/emacs-config/early-init.el @@ -0,0 +1,34 @@ +;;; early-init.el --- -*- lexical-binding: t -*- +;; PkgStartup +(setq package-enable-at-startup nil) +;; -PkgStartup + +;; FrameResize +(setq frame-inhibit-implied-resize t) +;; -FrameResize + +;; DisableUI +(menu-bar-mode -1) +(tool-bar-mode -1) +(scroll-bar-mode -1) +(horizontal-scroll-bar-mode -1) +;; -DisableUI + +;; GarbageCollection +(setq gc-cons-threshold 402653184 + gc-cons-percentage 0.6) +;; -GarbageCollection + +;; FileNameHandler +(defvar file-name-handler-alist-original file-name-handler-alist) +(setq file-name-handler-alist nil) +;; -FileNameHandler + +;; AfterInitHook +(add-hook 'after-init-hook + `(lambda () + (setq gc-cons-threshold 67108864 ; 64mb + gc-cons-percentage 0.1 + file-name-handler-alist file-name-handler-alist-original) + (garbage-collect)) t) +;; -AfterInitHook diff --git a/tmp/emacs-config/emacs.org b/tmp/emacs-config/emacs.org @@ -0,0 +1,1263 @@ +#+TITLE: Vincent Demeester's .emacs.d +#+AUTHOR: Vincent Demeester +#+EMAIL: vincent@sbr.pm +#+EXPORT_EXCLUDE_TAGS: noexport +#+CREATOR: Emacs 27.0.90 (Org mode 9.3) +#+LANGUAGE: en +#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="./notes.css"/> +#+OPTIONS: html-style:nil + +#+TOC: headlines 3 + + +* Overview +:PROPERTIES: +:CUSTOM_ID: h:64b142be-1326-479b-ab6e-e88ca298f56d +:END: +** Canonical links to this document +:PROPERTIES: +:CUSTOM_ID: h:9e025e71-b8c5-4cd3-88cc-c81f1e026d13 +:END: + ++ HTML version :: [[https://sbr.pm/dotemacs][sbr.pm/dotemacs]] ++ Git repo :: [[https://github.com/vdemeester/emacs-config.git][github.com/vdemeester/emacs-config]] + +** What is this +:PROPERTIES: +:CUSTOM_ID: h:6cf02bfd-0266-456f-be5f-728c75e3013e +:END: + +The present document, referred to in the source code version as =emacs.org=, contains the +bulk of my configurations for GNU Emacs. It is designed using principles of "literate +programming": a combination of ordinary language and inline code blocks. Emacs knows how +to parse this file properly so as to evaluate only the elisp ("Emacs Lisp") included +herein. The rest is for humans to make sense of my additions and their underlying +rationale. + +#+BEGIN_QUOTE +Literate programming allows us to be more expressive and deliberate. Not only we can use +typography to its maximum potential, but can also employ techniques such as internal links +between sections. This makes the end product much better for end users, than a terse +script. +#+END_QUOTE + +I switched back and forth on using =org-mode= and literate programming, so why re-using +it. First, I think I went for it the wrong way the first time. I copied part of the +configuration from elsewhere, sometimes without really needing what I was copying. for +some reason I think this is a common pattern when configuring Emacs. You start by using a +distribution (Doom Emacs, Spacemacs, β¦) or by copying configuration from all over the +place. Slowly but surely you realize this was a mistake as you didn't learn anything, so +you *reboot* your configuration. + +I'm taking [[https://protesilaos.com/][Protesilaos Stavrou]] approach on writing and configuring this file (see [[https://protesilaos.com/dotemacs/][his +dotemacs]]), although I am not loading it directly. I prefer using the [[https://orgmode.org/manual/tangle.html][tangle]] feature of +=org-mode= instead of loading it using ~org-babel~ function. This allows me to document my +configuration and generating final(s) ~.el~ files. Those files can then load and/or +pre-compile, without the need to load =org= first. It also means that I can add code +pieces in there that won't be /tangle/, like usage example ; and I also can use this to +generate any additional file I need, whatever the programming language they are written +in. [[https://protesilaos.com/][Protesilaos Stavrou]] is not my only source, here are some others: + ++ https://gitlab.com/ndw/dotfiles ++ https://github.com/MatthewZMD/.emacs.d ++ https://github.com/alhassy/emacs.d ++ https://github.com/chmouel/emacs-config ++ https://github.com/seagle0128/.emacs.d ++ https://github.com/hlissner/doom-emacs ++ http://doc.norang.ca/org-mode.html + +** Why using GNU/Emacs ? +:PROPERTIES: +:CUSTOM_ID: h:165fca5a-b87d-4140-963b-658a2438e769 +:END: + +This is a question I thought I needed to answer, or at least, document why I am choosing +GNU/Emacs as my primary editor. [[https://protesilaos.com/][Protesilaos Stavrou]] has a [[https://protesilaos.com/codelog/2019-12-20-vlog-switch-emacs/][video]] about it, really +interesting. + +There is a lot of reasons but for me, the following are the main ones: +- *Open Source*: this is a "of course", but my editor _has to be_ open-sourced. This seems + to be the norm these days anyway (and for a long time, with =vim=). +- *Lightweight*: the editor should be relatively lightweight. I don't want a full browser + loaded to edit files, and I want to be able to run it in a terminal, on a server. =vim= + can do that (and sometimes, =vim= or =vi= is enough πΌ). +- *Extensible*: to be honest, this is the most important reason. I want to be able to + extend my editor as much as possible. + +GNU/Emacs checks all the boxes for me. Even though GNU/Emacs is probably not as +lightweight as =vim=, it is definitely lightweight compared to all the Electron-based +editors (vscode, β¦). It is of course open-source, and since ages (almost as old as I am +π ). And best of all, GNU/Emacs is extensible as you couldn't dream of. Emacs is a lisp +interpreter, and it is designed to be extended in order to meet the user's +needs. /Extensibility/ is the quintessential Emacs quality. You can modify any piece of +elisp /in real time/. + +I'm also a huge fan of /text-based/ software, a.k.a. do whatever you can using text : +reading mails, news, organizing notes and todos, all can be done in text. And GNU/Emacs +shines at this. For emails and news, you've got Gnus built-in, for notes and todos, the +wonderful =org-mode= is the best thing on earth (seriously, this is the *one* mode that +made me switch from =vim=). + +** Assumptions +:PROPERTIES: +:CUSTOM_ID: h:657c38cd-d910-42c2-bd8c-8c20171a8bd5 +:END: + +I'll make a few assumption in the following document (that may or may not be true): + +- [[https://nixos.org/nix/][~nix~]] is available, either from [[https://nixos.org][NixOS]] or via an install of nix. I'll try my best to + support non-nix environment, but it's definitely not my current focus. + + As I am making the assumption that ~nix~ is available, I am also making the assumption + that all the library required are already present (in my [[https://github.com/vdemeester/home][~home~]], there is a file + called [[https://github.com/vdemeester/home/blob/master/modules/profiles/emacs.nix][~emacs.nix~]] that encapsulate those dependencies). This is why, by default + *use-package* doesn't use the =ensure= option in 99% of the configuration. +- Any function I wrote is going to be prefixed by ~vde/~ so that it doesn't conflicts with + function that would have been defined elsewhere. + +As it is detailed in each part of this configuration, I am trying to setup keybinding in a +/mnemonics/ way so it's easy to remember (and use). This is what [[https://www.spacemacs.org/][spacemacs]] does with evil +keybindings (aka vim-like keybindings). I am staying with the /standard/ emacs keybinding +as much as possible (as there is already some mnemonics in there). + +There are countless jokes and comics on Emacsβs seemingly ridiculous keybindings. Good +laughs indeed, but at the end of day, itβs not incomprehensible. It has well-defined +conventions listed at [[https://www.gnu.org/software/emacs/manual/html%5Fnode/elisp/Key-Binding-Conventions.html][Emacs Key Bindings Convention]]. In summary, the general rules are: + ++ =C-x= reserved for Emacs native essential keybindings: buffer, window, frame, file, directory, etcβ¦ ++ =C-c= reserved for user and major mode: + - =C-c letter= reserved for user. =<F5>=-=<F9>= reserved for user. + - =C-c C-letter= reserved for major mode. ++ Donβt rebind =C-g=, =C-h= and =ESC=. + +To give a small example, most of my personal =org-mode= keybinding will start with =C-c +o=, as it is reserved for user, and =o= is for =org-mode=. For version control, it's gonna +be =C-c v=, for projects it's gonna be =C-c p=, etcβ¦ + +** COPYING +:PROPERTIES: +:CUSTOM_ID: h:d4cfb344-dcff-4144-951a-8197c5ae2c84 +:END: + +Copyright (c) 2013-2020 Vincent Demeester <vincent@sbr.pm> + +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. + +You should have received a copy of the GNU General Public License +along with this file. If not, see <http://www.gnu.org/licenses/>. + +* Base settings +:PROPERTIES: +:CUSTOM_ID: h:e483cc48-eb2d-42a7-93ca-3e1a37fa6a7c +:END: + +This section contains configurations that are needed prior to the setup of everything +else. Anything that needs to be configured first should be in there, this includes the +~init.el~ and ~early-init.el~ files content. + +** Initiazing emacs +:PROPERTIES: +:CUSTOM_ID: h:4886d661-e2e0-4a75-bf3f-e85aef27b50c +:END: + +Starting with Emacs 27, an =early-init.el= file can be used to do early configuration +and optimization. + +#+begin_quote +Emacs can now be configured using an early init file. The file is called ~early-init.el~, +in ~user-emacs-directory~. It is loaded very early in the startup process: before +graphical elements such as the tool bar are initialized, and before the package manager is +initialized. The primary purpose is to allow customizing how the package system is +initialized given that initialization now happens before loading the regular init file +(see below). + +We recommend against putting any customizations in this file that don't need to be set up +before initializing installed add-on packages, because the early init file is read too +early into the startup process, and some important parts of the Emacs session, such as +'window-system' and other GUI features, are not yet set up, which could make some +customization fail to work. +#+end_quote + +We can use this to our advantage and optimize the initial loading of emacs. + +- Before Emacs 27, the init file was responsible for initializing the package manager by + calling `package-initialize'. Emacs 27 changed the default behavior: It now calls + `package-initialize' before loading the init file. + + #+INCLUDE: "./early-init.el" src emacs-lisp :range-begin "PkgStartup" :range-end "-PkgStartup" :lines "3-4" + +- Let's inhibit resizing the frame at early stage. + + #+INCLUDE: "./early-init.el" src emacs-lisp :range-begin "FrameResize" :range-end "-FrameResize" :lines "7-8" + +- I never use the /menu-bar/, or the /tool-bar/ or even the /scroll-bar/, so we can safely + disable those very very early. + + #+INCLUDE: "./early-init.el" src emacs-lisp :range-begin "DisableUI" :range-end "-DisableUI" :lines "11-15" + +- Finally we can try to avoid garbage collection at startup. The garbage collector can + easily double startup time, so we suppress it at startup by turning up ~gc-cons-threshold~ + (and perhaps ~gc-cons-percentage~) temporarily. + + #+INCLUDE: "./early-init.el" src emacs-lisp :range-begin "GarbageCollection" :range-end "-GarbageCollection" :lines "18-20" + +- Another small optimization concerns on =file-name-handler-alist= : on every .el and .elc + file loaded during start up, it has to runs those regexps against the filename ; setting + it to ~nil~ and after initialization finished put the value back make the initialization + process quicker. + + #+INCLUDE: "./early-init.el" src emacs-lisp :range-begin "FileNameHandler" :range-end "-FileNameHandler" :lines "23-25" + + However, it is important to reset it eventually. Not doing so will cause garbage + collection freezes during long-term interactive use. Conversely, a ~gc-cons-threshold~ + that is too small will cause stuttering. + + #+INCLUDE: "./early-init.el" src emacs-lisp :range-begin "AfterInitHook" :range-end "-AfterInitHook" :lines "28-34" + +One thing though, I am currently not necessarily running Emacs 27, so I am going to need +to have the same configuration in ~init.el~ for a little bit of time. + +/Note: the lowest emacs version I wanna support is 26 (as of today, might evolve)/ + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "CheckVer" :range-end "-CheckVer" :lines "3-13" + +We also want our configuration to be working the same on any computer, this means we want +to define every option by ourselves, not relying on default files (~default.el~) that +would be set by our distribution. This is where =inhibit-default-init= comes into play, +setting it to non-nil inhibit loading the ~default~ library. + +We also want to inhibit some initial default start messages and screen. The default screen +will be as bare as possible. + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "Inhibit" :range-end "-Inhibit" :lines "16-20" + +Let's also use =y= or =n= instead of =yes= and =no= when exiting Emacs. + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "Confirm" :range-end "-Confirm" :lines "23-24" + +One last piece to the puzzle is the default mode. Setting it to fundamental-mode means we +won't load any /heavy/ mode at startup (like =org-mode=). We also want this scratch buffer +to be empty, so let's set it as well + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "DefaultMode" :range-end "-DefaultMode" :lines "27-29" + +*** Unicode all the way +:PROPERTIES: +:CUSTOM_ID: h:df45a01a-177d-4909-9ce7-a5423e0ea20f +:END: + +By default, all my systems are configured and support =utf-8=, so let's just make it a +default in Emacs ; and handle special case on demand. + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "Unicode" :range-end "-Unicode" :lines "32-37" + +*** Package management with =use-package= +:PROPERTIES: +:CUSTOM_ID: h:112262a1-dd4d-4a50-a9e2-85b36bbbd95b +:END: + +=use-package= is a tool that streamlines the configuration of packages. It handles +everything from assigning key bindings, setting the value of customisation options, +writing hooks, declaring a package as a dependency for another, and so on. + +#+begin_quote +The =use-package= macro allows you to isolate package configuration in your =.emacs= file +in a way that is both performance-oriented and, well, tidy. I created it because I have +over 80 packages that I use in Emacs, and things were getting difficult to manage. Yet +with this utility my total load time is around 2 seconds, with no loss of functionality! +#+end_quote + +With =use-package= we can improve the start-up performance of Emacs in a few fairly simple +ways. Whenever a command is bound to a key it is configured to be loaded only once +invoked. Otherwise we can specify which functions should be autoloaded by means of the +=:commands= keyword. + +We need to setup the emacs package system and install =use-package= if not present +already. + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "UsePackageSetup" :range-end "-UsePackageSetup" :lines "40-89" + +*** =custom.el= +:PROPERTIES: +:CUSTOM_ID: h:1ddaf27e-ff7c-424e-8615-dd0bd22b685f +:END: + +When you install a package or use the various customisation interfaces to tweak things to +your liking, Emacs will append a piece of elisp to your init file. I prefer to have that +stored in a separate file. + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "CustomFile" :range-end "-CustomFile" :lines "92-107" + +*** Remove built-in =org-mode= +:PROPERTIES: +:CUSTOM_ID: h:9462c0d7-03be-4231-8f22-ce1a04be32b1 +:END: + +I want to make sure I am using the installed version of =orgmode= (from my org +configuration) instead of the built-in one. To do that safely, let's remove the built-in +version out of the load path. + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "NoBuiltinOrg" :range-end "-NoBuiltinOrg" :lines "110-116" + +*** Pinentry +:PROPERTIES: +:CUSTOM_ID: h:1f016a1a-f4ef-4ef0-be01-1fd68ca0d951 +:END: + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "Pinentry" :range-end "-PinEntry" :lines "119-123" + +*** Loading configuration files +:PROPERTIES: +:CUSTOM_ID: h:d6aebc56-aadb-4b01-8404-bb922d12f8a8 +:END: + +This =org-mode= document /tangles/ into several files in different folders : +- ~config~ for my configuration +- ~lisp~ for imported code or library I've written and not yet published + +I used to load them by hand in the ~init.el~ file, which is very cumbersome, so let's try +to automatically load them. I want to first load the file in the ~lisp~ folder as they are +potentially used by my configuration (in ~config~). + +Let's define some functions that would do the job. + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "LoadCfgFunc" :range-end "-LoadCfgFunc" :lines "126-136" + +Let's define some constants early, based on the system, and the environment, to be able to +use those later on to skip some package or change some configuration accordingly. + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "CfgConstant" :range-end "-CfgConstant" :lines "139-170" + +Now, in order to load ~lisp~ and ~config~ files, it's just a matter of calling this +function with the right argument. + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "CfgLoad" :range-end "-CfgLoad" :lines "173-176" + +Finally, I want to be able to load files for a specific machine, in case I need it (not +entirely sure why yet butβ¦) + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "CfgHostLoad" :range-end "-CfgHostLoad" :lines "179-181" + +*** Counting the time of loading +:PROPERTIES: +:CUSTOM_ID: h:2b645e95-6776-4f5b-a318-e5a915943881 +:END: + +#+INCLUDE: "./init.el" src emacs-lisp :range-begin "LastInit" :range-end "-LastInit" :lines "184-195" + +** ~PATH~'s customization +:PROPERTIES: +:header-args: :tangle config/00-environments.el +:CUSTOM_ID: h:2a72b00e-ea97-4a3b-a70c-cbbe648df428 +:END: + +To make sure my emacs instance and my user environment setup is always /similar/, I use +=exec-path-from-shell=. + +#+begin_quote +Ever find that a command works in your shell, but not in Emacs? + +This happens a lot on OS X, where an Emacs instance started from the GUI inherits a +default set of environment variables. + +This library solves this problem by copying important environment variables from the +user's shell: it works by asking your shell to print out the variables of interest, then +copying them into the Emacs environment. +#+end_quote + +#+begin_src emacs-lisp +(use-package exec-path-from-shell ; Set up environment variables + :if (display-graphic-p) + :unless (eq system-type 'windows-nt) + :config + (setq exec-path-from-shell-variables + '("PATH" ; Full path + "INFOPATH" ; Info directories + "GOPATH" ; Golang path + )) + (exec-path-from-shell-initialize)) + +(setenv "PAGER" "cat") +(setenv "TERM" "xterm-256color") +#+end_src + + +** Keep emacs clean +:PROPERTIES: +:header-args: :tangle config/00-clean.el +:CUSTOM_ID: h:8a9d7d0d-0900-4261-a9e3-923a0afc1324 +:END: + +I want to keep the =~/.emacs.d= folder as clean as possible. The [[https://github.com/emacscollective/no-littering][no-littering]] project +helps wit that. + +#+begin_quote +The default paths used to store configuration files and persistent data are not consistent +across Emacs packages. This isn't just a problem with third-party packages but even with +built-in packages. + +Some packages put these files directly in user-emacs-directory or $HOME or in a +subdirectory of either of the two or elsewhere. Furthermore sometimes file names are used +that don't provide any insight into what package might have created them. + +This package sets out to fix this by changing the values of path variables to put +configuration files in no-littering-etc-directory (defaulting to ~/.emacs.d/etc/) and +persistent data files in no-littering-var-directory (defaulting to ~/.emacs.d/var/), and +by using descriptive file names and subdirectories when appropriate. This is similar to a +color-theme; a "path-theme" if you will. +#+end_quote + +Let's configure it *and* make sure we load it as soon as possible (hence the +=config/00-clean.el=). + +As I am loading =recentf= during this cleanup part, I need to setup recentf before π . In +a gist: + +- I keep about 200 items. +- I don't want the /auto-cleanup/ of recentf items to happen when the mode is loaded (a.k.a. + at startup). It is configured to run after 360s of idle time. +- I don't really want to show the Nth number of the items. +- I don't want recentf to save remote, =su= and =sudo= items (=ssh:=, =sudo:=, β¦) + +#+begin_src emacs-lisp +(use-package recentf + :config + (setq recentf-max-saved-items 200 + recentf-auto-cleanup 360 + recentf-show-file-shortcuts-flag nil) + (recentf-mode 1) + (add-to-list 'recentf-exclude "^/\\(?:ssh\\|su\\|sudo\\)?:") + ;; Magic advice to rename entries in recentf when moving files in + ;; dired. + (defun rjs/recentf-rename-notify (oldname newname &rest args) + (if (file-directory-p newname) + (rjs/recentf-rename-directory oldname newname) + (rjs/recentf-rename-file oldname newname))) + + (defun rjs/recentf-rename-file (oldname newname) + (setq recentf-list + (mapcar (lambda (name) + (if (string-equal name oldname) + newname + oldname)) + recentf-list)) + recentf-cleanup) + + (defun rjs/recentf-rename-directory (oldname newname) + ;; oldname, newname and all entries of recentf-list should already + ;; be absolute and normalised so I think this can just test whether + ;; oldname is a prefix of the element. + (setq recentf-list + (mapcar (lambda (name) + (if (string-prefix-p oldname name) + (concat newname (substring name (length oldname))) + name)) + recentf-list)) + recentf-cleanup) + + (advice-add 'dired-rename-file :after #'rjs/recentf-rename-notify)) + +(use-package no-littering ; Keep .emacs.d clean + :config + (require 'recentf) + (add-to-list 'recentf-exclude no-littering-var-directory) + (add-to-list 'recentf-exclude no-littering-etc-directory) + + ;; Move this in its own thing + (setq + create-lockfiles nil + delete-old-versions t + kept-new-versions 6 + kept-old-versions 2 + version-control t) + + (setq + backup-directory-alist + `((".*" . ,(no-littering-expand-var-file-name "backup/"))) + auto-save-file-name-transforms + `((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))) +#+end_src + +** Server mode +:PROPERTIES: +:CUSTOM_ID: h:51ffd089-63c6-4ba6-8cc5-4c888521ef3a +:END: + +My current setup involves a =emacs --daemon= systemd service. We want to start the server +if it's not already running, so that =emacsclient= can connect to it. + +#+INCLUDE: "./config/01-server.el" src emacs-lisp :range-begin "UseServer" :range-end "-UseServer" :lines "4-6" + +* TODO Selection candidates and search methods +:PROPERTIES: +:CUSTOM_ID: h:4323a022-5419-48f7-acf9-7af94e43eddf +:END: + +* TODO Directory, buffer and window management +:PROPERTIES: +:CUSTOM_ID: h:88c7f450-bb9d-41f6-a8f9-3082a32d3179 +:END: + +* Applications and utilities +:PROPERTIES: +:CUSTOM_ID: h:8219f8ae-d4a8-4b9d-9a4a-3e457d69751e +:END: + +This section includes configurations for programs like email clients, messages, knowledge +database and other /applications/ that runs in Emacs. Most of those should be the "killer +apps" of the Emacs ecosystem. + +** TODO Org-mode (personal information manager) +:PROPERTIES: +:header-args: :tangle config/setup-org.el +:CUSTOM_ID: h:c8fd2624-6c91-4b89-9645-4261ca85d584 +:END: + +I am an heavy user of [[https://orgmode.org/][=org-mode=]]. This is most likely *the one* mode that made me switch +back to GNU/Emacs years back. + +#+begin_quote +Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring +documents with a fast and effective plain-text system. +#+end_quote + +I'm going to quote [[https://protesilaos.com/dotemacs/#h:4e8347de-415e-4804-b383-d61499e05ca1][Protesilaos Stavrou]] too as he describe it way better than I would do. + +#+begin_quote + Org offers you the basic tools to organise your life in super-efficient ways using + nothing but plain text. + +In its purest form, Org is a markup language that is similar to Markdown: symbols are used +to denote the meaning of a construct in its context, such as what may represent a headline +element or a phrase that calls for emphasis. + +What lends Org its super powers though is everything else built around it: a rich corpus +of elisp functions that automate, link, combine, enhance, structure, or otherwise enrich +the process of using this otherwise simple markup language. This very document is written +in org-mode while its website version is produced by a function that exports Org notation +into its HTML equivalent. +#+end_quote + +I am using =org-mode= for managing my tasks and partly my daily agenda, for /journaling/, +knowledge database (taking notes on stuff) and publishing documents (right now mainly on +[[https://sbr.pm][sbr.pm]]). I have been using =org-mode= for a while now, I feel some of my configuration may +be heavily /tailored/ to my needs. + +The /base/ user keybinding for =org-mode= (and related modes) is =C-c o= (e.g. showing +agenda is =C-c o a=, capture is =C-c o c=, β¦). + +*** Base settings :ATTACH: +:PROPERTIES: +:CUSTOM_ID: h:9287c076-1944-4c13-b4e4-c7cbc6587358 +:ID: 1f74bbae-c4a1-4723-977e-e48900fcd1c7 +:Attachments: 2020-02-29-13-46-08.png +:END: + +First, let's define some basic constants, mainly on how my main =org= folder is organized. + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgConstants" :range-end "-OrgConstants" :lines "4-14" + +In a nutshell, I am currently trying the following organization, with =~/desktop/org/= as +the base of almost all =org-mode= things: + ++ =projects= is the main /TODO/ folder. It holds todos and current projects along with ideas. + - =inbox.org= is my inbox, where most of my captured todo, ideas and link will be store, + waiting for reviews. + - =incubate.org= is where I store my ideas that could become projects at some point. It + is also waiting for reviews (once a week more or less). + - =next.org= is where simple todos are stored, quick one shot /things/ that do not need + a project to be created. + - ={project}.org= are files that holds a project information and todos. It can be + /long-lived/ projects (like =redhat.org= or =tekton.org=) or, prefered, /short-lived/ + projects, like =rework-infra.org= or =tekton-beta.org=. Once a project is marked as + done or completed, it either goes into the =archive=, or into =technical= ; if it can + be published. ++ =technical= is the public / to-be-published documents and /public/ knowledge base. It can holds todos, but its main + purpose is to be publish, at [[https://sbr.pm][sbr.pm]]. Thus, it's organization is the same as the + website. ++ =personal= is my private knowledge base. Those are private information or notes that I + don't want to publish *and* might be encrypted (using =gnupg=). ++ =archive= holds all archived files (projects, todos from =projects= files, β¦) + +Additionnaly, I may have =org-mode= files and /todos/ in other files, like in my +=~/.emacs.d= folder or my [[https://github.com/vdemeester/home][=home=]] configuration. + +I want a way to quickly jump to certain =org-mode= files, like =next.org= or the +=inbox.org=. For this, we can use the emacs [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Registers.html][registers]] and more accurately the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/File-Registers.html#File-Registers][file +registers]]. + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgRegisters" :range-end "-OrgRegisters" :lines "17-22" + +With this, I can jump to the inbox with ~C-x r j i~, to the journal using ~C-x r j j~, β¦ + +Let's setup the base of =org-mode=, with the following things in mind: + +- Agenda :: =org-agenda-files= contains =~/desktop/org/=, =~/.emacs.d/= and + =~/.config/nixpkgs/=. The rest of the configuration will happen when configuring + =org-agenda=. +- Navigation and key bindings :: + + As said before, =C-c o= is the prefix of my user specific keybindings + - =C-c o l= is to store the link (default keybinding is =C-c C-l=) + - =C-c o r r= is to refile a task from an org-mode buffer (default keybinding is =C-c + C-w=, and there is a different keybinding when in an org-mode agenda buffer) + + Activating [[https://orgmode.org/manual/Speed-Keys.html][/speed commands/]], aka being able to use one keystroke to do some action (like + changing the TODO state, β¦) + + =C-a=, =C-e= and =C-k= should be =org-mode= aware. This is achieved by setting + =org-special-ctrl-a/e= and =org-special-ctrl-k= to =t=. +- To-do settings :: My current setup of /todo-keywords/ (a.k.a. =org-todo-keywords=) might + be more complicated that it should be but I've been using it a while + now. =org-todo-keywords= is a list of sequences, I have three: + + =TODO= β =NEXT= β =STARTED= β =DONE= /or/ =CANCELED= + + =WAITING= β =SOMEDAY= β move to a =TODO= or =CANCELED= + + =IDEA= β move to a =TODO= or =CANCELED= + + I am leaning towards simplifying this, especially as =NEXT= is not really useful (I have + =next.org= for this), and =IDEA= or =WAITING= are not really used either (=IDEA= goes + into =incubate.org= and I don't seem to use =WAITING=). + + /I need to update and document =org-todo-state-tags-triggers= too/ +- Tags :: I am using generic tags and some groups. Groups allow to define mutually + exclusive tags, like =@home= and =@work= (can't be both). This is achieve by using + =:startgroup= and =:endgroup= in the =org-tag-alist= variable. It is also possible to + define [[https://orgmode.org/manual/Tag-Hierarchy.html#Tag-Hierarchy][tag hierarchies]] but I didn't look into it yet. + + I also want to have tag inheritance, aka children entry inherits their parent's tag β + even though it may have a cost (search, β¦), it allows to reduce lots of /duplications/. +- Refile :: In the =org-mode= jargon, this means moving an entry from one heading (parent + entry) to another. This move can be done across files. =org-mode= displays a list of + choice, this list is controlled by the =org-refile-targets= variable. + + The =org-refile-targets= is pretty powerful if you read the doc. You specify a list of + file and some /search/ options for org to build its list from. Those options can be the + level of the entry, some tag, regular expression, β¦ In my case, I want this list to be + all the =org= file in the =project= folder and also the =inbox.org= file. For the inbox, + I want to look only at level 0 (aka root), for the other, I want to look at level 1 (aka + root and sub entries). + + I also changed the default way to show the refile targets (=level1/level2/level3=) to + include the file name. When refiling, you can either do the completion hierarchically + (select the file, then the first level, β¦) or you can display all the choice at once. I + tend to prefer having all the choice at once and let my completion framework (=ivy= as + of now) to do the /fuzzy/ selection. + + Finally, I want to be able to create new node if I want, while refiling, so I'm setting + =org-refile-allow-creating-parent-nodes= to =confirm=, to ask me if I am sure πΌ. +- User Interface :: + + I want, by default, to display the effort and clock summary on org columns, so I am + setting the =org-columns-default-format= to do that. + + [[att:2020-02-29-13-46-08.png]] + + + I want to /fontify/ the whole header line (it tends to look better for some theme) + + I want things /pretty/, hence the =org-pretty-entities= πΉ + + When a entry (or a drawer) is closed, I like having a visual cue that it is. I chose + the =β¦= character to show that. It can be set with =org-ellipsis=. +- Logging :: =org-mode= allows to write the time (or a note) on a entry state change, this + is achieved by the =org-log-*= variables. On marking entries as =DONE= or when + rescheduling them (or changing the deadline), I want to mark the time. + + Additionally, when I log those state changes, I don't want them to pollute the content + of the to-do (aka description, β¦). Setting =org-log-int-drawer= will insert those logs + in a =LOGBOOK= drawer (same as the property drawer). +- Archiving :: I don't want to pollute my current folder with =_archive= files, so I am + redefining =org-archive-location= to archive to my =org-default-completed-dir=, also + using =datetree= to put archived items in a datetree. +- Miscellaneous :: + + I am setting up =org-use-property-inheritance= to make children node inherit their + parent property. It has a cost on search but I feel, as for tag inheritance, it is + worth the cost. + + Still on properties, =org-global-properties= allows you to add values to properties + that will show in the completion when setting those. For example, setting =EFFORT_ALL= + to a list, will give you those options when you are trying to set the effort property. + + I am setting =org-enforce-todo-dependencies= to make sure a parent entry cannot be + mark as done if children are not in complete state (=DONE=, =CANCELLED=, β¦). + + I want to add a new blank line whenever I create a new entry *but* I don't want that + extra new blank line when adding a new list item. =org-blank-before-new-entry= allow + to customize that behaviour. + + I don't want to load inline image at startup ; it slows down for nothing. + +/The =ensure org-plus-contrib= is there to make sure I am loading the =org= module from my +nix configuration and not the built-in =org= module (that might lag in terms of version)/ + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgMain" :range-end "-OrgMain" :lines "25-89" + +I've set-up an =org-mode= hook to add few modes to the default setup. +- I am really annoyed by trailing white-space so I want them to be shown +- If the major mod is not =org-agenda-mode= (a sub-mode of =org-mode=) + + I set the =fill-column= to ~90~ (instead of the usual ~80~), and I enable =auto-fill= mode. + + I turn on =auto-revert-mode= so that the buffer is always up-to-date. + + I like to have header indented, so I'm enabling =org-indent-mode=. + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgHook" :range-end "-OrgHook" :lines "92-101" + +Let's also use =org-id=β¦ + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgId" :range-end "-OrgId" :lines "104-133" + +β¦ and =org-crypt= (for encrypted =org-mode= files). + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgCrypt" :range-end "-OrgCrypt" :lines "136-141" + +*** TODO Agenda +:PROPERTIES: +:CUSTOM_ID: h:ba2a773a-88d1-4df9-a98c-5e547ee50691 +:END: + +The =org-mode= agenda is *the* source of my day-to-day organization. This is how I know +what I have to do that, what I can do. This is also where I log my work (see /Clocking/ +below). + +#+begin_quote +Due to the way Org works, TODO items, time-stamped items, and tagged headlines can be +scattered throughout a file or even a number of files. To get an overview of open action +items, or of events that are important for a particular date, this information must be +collected, sorted and displayed in an organized way. +#+end_quote + +Invoking =org-agenda= presents a list of possible options. There as a list of built-in +agenda views, where =a= shows all the items that have date assigned to them (=SCHEDULED= +or =DEADLINE=), =t= for listing to-dos, =T= for listing to-dos with a specific state and +=m= for more advanced matching possibilities. + +I am using [[https://github.com/alphapapa/org-super-agenda/][=org-super-agenda=]] to /supercharge/ the =org-mode= agenda πΌ to define my own +agenda views. This allows to group things and overall set-up the agenda view I want. This +agenda view uses the =n= key. + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgAgenda" :range-end "-OrgAgenda" :lines "144-181" + +Let's try to get my work calendar entries in my agenda too. It is a little bit tricky πΌ. + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgGcal" :range-end "-OrgGcal" :lines "184-198" + +*** Habits :ATTACH: +:PROPERTIES: +:CUSTOM_ID: h:291bae2c-f3eb-4c2a-9415-606afa28ac86 +:ID: 17a3ed73-aaca-4a18-8ed1-3efe7bac855a +:Attachments: 2020-02-29-14-41-59.png +:END: + +Org has the ability to track the consistency of a special category of +TODO, called /habits/. + +#+begin_quote +Whatβs really useful about habits is that they are displayed along +with a consistency graph, to show how consistent youβve been at getting +that task done in the past. This graph shows every day that the task +was done over the past three weeks, with colors for each day. The +colors used are: + +Blue + If the task was not to be done yet on that day. +Green + If the task could have been done on that day. +Yellow + If the task was going to be overdue the next day. +Red + If the task was overdue on that day. +#+end_quote + +This look as followed in the agenda. + +[[att:2020-02-29-14-41-59.png]] + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgHabit" :range-end "-OrgHabit" :lines "201-206" + +*** TODO Sources +:PROPERTIES: +:CUSTOM_ID: h:82c3b800-9d80-408d-b3b6-54dc15b0590c +:END: + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgSrc" :range-end "-OrgSrc" :lines "209-216" + +*** TODO Capture +:PROPERTIES: +:CUSTOM_ID: h:b29abe71-6e9a-4ddf-8519-453170212777 +:END: + +The =org-capture= tool is a powerful way to quickly produce some kind of structured +information with little interruption of your workflow. With =org-agenda=, this is one of +the most used feature of =org-mode= (at least for me). + +Each template is accessed via a key. These are listed in a buffer when you call +=org-capture=. Unique keys give direct access to their template, whereas templates that +share a common initial key will produce a second selection list with the remaining +options. This is very interesting when you want to group some capture template together +(like templates related to /work/, β¦). + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgCaptureStart" :range-end "-OrgCaptureStart" :lines "219-223" +#+begin_src emacs-lisp +(use-package org-capture + :after org + :commands (org-capture) + :config +#+end_src + +Some of my capture template are big and hard to read if embedded in the =emacs-lisp= +code. The good thing is that =org-mode= is able to load the template from files too π. + +Here is a list of my templates: +- Default :: /I need to rework those/ + + #+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgCaptureOldTemplate" :range-end "-OrgCaptureOldTemplate" :lines "226-245" + +- journaling :: As I use =org-mode= for my /journal/ too, I need capture entry for + it. I currently have two types of journal entry : + + standard: one title and some text + + #+INCLUDE: "etc/orgmode/journal.org" src org + + #+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgCaptureJournal" :range-end "-OrgCaptureJournal" :lines "248-253" + + + worklog: related to work, to be able to say what I did, what I wanted to do, problems, + β¦ during the daily + + #+INCLUDE: "etc/orgmode/worklog.org" src org + + #+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgCaptureWorklog" :range-end "-OrgCaptureWorklog" :lines "256-261" + +- weekly review :: each and every week, I am going through this item to make my review of + the week. + + #+INCLUDE: "etc/orgmode/weekly.org" src org + + #+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgCaptureWeekly" :range-end "-OrgCaptureWeekly" :lines "264-269" + +- blog posts :: + + #+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgCaptureBlog" :range-end "-OrgCaptureBlog" :lines "272-282" + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgCaptureEnd" :range-end "-OrgCaptureEnd" :lines "285-286" + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgProtocol" :range-end "-OrgProtocol" :lines "289-291" + +*** Clocking +:PROPERTIES: +:CUSTOM_ID: h:264afe05-79e3-4bff-aafc-9fc726c4034b +:END: + +I am heavily using the clocking along with =org-agenda=. My usual workflow, related to +clocking is : + +- I bring the Agenda up +- I clock the task I am working on, using =I= in the agenda +- When I stop working on the task + + if the task is completed, I use =t d= to mark it as done, the clock should + automatically stop. + + if the task is not completed, I use =O= to stop the clock + +In addition to that workflow, I want to switch the state of the task to =STARTED= when I +am clocking-in, if it's not already =STARTED=. + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgClock" :range-end "-OrgClock" :lines "294-387" + +*** TODO Links +:PROPERTIES: +:CUSTOM_ID: h:afc81fbb-f7a0-401c-8b56-19f51edebd88 +:END: + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgAttach" :range-end "-OrgAttach" :lines "390-393" + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgLinks" :range-end "-OrgLinks" :lines "396-421" + +*** TODO Litterate programming +:PROPERTIES: +:CUSTOM_ID: h:b5f6beba-6195-4ff0-a194-502ac2a9e3da +:END: + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgBabel" :range-end "-OrgBabel" :lines "424-432" + +*** TODO Exporting +:PROPERTIES: +:CUSTOM_ID: h:afad00e0-367c-4c7b-b191-e3ed72be754b +:END: + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgExportConstants" :range-end "-OrgExportConstants" :lines "435-437" + +#+INCLUDE: "./config/setup-org.el" src emacs-lisp :range-begin "OrgExportCfg" :range-end "-OrgExportCfg" :lines "440-451" + +** TODO Email and newsgroup +:PROPERTIES: +:header-args: :tangle config/setup-mails.el +:CUSTOM_ID: h:afa562d5-b07e-413b-8c1d-2d489fb72900 +:END: + +I have been back and forth on using email inside Emacs, from ~mu4e~ to ~notmuch~. In the +past I have used Thunderbird, and for a while now, I have been only using webmail UI for +emails (and mobile apps of course). I recently re-discover [[https://www.gnus.org/][Gnus]] as a mail reader, so my +current setup is the following: + +- [[https://www.gnus.org/][Gnus]], the Emacs built-in newsreader and email client. +- ~notmuch~ to be able to browse my mail backups (using ~isync~, β¦), see [[https://sbr.pm/technical/mail-setup.html][here]] for the + current setup. + +One of the main reason to rely on [[https://www.gnus.org/][Gnus]] instead of ~notmuch~ for the mails, is that I don't +need to worry about some complex mechanism for syncing, storing and indexing email. I +still use ~notmuch~ with ~isync~ to backup my mails somewhere, with the possibility to +search them. + +*** Base email settings +:PROPERTIES: +:CUSTOM_ID: h:765191a3-81cb-4e6e-9360-6a42b2a55b0f +:END: + +Before configuring any email client, we need to establish some essentials: who we are, +where our credentials are stored and whether encryption is supported. + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "AuthSource" :range-end "-AuthSource" :lines "4-9" + +*** Gnus +:PROPERTIES: +:CUSTOM_ID: h:0aeec7d8-b6c9-4244-8c10-2788c6e89cc5 +:END: + +The documentation describes Gnus as the /"coffee-brewing, all singing, all dancing, +kitchen sink newsreader"/. It is massive, which means the learning curve is more or less +similar to =org-mode=. You need to go slowly, starting simple and enhance your workflow +and configuration along the way. + +Now some basic information on the abstractions that Gnus relies on: + +1. The default Gnus buffer is called "Group". It will present you with a list of all the + news sources you have subscribed to. By default, Gnus only displays messages that have + not been read. The same applies for groups. The "Group" buffer will be empty the very + first time you log in because you have not subscribed to anything yet. Use =g= to + fetch new messages from the sources. If you only want to refresh the group at point, + do it with =M-g=. +2. The "Server" buffer contains a list with all the sources you have specified for + discovering news. In my case, these are my email accounts and a Usenet server where + mailing lists are hosted. To access the "Server" buffer from inside the "Group" + buffer, just hit the caret sign =^=. To subscribe to an item, place the point over it + and hit =u=. Do that for your email's inbox and for whatever mailing lists you intend + to follow. +3. The "Summary" buffer contains all the messages of a group. Hitting the return key over + a message will split the view in two, with the list above and the message below. Use + =n= or =p= to move to the next or previous unread message (or =N= and =P= to just the + next/prev). You access the "Summary" buffer both from the "Group" and the "Server" by + entering a group. + +As noted, Gnus will only show you a list of unread items. To view all your groups, hit +=L=. Use the lower case version =l= to view only the unread ones. To produce a Summary +buffer with read items, hit =C-u RET= over a group and specify the number of messages you +want to list (the other option is =C-u M-g= from inside the Summary). Another useful trick +for the Summary buffer is the use of the caret sign (=^=) to show you the previous message +that the current item is a reply to. + +**** Account settings +:PROPERTIES: +:CUSTOM_ID: h:be7bbb5b-4b13-49f0-8044-b79363ccba7f +:END: + +Let's first configure the essentials of Gnus. + +The =gnus-select-method= sets the default method for fetching news items. As I want to +read mail from several accounts in addition to following Usenet sources, I choose to set +it to nil. + +The =gnus-secondary-select-methods= is where my accounts are specified. Each =nnimap= list +points to a specific line in my =authinfo.gpg= file. My emails all use the same server so +this method allows me to specify the username (email) and password combination for each of +them /without/ making this information public. I am not sure whether the =nnimap-stream= +and =nnimap-authinfo-file= are needed, but I keep them for the sake of completeness. + +- [[http://www.cataclysmicmutation.com/2010/11/multiple-gmail-accounts-in-gnus/][Multiple GMail Accounts in Gnus - Cataclysmic Mutation]] +- [[https://github.com/redguardtoo/mastering-emacs-in-one-year-guide/blob/master/gnus-guide-en.org][mastering-emacs-in-one-year-guide/gnus-guide-en.org at master Β· redguardtoo/mastering-emacs-in-one-year-guide]] + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "GnusCfg" :range-end "-GnusCfg" :lines "20-77" + +Let's also give to gnus my GnuPG key. + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "GnusMmlSec" :range-end "-GnusMmlSec" :lines "80-84" + + +**** Gnus agent +:PROPERTIES: +:CUSTOM_ID: h:2beac436-62ba-4b52-acc5-559016ec477f +:END: + +Gnus has something call the "agent", which represent the bridge between Gnus and the +server it connects to. Gnus is said to be "plugged" when a connection is established, +otherwise it is "unplugged". + +Technicalities aside, we basically use this to save a local copy of the items we have +already fetched from the server. We can also use the agent to configure the handling of +local messages. For example, we can set an expiry date, after which the message is +deleted, or we can create a queue of outgoing messages when Gnus is in an unplugged state. + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "GnusAgent" :range-end "-GnusAgent" :lines "87-101" + +**** Gnus asynchronous operations +:PROPERTIES: +:CUSTOM_ID: h:c089372e-4aeb-4daf-96d5-77a997ff2dd0 +:END: + +By default, Gnus performs all its actions in a synchronous fashion. This means that Emacs +is blocked until Gnus has finished. By enabling this library, we can use certain functions +in a non-blocking way. I do this for [[#h:8cd8c972-ba38-40c2-b30f-68a4233593d6][sending email]]. + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "GnusAsync" :range-end "-GnusAsync" :lines "104-109" + +**** Gnus group +:PROPERTIES: +:CUSTOM_ID: h:4e52ab94-4e54-41df-a43e-db0c8d23a55a +:END: + +Let's dig a bit more into groups : + ++ A group can be assigned a level of importance. This is a grade whose highest score is 1 + and the lowest is 6 (customisable though). Each level has a different colour. To assign + a new value to the group at point, do it with =S l= and then give it a number. Once you + have graded your groups, you can perform various actions on a per-level basis. For + example, to refresh all levels from 1 up to 3 but not higher, pass a numeric argument to + the standard =g= command. So =C-3 g= (this is the same as =C-u 3 g=). ++ Groups can be organised by topic. Create a new one with =T n= and give it a name. Move + a group to a topic with =T m=. To toggle the view of topics use =t= (I have a hook that + does this automatically at startup). The level of indentation tells us whether a topic + is a sub-set of another. Use =TAB= or =C-u TAB= to adjust it accordingly. As with + levels, you can operate on a per-topic basis. For example, to catch up on all the news + of a given topic (mark all as read), you place the point over it, hit =c= and then + confirm your choice. + +Note that =gnus-group-sort-functions= requires the most important function to be declared +last. + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "GnusGroup" :range-end "-GnusGroup" :lines "112-128" + +**** Gnus Summary +:PROPERTIES: +:CUSTOM_ID: h:dfe4a692-1f0f-44c7-8d72-a1488e4ef80b +:END: + +Threads should not be hidden, while messages whose root has been removed should be grouped +together in some meaningful way. Furthermore, when moving up or down in the list of +messages using just =n= or =p=, I want to go to the next message, regardless of whether it +has been read or not. I can otherwise rely on standard Emacs motions. + +The formatting of the threads using Unicode characters was taken from the [[https://www.emacswiki.org/emacs/GnusFormatting][relevant Emacs +wiki entry]] plus some minor tweaks by me. + +The =gnus-user-date-format-alist=, this basically adapts the date to whether the message +was within the day or the one before, else falls back to a default value. It is then +called with =%&user-date;=. + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "GnusSummary" :range-end "-GnusSummary" :lines "140-183" + +Gnus summary displays a mark for each messages, those `O`, `!`, β¦ Let's first describe +what are those marks (from the [[https://www.gnu.org/software/emacs/manual/html_node/gnus/Marking-Articles.html#Marking-Articles][documentation]]) and which one make the more sense for me. +Most of those marks can be set using the =M= prefix (or =M M=) from the Summary buffer. + +First there is two groups of /marks/ : *unread* and *read*. Note they do not entirely map +to what IMAP defines or what you would see in another mail UI (webmail, β¦). + ++ *unread*: those will appear by default on a Summary buffer (almost π) + - =<SPC>= are the /standard/ unread, never read. Once a mail is read you can mark it back as + unread with =M M u u=. + - =!= is for /ticked/. This is similar to the *starred* thread/message on GMail (or + Thunderbird, β¦ β in ~notmuch~ it appears as =flagged=). Those will always appear in + the summary, so this is mainly for really important message to be remembered all the + time. + - =?= is for /dormant/. This is similar to /ticked/ *but* the article will only appear + if there is a follow-up of the message. This would be a good use of "waiting for an + answer so keep it". ++ *read*: those will not appear by default on a Summary buffer + - =r= and =R= are /just read/ (like in the /reading session/) more or less + - =O= is /read/ in an older session + - =Y= is for /too low of a score/, this means this message got automatically read + because it had low score (/more on that later/). + - =E= is for /marked as expirable/, so that Gnus can delete/expunge them (or do + something else β /more on that later/). + - =M= is for /duplicated/. + - =K=, =X= are for /killed/, =C= is for /catchup/ =Q= is for /sparsely reffed article/ + and =G= is for cancelled β not sure what this means yetβ¦ + +**** Gnus intersection with Dired +:PROPERTIES: +:CUSTOM_ID: h:35901f1a-4a24-46a8-bc8f-a334cd156f2b +:END: + +We can use the built-in directory editor (file manager) as a more convenient way of +performing certain tasks that relate to emails, such as attaching all the marked items of +the =dired= buffer to an email we are currently composing or wish to initiate the +composition of. + +Run =C-h m= inside of a Dired buffer that has =gnus-dired-mode= enabled and search for +"gnus" to see all the relevant key bindings and the functions they call. I only ever use +=C-c C-m C-a= (=C-m= is the same as =RET=). + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "GnusDired" :range-end "-GnusDired" :lines "186-189" + +**** TODO Searching mails +:PROPERTIES: +:CUSTOM_ID: h:8288c9b3-cfe2-4599-a55b-9b2b1c71f524 +:END: + +**** TODO Subscribing to RSS +:PROPERTIES: +:CUSTOM_ID: h:259bbc05-4ea6-43b7-bfef-0036434a86f8 +:END: + +*** TODO Sending mails +:PROPERTIES: +:CUSTOM_ID: h:8cd8c972-ba38-40c2-b30f-68a4233593d6 +:END: + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "SendmailCfg" :range-end "-SendmailCfg" :lines "193-207" + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "MessageCfg" :range-end "-MessageCfg" :lines "210-221" + +*** TODO ~notmuch~ configuration +:PROPERTIES: +:CUSTOM_ID: h:b67b377e-0fbc-4237-857c-641cdf2de1cf +:END: + +#+INCLUDE: "./config/setup-mails.el" src emacs-lisp :range-begin "Notmuch" :range-end "-Notmuch" :lines "224-241" + +* User interface and interactions +:PROPERTIES: +:CUSTOM_ID: h:93826a52-2f51-437b-8625-ce7cd36d53b6 +:END: +** Mouse +:PROPERTIES: +:CUSTOM_ID: h:cb0ad0e0-62a8-469a-970d-074a423b720d +:header-args: :tangle config/setup-mouse.el +:END: + +The value of mouse-wheel-scroll-amount means the following: + +- By default scroll by one line. +- Hold down Shift to do so by five lines. +- Hold down Meta to scroll half a screen. +- Hold down Control to adjust the size of the text. This is added in Emacs 27. + +By enabling mouse-drag-copy-region we automatically place the mouse selection to the kill +ring. This is the same behaviour as terminal emulators that place the selection to the +clipboard (or the primary selection). + +The other options in short: + +- Hide mouse pointer while typing. +- Enable mouse scroll. +- Faster wheel movement means faster scroll. + +#+begin_src emacs-lisp +(use-package mouse + :config + (setq mouse-wheel-scroll-amount + '(1 + ((shift) . 5) + ((meta) . 0.5) + ((control) . text-scale))) + (setq make-pointer-invisible t + mouse-wheel-progressive-speed t + mouse-wheel-follow-mouse t) + :hook (after-init . mouse-wheel-mode)) +#+end_src + +** Theme +:PROPERTIES: +:CUSTOM_ID: h:18fcf62d-a919-4614-803d-f5d28bc47985 +:END: + +*** My own theme :ATTACH: +:PROPERTIES: +:CUSTOM_ID: h:1a7c1e91-d3c5-4395-b956-8001a1a1a393 +:ID: 83bc2073-0681-4fe9-bcf7-3070bd1ab695 +:Attachments: 2020-03-03-21-57-41.png 2020-03-03-21-59-22.png +:END: + +I navigate between themes, but the more I use Emacs (or any editor really), the more I +lean towards writing my own. Those theme are base on [[https://github.com/Jannis/emacs-constant-theme][=emacs-constant-theme=]] which is "A +calm, almost monochrome color theme for Emacs with a dark and light variant". + +My main goal is to make a theme that, at least for syntax highlighting, differs from the +usual color(ful) themes. The reason come from a [[https://www.linusakesson.net/programming/syntaxhighlighting/][bunch]] [[https://jameshfisher.com/2014/05/11/your-syntax-highlighter-is-wrong/][of]] [[https://www.robertmelton.com/project/syntax-highlighting-off/][articles]] and [[https://asylum.madhouse-project.org/blog/2018/09/06/the-brutalist-path/][repositories]] that +discuss how, /maybe/ the way we see and use syntax highlighting today is not optimum. This +is a _touchy_ subject to see the least but it does make sense to me: I want to highlight +comments (because they may be important to understand the code), and I don't want to +highlight the language keyword more than the actual code. + +I wrote two version, a dark one and a light one. I currently mainly use the light theme +(as this is when I do work π ). + +**** Light theme +:PROPERTIES: +:CUSTOM_ID: h:8997adc9-8681-4d3a-a118-616866895f93 +:ID: 83bc2073-0681-4fe9-bcf7-3070bd1ab695 +:Attachments: 2020-03-03-21-57-41.png +:END: + + [[att:2020-03-03-21-57-41.png]] + +#+INCLUDE: lisp/shortbrain-light-theme.el src emacs-lisp + +See [[https://github.com/vdemeester/emacs-config/blob/master/lisp/shortbrain-light-theme.el][=lisp/shortbrain-light-theme.el=]]. + +**** Dark theme +:PROPERTIES: +:CUSTOM_ID: h:e986baca-a7dc-463e-85ee-ea10fb69bf0f +:ID: 83bc2073-0681-4fe9-bcf7-3070bd1ab695 +:Attachments: 2020-03-03-21-57-41.png +:END: + + [[att:2020-03-03-21-59-22.png]] + +#+INCLUDE: lisp/shortbrain-theme.el src emacs-lisp + +See [[https://github.com/vdemeester/emacs-config/blob/master/lisp/shortbrain-theme.el][=lisp/shortbrain-theme.el=]]. + +* TODO Programming +:PROPERTIES: +:CUSTOM_ID: h:635a27c4-5ff9-46e4-8d42-283d316cf4d6 +:END: + +* External libraries +:PROPERTIES: +:CUSTOM_ID: h:96ce2856-182e-42c8-a8b3-418c38124dcc +:END: + +** ~use-package-list.el~ +:PROPERTIES: +:CUSTOM_ID: h:bd8804a0-df0e-4aca-b748-429ea9402cd6 +:END: + +#+INCLUDE: lisp/use-package-list.el src emacs-lisp + +** ~gotest-ui.el~ +:PROPERTIES: +:CUSTOM_ID: h:a94b8ba9-2d74-4fb3-a43a-58f4cd6e5141 +:END: + +From [[https://github.com/antifuchs/gotest-ui-mode/][antifuchs/gotest-ui-mode]]. + +#+INCLUDE: lisp/gotest-ui.el src emacs-lisp + +** Org mode links +:PROPERTIES: +:CUSTOM_ID: h:80cc4939-759a-456b-8dfd-220dd8b48727 +:END: + +I am defining additonal org-mode links for my day to day usage. + +- ~ol-github.el~: link to GitHub repositories, issues and pull-requests. + + #+INCLUDE: lisp/ol-github.el src emacs-lisp + +- ~ol-gitlab.el~: link to GitLab repositories, issues and merge-requests. + + #+INCLUDE: lisp/ol-gitlab.el src emacs-lisp + +- ~ol-ripgrep.el~: link to a =ripgrep= search buffer. + + #+INCLUDE: lisp/ol-ripgrep.el src emacs-lisp + +- ~ol-grep.el~: link to a =grep= search buffer. + + #+INCLUDE: lisp/ol-grep.el src emacs-lisp + +And that's all folks π diff --git a/tmp/emacs-config/etc/orgmode/journal.org b/tmp/emacs-config/etc/orgmode/journal.org @@ -0,0 +1,7 @@ +* %^{title} +%U + +%? +%i + +From: %a diff --git a/tmp/emacs-config/etc/orgmode/weekly.org b/tmp/emacs-config/etc/orgmode/weekly.org @@ -0,0 +1,19 @@ +* weekly review :weekly:review: +%U + +- [ ] review [[file:../projects/inbox.org][~inbox.org~]] + Clean the file by either + - refiling it to ~incubate.org~ + - removing it / archiving it +- [ ] review [[file:../projects/incubate.org][~incubate.org~]] + - Is something worth becoming a project + - Is something not worth thinking about anymoreΒ ? +- [ ] empty mail inbox (and create task if needed) + - [ ] work + - [ ] perso +- [ ] Review next week ~F12 n w f~ +- [ ] review ~org-mode~ workflow + - *what works, what doesn't ?* + - *is there task / stuck projects ?* + - *enhancement possible ?* +- [ ] export previous agenda (somewhere) diff --git a/tmp/emacs-config/etc/orgmode/worklog.org b/tmp/emacs-config/etc/orgmode/worklog.org @@ -0,0 +1,4 @@ +* worklog :log:@work: +%U + +%? diff --git a/tmp/emacs-config/etc/pandoc.css b/tmp/emacs-config/etc/pandoc.css @@ -0,0 +1,245 @@ +/***************************************************************************/ +/* My Stylesheet for Pandoc generated files */ +/* Copyright (c) 2015 Sebastian Wiesner <swiesner@lunaryorn.com> */ +/* */ +/* 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. */ +/***************************************************************************/ + +body { + font-family: "Source Sans Pro", sans-serif; + font-size: 16px; + line-height: 1.35; + color: #444; + font-feature-settings: "onum", "kern", "liga", "clig", "dlig", "calt"; + -webkit-font-feature-settings: "onum", "kern", "liga", "clig", "dlig", "calt"; + margin: 0 auto; + padding: 15px; + margin-bottom: 1.35em; + word-wrap: break-word; +} + +p { + margin: 0 0; + text-indent: 1.5em; + text-align: left; +} + +p:only-child { + text-indent: 0; +} + +strong { + font-weight: 600; +} + +ul, ol { + margin: 1em 4em; + padding: 0; +} + +ol { + list-style-type: decimal; +} + +ul { + list-style-type: disc; +} + +small, sup { + font-size: 0.86em; +} + +h1 small, h2 small, h3 small, h4 small { + font-weight: normal; + font-size: 0.65em; + line-height: 1; + color: #777; +} + +blockquote { + margin: 1.2em 0; + padding: 0 2em; + line-height: 1.25; + font-size: 0.9em; + border-left: 5px solid #EEE; +} + +a { + color: #333; + text-decoration: underline; +} + +a:hover { + background-color: #fbf3f3; + border-radius: 4px; + transition-property: background; + transition-duration: 0.2s; +} + +.footnoteRef { /* Use body font for footnotes */ + font-size: 1rem; + text-decoration: none; +} + +h1, h2, h3, h4 { /* Text headings*/ + font-family: "Source Sans Pro", sans-serif; + font-weight: 600; + line-height: 1; + color: #222; + margin-top: 2em; + margin-bottom: 0.8em; + hyphens: none; + font-feature-settings: "salt", "lnum"; + -webkit-font-feature-settings: "salt", "lnum"; +} + +h1 { + font-size: 1.2em; +} + +h2 { + font-size: 1.1em; +} + +h3 { + font-size: 1em; +} + +.header-section-number { + margin-right: 0.5em; +} + +.header-section-number:after { + content: "." +} + +hr { + border-width: 1px; + border-color: #CCC; + border-style: none none solid; + margin: 1.35em 0; +} + +/* Images and figures */ +img { + max-width: 100%; + max-height: 100%; +} + +figure { + margin: 2em; +} + +figcaption { + margin-top: 0.8em; + text-align: center; + font-size: 0.9em; +} + +figcaption:before { + content: "Figure."; + font-weight: 700; + margin-right: 0.5em; +} + +/* Code and pre-formatted text */ +kbd, code { + font-family: "Source Code Pro", monospace; + font-size: 0.83em; +} + +kbd { + border: 1px solid #CCC; + border-radius: 4px; + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px #FFF inset; + padding: 0 4px; +} + +code { + padding: 0.11em 0.22em; +} + +pre { + overflow: auto; + padding: 10px; + border: 1px solid #CCC; + border-radius: 4px; +} + +pre:hover { /* Auto-expand pre on hover */ + position: relative; + width: 900px; + z-index: 99; +} + +pre code { + padding: 0; +} + +.title { /* Page title */ + font-size: 1.5rem; + font-weight: 700; + margin-bottom: 0.2em; + margin-top: 0; +} + +nav { + margin: 1em; + font-feature-settings: "salt", "lnum"; + -webkit-font-feature-settings: "salt", "lnum"; +} + +nav a { + text-decoration: none; +} + +nav ul { + list-style: none inside disc; + margin: 0; + padding: 0 0.5em; +} + +header { + border-width: 1px; + border-color: #CCC; + border-style: none none solid; + margin: 1.35em 0; +} + + +@media print { + body { + width: auto; + height: auto; + font-size: 10pt; + } +} + +@media screen and (min-width: 650px) { /* Larger devices */ + body { + width: 600px; + } +} + +@page +{ + size: A4; + margin: 24.75mm 17.50mm; +} diff --git a/tmp/emacs-config/etc/transient/levels.el b/tmp/emacs-config/etc/transient/levels.el @@ -0,0 +1,4 @@ +((magit-commit + (magit:--gpg-sign . 3)) + (magit-rebase + (magit:--gpg-sign . 3))) diff --git a/tmp/emacs-config/etc/transient/values.el b/tmp/emacs-config/etc/transient/values.el @@ -0,0 +1,3 @@ +((magit-commit "--signoff" "--gpg-sign=B7E7CF1C634256FA") + (magit-fetch "--prune") + (magit-rebase "--autostash" "--gpg-sign=B7E7CF1C634256FA")) diff --git a/tmp/emacs-config/etc/yasnippet/snippets/c++-mode/.yas-parents b/tmp/emacs-config/etc/yasnippet/snippets/c++-mode/.yas-parents @@ -0,0 +1 @@ +cc-mode+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/c-mode/.yas-parents b/tmp/emacs-config/etc/yasnippet/snippets/c-mode/.yas-parents @@ -0,0 +1 @@ +cc-mode+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/add b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/add @@ -0,0 +1,4 @@ +#name : /*** START TI ADD ***/ ... /*** END TI ADD ***/ +# -- +/*** START TI ADD ***/ +$0/*** END TI ADD ***/ diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/addif b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/addif @@ -0,0 +1,7 @@ +#name : START TI ADD + #if OPENCL +# -- +/*** START TI ADD ***/ +#if OPENCL_EXTENSIONS_SUPPORTED +$0 +#endif /* OPENCL_EXTENSIONS_SUPPORTED */ +/*** END TI ADD ***/+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/class b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/class @@ -0,0 +1,71 @@ +#name : class ... { ... } +# -- +/** + * @brief Summary + * + * Description. + */ +class $1 +{ + $0 + +public: + /** @name Construction and Destruction + @{ */ + + $1() noexcept? { + TRACE_CTOR($1, ""); + } + +#if defined(DEBUG_MODE) + virtual? ~$1() { + try { + TRACE_DTOR($1); + } + catch (...) { + std::terminate(); + } + } +#else + ~$1() = default|delete; +#endif + + /*@}*/ + + /** @name Assignment, Copy and Move + @{*/ + +#if defined(DEBUG_MODE) + $1(const $1& rhs) noexcept? { + TRACE_CTOR($1, "copy"); + *this = rhs; + } +#else + $1(const $1&) = default|delete; +#endif + + $1& operator=(const $1&) = default|delete; + $1& operator=(const $1& rhs) noexcept? { + //if (this != &rhs) { + //} + return *this; + } + +#if defined(DEBUG_MODE) + $1($1&&r rhs) noexcept? { + TRACE_CTOR($1, "move"); + *this = rhs; + } +#else + $1($1&&r) = default|delete; +#endif + + $1& operator=($1&&r) = default|delete; + $1& operator=($1&&r rhs) noexcept? { + //if (this != &rhs) { + //} + return *this; + } + + /*@}*/ +}; // class $1 diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/com b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/com @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: TI comment +# -- +/*------------------------------------------------------------*/ +/* $0 */ +/*------------------------------------------------------------*/ diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/fopen b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/fopen @@ -0,0 +1,3 @@ +#name : FILE *fp = fopen(..., ...); +# -- +FILE *${fp} = fopen(${"file"}, "${r}"); diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/inc b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/inc @@ -0,0 +1,3 @@ +#name : #include "..." +# -- +#include "$1" diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/inc.1 b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/inc.1 @@ -0,0 +1,3 @@ +#name : #include <...> +# -- +#include <$1> diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/main b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/main @@ -0,0 +1,7 @@ +#name: int main(argc, argv) { ... } +# -- +int main(int argc, char *argv[]) +{ + $0 + return 0; +} diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/misra b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/misra @@ -0,0 +1,14 @@ +#name : MISRA-C:2004 rule implementation +# -- +/*** START TI ADD ***/ +#if MISRA_C_2004_VALIDATION + if (check_misra_c_2004) + { + /*----------------------------------------------------------------*/ + /* MISRA-C:2004 - Rule ${1:Rule} (${2:required}) */ + /* ${3:Description} $0*/ + /*----------------------------------------------------------------*/ + diagnostic(misra_${2:required}_severity, ec_misra_c_2004_$1); + } /* if */ +#endif /* MISRA_C_2004_VALIDATION */ +/*** END TI ADD ***/ diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/ns b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/ns @@ -0,0 +1,5 @@ +#name : namespace ... +# -- +namespace $1 { + $0 +} diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/once b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/once @@ -0,0 +1,8 @@ +#name : #ifndef XXX; #define XXX; #endif +# -- +#ifndef ${1:_`(upcase (file-name-nondirectory (file-name-sans-extension (buffer-file-name))))`_H_} +#define $1 + +$0 + +#endif /* $1 */+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/tfunc b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/tfunc @@ -0,0 +1,11 @@ +#name : Texas Instruments function +# -- +/******************************************************************************/ +/* jww (`(format-time-string "%Y-%m-%d")`): NYI */ +/******************************************************************************/ +a_boolean $1($2) +{ + a_boolean result = FALSE; + $0 + return result; +} /* $1 */ diff --git a/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/using b/tmp/emacs-config/etc/yasnippet/snippets/cc-mode/using @@ -0,0 +1,4 @@ +#name : using namespace ... +# -- +using namespace ${std}; +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/emacs-lisp-mode/hdr b/tmp/emacs-config/etc/yasnippet/snippets/emacs-lisp-mode/hdr @@ -0,0 +1,36 @@ +;;; `(file-name-sans-extension (file-name-nondirectory buffer-file-name))` --- $1 + +;; Copyright (C) `(format-time-string "%Y")` `user-full-name` + +;; Author: `user-full-name` <`user-mail-address`> +;; Created: `(format-time-string "%d %b %Y")` +;; Version: 1.0 +;; Keywords: $2 +;; X-URL: https://github.com/jwiegley/${3:`(file-name-sans-extension (file-name-nondirectory buffer-file-name))`} + +;; 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 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: + +;; $0 + +(defgroup `(file-name-sans-extension (file-name-nondirectory buffer-file-name))` nil + "$1" + :group '$4) + +(provide '`(file-name-sans-extension (file-name-nondirectory buffer-file-name))`) + +;;; `(file-name-nondirectory buffer-file-name)` ends here diff --git a/tmp/emacs-config/etc/yasnippet/snippets/emacs-lisp-mode/test b/tmp/emacs-config/etc/yasnippet/snippets/emacs-lisp-mode/test @@ -0,0 +1,2 @@ +(ert-deftest $1 () + (should (equal $0)))+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/fundamental-mode/date b/tmp/emacs-config/etc/yasnippet/snippets/fundamental-mode/date @@ -0,0 +1,3 @@ +#name : (current date) +# -- +`(format-time-string "%Y-%m-%d")` diff --git a/tmp/emacs-config/etc/yasnippet/snippets/fundamental-mode/mail b/tmp/emacs-config/etc/yasnippet/snippets/fundamental-mode/mail @@ -0,0 +1,3 @@ +#name : (user's email) +# -- +`user-mail-address`+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/fundamental-mode/time b/tmp/emacs-config/etc/yasnippet/snippets/fundamental-mode/time @@ -0,0 +1,3 @@ +#name : (current time) +# -- +`(current-time-string)`+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/coloneq b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/coloneq @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: ... := ... +# key: := +# -- +${1:x} := ${2:`%`}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/f b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/f @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: func +# -- +func ${1:fun}($2) { + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/fm b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/fm @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: func (target) name(args) (results) { ... } +# -- +func (${1:target}) ${2:name}(${3:args}) (${4:results}) { + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/for b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/for @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: for ... { ... } +# -- +for $1 { + `%`$0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/fore b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/fore @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: for key, value := range ... { ... } +# -- +for ${1:key}, ${2:value} := range ${3:target} { + `%`$0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/foreach b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/foreach @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: for key, value := range ... { ... } +# -- +for ${1:key}, ${2:value} := range ${3:target} { + `%`$0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/fori b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/fori @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: for i := 0; i < n; i++ { ... } +# -- +for ${1:i} := ${2:0}; $1 < ${3:10}; $1++ { + `%`$0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/forw b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/forw @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name : for ... { ... } +# -- +for $1 { + `%`$0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/func b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/func @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: func +# -- +func ${1:fun}($2) { + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/iferr b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/iferr @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: if err != nil { ... } +# -- +if err != nil { + `%`$0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/ifunc b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/ifunc @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: func (...) ... { ... } +# -- +func ($1) $2 { + `%`$0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/imp b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/imp @@ -0,0 +1,4 @@ +# -*- mode: snippet -*- +# name: import +# -- +import ${1:package}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/import b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/import @@ -0,0 +1,4 @@ +# -*- mode: snippet -*- +# name: import +# -- +import ${1:package}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/main b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/main @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: func main() { ... } +# -- +func main() { + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/map b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/map @@ -0,0 +1,4 @@ +# -*- mode: snippet -*- +# name: map +# -- +map[${1:KeyType}]${2:ValueType}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/method b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/method @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: func (target) name(args) (results) { ... } +# -- +func (${1:target}) ${2:name}(${3:args}) (${4:results}) { + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/package b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/package @@ -0,0 +1,4 @@ +# -*- mode: snippet -*- +# name: package +# -- +package ${1:`(car (last (split-string (file-name-directory buffer-file-name) "/") 2))`}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/pkg b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/pkg @@ -0,0 +1,4 @@ +# -*- mode: snippet -*- +# name: package +# -- +package ${1:`(car (last (split-string (file-name-directory buffer-file-name) "/") 2))`}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/pr b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/pr @@ -0,0 +1,4 @@ +# -*- mode: snippet -*- +# name: printf +# -- +fmt.Printf("$1\n"${2:, ${3:str}})+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/printf b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/printf @@ -0,0 +1,4 @@ +# -*- mode: snippet -*- +# name: printf +# -- +fmt.Printf("$1\n"${2:, ${3:str}})+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/struct b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/struct @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: type ... struct { ... } +# -- +type $1 struct { + `%`$0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/switch b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/switch @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# name: switch +# key: switch +# -- +switch { + case ${1:cond}: + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/test b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/test @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: func Test...() { ... } +# -- +func Test${1:Name}(${2:t *testing.T}) { + `%`$0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/go-mode/while b/tmp/emacs-config/etc/yasnippet/snippets/go-mode/while @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name : for ... { ... } +# -- +for $1 { + `%`$0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/break b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/break @@ -0,0 +1 @@ +break _ZL12diag_message13an_error_codeP17a_source_position17an_error_severity30a_diagnostic_category_kind_tag+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/cd b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/cd @@ -0,0 +1 @@ +cd ~/Contracts/TI/bugslayer/cl_+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/const b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/const @@ -0,0 +1 @@ +(void)_Z11db_constantP10a_constant($0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/cree b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/cree @@ -0,0 +1 @@ +run --gcc -DUSE_ASCII -I/usr/local/opt/libffi/lib/libffi-3.0.11/include --llvm_file_name - ~/src/cree/test/wc.c+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/expr b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/expr @@ -0,0 +1 @@ +(void)_Z13db_expressionP12an_expr_node($0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/iar b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/iar @@ -0,0 +1 @@ +run --advice:power=all --diag_suppress=163 --ulp_standalone_mode=iar -D__IAR_SYSTEMS_ICC__ -D__TID__=11008 -D__intrinsic= -D__no_init= -D__persistent= --c iar.c+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/icd b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/icd @@ -0,0 +1 @@ +cd ~/Contracts/TI/tmp/iar+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/line b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/line @@ -0,0 +1 @@ +(a_line_number)_Z15db_line_for_seqm (pos_curr_token.seq)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/mrun b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/mrun @@ -0,0 +1 @@ +run -I../../exec/arm -Imc2_headers --check_misra=all,-5.3 --c mc2_$0.c+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/opencl b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/opencl @@ -0,0 +1 @@ +run --abi=eabi --opencl --c -I.. cl_$0.c+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/oper b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/oper @@ -0,0 +1 @@ +(void)_Z10db_operandP10an_operand($0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/operkind b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/operkind @@ -0,0 +1 @@ +(an_expr_operator_kind_tag)$0->variant.operation.kind+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/run b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/run @@ -0,0 +1 @@ +run --abi=eabi --opencl --c -I.. cl_$0.c+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/type b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/type @@ -0,0 +1 @@ +(void)_Z7db_typeP6a_type($0->type)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/ulpcd b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/ulpcd @@ -0,0 +1 @@ +cd ~/Contracts/TI/bugslayer/ulp_+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/ulprun b/tmp/emacs-config/etc/yasnippet/snippets/gud-mode/ulprun @@ -0,0 +1 @@ +run --abi=eabi --advice:power=all --remarks --c -I.. ulp_$0.c+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/.hgignore b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/.hgignore @@ -0,0 +1,7 @@ +syntax: regexp +~$ +\#.*$ +\.DS_Store +\.yas-compiled-snippets\.el$ + + diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/README.md b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/README.md @@ -0,0 +1,89 @@ +# Shnippet + + +**Shnippet** is a collection of +[YASnippet][yas] +[Haskell][haskell] snippets for Emacs. + + +## Installation + +Clone repository: + + $ cd ~/.emacs.d/snippets + $ git clone https://github.com/LukeHoersten/shnippet + OR + $ hg clone https://bitbucket.org/LukeHoersten/shnippet + +Add the cloned repository to YASnippet's `yas-snippet-dirs`: + + (setq yas-snippet-dirs + '("~/.emacs.d/snippets/shnippet" + "/other/paths/" + )) + +Snippets may have to be recompiled and reloaded in Emacs if YASnippet +is already in use: + + M-x yas-recompile-all + M-x yas-reload-all + + +Haskell snippts should now be available to use! In a `haskell-mode` +buffer, type `fn<TAB>`. A prompt should appear asking which `fn` +snippet to expand. + +I **highly** recommend using YASnippet with [ido-mode]. Configure +Emacs: + + (setq-default yas-prompt-functions '(yas-ido-prompt yas-dropdown-prompt)) + +This is important so that alternatives (like `import` vs. `import +qualified`) can quickly be selected with a single key stroke. + + +## Available Expansion Keys + +* `new` - newtype +* `mod` - module [simple, exports] +* `main ` - main module and function +* `let` - let bindings +* `lang` - language extension pragmas +* `\` - lambda function +* `inst` - instance declairation +* `imp` - import modules [simple, qualified] +* `if` - if conditional [inline, block] +* `<-` - monadic get +* `fn` - top level function [simple, guarded, clauses] +* `data` - data type definition [inline, record] +* `=>` - type constraint +* `{-` - block comment +* `case` - case statement + + +## Design Ideals + +* Keep snippet keys (the prefix used to auto-complete) to four + characters or less while still being as easy to guess as possible. + +* Have as few keys as possible. The more keys there are to remember, + the harder snippets are to use and learn. + +* Leverage [ido-mode][] when reasonable. For instance, to keep the + number of snippet keys to a minimum as well as auto complete things + like [Haskell Langauge Extension Pragmas][lang-pragma]. When + multiple snippets share a key (ex: `fn`), the `ido-mode` prompts are + unique to one character (ex: `guarded function` and `simple + function` are `g` and `s` respectively). + + +## Authors + +This code is written and maintained by Luke Hoersten, +<luke@hoersten.org>. + + +[yas]: https://github.com/capitaomorte/yasnippet +[ido-mode]: http://www.emacswiki.org/emacs/InteractivelyDoThings +[lang-pragma]: http://hackage.haskell.org/packages/archive/Cabal/1.16.0.3/doc/html/Language-Haskell-Extension.html#t:KnownExtension +[haskell]: http://haskell.org/ diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/.yas-ignore-filenames-as-triggers b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/.yas-ignore-filenames-as-triggers diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/.yas-make-groups b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/.yas-make-groups diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/case b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/case @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# key: case +# name: case +# expand-env: ((yas-indent-line 'fixed)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +case ${1:x} of + ${2:Data} -> ${4:expression} + ${3:Data} -> ${5:expression}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/comment.block b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/comment.block @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# key: {- +# name: block comment +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +{- $0 -}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/constraint b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/constraint @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# key: => +# name: Type constraint +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +(${1:Class} ${2:m}) => $0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/data.inline b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/data.inline @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# key: data +# name: inline data +# condition: (= (length "data") (current-column)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +data ${1:Type} = ${2:Data}$0 ${3:deriving (${4:Show, Eq})}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/data.record b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/data.record @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# key: data +# name: record data +# condition: (= (length "data") (current-column)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +data ${1:Type} = $1 + { ${2:field} :: ${3:Type} + , ${4:field} :: ${5:Type}$0 + } ${6:deriving (${7:Show, Eq})}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/fn b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/fn @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# key: fn +# name: simple function +# condition: (= (length "fn") (current-column)) +# expand-env: ((yas-indent-line 'fixed)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +${1:f} :: ${2:a} ${3:-> ${4:b}} +$1 ${5:x} = ${6:expression}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/fn.clause b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/fn.clause @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# key: fn +# name: clause function +# condition: (= (length "fn") (current-column)) +# expand-env: ((yas-indent-line 'fixed)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +${1:f} :: ${2:a} ${3:-> ${4:b}} +$1 ${5:pattern} = ${7:expression} +$1 ${6:pattern} = ${8:expression}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/fn.guarded b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/fn.guarded @@ -0,0 +1,11 @@ +# -*- mode: snippet -*- +# key: fn +# name: guarded function +# condition: (= (length "fn") (current-column)) +# expand-env: ((yas-indent-line 'fixed)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +${1:f} :: ${2:a} ${3:-> ${4:b}} +$1 ${5:x} + | ${6:conditional} = ${8:expression} + | ${7:conditional} = ${9:expression}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/get b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/get @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# key: <- +# name: monadic get +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +${1:x} <- ${2:expression}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/if.block b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/if.block @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# key: if +# name: block if +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +if ${1:condition} + then ${2:expression} + else ${3:expression}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/if.inline b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/if.inline @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# key: if +# name: inline if +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +if ${1:condition} then ${2:expression} else ${3:expression}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/import b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/import @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# key: imp +# name: simple import +# condition: (= (length "imp") (current-column)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +import ${1:Module} ${2:(${3:f})}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/import.qualified b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/import.qualified @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# key: imp +# name: qualified import +# condition: (= (length "imp") (current-column)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +import qualified ${1:Module} as ${2:${1:$(let ((name (car (last (split-string yas-text "\\\."))))) + (if (not (nil-blank-string name)) "" + (subseq name 0 1)))}}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/instance b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/instance @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# key: inst +# name: instance +# condition: (= (length "inst") (current-column)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +instance ${1:Class} ${2:Data} where + ${3:f} = ${4:expression}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/lambda b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/lambda @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# key: \ +# name: lambda +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +\\${1:x} -> ${2:expression}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/lang-pragma b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/lang-pragma @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# key: lang +# name: language pragma +# condition: (= (length "lang") (current-column)) +# contributor: Luke Hoersten <luke@hoersten.org>, John Wiegley +# -- +{-# LANGUAGE `(progn (require 'haskell-yas) (haskell-yas-complete "Extension: " haskell-yas-ghc-language-pragmas))` #-}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/let b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/let @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# key: let +# name: let +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +let ${1:x} = ${2:expression}$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/main b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/main @@ -0,0 +1,13 @@ +# -*- mode: snippet -*- +# key: main +# name: main module +# condition: (= (length "main") (current-column)) +# expand-env: ((yas-indent-line 'fixed)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +module Main where + +main :: IO () +main = do + ${1:expression}$0 + return ()+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/module b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/module @@ -0,0 +1,14 @@ +# -*- mode: snippet -*- +# key: mod +# name: simple module +# condition: (= (length "mod") (current-column)) +# expand-env: ((yas-indent-line 'fixed)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +module ${1:`(if (not buffer-file-name) "Module" + (let ((name (file-name-sans-extension (buffer-file-name)))) + (if (search "src/" name) + (replace-regexp-in-string "/" "." (car (last (split-string name "src/")))) + (file-name-nondirectory name))))`} where + +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/module.exports b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/module.exports @@ -0,0 +1,17 @@ +# -*- mode: snippet -*- +# key: mod +# name: exports module +# condition: (= (length "mod") (current-column)) +# expand-env: ((yas-indent-line 'fixed)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +module ${1:`(if (not buffer-file-name) "Module" + (let ((name (file-name-sans-extension (buffer-file-name)))) + (if (search "src/" name) + (replace-regexp-in-string "/" "." (car (last (split-string name "src/")))) + (file-name-nondirectory name))))`} + ( ${3:export} + ${4:, ${5:export}} + ) where + +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/newtype b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/haskell-mode/newtype @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# key: new +# name: newtype +# condition: (= (length "new") (current-column)) +# contributor: Luke Hoersten <luke@hoersten.org> +# -- +newtype ${1:Type} = $1 { un$1 :: ${2:a} } ${3:deriving (${4:Show, Eq})}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/hdr.yasnippet b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/hdr.yasnippet @@ -0,0 +1,23 @@ +# -*- mode: snippet -*- +# key: hdr +# name: haskell header +# expand-env: ((yas-indent-line 'fixed)) +# contributor: John Wiegley <johnw@newartisans.com> +# -- +{-# LANGUAGE OverloadedStrings #-} + +module `(file-name-sans-extension (buffer-name))` where + +import Control.Applicative +import Control.Monad +import Control.Monad.IO.Class +import Control.Monad.Trans.Class +import Control.Monad.Trans.Control +import Data.Maybe +import Data.Monoid + +$1 :: $0 +$1 = undefined + +main :: IO () +main = undefined+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/tr.yasnippet b/tmp/emacs-config/etc/yasnippet/snippets/haskell-mode/tr.yasnippet @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# key: tr +# name: trace +# contributor: John Wiegley <johnw@newartisans.com> +# -- +trace ("$1: " ++ show ($1)) $ + \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/js-mode/commonjs.require b/tmp/emacs-config/etc/yasnippet/snippets/js-mode/commonjs.require @@ -0,0 +1,5 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# name: commonjs.require +# key: req +# -- +var ${3:${1:$(s-lower-camel-case (file-name-nondirectory yas/text))}} = require("${1:module}")$2;$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/js-mode/es6.import b/tmp/emacs-config/etc/yasnippet/snippets/js-mode/es6.import @@ -0,0 +1,6 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# name: es6.import +# key: imp +# binding: direct-keybinding +# -- +import ${3:${1:$(s-lower-camel-case (file-name-nondirectory yas/text))}} from "${1:module}";$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.es5exportedfunction b/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.es5exportedfunction @@ -0,0 +1,6 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# name: js.exportedfunction +# key: 5xf +# -- +function $1($2) {$0}; +module.exports.$1 = $1; diff --git a/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.exportedconst b/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.exportedconst @@ -0,0 +1,5 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# name: js.exportedconst +# key: xc +# -- +export const $1 = $0; diff --git a/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.exportedfunction b/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.exportedfunction @@ -0,0 +1,7 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# name: js.exportedfunction +# key: xf +# -- +export function ${1:f}($2) { + $0 +} diff --git a/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.exportedvar b/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.exportedvar @@ -0,0 +1,5 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# name: js.exportedvar +# key: xv +# -- +var $1 = module.exports.$1 = $0; diff --git a/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.function b/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.function @@ -0,0 +1,5 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# name: js.function +# key: fn +# -- +function($1) {$0}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.generator b/tmp/emacs-config/etc/yasnippet/snippets/js-mode/js.generator @@ -0,0 +1,5 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# name: js.generator +# key: gen +# -- +function*() {$0}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/js-mode/jsdoc b/tmp/emacs-config/etc/yasnippet/snippets/js-mode/jsdoc @@ -0,0 +1,7 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# name: jsdoc +# key: jd +# -- +/** + * $0 + */+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/latex-mode/acro b/tmp/emacs-config/etc/yasnippet/snippets/latex-mode/acro @@ -0,0 +1 @@ +\newacronym{$1}{${1:$(upcase yas-text)}}{$0}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/latex-mode/code b/tmp/emacs-config/etc/yasnippet/snippets/latex-mode/code @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# key: code +# expand-env: ((yas-indent-line 'fixed)) +# -- +\begin{listing}[!ht] + \begin{minted}[frame=single,gobble=4]{coq} + $0 + \end{minted} + \caption{$1} +\end{listing}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/latex-mode/gloss b/tmp/emacs-config/etc/yasnippet/snippets/latex-mode/gloss @@ -0,0 +1,4 @@ +\newglossaryentry{$1}{ + name={$1}, + description={$0} +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/latex-mode/hafez b/tmp/emacs-config/etc/yasnippet/snippets/latex-mode/hafez @@ -0,0 +1,3 @@ +\begin{hafez}{$1}{${2:pp.~1--2}} + $0 +\end{hafez}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/case b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/case @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: case +# key: case +# -- +(case ${1:key-form} + (${2:match} ${3:result})${4: + (t ${5:otherwise})})+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/ccase b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/ccase @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: ccase +# key: ccase +# -- +(ccase ${1:key-form} + (${2:match} ${3:result}))+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/cond b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/cond @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: cond +# key: cond +# -- +(cond (${1:test} ${2:then}) + (t ${3:else}))+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/ctypecase b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/ctypecase @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: ctypecase +# key: ctypecase +# -- +(ctypecase ${1:key-form} + (${2:match} ${3:result}))+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defclass b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defclass @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defclass +# key: defclass +# -- +(defclass ${1:name} (${2:parents}) + ($0)${3: + (:documentation "${4:doc}")})+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defconstant b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defconstant @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defconstant +# key: defconstant +# -- +(defconstant +${1:name}+ ${2:nil}${3: + "${4:doc}"}) +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defgeneric b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defgeneric @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defgeneric +# key: defgeneric +# -- +(defgeneric ${1:name} (${2:args})${3: + (:documentation "${4:doc}")}) +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/define-compiler-macro b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/define-compiler-macro @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: define-compiler-macro +# key: define-compiler-macro +# -- +(define-compiler-macro ${1:name} (${2:args}) + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/define-condition b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/define-condition @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: define-condition +# key: define-condition +# -- +(define-condition ${1:name} (${2:parents}) + ($0)${3: + (:documentation "${4:doc}")})+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/define-symbol-macro b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/define-symbol-macro @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: define-symbol-macro +# key: define-symbol-macro +# -- +(define-symbol-macro ${1:name} ${2:expansion}) +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defmacro b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defmacro @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defmacro +# key: defmacro +# -- +(defmacro ${1:name} (${2:args }${3:&body body})${4: + "${5:doc}"} + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defmethod b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defmethod @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defmethod +# key: defmethod +# -- +(defmethod ${1:name} (${2:args}) + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defpackage b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defpackage @@ -0,0 +1,12 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defpackage +# key: defpackage +# -- +(defpackage :${1:package}${2: + (:nicknames ${3:nicks})}${4: + (:use ${5:packages})}${6: + (:shadow ${7:packages})}${8: + (:export ${9:packages})}${10: + (:documentation "${11:doc}")}) +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defparameter b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defparameter @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defparameter +# key: defparameter +# -- +(defparameter *${1:name}* ${2:nil}${3: + "${4:doc}"}) +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defstruct b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defstruct @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defstruct +# key: defstruct +# -- +(defstruct ${1:name}${2: + "${3:doc}"} + ($0))+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defsystem b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defsystem @@ -0,0 +1,14 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defsystem +# key: defsystem +# -- +(asdf:defsystem :${1:system}${2: + :version "${3:0.1.0}"}${4: + :description "${5:description}"}${6: + :author "${7:`user-full-name` <`user-mail-address`>}"}${8: + :serial t}${10: + :license "${11:GNU GPL, version 3}"}${12: + :components (${13:(:file "file.lisp")})}${14: + :depends-on (${15:#:alexandria})}) +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/deftype b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/deftype @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: deftype +# key: deftype +# -- +(deftype ${1:name} (${2:args})${3: + "${4:doc}"} + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defun b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defun @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defun +# key: defun +# -- +(defun ${1:name} (${2:args})${3: + "${4:doc}"} + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defvar b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/defvar @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: defvar +# key: defvar +# -- +(defvar *${1:name}*${2: nil}${3: + "${4:doc}"}) +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/destructuring-bind b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/destructuring-bind @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: destructuring-bind +# key: dbind +# -- +(destructuring-bind (${1:vars}) ${2:value} + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/do b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/do @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: do +# key: do +# -- +(do (${1:vars}) + (${2:end-test-form}${3: result}) + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/do_ b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/do_ @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: do* +# key: do* +# -- +(do* (${1:vars}) + (${2:end-test-form}${3: result}) + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/dolist b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/dolist @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: dolist +# key: dolist +# -- +(dolist (${1:var} ${2:list}${3: result}) + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/dotimes b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/dotimes @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: dotimes +# key: dotimes +# -- +(dotimes (${1:var} ${2:count}${3: result}) + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/ecase b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/ecase @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: ecase +# key: ecase +# -- +(ecase ${1:key-form} + (${2:match} ${3:result}))+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/etypecase b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/etypecase @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: etypecase +# key: etypecase +# -- +(etypecase ${1:key-form} + (${2:match} ${3:result}))+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/flet b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/flet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor: Toni Querol +# name: flet +# key: flet +# -- +(flet ((${1:name} (${2:args})${3: + "${4:doc}"} + ${5:body})) + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/format b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/format @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: format +# key: format +# -- +(format ${1:nil} ${2:str} $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/gnugpl b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/gnugpl @@ -0,0 +1,25 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: GNU GPL 3 Header +# key: gnugpl +# -- +;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; -*- +;;; +;;; ${1:description} +;;; +;;; Copyright Β© ${2:`(format-time-string "%Y")`} `user-full-name` <`user-mail-address`> +;;; +;;; ${3:This program$(prog1 yas-text (fill-paragraph))} 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. +;;; +;;; ${3:$(prog1 yas-text (fill-paragraph))} 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/>. + +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/if b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/if @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: if +# key: if +# -- +(if ${1:test} ${2:then}${3: else}) diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/in-package b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/in-package @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: in-package +# key: in-package +# -- +(in-package #:${1:package}) +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/labels b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/labels @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor: Toni Querol +# name: labels +# key: labels +# -- +(labels ((${1:name} (${2:args})${3: + "${4:doc}"} + ${5:body})) + $0)+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/let b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/let @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: let +# key: let +# -- +(let ((${1:var} ${2:val})) + $0) diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/mapc b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/mapc @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: mapc +# key: mapc +# -- +(mapc ${1:fnc} ${2:list}) +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/mapcar b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/mapcar @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: mapcar +# key: mapcar +# -- +(mapcar ${1:fnc} ${2:list}) +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/mitlic b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/mitlic @@ -0,0 +1,31 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: MIT License Header +# key: mitlic +# -- +;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; -*- +;;; +;;; ${1:description} +;;; +;;; Copyright Β© ${2:`(format-time-string "%Y")`} `user-full-name` <`user-mail-address`> +;;; +;;; 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. + +$0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/typecase b/tmp/emacs-config/etc/yasnippet/snippets/lisp-mode/typecase @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mark Karpov +# name: typecase +# key: typecase +# -- +(typecase ${1:key-form} + (${2:match} ${3:result})${4: + (t ${5:otherwise})})+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/message-mode/check b/tmp/emacs-config/etc/yasnippet/snippets/message-mode/check @@ -0,0 +1,4 @@ +Hi $1, + +On $2 you mentioned you were going to check part $3. How's it going? + diff --git a/tmp/emacs-config/etc/yasnippet/snippets/message-mode/granted b/tmp/emacs-config/etc/yasnippet/snippets/message-mode/granted @@ -0,0 +1,38 @@ +# expand-env: ((yas-indent-line 'fixed) (yas-wrap-around-region 'nil)) +# -- + +Your wish has been granted. You can commit to Emacs and GNU ELPA. Feel free to +use this power, but please try to be extra careful and prove yourself worthy +of this privilege: + +- Send your patches for review before installing them. + +- Only install changes whose code follows the usual coding conventions. Some + of those conventions are documented in http://www.gnu.org/prep/standards; + you'll discover others during code review. + +- Always provide a good commit message (copied into or from the ChangeLog for + emacs.git), following the GNU coding standards (e.g. using the + present/imperative tense, and syntax described at + http://www.gnu.org/prep/standards/html_node/Change-Logs.html), and properly + labelling the author of the code. + +- If the change is a new feature or a change in behavior, don't forget to + mention it in the etc/NEWS file and to update the Texinfo doc accordingly. + +- Be sure your change is accepted as being for the better by the package's + maintainer. As a general rule send your patch for review before installing + it, unless you're absolutely positively 200% sure that everyone will be + pleased with the content and the form of the patch. + +Last but not least: + +- And make extra sure that all the code you install has the proper copyright: + if it is not your own code, make sure the author has signed the relevant + copyright papers (for non-trivial contributions), and indicate the author + correctly in the commit (and the ChangeLog if applicable). + +If you have the slightest doubt about any of those points, send your question +or your patch to emacs-devel@gnu.org (or bug-gnu-emacs@gnu.org). + +Thank you very much for your contribution to Emacs, diff --git a/tmp/emacs-config/etc/yasnippet/snippets/message-mode/proof b/tmp/emacs-config/etc/yasnippet/snippets/message-mode/proof @@ -0,0 +1,22 @@ +The list of sections still needing to be proofread is here: + + http://ftp.newartisans.com/pub/emacs-manual.html + +If you'd like a suggestion, how about: + +| Chapter | Part | Title | Page | Length | +|---------+------+--------------------------------+------+--------| +| 24 | 17 | Compiling and Testing Programs | 277 | 20 | + +Otherwise, please pick any section(s) without a "Checked By" name, and e-mail +emacs-manual-bugs@gnu.org with the Ch/Pt numbers. I'll then add you to the +volunteered list. Once you have some edits, send them to the same list, and +I'll add you to the Checked By column for that section. + +It's OK to proofread something that's already been done, if you were hoping to +brush up on that part of the manual. It's our goal to make sure everything is +seen at least three times. + +Richard has sent instructions to many of you, but in case you haven't received +them yet, they can be found here: +https://lists.gnu.org/archive/html/help-gnu-emacs/2018-01/msg00295.html diff --git a/tmp/emacs-config/etc/yasnippet/snippets/message-mode/suggest b/tmp/emacs-config/etc/yasnippet/snippets/message-mode/suggest @@ -0,0 +1,21 @@ +Hi $1, + +I was wondering if you'd be willing to check any of these parts for us: + +| Ch | Pt | Title | Page | Len | +|----+-----+---------------------------------------------+------+-----| +| 11 | 7a | Chapter Beginning - Font Lock mode | 72 | 9 | +| 13 | 9 | Commands for Fixing Typos | 119 | 6 | +| 14 | | Keyboard Macros | 125 | 8 | +| | 10b | Reverting a Buffer - Chapter End | | 13 | +| 17 | | Multiple Windows | 167 | 7 | +| 24 | 17 | Compiling and Testing Programs | 277 | 20 | +| | 18b | Change Logs - Chapter End | | 13 | +| 28 | 21 | The Calendar and the Diary | 351 | 19 | +| 30 | 23 | Reading Mail with Rmail | 379 | 20 | +| | 26b | Customizing Key Bindings - Chapter End | | 14 | +| C | 29 | Command Line Arguments for Emacs Invocation | 507 | 15 | +| E | | Emacs 25 Antinews | 529 | 3 | +| F | 31 | Emacs and Mac OS / GNUstep | 532 | 3 | +| G | | Emacs and Microsoft Windows/MS-DOS | 535 | 10 | +| GL | 33 | Glossary | 553 | 23 | diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/appt b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/appt @@ -0,0 +1,7 @@ +#name : APPT +# -- +APPT $0 +SCHEDULED: `(with-temp-buffer (org-insert-time-stamp (current-time)))` +:PROPERTIES: +:ID: `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))` +:END:+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/assem b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/assem @@ -0,0 +1,31 @@ +* NOTE Assembly meeting agenda for `(with-temp-buffer (org-insert-time-stamp (current-time) nil t))` +:PROPERTIES: +:ID: `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))` +:OVERLAY: (face (:background "#e8f9e8")) +:END: +** Opening Prayers +** Attendance [0/9] +- [$0 ] Caroline Delaney +- [ ] Todd Zeigler +- [ ] Becky Thomas +- [ ] Pamela Fox +- [ ] Nasim Wiegley +- [ ] Beth Youker-Schwab +- [ ] Gail Hill +- [ ] Christina Stone +- [ ] John Wiegley +** Review prior minutes of [2013-01-01 Tue] +** New Business +** Outstanding business +** Upcoming events +** Secretary's report +** Feast suggestions +** Treasurer's Report +** Consultation +** Affairs of the Local Spiritual Assembly +*** P.I. Rep: Caroline +*** Center Manager: Caroline +*** Children's Education: Mary Anne, Sisi, Keith +*** Teaching Committee: Mary Anne, Christina, JohnW and Katy +*** Center Improvement Committee: Beth, Pamela +** Next Assembly meeting is [2013-01-01 Tue 00:00] diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/bbdb b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/bbdb @@ -0,0 +1,3 @@ +#name : bbdb +# -- +[[bbdb:$1][$1]] $0+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/hask b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/hask @@ -0,0 +1,2 @@ +#+begin_src haskell +$0#+end_src diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/list b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/list @@ -0,0 +1,7 @@ +#name : List NOTE +# -- +*** NOTE $1 [/] +- [ ] $0 +:PROPERTIES: +:ID: `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))` +:END:+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/note b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/note @@ -0,0 +1,6 @@ +#name : NOTE +# -- +NOTE $0 +:PROPERTIES: +:ID: `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))` +:END:+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/out b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/out @@ -0,0 +1,4 @@ +#name : :OUTPUT: ... :END: +# -- +:OUTPUT: +$0:END: diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/proj b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/proj @@ -0,0 +1,6 @@ +#name : PROJECT +# -- +PROJECT $0 +:PROPERTIES: +:ID: `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))` +:END:+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/sh b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/sh @@ -0,0 +1,2 @@ +#+begin_src sh +$0#+end_src diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/skip b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/skip @@ -0,0 +1,3 @@ +:PROPERTIES: +:BEAMER_act: <2-> +:END: diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/src b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/src @@ -0,0 +1,4 @@ +# -- +#+begin_src $1 +$0 +#+end_src diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/status b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/status @@ -0,0 +1,23 @@ +**** NOTE Status Report for `(with-temp-buffer (org-insert-time-stamp (current-time) nil t))` +:PROPERTIES: +:ID: `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))` +:END: +***** Planned and implemented + +- + +***** Not planned but implemented + +- + +***** Planned but not implemented + +- + +***** Planned for next week + +- + +***** Questions and concerns + +- None this week. diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/teach b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/teach @@ -0,0 +1,21 @@ +* NOTE Assembly meeting agenda for `(with-temp-buffer (org-insert-time-stamp (current-time) nil t))` +:PROPERTIES: +:ID: `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))` +:OVERLAY: (face (:background "#e8f9e8")) +:END: +** Opening Prayers +** Attendance [0/9] +- [$0 ] Caroline Delaney +- [ ] Sisi Mereness +- [ ] John Tempey +- [ ] Pamela Fox +- [ ] Nami Peymani +- [ ] Beth Youker-Schwab +- [ ] Gail Hill +- [ ] Christina Stone +- [ ] John Wiegley +** Not reviewing prior minutes at this meeting +** Teaching +** Consultation +** New Business +** Next Assembly meeting is [2013-01-01 Tue 00:00]+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/org-mode/todo b/tmp/emacs-config/etc/yasnippet/snippets/org-mode/todo @@ -0,0 +1,7 @@ +#name : TODO +# -- +TODO $0 +SCHEDULED: `(with-temp-buffer (org-insert-time-stamp (current-time)))` +:PROPERTIES: +:ID: `(shell-command-to-string "uuidgen")`:CREATED: `(with-temp-buffer (org-insert-time-stamp (current-time) t t))` +:END:+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/python-mode/def b/tmp/emacs-config/etc/yasnippet/snippets/python-mode/def @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# name: de +# contributor: Orestis Markou +# contributor: Yasser GonzΓ‘lez FernΓ‘ndez <yglez@uh.cu> +# contributor: Tibor Simko <tibor.simko@cern.ch> +# -- +def ${1:name}($2): + """ + $3 + ${2:$ + (let* ((indent + (concat "\n" (make-string (current-column) 32))) + (args + (mapconcat + '(lambda (x) + (if (not (string= (nth 0 x) "")) + (concat "@param " (nth 0 x) ": " indent + "@type " (nth 0 x) ": "))) + (mapcar + '(lambda (x) + (mapcar + '(lambda (x) + (replace-regexp-in-string "[[:blank:]]*$" "" + (replace-regexp-in-string "^[[:blank:]]*" "" x))) + x)) + (mapcar '(lambda (x) (split-string x "=")) + (split-string yas-text ","))) + indent))) + (if (string= args "") + (concat indent "@return: " indent "@rtype: " indent (make-string 3 34)) + (mapconcat + 'identity + (list "" args "@return: " "@rtype: " (make-string 3 34)) + indent))) + } + $0 diff --git a/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/clone b/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/clone @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: clone +# key: clone +# -- +clone(&self) -> Self { + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/default b/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/default @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: default +# key: default +# -- +default() -> Self { + ${0:Self::new()} +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/fmt b/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/fmt @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: fmt +# key: fmt +# -- +fmt(&self, f: &mut Formatter) -> Result<(), Error> { + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/impl b/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/impl @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: impl +# key: impl +# -- +impl$3 ${1:Trait} for ${2:Type}$3 { + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/implClone b/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/implClone @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# name: implClone +# key: Clone +# -- +impl$2 Clone for ${1:Type}$2 { + fn clone(&self) -> Self { + $0 + } +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/implDefault b/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/implDefault @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# name: implDefault +# key: Default +# -- +impl$2 Default for ${1:Type}$2 { + fn default() -> Self { + ${0:Self::new()} + } +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/is_empty b/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/is_empty @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: is_empty +# key: is_empty +# -- +is_empty(&self) -> bool { + ${0:self.len() == 0} +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/len b/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/len @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: len +# key: len +# -- +len(&self) -> usize { + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/new b/tmp/emacs-config/etc/yasnippet/snippets/rust-mode/new @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: new +# key: new +# -- +new() -> Self { + $0 +}+ \ No newline at end of file diff --git a/tmp/emacs-config/etc/yasnippet/snippets/text-mode/ggit b/tmp/emacs-config/etc/yasnippet/snippets/text-mode/ggit @@ -0,0 +1 @@ +https://github.com/vdemeester/$0 diff --git a/tmp/emacs-config/host/README.org b/tmp/emacs-config/host/README.org @@ -0,0 +1 @@ +Put stuff here that are local to a specific machine, those are private, aka not shared via this git repository. diff --git a/tmp/emacs-config/host/naruhodo.el b/tmp/emacs-config/host/naruhodo.el @@ -0,0 +1 @@ +../../sync/emacs/naruhodo.el+ \ No newline at end of file diff --git a/tmp/emacs-config/host/wakasu.el b/tmp/emacs-config/host/wakasu.el @@ -0,0 +1 @@ +../../sync/emacs/wakasu.el+ \ No newline at end of file diff --git a/tmp/emacs-config/index.org b/tmp/emacs-config/index.org @@ -0,0 +1,40 @@ +#+TITLE: vdemeester's .emacs.d +#+AUTHOR: Vincent Demeester +#+EMAIL: vincent@sbr.pm +#+EXPORT_EXCLUDE_TAGS: noexport +#+CREATOR: Emacs 27.0.90 (Org mode 9.3) +#+LANGUAGE: en +#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="./notes.css"/> +#+OPTIONS: html-style:nil + +#+BEGIN_QUOTE +My emacs setup is tested to work only with emacs 26.1 and newer versions. If you are on +older versions, I would recommend that you upgrade to the [[https://www.gnu.org/software/emacs/download.html][latest available stable version]]. +#+END_QUOTE + +*Warning: this repository is being /transformed/ a bit: slowly migrating to literate programming ([[./emacs.org][emacs.org]]) and most likely moving into [[https://github.com/vdemeester/home][=home=]] at some point* + +* Few notes + +- This works best in =NixOS=, coupled with my [[https://github.com/vdemeester/home][=home=]] repository (especially with my + [[https://github.com/vdemeester/home/blob/master/modules/profiles/emacs.nix][emacs.nix]] file). +- Almost all setup files have setup done as per my personal tastes and needs. +- If you want to change the default theme, font size, etc, you would want to edit + =setup-files/setup-style.el= + +* Key points + +- Use of my minor mode =vde-mode= to enable my custom key-bindings. Doing so allows me to + force override my bindings in all major and minor modes. If I ever need to try out the + default emacs bindings, I can simply disable =vde-mode= by doing =M-x vde-mode=. /It + is enabled globally by default./ +- Use of =use-package= in load all packages for faster load times. +- Use of =bind-keys= allows me to review my custom bindings in a single buffer by doing + =M-x describe-personal-keybindings=. +- Certain packages will be loaded only if you have the associated applications installed. + +* Feedback + +Use at your own risk, but I am definitely looking forward to suggestions, corrections. + +Thanks! diff --git a/tmp/emacs-config/init.el b/tmp/emacs-config/init.el @@ -0,0 +1,195 @@ +;;; init.el --- -*- lexical-binding: t -*- +;; +CheckVer +(let ((minver 26)) + (unless (>= emacs-major-version minver) + (error "Your Emacs is too old -- this configuration requires v%s or higher" minver))) + +(defconst emacs-start-time (current-time)) + +;; load early-init.el before Emacs 27.0 +(unless (>= emacs-major-version 27) + (message "Early init: Emacs Version < 27.0") + (load (expand-file-name "early-init.el" user-emacs-directory))) +;; -CheckVer + +;; Inhibit +(setq inhibit-default-init t) ; Disable the site default settings + +(setq inhibit-startup-message t + inhibit-startup-screen t) +;; -Inhibit + +;; Confirm +(setq confirm-kill-emacs #'y-or-n-p) +;; -Confirm + +;; DefaultMode +(setq initial-major-mode 'fundamental-mode + initial-scratch-message nil) +;; -DefaultMode + +;; Unicode +(prefer-coding-system 'utf-8) +(set-default-coding-systems 'utf-8) +(set-language-environment 'utf-8) +(set-selection-coding-system 'utf-8) +(set-terminal-coding-system 'utf-8) +;; -Unicode + +;;; UsePackageSetup +(require 'package) + +(setq package-archives + '(("melpa" . "http://melpa.org/packages/") + ("org" . "https://orgmode.org/elpa/") + ("gnu" . "https://elpa.gnu.org/packages/"))) + +(setq package-archive-priorities + '(("melpa" . 3) + ("org" . 2) + ("gnu" . 1))) + +(require 'tls) + +;; From https://github.com/hlissner/doom-emacs/blob/5dacbb7cb1c6ac246a9ccd15e6c4290def67757c/core/core-packages.el#L102 +(setq gnutls-verify-error (not (getenv "INSECURE")) ; you shouldn't use this + tls-checktrust gnutls-verify-error + tls-program (list "gnutls-cli --x509cafile %t -p %p %h" + ;; compatibility fallbacks + "gnutls-cli -p %p %h" + "openssl s_client -connect %h:%p -no_ssl2 -no_ssl3 -ign_eof")) + +;; Initialise the packages, avoiding a re-initialisation. +(unless (bound-and-true-p package--initialized) + (setq package-enable-at-startup nil) + (package-initialize)) + +(setq load-prefer-newer t) ; Always load newer compiled files +(setq ad-redefinition-action 'accept) ; Silence advice redefinition warnings + +;; Init `delight' +(unless (package-installed-p 'delight) + (package-refresh-contents) + (package-install 'delight)) + +;; Configure `use-package' prior to loading it. +(eval-and-compile + (setq use-package-always-ensure nil) + (setq use-package-always-defer nil) + (setq use-package-always-demand nil) + (setq use-package-expand-minimally nil) + (setq use-package-enable-imenu-support t)) + +(unless (package-installed-p 'use-package) + (package-refresh-contents) + (package-install 'use-package)) + +(eval-when-compile + (require 'use-package)) +;; -UsePackageSetup + +;; CustomFile +(defconst vde/custom-file (locate-user-emacs-file "custom.el") + "File used to store settings from Customization UI.") + +(use-package cus-edit + :config + (setq + custom-file vde/custom-file + custom-buffer-done-kill nil ; Kill when existing + custom-buffer-verbose-help nil ; Remove redundant help text + custom-unlispify-tag-names nil ; Show me the real variable name + custom-unlispify-menu-entries nil) + (unless (file-exists-p custom-file) + (write-region "" nil custom-file)) + + (load vde/custom-file 'no-error 'no-message)) +;; -CustomFile + +;; NoBuiltinOrg +(require 'cl-seq) +(setq load-path + (cl-remove-if + (lambda (x) + (string-match-p "org$" x)) + load-path)) +;; -NoBuiltinOrg + +;; PinEntry +(use-package pinentry + :config + (setenv "INSIDE_EMACS" (format "%s,comint" emacs-version)) + (pinentry-start)) +;; -PinEntry + +;; LoadCfgFunc +(defun vde/el-load-dir (dir) + "Load el files from the given folder" + (let ((files (directory-files dir nil "\.el$"))) + (while files + (load-file (concat dir (pop files)))))) + +(defun vde/short-hostname () + "Return hostname in short (aka wakasu.local -> wakasu)" + (string-match "[0-9A-Za-z-]+" system-name) + (substring system-name (match-beginning 0) (match-end 0))) +;; -LoadCfgFunc + +;; CfgConstant +(defconst *sys/gui* + (display-graphic-p) + "Are we running on a GUI Emacs ?") +(defconst *sys/linux* + (eq system-type 'gnu/linux) + "Are we running on a GNU/Linux system?") +(defconst *sys/mac* + (eq system-type 'darwin) + "Are we running on a Mac system?") +(defconst *sys/root* + (string-equal "root" (getenv "USER")) + "Are you a ROOT user?") +(defconst *nix* + (executable-find "nix") + "Do we have nix? (aka are we running in NixOS or a system using nixpkgs)") +(defconst *rg* + (executable-find "rg") + "Do we have ripgrep?") +(defconst *gcc* + (executable-find "gcc") + "Do we have gcc?") +(defconst *git* + (executable-find "git") + "Do we have git?") + +(defvar *sys/full* + (member (vde/short-hostname) '("wakasu" "naruhodo")) ; "naruhodo" <- put naruhodo back in + "Is it a full system ?") +(defvar *sys/light* + (not *sys/full*) + "Is it a light system ?") +;; -CfgConstant + +;; CfgLoad +(add-to-list 'load-path (concat user-emacs-directory "lisp/")) +(require 'init-func) +(vde/el-load-dir (concat user-emacs-directory "/config/")) +;; -CfgLoad + +;; CfgHostLoad +(if (file-exists-p (downcase (concat user-emacs-directory "/hosts/" (vde/short-hostname) ".el"))) + (load-file (downcase (concat user-emacs-directory "/hosts/" (vde/short-hostname) ".el")))) +;; -CfgHostLoad + +;; LastInit +(let ((elapsed (float-time (time-subtract (current-time) + emacs-start-time)))) + (message "Loading %s...done (%.3fs)" load-file-name elapsed)) + +(add-hook 'after-init-hook + `(lambda () + (let ((elapsed + (float-time + (time-subtract (current-time) emacs-start-time)))) + (message "Loading %s...done (%.3fs) [after-init]" + ,load-file-name elapsed))) t) +;; -LastInit diff --git a/tmp/emacs-config/lisp/gotest-ui.el b/tmp/emacs-config/lisp/gotest-ui.el @@ -0,0 +1,625 @@ +;;; gotest-ui.el --- Major mode for running go test -json + +;; Copyright 2018 Andreas Fuchs +;; Authors: Andreas Fuchs <asf@boinkor.net> + +;; URL: https://github.com/antifuchs/gotest-ui-mode +;; Created: Feb 18, 2018 +;; Keywords: languages go +;; Version: 0.1.0 +;; Package-Requires: ((emacs "25") (s "1.12.0") (gotest "0.14.0")) + +;; This file is not a 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.0, 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. + +;;; Commentary: + +;; Provides support for running go tests with a nice user interface +;; that allows folding away output, highlighting failing tests. + +;;; Code: + +(eval-when-compile + (require 'cl)) + +(require 'subr-x) +(require 'ewoc) +(require 'json) +(require 'compile) + +(defgroup gotest-ui nil + "The go test runner." + :group 'tools) + +(defface gotest-ui-pass-face '((t :foreground "green")) + "Face for displaying the status of a passing test." + :group 'gotest-ui) + +(defface gotest-ui-skip-face '((t :foreground "grey")) + "Face for displaying the status of a skipped test." + :group 'gotest-ui) + +(defface gotest-ui-fail-face '((t :foreground "pink" :weight bold)) + "Face for displaying the status of a failed test." + :group 'gotest-ui) + +(defface gotest-ui-link-face '((t :foreground "white" :weight bold)) + "Face for displaying links to go source files." + :group 'gotest-ui) + +(defcustom gotest-ui-expand-test-statuses '(fail) + "Statuses to expand test cases for. +Whenever a test enters this state, it is automatically expanded." + :group 'gotest-ui) + +(defcustom gotest-ui-test-binary '("go") + "Command list used to invoke the `go' binary." + :group 'gotest-ui) + +(defcustom gotest-ui-test-args '("test" "-json") + "Argument list used to run tests with JSON output." + :group 'gotest-ui) + +(defcustom gotest-ui-additional-test-args '() + "Additional args to pass to `go test'." + :group 'gotest-ui) + +;;;; Data model: + +(defstruct (gotest-ui-section :named + (:constructor gotest-ui-section-create) + (:type vector) + (:predicate gotest-ui-section-p)) + title tests node) + +;;; `gotest-ui-thing' is a thing that can be under test: a +;;; package, or a single test. + +(defstruct gotest-ui-thing + (name) + (node) + (expanded-p) + (status) + (buffer) ; the buffer containing this test's output + (elapsed) ; a floating-point amount of seconds + ) + +;;; `gotest-ui-test' is a single test. It contains a status and +;;; output. +(defstruct (gotest-ui-test (:include gotest-ui-thing) + (:constructor gotest-ui--make-test-1)) + (package) + (reason)) + +(defun gotest-ui-test->= (test1 test2) + "Returns true if TEST1's name sorts greater than TEST2's." + (let ((pkg1 (gotest-ui-test-package test1)) + (pkg2 (gotest-ui-test-package test2)) + (name1 (or (gotest-ui-thing-name test1) "")) + (name2 (or (gotest-ui-thing-name test2) ""))) + (if (string= pkg1 pkg2) + (string> name1 name2) + (string> pkg1 pkg2)))) + +(defstruct (gotest-ui-status (:constructor gotest-ui--make-status-1)) + (state) + (cmdline) + (dir) + (output) + (node)) + +(cl-defun gotest-ui--make-status (ewoc cmdline dir) + (let ((status (gotest-ui--make-status-1 :state 'run :cmdline (s-join " " cmdline) :dir dir))) + (let ((node (ewoc-enter-first ewoc status))) + (setf (gotest-ui-status-node status) node)) + status)) + +(cl-defun gotest-ui--make-test (ewoc &rest args &key status package name &allow-other-keys) + (apply #'gotest-ui--make-test-1 :status (or status "run") args)) + +;;; Data manipulation routines: + +(cl-defun gotest-ui-ensure-test (ewoc package-name base-name &key (status 'run)) + (let* ((test-name (format "%s.%s" package-name base-name)) + (test (gethash test-name gotest-ui--tests))) + (if test + test + (setf (gethash test-name gotest-ui--tests) + (gotest-ui--make-test ewoc :name base-name :package package-name :status status))))) + +(defun gotest-ui-update-status (new-state) + (setf (gotest-ui-status-state gotest-ui--status) new-state) + (ewoc-invalidate gotest-ui--ewoc (gotest-ui-status-node gotest-ui--status))) + +(defun gotest-ui-update-status-output (new-output) + (setf (gotest-ui-status-output gotest-ui--status) new-output) + (ewoc-invalidate gotest-ui--ewoc (gotest-ui-status-node gotest-ui--status))) + +(defun gotest-ui-ensure-output-buffer (thing) + (unless (gotest-ui-thing-buffer thing) + (with-current-buffer + (setf (gotest-ui-thing-buffer thing) + (generate-new-buffer (format " *%s" (gotest-ui-thing-name thing)))) + (setq-local gotest-ui-parse-marker (point-min-marker)) + (setq-local gotest-ui-insertion-marker (point-min-marker)) + (set-marker-insertion-type gotest-ui-insertion-marker t))) + (gotest-ui-thing-buffer thing)) + +(defun gotest-ui-mouse-open-file (event) + "In gotest-ui mode, open the file/line reference in another window." + (interactive "e") + (let ((window (posn-window (event-end event))) + (pos (posn-point (event-end event))) + file line) + (if (not (windowp window)) + (error "No file chosen")) + (with-current-buffer (window-buffer window) + (goto-char pos) + (setq file (gotest-ui-get-file-for-visit)) + (setq line (gotest-ui-get-line-for-visit))) + (unless (file-exists-p file) + (error "Could not open %s:%d" file line)) + (with-current-buffer (find-file-other-window file) + (goto-char (point-min)) + (forward-line (1- line))))) + +(defun gotest-ui-get-file-for-visit () + (get-text-property (point) 'gotest-ui-file)) + +(defun gotest-ui-get-line-for-visit () + (string-to-number (get-text-property (point) 'gotest-ui-line))) + +(defun gotest-ui-file-from-gopath (package file-basename) + (if (or (file-name-absolute-p file-basename) + (string-match-p "/" file-basename)) + file-basename + (let ((gopath (or (getenv "GOPATH") + (expand-file-name "~/go")))) + (expand-file-name (concat gopath "/src/" package "/" file-basename))))) + +(defvar gotest-ui-click-map + (let ((map (make-sparse-keymap))) + (define-key map [mouse-2] 'gotest-ui-mouse-open-file) + map)) + +(defun gotest-ui-ensure-parsed (thing) + (save-excursion + (goto-char gotest-ui-parse-marker) + (while (re-search-forward "\\([^ \t]+\\.go\\):\\([0-9]+\\)" gotest-ui-insertion-marker t) + (let* ((file-basename (match-string 1)) + (file (gotest-ui-file-from-gopath (gotest-ui-test-package thing) file-basename))) + (set-text-properties (match-beginning 0) (match-end 0) + `(face gotest-ui-link-face + gotest-ui-file ,file + gotest-ui-line ,(match-string 2) + keymap ,gotest-ui-click-map + follow-link t + )))) + (set-marker gotest-ui-parse-marker gotest-ui-insertion-marker))) + +(defun gotest-ui-update-thing-output (thing output) + (with-current-buffer (gotest-ui-ensure-output-buffer thing) + (goto-char gotest-ui-insertion-marker) + (let ((overwrites (split-string output "\r"))) + (insert (car overwrites)) + (dolist (segment (cdr overwrites)) + (let ((delete-to (point))) + (forward-line 0) + (delete-region (point) delete-to)) + (insert segment))) + (set-marker gotest-ui-insertion-marker (point)) + (gotest-ui-ensure-parsed thing))) + +;; TODO: clean up buffers on kill + +;;;; Mode definition + +(defvar gotest-ui-mode-map + (let ((m (make-sparse-keymap))) + (suppress-keymap m) + ;; key bindings go here + (define-key m (kbd "TAB") 'gotest-ui-toggle-expanded) + (define-key m (kbd "g") 'gotest-ui-rerun) + m)) + +(define-derived-mode gotest-ui-mode special-mode "go test UI" + "Major mode for running go test with JSON output." + (setq truncate-lines t) + (setq buffer-read-only t) + (setq-local line-move-visual t) + (setq show-trailing-whitespace nil) + (setq list-buffers-directory default-directory) + (make-local-variable 'text-property-default-nonsticky) + (push (cons 'keymap t) text-property-default-nonsticky)) + + +(defun gotest-ui--clear-buffer (buffer) + (let ((dir default-directory)) + (with-current-buffer buffer + (when (buffer-live-p gotest-ui--process-buffer) + (kill-buffer gotest-ui--process-buffer)) + (kill-all-local-variables) + (let ((buffer-read-only nil)) + (erase-buffer)) + (buffer-disable-undo) + (setq-local default-directory dir)))) + +(defun gotest-ui--setup-buffer (buffer name cmdline dir) + (setq-local default-directory dir) + (setq gotest-ui--cmdline cmdline + gotest-ui--dir dir) + (let ((ewoc (ewoc-create 'gotest-ui--pp-test nil nil t)) + (tests (make-hash-table :test #'equal))) + (setq gotest-ui--tests tests) + (setq gotest-ui--ewoc ewoc) + ;; Drop in the first few ewoc nodes: + (setq gotest-ui--status (gotest-ui--make-status ewoc cmdline dir)) + (gotest-ui-add-section gotest-ui--ewoc 'fail "Failed Tests:") + (gotest-ui-add-section gotest-ui--ewoc 'run "Currently Running:") + (gotest-ui-add-section gotest-ui--ewoc 'skip "Skipped:") + (gotest-ui-add-section gotest-ui--ewoc 'pass "Passed Tests:")) + ;; Set up the other buffers: + (setq gotest-ui--stderr-process-buffer (generate-new-buffer (format " *%s (stderr)" name))) + (with-current-buffer gotest-ui--stderr-process-buffer + (setq gotest-ui--ui-buffer buffer)) + (setq gotest-ui--process-buffer (generate-new-buffer (format " *%s" name))) + (with-current-buffer gotest-ui--process-buffer + (setq gotest-ui--ui-buffer buffer))) + +(defun gotest-ui-add-section (ewoc state name) + (let ((section (gotest-ui-section-create :title name :tests (list nil)))) + (setf (gotest-ui-section-node section) + (ewoc-enter-last ewoc section)) + (push (cons state section) gotest-ui--section-alist))) + +(defun gotest-ui-sort-test-into-section (test previous-state) + (let (invalidate-nodes) + (when-let ((previous-section* (and previous-state + (assoc previous-state gotest-ui--section-alist)))) + (let ((previous-section (cdr previous-section*))) + (setf (gotest-ui-section-tests previous-section) + (delete test (gotest-ui-section-tests previous-section))) + (when (null (cdr (gotest-ui-section-tests previous-section))) + (push (gotest-ui-section-node previous-section) invalidate-nodes)))) + ;; Drop the node from the buffer: + (when-let (node (gotest-ui-thing-node test)) + (let ((buffer-read-only nil)) + (ewoc-delete gotest-ui--ewoc node)) + (setf (gotest-ui-thing-node test) nil)) + + ;; Put it in the next secion: + (when-let ((section* (assoc (gotest-ui-thing-status test) + gotest-ui--section-alist))) + (let* ((section (cdr section*)) + (insertion-cons (gotest-ui-section-tests section))) + (while (and (cdr insertion-cons) + (gotest-ui-test->= test (cadr insertion-cons))) + (setq insertion-cons (cdr insertion-cons))) + (rplacd insertion-cons (cons test (cdr insertion-cons))) + (let ((insertion-node (if (car insertion-cons) + (gotest-ui-thing-node (car insertion-cons)) + (gotest-ui-section-node section)))) + (setf (gotest-ui-thing-node test) + (ewoc-enter-after gotest-ui--ewoc insertion-node test))) + (when (null (cddr (gotest-ui-section-tests section))) + (push (gotest-ui-section-node section) invalidate-nodes)))) + (unless (null invalidate-nodes) + (apply 'ewoc-invalidate gotest-ui--ewoc invalidate-nodes)) + (gotest-ui-thing-node test))) + +;;;; Commands: + +(defun gotest-ui-toggle-expanded () + "Toggle expandedness of a test/package node" + (interactive) + (let* ((node (ewoc-locate gotest-ui--ewoc (point))) + (data (ewoc-data node))) + (when (and data (gotest-ui-thing-p data)) + (setf (gotest-ui-thing-expanded-p data) + (not (gotest-ui-thing-expanded-p data))) + (ewoc-invalidate gotest-ui--ewoc node)))) + +(defun gotest-ui-rerun () + (interactive) + (gotest-ui gotest-ui--cmdline :dir gotest-ui--dir)) + +;;;; Displaying the data: + +(defvar-local gotest-ui--tests nil) +(defvar-local gotest-ui--section-alist nil) +(defvar-local gotest-ui--ewoc nil) +(defvar-local gotest-ui--status nil) +(defvar-local gotest-ui--process-buffer nil) +(defvar-local gotest-ui--stderr-process-buffer nil) +(defvar-local gotest-ui--ui-buffer nil) +(defvar-local gotest-ui--process nil) +(defvar-local gotest-ui--stderr-process nil) +(defvar-local gotest-ui--cmdline nil) +(defvar-local gotest-ui--dir nil) + +(cl-defun gotest-ui (cmdline &key dir) + (let* ((dir (or dir default-directory)) + (name (format "*go test: %s in %s" (s-join " " cmdline) dir)) + (buffer (get-buffer-create name))) + (unless (eql buffer (current-buffer)) + (display-buffer buffer)) + (with-current-buffer buffer + (let ((default-directory dir)) + (gotest-ui--clear-buffer buffer) + (gotest-ui-mode) + (gotest-ui--setup-buffer buffer name cmdline dir)) + (setq gotest-ui--stderr-process + (make-pipe-process :name (s-concat name "(stderr)") + :buffer gotest-ui--stderr-process-buffer + :sentinel #'gotest-ui--stderr-process-sentinel + :filter #'gotest-ui-read-stderr)) + (setq gotest-ui--process + (make-process :name name + :buffer gotest-ui--process-buffer + :sentinel #'gotest-ui--process-sentinel + :filter #'gotest-ui-read-stdout + :stderr gotest-ui--stderr-process + :command cmdline))))) + +(defun gotest-ui-pp-status (status) + (propertize (format "%s" status) + 'face + (case status + (fail 'gotest-ui-fail-face) + (skip 'gotest-ui-skip-face) + (pass 'gotest-ui-pass-face) + (otherwise 'default)))) + +(defun gotest-ui--pp-test-output (test) + (with-current-buffer (gotest-ui-ensure-output-buffer test) + (propertize (buffer-substring (point-min) (point-max)) + 'line-prefix "\t"))) + +(defun gotest-ui--pp-test (test) + (cond + ((gotest-ui-section-p test) + (unless (null (cdr (gotest-ui-section-tests test))) + (insert "\n" (gotest-ui-section-title test) "\n"))) + ((gotest-ui-status-p test) + (insert (gotest-ui-pp-status (gotest-ui-status-state test))) + (insert (format " %s in %s\n\n" + (gotest-ui-status-cmdline test) + (gotest-ui-status-dir test))) + (unless (zerop (length (gotest-ui-status-output test))) + (insert (format "\n\n%s" (gotest-ui-status-output test))))) + ((gotest-ui-test-p test) + (let ((status (gotest-ui-thing-status test)) + (package (gotest-ui-test-package test)) + (name (gotest-ui-thing-name test))) + (insert (gotest-ui-pp-status status)) + (insert " ") + (insert (if name + (format "%s.%s" package name) + package)) + (when-let ((elapsed (gotest-ui-thing-elapsed test))) + (insert (format " (%.3fs)" elapsed))) + (when-let ((reason (gotest-ui-test-reason test))) + (insert (format " [%s]" reason)))) + (when (and (gotest-ui-thing-expanded-p test) + (> (length (gotest-ui--pp-test-output test)) 0)) + (insert "\n") + (insert (gotest-ui--pp-test-output test))) + (insert "\n")))) + +;;;; Handling input: + +(defun gotest-ui--process-sentinel (proc event) + (let* ((process-buffer (process-buffer proc)) + (ui-buffer (with-current-buffer process-buffer gotest-ui--ui-buffer)) + (inhibit-quit t)) + (with-local-quit + (with-current-buffer ui-buffer + (cond + ((string= event "finished\n") + (gotest-ui-update-status 'pass)) + ((s-prefix-p "exited abnormally" event) + (gotest-ui-update-status 'fail)) + (t + (gotest-ui-update-status event))))))) + +(defun gotest-ui--stderr-process-sentinel (proc event) + ;; ignore all events + nil) + +(defun gotest-ui-read-stderr (proc input) + (let* ((process-buffer (process-buffer proc)) + (ui-buffer (with-current-buffer process-buffer gotest-ui--ui-buffer)) + (inhibit-quit t)) + (with-local-quit + (when (buffer-live-p process-buffer) + (with-current-buffer process-buffer + (gotest-ui-read-compiler-spew proc process-buffer ui-buffer input)))))) + +(defun gotest-ui-read-stdout (proc input) + (let* ((process-buffer (process-buffer proc)) + (ui-buffer (with-current-buffer process-buffer gotest-ui--ui-buffer)) + (inhibit-quit t)) + (with-local-quit + (when (buffer-live-p process-buffer) + (gotest-ui-read-json process-buffer (process-mark proc) input))))) + +(defun gotest-ui-read-json (process-buffer marker input) + (with-current-buffer process-buffer + (gotest-ui-read-json-1 process-buffer marker gotest-ui--ui-buffer input))) + +(defvar-local gotest-ui--current-failing-test nil) + +(defun gotest-ui-read-failing-package (ui-buffer) + (when (looking-at "^# \\(.*\\)$") + (let* ((package (match-string 1)) + test) + (with-current-buffer ui-buffer + (setq test (gotest-ui-ensure-test gotest-ui--ewoc package nil :status 'fail)) + (gotest-ui-maybe-expand test) + (gotest-ui-sort-test-into-section test nil)) + (forward-line 1) + test))) + +(defun gotest-ui-read-compiler-spew (proc process-buffer ui-buffer input) + (with-current-buffer process-buffer + (save-excursion + (goto-char (point-max)) + (insert input) + (goto-char (process-mark proc)) + (while (and (/= (point-max) (line-end-position)) ; incomplete line + (/= (point-max) (point))) + (cond + (gotest-ui--current-failing-test + (cond + ((looking-at "^# \\(.*\\)$") + (gotest-ui-read-failing-package ui-buffer)) + (t + (let* ((line (buffer-substring (point) (line-end-position))) + (test gotest-ui--current-failing-test)) + (forward-line 1) + (set-marker (process-mark proc) (point)) + (with-current-buffer ui-buffer + (gotest-ui-update-thing-output test (concat line "\n")) + (ewoc-invalidate gotest-ui--ewoc (gotest-ui-thing-node test))))))) + (t + (let ((test (gotest-ui-read-failing-package ui-buffer))) + (setq gotest-ui--current-failing-test test) + (set-marker (process-mark proc) (point)) + (with-current-buffer ui-buffer + (ewoc-invalidate gotest-ui--ewoc (gotest-ui-thing-node test)))))))))) + +(defun gotest-ui-read-json-1 (process-buffer marker ui-buffer input) + (with-current-buffer process-buffer + (save-excursion + ;; insert the chunk of output at the end + (goto-char (point-max)) + (insert input) + + ;; try to read the next object (which is hopefully complete now): + (let ((nodes + (cl-loop + for (node . continue) = (gotest-ui-read-test-event process-buffer marker ui-buffer) + when node collect node into nodes + while continue + finally (return nodes)))) + (when nodes + (with-current-buffer ui-buffer + (apply #'ewoc-invalidate gotest-ui--ewoc + (cl-remove-if-not (lambda (node) (marker-buffer (ewoc-location node))) (cl-remove-duplicates nodes))))))))) + +(defun gotest-ui-read-test-event (process-buffer marker ui-buffer) + (goto-char marker) + (when (= (point) (line-end-position)) + (forward-line 1)) + (case (char-after (point)) + (?\{ + ;; It's JSON: + (condition-case err + (let ((obj (json-read))) + (set-marker marker (point)) + (with-current-buffer ui-buffer + (cons (gotest-ui-update-test-status obj) t))) + (json-error (cons nil nil)) + (wrong-type-argument + (if (and (eql (cadr err) 'characterp) + (eql (caddr err) :json-eof)) + ;; This is peaceful & we can ignore it: + (cons nil nil) + (signal 'wrong-type-argument err))))) + (?\F + ;; It's a compiler error: + (when (looking-at "^FAIL\t\\(.*\\)\s+\\[\\([^]]+\\)\\]\n") + (let* ((package-name (match-string 1)) + (reason (match-string 2)) + test node) + (with-current-buffer ui-buffer + (setq test (gotest-ui-ensure-test gotest-ui--ewoc package-name nil :status 'fail) + node (gotest-ui-thing-node test)) + (setf (gotest-ui-test-reason test) reason) + (gotest-ui-sort-test-into-section test nil) + (gotest-ui-maybe-expand test)) + (forward-line 1) + (set-marker marker (point)) + (cons node t)))) + (otherwise + ;; We're done: + (cons nil nil)))) + +(defun gotest-ui-maybe-expand (test) + (when (memq (gotest-ui-test-status test) gotest-ui-expand-test-statuses) + (setf (gotest-ui-test-expanded-p test) t))) + +(defun gotest-ui-update-test-status (json) + (let-alist json + (let* ((action (intern .Action)) + (test (gotest-ui-ensure-test gotest-ui--ewoc .Package .Test)) + (previous-status (gotest-ui-thing-status test))) + (case action + (run + (gotest-ui-sort-test-into-section test nil)) + (output (gotest-ui-update-thing-output test .Output)) + (pass + (setf (gotest-ui-thing-status test) 'pass + (gotest-ui-thing-elapsed test) .Elapsed) + (gotest-ui-sort-test-into-section test previous-status) + (gotest-ui-maybe-expand test)) + (fail + (setf (gotest-ui-thing-status test) 'fail + (gotest-ui-thing-elapsed test) .Elapsed) + (gotest-ui-sort-test-into-section test previous-status) + (gotest-ui-maybe-expand test)) + (skip + (setf (gotest-ui-thing-status test) 'skip + (gotest-ui-thing-elapsed test) .Elapsed) + (gotest-ui-sort-test-into-section test previous-status) + (gotest-ui-maybe-expand test)) + (otherwise + (setq test nil))) + (when test (gotest-ui-thing-node test))))) + +;;;; Commands for go-mode: + +(defun gotest-ui--command-line (&rest cmdline) + (append gotest-ui-test-binary gotest-ui-test-args gotest-ui-additional-test-args + cmdline)) + +;;;###autoload +(defun gotest-ui-current-test () + "Launch go test with the test that (point) is in." + (interactive) + (cl-destructuring-bind (test-suite test-name) (go-test--get-current-test-info) + (let ((test-flag (if (> (length test-suite) 0) "-m" "-run"))) + (when test-name + (gotest-ui (gotest-ui--command-line test-flag (s-concat test-name "$") ".")))))) + +;;;###autoload +(defun gotest-ui-current-file () + "Launch go test on the current buffer file." + (interactive) + (let* ((data (go-test--get-current-file-testing-data)) + (run-flag (s-concat "-run=" data "$"))) + (gotest-ui (gotest-ui--command-line run-flag ".")))) + +;;;###autoload +(defun gotest-ui-current-project () + "Launch go test on the current buffer's project." + (interactive) + (let ((default-directory (projectile-project-root))) + (gotest-ui (gotest-ui--command-line "./...")))) + +(provide 'gotest-ui) + +;;; gotest-ui.el ends here diff --git a/tmp/emacs-config/lisp/init-func.el b/tmp/emacs-config/lisp/init-func.el @@ -0,0 +1,53 @@ +;;; init-func.el --- -*- lexical-binding: t -*- +;; +;; OrgIncludeAuto +;; https://endlessparentheses.com/updating-org-mode-include-statements-on-the-fly.html +(defun save-and-update-includes () + "Update the line numbers of #+INCLUDE:s in current buffer. +Only looks at INCLUDEs that have either :range-begin or :range-end. +This function does nothing if not in `org-mode', so you can safely +add it to `before-save-hook'." + (interactive) + (when (derived-mode-p 'org-mode) + (save-excursion + (goto-char (point-min)) + (while (search-forward-regexp + "^\\s-*#\\+INCLUDE: *\"\\([^\"]+\\)\".*:range-\\(begin\\|end\\)" + nil 'noerror) + (let* ((file (expand-file-name (match-string-no-properties 1))) + lines begin end) + (forward-line 0) + (when (looking-at "^.*:range-begin *\"\\([^\"]+\\)\"") + (setq begin (match-string-no-properties 1))) + (when (looking-at "^.*:range-end *\"\\([^\"]+\\)\"") + (setq end (match-string-no-properties 1))) + (setq lines (decide-line-range file begin end)) + (when lines + (if (looking-at ".*:lines *\"\\([-0-9]+\\)\"") + (replace-match lines :fixedcase :literal nil 1) + (goto-char (line-end-position)) + (insert " :lines \"" lines "\"")))))))) + +(add-hook 'before-save-hook #'save-and-update-includes) + +(defun decide-line-range (file begin end) + "Visit FILE and decide which lines to include. +BEGIN and END are regexps which define the line range to use." + (let (l r) + (save-match-data + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (if (null begin) + (setq l "") + (search-forward-regexp begin) + (setq l (line-number-at-pos (match-beginning 0)))) + (if (null end) + (setq r "") + (search-forward-regexp end) + (setq r (1+ (line-number-at-pos (match-end 0))))) + (format "%s-%s" (+ l 1) (- r 1)))))) ;; Exclude wrapper +;; -OrgIncludeAuto + +(provide 'init-func) +;;; init-func.el ends here diff --git a/tmp/emacs-config/lisp/ol-github.el b/tmp/emacs-config/lisp/ol-github.el @@ -0,0 +1,67 @@ +;;; ol-github.el --- Links to GitHub -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 Vincent Demeester + +;; Author: Vincent Demeester <vincent@sbr.pm> +;; Keywords: org link github +;; +;; 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.0, 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: + +;; This file implements links to GitHub from within Org mode. +;; gh:tektoncd/pipeline : project +;; gh:tektoncd/pipeline#1 : issue or pr #1 + +;;; Code: + +(require 'ol) + +;; Install the link type +(org-link-set-parameters "gh" + :follow #'org-github-follow-link + :export #'org-github-export + :face '(:foreground "DimGrey" :underline t)) + + +(defun org-github-export (link description format) + "Export a github page link from Org files." + (let ((path (org-github-get-url link)) + (desc (or description link))) + (cond + ((eq format 'html) (format "<a hrefl=\"_blank\" href=\"%s\">%s</a>" path desc)) + ((eq format 'latex) (format "\\href{%s}{%s}" path desc)) + ((eq format 'texinfo) (format "@uref{%s,%s}" path desc)) + ((eq format 'ascii) (format "%s (%s)" desc path)) + (t path)))) + +(defun org-github-follow-link (issue) + "Browse github issue/pr specified." + (browse-url (org-github-get-url issue))) + +(defun org-github-get-url (path) + "Translate org-mode link `gh:foo/bar#1' to github url." + (setq expressions (split-string path "#")) + (setq project (nth 0 expressions)) + (setq issue (nth 1 expressions)) + (if issue + (format "https://github.com/%s/issues/%s" project issue) + (format "https://github.com/%s" project))) + +(provide 'ol-github) +;;; ol-github.el ends here diff --git a/tmp/emacs-config/lisp/ol-gitlab.el b/tmp/emacs-config/lisp/ol-gitlab.el @@ -0,0 +1,78 @@ +;;; ol-gitlab.el --- Links to Gitlab -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 Vincent Demeester + +;; Author: Vincent Demeester <vincent@sbr.pm> +;; Keywords: org link gitlab +;; +;; 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.0, 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: + +;; This file implements links to Gitlab from within Org mode. +;; gl:vdemeester/emacs-config : project +;; gl:vdemeester/emacs-config#1 : issue #1 +;; gl:vdemeester/emacs-config##1 : merge-request #1 + +;;; Code: + +(require 'ol) + +;; Install the link type +(org-link-set-parameters "gl" + :follow #'org-gitlab-follow-link + :export #'org-gitlab-export + :face '(:foreground "DimGrey" :underline t)) + + +(defun org-gitlab-export (link description format) + "Export a gitlab page link from Org files." + (let ((path (org-gitlab-get-url link)) + (desc (or description link))) + (cond + ((eq format 'html) (format "<a hrefl=\"_blank\" href=\"%s\">%s</a>" path desc)) + ((eq format 'latex) (format "\\href{%s}{%s}" path desc)) + ((eq format 'texinfo) (format "@uref{%s,%s}" path desc)) + ((eq format 'ascii) (format "%s (%s)" desc path)) + (t path)))) + +(defun org-gitlab-follow-link (issue) + "Browse gitlab issue/pr specified." + (browse-url (org-gitlab-get-url issue))) + +(defun org-gitlab-get-url (path) + "Translate org-mode link `gh:foo/bar#1' to gitlab url." + (setq expressions (split-string path "#")) + (setq project (nth 0 expressions)) + (setq issue (nth 1 expressions)) + (setq mr (nth 2 expressions)) + (message (format "issue: %s" issue)) + (message (format "mr: %s" mr)) + (if (not (empty-string-p mr)) + (format "https://gitlab.com/%s/-/merge_requests/%s" project mr) + (if (not (empty-string-p issue)) + (format "https://gitlab.com/%s/-/issues/%s" project issue) + (format "https://gitlab.com/%s" project)))) + +(defun empty-string-p (string) + "Return true if the STRING is empty or nil. Expects string type." + (or (null string) + (zerop (length (string-trim string))))) + +(provide 'ol-gitlab) +;;; ol-gitlab.el ends here diff --git a/tmp/emacs-config/lisp/ol-grep.el b/tmp/emacs-config/lisp/ol-grep.el @@ -0,0 +1,54 @@ +;;; ol-grep.el --- Links to Grep -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 Vincent Demeester + +;; Author: Vincent Demeester <vincent@sbr.pm> +;; Keywords: org link grep +;; +;; 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.0, 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: + +;; This file implements links to Grep from within Org mode. +;; grep:orgmode : run grep on current working dir with orgmode expression +;; grep:orgmode:config/ : run grep on config/ dir with orgmode expression + +;;; Code: + +(require 'ol) + +;; Install the link type +(org-link-set-parameters "rg" + :follow #'org-grep-follow-link + :face '(:foreground "DarkRed" :underline t)) + +(defun org-grep-follow-link (issue) + "Run `rgrep' with REGEXP and FOLDER as argument, +like this : [[grep:REGEXP:FOLDER]]." + (setq expressions (split-string regexp ":")) + (setq exp (nth 0 expressions)) + (grep-compute-defaults) + (if (= (length expressions) 1) + (progn + (rgrep exp "*" (expand-file-name "./"))) + (progn + (setq folder (nth 1 expressions)) + (rgrep exp "*" (expand-file-name folder))))) + +(provide 'ol-grep) +;;; ol-grep.el ends here diff --git a/tmp/emacs-config/lisp/ol-ripgrep.el b/tmp/emacs-config/lisp/ol-ripgrep.el @@ -0,0 +1,53 @@ +;;; ol-ripgrep.el --- Links to Ripgrep -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 Vincent Demeester + +;; Author: Vincent Demeester <vincent@sbr.pm> +;; Keywords: org link ripgrep +;; +;; 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.0, 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. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: + +;; This file implements links to Ripgrep from within Org mode. +;; rg:orgmode : run ripgrep on current working dir with orgmode expression +;; rg:orgmode:config/ : run ripgrep on config/ dir with orgmode expression + +;;; Code: + +(require 'ol) + +;; Install the link type +(org-link-set-parameters "rg" + :follow #'org-ripgrep-follow-link + :face '(:foreground "DarkGreen" :underline t)) + +(defun org-ripgrep-follow-link (issue) + "Run `ripgrep-regexp` with REXEP and FOLDER as argument, +like this : [[pt:REGEXP:FOLDER]]" + (setq expressions (split-string regexp ":")) + (setq exp (nth 0 expressions)) + (if (= (length expressions) 1) + (progn + (ripgrep-regexp exp (expand-file-name "./"))) + (progn + (setq folder (nth 1 expressions)) + (ripgrep-regexp exp (file-name-as-directory (expand-file-name folder)))))) + +(provide 'ol-ripgrep) +;;; ol-ripgrep.el ends here diff --git a/tmp/emacs-config/lisp/shortbrain-light-theme.el b/tmp/emacs-config/lisp/shortbrain-light-theme.el @@ -0,0 +1,272 @@ +;;; shortbrain-light-theme.el --- A calm, light, almost monochrome color theme based on emacs-shortbrain-theme. + +;; Copyright (C) 2020 Vincent Demeester <vincent@sbr.pm> + +;; Author: Vincent Demeester <vincent@sbr.pm> +;; Keywords: themes +;; URL: https://github.com/vdemeester/emacs-config +;; Version: 2020.03 +;; Package-Requires: ((emacs "24.1")) + +;; 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: + +;; To use the shortbrain-light theme, add the following to your Emacs +;; configuration file: +;; +;; (load-theme 'shortbrain-light) +;; +;; Requirements: Emacs 24. + +;;; Code: + + +(deftheme shortbrain-light "A calm, light, almost monochrome color theme") + + +(defconst shortbrain-light-theme-colors + '(;; Basics + (white . "#ffffff") + + ;; Greys + (default-grey . "#0f1619") + (grey . "#0f1619") + (grey-50 . "#fdfdfe") + (grey-100 . "#f5f8fa") + (grey-200 . "#d8dcde") + (grey-300 . "#bcc0c2") + (grey-400 . "#9fa3a6") + (grey-500 . "#9fa3a6") + (grey-600 . "#656b6e") + (grey-700 . "#494f52") + (grey-720 . "#474d50") + (grey-800 . "#2c3236") + (grey-820 . "#1e2428") + (grey-850 . "#1d2226") + (grey-900 . "#0f1619") + + ;; Primaries + (default-primary . "#0be5e5") + (primary . "#0be5e5") + (primary-50 . "#f3fefe") + (primary-100 . "#d4fafa") + (primary-200 . "#91f3f3") + (primary-300 . "#4eecec") + (primary-400 . "#0be5e5") + (primary-500 . "#09cccc") + (primary-600 . "#07b3b3") + (primary-700 . "#059999") + (primary-800 . "#028080") + (primary-900 . "#006666") + + ;; Greens + (default-green . "#0be541") + (green . "#0be441") + (green-50 . "#e7feec") + (green-100 . "#b6fcc7") + (green-200 . "#85f9a2") + (green-300 . "#3cf66b") + (green-400 . "#0be441") + (green-500 . "#0adb3f") + (green-600 . "#09c338") + (green-700 . "#08aa31") + (green-800 . "#07922a") + (green-900 . "#067a23") + + ;; Reds + (default-red. "#f24965") + (red . "#f24965") + (danger . "#f24965") + (red-50 . "#fff0f2") + (red-100 . "#ffd9df") + (red-200 . "#fba9b6") + (red-300 . "#f6798e") + (red-400 . "#f24965") + (red-500 . "#d6455d") + (red-600 . "#ba4054") + (red-700 . "#9e3c4c") + (red-800 . "#823743") + (red-900 . "#66333b") + + ;; Purples + (purple . "#b965e8"))) + + +(defun shortbrain-light-theme-color (name) + "Return the shortbrain-light theme color with the given NAME." + (cdr (assoc name shortbrain-light-theme-colors))) + + +(let ((class '((class color) (min-colors 256))) + (default-fg (shortbrain-light-theme-color 'grey-900)) + (default-bg (shortbrain-light-theme-color 'grey-50)) + (inactive-bg (shortbrain-light-theme-color 'grey-200)) + (minor-fg (shortbrain-light-theme-color 'grey-200)) + (minor-bg (shortbrain-light-theme-color 'grey-50)) + (inactive-fg (shortbrain-light-theme-color 'grey-600)) + (border-fg (shortbrain-light-theme-color 'grey-200)) + (frame-fg (shortbrain-light-theme-color 'grey-500)) + (cursor-fg (shortbrain-light-theme-color 'grey-900)) + (cursor-bg (shortbrain-light-theme-color 'grey-300)) + + ;; Scrollbars + (scrollbar-fg (shortbrain-light-theme-color 'grey-600)) + (scrollbar-bg (shortbrain-light-theme-color 'grey-100)) + + ;; Highlighting + (highlight-fg (shortbrain-light-theme-color 'white)) + (highlight-bg (shortbrain-light-theme-color 'red)) + + ;; Current line + (hl-line-bg (shortbrain-light-theme-color 'grey-100)) + + ;; Search + (search-fg (shortbrain-light-theme-color 'white)) + (search-bg (shortbrain-light-theme-color 'primary-600)) + (search-bg-0 (shortbrain-light-theme-color 'primary-500)) + (search-bg-1 (shortbrain-light-theme-color 'primary-400)) + (search-bg-2 (shortbrain-light-theme-color 'primary-300)) + (search-bg-3 (shortbrain-light-theme-color 'primary-100)) + + ;; Selection + (selection-bg (shortbrain-light-theme-color 'grey-200)) + + ;; Auto-completion + (completion-fg (shortbrain-light-theme-color 'grey-500)) + (completion-bg (shortbrain-light-theme-color 'grey-800)) + (completion-match-fg (shortbrain-light-theme-color 'red-500)) + (completion-mouse-fg (shortbrain-light-theme-color 'white)) + (completion-selection-fg (shortbrain-light-theme-color 'red-500)) + (completion-selection-bg (shortbrain-light-theme-color 'grey-200)) + (completion-annotation-fg (shortbrain-light-theme-color 'red-400)) + + ;; Warnings & errors + (warning-fg (shortbrain-light-theme-color 'white)) + (warning-bg (shortbrain-light-theme-color 'red-600)) + (error-fg (shortbrain-light-theme-color 'white)) + (error-bg (shortbrain-light-theme-color 'red)) + + ;; Org + (org-color-1 (shortbrain-light-theme-color 'green-900)) + (org-color-2 (shortbrain-light-theme-color 'purple)) + (org-color-3 (shortbrain-light-theme-color 'primary-700)) + (org-color-4 (shortbrain-light-theme-color 'primary-500)) + (org-color-5 (shortbrain-light-theme-color 'primary-400)) + (org-meta-fg (shortbrain-light-theme-color 'primary-900)) + + ;; Language syntax highlighting + (variable-fg (shortbrain-light-theme-color 'black)) + (function-fg (shortbrain-light-theme-color 'grey-900)) + (type-fg (shortbrain-light-theme-color 'grey-700)) + (constant-fg (shortbrain-light-theme-color 'grey-600)) + (keyword-fg (shortbrain-light-theme-color 'grey-500)) + (builtin-fg (shortbrain-light-theme-color 'grey-400)) + (string-fg (shortbrain-light-theme-color 'grey-600)) + (doc-fg (shortbrain-light-theme-color 'primary-600)) + (doc-bg (shortbrain-light-theme-color 'grey-50))) + (custom-theme-set-faces + 'shortbrain-light + ;; Regular + `(cursor ((,class (:foreground ,cursor-fg :background ,cursor-bg)))) + `(default ((,class (:foreground ,default-fg :background ,default-bg)))) + `(default-italic ((,class (:italic t)))) + + ;; Emacs UI + `(fringe ((,class (:foreground ,error-fg :background ,default-bg)))) + `(header-line ((,class :background ,default-bg))) + `(linum ((,class (:inherit shadow :background ,default-bg)))) + `(mode-line ((,class (:foreground ,frame-fg :background ,default-bg + :box (:line-width -1 :color ,default-bg))))) + `(mode-line-inactive ((,class (:foreground ,inactive-fg :background ,inactive-bg + :box (:line-width -1 :color ,inactive-bg))))) + `(nlinum-relative-current-face ((,class (:foreground ,frame-fg :background ,default-bg)))) + `(vertical-border ((,class (:foreground ,border-fg :background ,default-bg)))) + + ;; Highlighting + `(highlight ((,class (:foreground ,highlight-fg :background ,highlight-bg)))) + `(hl-line ((,class (:background ,hl-line-bg)))) + + ;; Search + `(isearch ((,class (:foreground ,search-fg :background ,search-bg :weight bold)))) + `(lazy-highlight ((,class (:foreground ,highlight-fg :background ,highlight-bg) :weight normal))) + + ;; Selection + `(region ((,class (:background ,selection-bg)))) + + ;; Erroneous whitespace + `(whitespace-line ((,class (:foreground ,error-fg :background ,error-bg)))) + `(whitespace-space ((,class (:foreground ,builtin-fg :background ,hl-line-bg)))) + `(whitespace-tab ((,class (:foreground ,builtin-fg :background ,hl-line-bg)))) + + ;; Language syntax highlighting + `(font-lock-builtin-face ((,class (:foreground ,builtin-fg)))) + `(font-lock-comment-face ((,class (:foreground ,doc-fg :background ,doc-bg)))) + `(font-lock-comment-delimiter-face ((,class (:foreground ,minor-fg, :background ,minor-bg)))) + `(font-lock-constant-face ((,class (:foreground ,constant-fg)))) + `(font-lock-doc-face ((,class (:foreground ,doc-fg)))) + `(font-lock-function-name-face ((,class (:foreground ,function-fg)))) + `(font-lock-keyword-face ((,class (:foreground ,keyword-fg)))) + `(font-lock-negation-char-face ((,class (:foreground ,error-fg)))) + `(font-lock-preprocessor-face ((,class (:foreground ,builtin-fg)))) + `(font-lock-string-face ((,class (:foreground ,string-fg)))) + `(font-lock-type-face ((,class (:foreground ,type-fg)))) + `(font-lock-variable-name-face ((,class (:foreground ,variable-fg)))) + `(font-lock-warning-face ((,class (:foreground ,warning-fg :background ,warning-bg)))) + + ;; Org + `(org-level-1 ((,class (:foreground ,org-color-1 :bold t :height 1.2)))) + `(org-level-2 ((,class (:foreground ,org-color-2 :bold t :height 1.1)))) + `(org-level-3 ((,class (:foreground ,org-color-3 :bold t :height 1.0)))) + `(org-level-4 ((,class (:foreground ,org-color-4 :bold t :height 1.0)))) + `(org-level-5 ((,class (:foreground ,org-color-5 :bold t :height 1.0)))) + `(org-level-6 ((,class (:foreground ,org-color-5 :bold t :height 1.0)))) + `(org-document-title ((,class (:bold t :foreground ,org-meta-fg :height 1.4)))) + `(org-meta-line ((,class (:foreground ,org-meta-fg :bold t)))) + + ;; Avy + `(avy-lead-face ((,class (:background ,search-bg-0 :foreground ,search-fg)))) + `(avy-lead-face-0 ((,class (:background ,search-bg-1 :foreground ,search-fg)))) + `(avy-lead-face-1 ((,class (:background ,search-bg-2 :foreground ,search-fg)))) + `(avy-lead-face-2 ((,class (:background ,search-bg-3 :foreground ,search-fg)))) + + ;; Company (auto-completion) + `(company-preview ((,class (:background ,default-bg :foreground ,completion-match-fg)))) + `(company-preview-common ((,class (:background ,completion-bg :foreground ,completion-fg)))) + `(company-preview-search ((,class (:background ,completion-bg :foreground ,completion-fg)))) + `(company-scrollbar-bg ((,class (:background ,scrollbar-bg)))) + `(company-scrollbar-fg ((,class (:background ,scrollbar-fg)))) + `(company-tooltip ((,class (:background ,completion-bg :foreground ,completion-fg)))) + `(company-tooltip-annotation ((,class (:foreground ,completion-annotation-fg)))) + `(company-tooltip-common ((,class (:background nil :foreground ,completion-match-fg)))) + `(company-tooltip-common-selection ((,class (:foreground ,completion-selection-fg + :background ,completion-selection-bg)))) + `(company-tooltip-mouse ((,class (:background ,selection-bg :foreground ,completion-mouse-fg)))) + `(company-tooltip-search ((,class (:foreground ,completion-match-fg)))) + `(company-tooltip-selection ((,class (:background ,selection-bg :foreground nil)))))) + + +;;;###autoload +(when (and (boundp 'custom-theme-load-path) + load-file-name) + ;; add theme folder to `custom-theme-load-path' when installing over MELPA + (add-to-list 'custom-theme-load-path + (file-name-as-directory (file-name-directory load-file-name)))) + + +(provide-theme 'shortbrain-light) +(provide 'shortbrain-light-theme) + + +;;; shortbrain-light-theme.el ends here diff --git a/tmp/emacs-config/lisp/shortbrain-theme.el b/tmp/emacs-config/lisp/shortbrain-theme.el @@ -0,0 +1,235 @@ +;;; shortbrain-theme.el --- A calm, dark, almost monochrome color theme based on emacs-constant-theme + +;; Copyright (C) 2020 Vincent Demeester <vincent@sbr.pm> + +;; Author: Vincent Demeester <vincent@sbr.pm> +;; Keywords: themes +;; URL: https://github.com/vdemeester/emacs-config +;; Version: 2020:03 +;; Package-Requires: ((emacs "24.1")) + +;; 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: + +;; To use the shortbrain theme, add the following to your Emacs +;; configuration file: +;; +;; (load-theme 'shortbrain) +;; +;; Requirements: Emacs 24. + +;;; Code: + + +(deftheme shortbrain "A calm, dark, almost monochrome theme") + +(defconst shortbrain-theme-colors + '(;; Basics + (white . "#ffffff") + + ;; Shades of grey + (default-grey . "#0f1619") + (grey . "#0f1619") + (grey-50 . "#fdfdfe") + (grey-100 . "#f5f8fa") + (grey-200 . "#d8dcde") + (grey-300 . "#bcc0c2") + (grey-400 . "#9fa3a6") + (grey-500 . "#9fa3a6") + (grey-600 . "#656b6e") + (grey-700 . "#494f52") + (grey-720 . "#474d50") + (grey-800 . "#2c3236") + (grey-820 . "#1e2428") + (grey-850 . "#1d2226") + (grey-900 . "#0f1619") + + ;; Priary color shades + (default-primary . "#0be5e5") + (primary . "#0be5e5") + (primary-50 . "#f3fefe") + (primary-100 . "#d4fafa") + (primary-200 . "#91f3f3") + (primary-300 . "#4eecec") + (primary-400 . "#0be5e5") + (primary-500 . "#09cccc") + (primary-600 . "#07b3b3") + (primary-700 . "#059999") + (primary-800 . "#028080") + (primary-900 . "#006666") + + ;; Reds + (default-red. "#f24965") + (red . "#f24965") + (danger . "#f24965") + (red-50 . "#fff0f2") + (red-100 . "#ffd9df") + (red-200 . "#fba9b6") + (red-300 . "#f6798e") + (red-400 . "#f24965") + (red-500 . "#d6455d") + (red-600 . "#ba4054") + (red-700 . "#9e3c4c") + (red-800 . "#823743") + (red-900 . "#66333b") + + ;; Purples + (purple . "#b965e8"))) + + +(defun shortbrain-theme-color (name) + "Return the shortbrain theme color with the given NAME." + (cdr (assoc name shortbrain-theme-colors))) + + +(let ((class '((class color) (min-colors 256))) + (default-fg (shortbrain-theme-color 'grey-100)) + (default-bg (shortbrain-theme-color 'grey-900)) + (minor-fg (shortbrain-theme-color 'grey-700)) + (inactive-fg (shortbrain-theme-color 'grey-600)) + (border-fg (shortbrain-theme-color 'grey-850)) + (frame-fg (shortbrain-theme-color 'grey-500)) + (cursor-fg (shortbrain-theme-color 'grey-500)) + (cursor-bg (shortbrain-theme-color 'grey-500)) + + ;; Scrollbars + (scrollbar-fg (shortbrain-theme-color 'grey-800)) + (scrollbar-bg (shortbrain-theme-color 'grey-600)) + + ;; Highlighting + (highlight-fg (shortbrain-theme-color 'white)) + (highlight-bg (shortbrain-theme-color 'red)) + + ;; Current line + (hl-line-bg (shortbrain-theme-color 'grey-810)) + + ;; Search + (search-fg (shortbrain-theme-color 'white)) + (search-bg (shortbrain-theme-color 'primary-700)) + (search-bg-0 (shortbrain-theme-color 'primary-700)) + (search-bg-1 (shortbrain-theme-color 'primary-500)) + (search-bg-2 (shortbrain-theme-color 'primary-300)) + (search-bg-3 (shortbrain-theme-color 'primary-100)) + + ;; Selection + (selection-bg (shortbrain-theme-color 'grey-800)) + + ;; Auto-completion + (completion-fg (shortbrain-theme-color 'primary)) + (completion-bg (shortbrain-theme-color 'grey-820)) + (completion-match-fg (shortbrain-theme-color 'red-500)) + (completion-mouse-fg (shortbrain-theme-color 'white)) + (completion-selection-fg (shortbrain-theme-color 'white)) + (completion-annotation-fg (shortbrain-theme-color 'purple)) + + ;; Warnings & errors + (warning-fg (shortbrain-theme-color 'white)) + (warning-bg (shortbrain-theme-color 'red-600)) + (error-fg (shortbrain-theme-color 'white)) + (error-bg (shortbrain-theme-color 'red)) + + ;; Language syntax highlighting + (variable-fg (shortbrain-theme-color 'white)) + (function-fg (shortbrain-theme-color 'grey-200)) + (type-fg (shortbrain-theme-color 'grey-300)) + (constant-fg (shortbrain-theme-color 'grey-500)) + (keyword-fg (shortbrain-theme-color 'grey-600)) + (builtin-fg (shortbrain-theme-color 'grey-700)) + (string-fg (shortbrain-theme-color 'grey-500)) + (doc-fg (shortbrain-theme-color 'primary-600))) + (custom-theme-set-faces + 'shortbrain + + ;; Regular + `(cursor ((,class (:foreground ,cursor-fg :background ,cursor-bg)))) + `(default ((,class (:foreground ,default-fg :background ,default-bg)))) + `(default-italic ((,class (:italic t)))) + + ;; Emacs UI + `(fringe ((,class (:foreground ,error-fg :background ,default-bg)))) + `(header-line ((,class :background ,default-bg))) + `(linum ((,class (:inherit shadow :background ,default-bg)))) + `(mode-line ((,class (:foreground ,frame-fg :background ,default-bg + :box (:line-width -1 :color ,default-bg))))) + `(mode-line-inactive ((,class (:foreground ,inactive-fg :background ,default-bg + :box (:line-width -1 :color ,default-bg))))) + `(nlinum-relative-current-face ((,class (:foreground ,frame-fg :background ,default-bg)))) + `(vertical-border ((,class (:foreground ,border-fg :background ,default-bg)))) + + ;; Highlighting + `(highlight ((,class (:foreground ,highlight-fg :background ,highlight-bg)))) + `(hl-line ((,class (:background ,hl-line-bg)))) + + ;; Search + `(isearch ((,class (:foreground ,search-fg :background ,search-bg :weight bold)))) + `(lazy-highlight ((,class (:foreground ,highlight-fg :background ,highlight-bg) :weight normal))) + + ;; Selection + `(region ((,class (:background ,selection-bg)))) + + ;; Erroneous whitespace + `(whitespace-line ((,class (:foreground ,error-fg :background ,error-bg)))) + `(whitespace-space ((,class (:foreground ,builtin-fg :background ,hl-line-bg)))) + `(whitespace-tab ((,class (:foreground ,builtin-fg :background ,hl-line-bg)))) + + ;; Language syntax highlighting + `(font-lock-builtin-face ((,class (:foreground ,builtin-fg)))) + `(font-lock-comment-face ((,class (:foreground ,doc-fg)))) + `(font-lock-comment-delimiter-face ((,class (:foreground ,minor-fg)))) + `(font-lock-constant-face ((,class (:foreground ,constant-fg)))) + `(font-lock-doc-face ((,class (:foreground ,doc-fg)))) + `(font-lock-function-name-face ((,class (:foreground ,function-fg)))) + `(font-lock-keyword-face ((,class (:foreground ,keyword-fg)))) + `(font-lock-negation-char-face ((,class (:foreground ,error-fg)))) + `(font-lock-preprocessor-face ((,class (:foreground ,builtin-fg)))) + `(font-lock-string-face ((,class (:foreground ,string-fg)))) + `(font-lock-type-face ((,class (:foreground ,type-fg)))) + `(font-lock-variable-name-face ((,class (:foreground ,variable-fg)))) + `(font-lock-warning-face ((,class (:foreground ,warning-fg :background ,warning-bg)))) + + ;; Avy + `(avy-lead-face ((,class (:background ,search-bg-0 :foreground ,search-fg)))) + `(avy-lead-face-0 ((,class (:background ,search-bg-1 :foreground ,search-fg)))) + `(avy-lead-face-1 ((,class (:background ,search-bg-2 :foreground ,search-fg)))) + `(avy-lead-face-2 ((,class (:background ,search-bg-3 :foreground ,search-fg)))) + + ;; Company (auto-completion) + `(company-preview ((,class (:background ,default-bg :foreground ,completion-match-fg)))) + `(company-preview-common ((,class (:background ,completion-bg :foreground ,completion-fg)))) + `(company-preview-search ((,class (:background ,completion-bg :foreground ,completion-fg)))) + `(company-scrollbar-bg ((,class (:background ,scrollbar-bg)))) + `(company-scrollbar-fg ((,class (:background ,scrollbar-fg)))) + `(company-tooltip ((,class (:background ,completion-bg :foreground ,completion-fg)))) + `(company-tooltip-annotation ((,class (:foreground ,completion-annotation-fg)))) + `(company-tooltip-common ((,class (:background nil :foreground ,completion-match-fg)))) + `(company-tooltip-common-selection ((,class (:foreground ,completion-selection-fg)))) + `(company-tooltip-mouse ((,class (:background ,selection-bg :foreground ,completion-mouse-fg)))) + `(company-tooltip-search ((,class (:foreground ,completion-match-fg)))) + `(company-tooltip-selection ((,class (:background ,selection-bg :foreground nil)))))) + + +;;;###autoload +(when (and (boundp 'custom-theme-load-path) + load-file-name) + ;; add theme folder to `custom-theme-load-path' when installing over MELPA + (add-to-list 'custom-theme-load-path + (file-name-as-directory (file-name-directory load-file-name)))) + + +(provide-theme 'shortbrain) +(provide 'shortbrain-theme) + + +;;; shortbrain-theme.el ends here diff --git a/tmp/emacs-config/lisp/use-package-list.el b/tmp/emacs-config/lisp/use-package-list.el @@ -0,0 +1,64 @@ +;;; use-package-list.el --- List use-package declarations in config file + +;; Copyright (C) 2017 Matthew Bauer + +;; Author: Matthew Bauer <mjbauer95@gmail.com> + +;; This file is NOT part of GNU Emacs. + +;;; Commentary: + +;; βensureβ packages at compile time. + +;;; Code: + +(require 'json) +(require 'use-package) +(require 'package) +(eval-when-compile + (require 'cl)) + +(defun use-package-list (script) + "Count use-package declarations listed in SCRIPT." + + (defvar use-package-list--is-running t) + (lexical-let ((use-package-verbose t) + (use-package-debug t) + (use-package-always-ensure nil) + (use-package-always-defer t) + (use-package-list--packages nil) + (use-package-ensure-function 'ignore)) + (advice-add 'use-package + :before (lambda (name &rest args) + (unless (or (and (member :disabled args) + (plist-get args :disabled)) + (and (member :ensure args) + (not (plist-get args :ensure))) + (and (not (member :ensure args)) + (package-built-in-p name))) + (when (and (member :ensure args) + (not (eq (plist-get args :ensure) t)) + (symbolp (plist-get args :ensure))) + (setq name (plist-get args :ensure))) + (add-to-list 'use-package-list--packages name)))) + + (advice-add 'use-package-handler/:defer + :around (lambda (x name keyword arg rest state) + (let ((body (use-package-process-keywords name rest + (plist-put state :deferred t))) + (name-string (use-package-as-string name))) + (dolist (command + (delete-dups (plist-get state :commands))) + (fset command (lambda (&rest args)))) + body))) + + (advice-add 'use-package-load-name :override #'ignore) + + (load script nil nil t) + + (princ (json-encode use-package-list--packages)) + + use-package-list--packages)) + +(provide 'use-package-list) +;;; use-package-list.el ends here diff --git a/tmp/emacs-config/notes.css b/tmp/emacs-config/notes.css @@ -0,0 +1,1274 @@ +@font-face { + font-family: "GraublauWeb"; + src: url("/fonts/GraublauWeb.otf") format("opentype"); +} +@font-face { + font-family: "GraublauWeb"; + font-weight: bold; + src: url("/fonts/GraublauWebBold.otf") format("opentype"); +} +@font-face { + font-family: "Merriweather"; + src: url("/fonts/Merriweather-Regular.otf") format("opentype"); +} +@font-face { + font-family: "Merriweather"; + font-weight: bold; + src: url("/fonts/Merriweather-Bold.otf") format("opentype"); +} +@font-face { + font-family: "Merriweather"; + font-weight: bold; + font-style: italic; + src: url("/fonts/Merriweather-BoldItalic.otf") format("opentype"); +} +@font-face { + font-family: "Merriweather"; + font-style: italic; + src: url("/fonts/Merriweather-Italic.otf") format("opentype"); +} +@font-face { + font-family: "Merriweather"; + font-weight: lighter; + font-style: italic; + src: url("/fonts/Merriweather-LightItalic.otf") format("opentype"); +} +@font-face { + font-family: "Merriweather"; + font-weight: lighter; + src: url("/fonts/Merriweather-Light.otf") format("opentype"); +} + +html { + font-family:sans-serif; + line-height:1.15; + -ms-text-size-adjust:100%; + -webkit-text-size-adjust:100%; + --font-mono: 'Fira Code','Deja Vu Sans Mono','Bitstream Vera Sans Mono','Source Code Pro','Courier New',monospace; + --font-header: 'Merriweather','Linux Libertine','Georgia','Times',serif; + +} +body { + margin:0 +} +article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary { + display:block +} +audio,canvas,progress,video { + display:inline-block +} +audio:not([controls]) { + display:none; + height:0 +} +progress { + vertical-align:baseline +} +[hidden],template { + display:none +} +a { + background-color:transparent; + -webkit-text-decoration-skip:objects; + border-bottom:1px solid; +} +a:active,a:hover { + outline-width:0 +} +div#table-of-contents a { + border-bottom: 0px solid; +} +abbr[title] { + border-bottom:none; + text-decoration:underline; + text-decoration:underline dotted +} +b,strong { + font-weight:inherit; + font-weight:bolder +} +dfn { + font-style:italic +} +h1 { + font-size:2em; + margin:.67em 0 +} +mark { + background-color:#ff0; + color:#000 +} +small { + font-size:80% +} +sub,sup { + font-size:75%; + line-height:0; + position:relative; + vertical-align:baseline +} +sub { + bottom:-.25em +} +sup { + top:-.5em +} +img { + border-style:none +} +svg:not(:root) { + overflow:hidden +} +code,kbd,pre,samp { + font-family:monospace,monospace; + font-family: var(--font-mono); + font-size:1em +} +figure { + margin:1em 40px +} +hr { + box-sizing:content-box; + height:0; + overflow:visible +} +button,input,optgroup,select,textarea { + font:inherit; + margin:0 +} +optgroup { + font-weight:700 +} +button,input { + overflow:visible +} +button,select { + text-transform:none +} +[type=reset],[type=submit],button,html [type=button] { + -webkit-appearance:button +} +[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner { + border-style:none; + padding:0 +} +[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring { + outline:1px dotted ButtonText +} +fieldset { + border:1px solid silver; + margin:0 2px; + padding:.35em .625em .75em +} +legend { + box-sizing:border-box; + color:inherit; + display:table; + max-width:100%; + padding:0; + white-space:normal +} +textarea { + overflow:auto +} +[type=checkbox],[type=radio] { + box-sizing:border-box; + padding:0 +} +[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button { + height:auto +} +[type=search] { + -webkit-appearance:textfield; + outline-offset:-2px +} +[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration { + -webkit-appearance:none +} +::-webkit-input-placeholder { + color:inherit; + opacity:.54 +} +::-webkit-file-upload-button { + -webkit-appearance:button; + font:inherit +} +.org-bold { + font-weight:700 +} +.org-bold-italic { + font-weight:700; + font-style:italic +} +.org-buffer-menu-buffer { + font-weight:700 +} +.org-builtin { + color:#483d8b +} +.org-button { + color:#3a5fcd; + text-decoration:underline +} +.org-calendar-month-header { + color:#00f +} +.org-calendar-today { + text-decoration:underline +} +.org-calendar-weekday-header { + color:#008b8b +} +.org-calendar-weekend-header { + color:#b22222 +} +.org-comint-highlight-input { + font-weight:700 +} +.org-comint-highlight-prompt { + color:#0000cd +} +.org-comment,.org-comment-delimiter { + color:#b22222 +} +.org-constant { + color:#008b8b +} +.org-diary { + color:red +} +.org-doc { + color:#8b2252 +} +.org-error { + color:red; + font-weight:700 +} +.org-escape-glyph { + color:brown +} +.org-file-name-shadow { + color:#7f7f7f +} +.org-fringe { + background-color:#f2f2f2 +} +.org-function-name { + color:#00f +} +.org-glyphless-char { + font-size:60% +} +.org-header-line { + color:#333; + background-color:#e5e5e5 +} +.org-help-argument-name { + font-style:italic +} +.org-highlight { + background-color:#b4eeb4 +} +.org-holiday { + background-color:pink +} +.org-info-header-node { + color:brown; + font-weight:700; + font-style:italic +} +.org-info-header-xref { + color:#3a5fcd; + text-decoration:underline +} +.org-info-index-match { + background-color:#ff0 +} +.org-info-menu-header { + font-weight:700 +} +.org-info-menu-star { + color:red +} +.org-info-node { + color:brown; + font-weight:700; + font-style:italic +} +.org-info-title-1 { + font-size:172%; + font-weight:700 +} +.org-info-title-2 { + font-size:144%; + font-weight:700 +} +.org-info-title-3 { + font-size:120%; + font-weight:700 +} +.org-info-title-4 { + font-weight:700 +} +.org-info-xref { + color:#3a5fcd; + text-decoration:underline +} +.org-italic { + font-style:italic +} +.org-keyword { + color:#a020f0 +} +.org-lazy-highlight { + background-color:#afeeee +} +.org-link { + color:#3a5fcd; + text-decoration:underline +} +.org-link-visited { + color:#8b008b; + text-decoration:underline +} +.org-makefile-makepp-perl { + background-color:#bfefff +} +.org-makefile-space { + background-color:#ff69b4 +} +.org-makefile-targets { + color:#00f +} +.org-match { + background-color:#ff0 +} +.org-next-error { + background-color:gtk_selection_bg_color +} +.org-nobreak-space { + color:brown; + text-decoration:underline +} +.org-org-agenda-calendar-event,.org-org-agenda-calendar-sexp { + color:#000; + background-color:#fff +} +.org-org-agenda-clocking { + background-color:#ff0 +} +.org-org-agenda-column-dateline { + background-color:#e5e5e5 +} +.org-org-agenda-current-time { + color:#b8860b +} +.org-org-agenda-date { + color:#00f +} +.org-org-agenda-date-today { + color:#00f; + font-weight:700; + font-style:italic +} +.org-org-agenda-date-weekend { + color:#00f; + font-weight:700 +} +.org-org-agenda-diary { + color:#000; + background-color:#fff +} +.org-org-agenda-dimmed-todo { + color:#7f7f7f +} +.org-org-agenda-done { + color:#228b22 +} +.org-org-agenda-filter-category,.org-org-agenda-filter-effort,.org-org-agenda-filter-regexp,.org-org-agenda-filter-tags { + color:#000; + background-color:#bfbfbf +} +.org-org-agenda-restriction-lock { + background-color:#eee +} +.org-org-agenda-structure { + color:#00f +} +.org-org-archived,.org-org-block { + color:#7f7f7f +} +.org-org-block-begin-line,.org-org-block-end-line { + color:#b22222 +} +.org-org-checkbox { + font-weight:700 +} +.org-org-checkbox-statistics-done { + color:#228b22; + font-weight:700 +} +.org-org-checkbox-statistics-todo { + color:red; + font-weight:700 +} +.org-org-clock-overlay { + color:#000; + background-color:#d3d3d3 +} +.org-org-code { + color:#7f7f7f +} +.org-org-column,.org-org-column-title { + background-color:#e5e5e5 +} +.org-org-column-title { + font-weight:700; + text-decoration:underline +} +.org-org-date { + color:#a020f0; + text-decoration:underline +} +.org-org-date-selected { + color:red +} +.org-org-default { + color:#000; + background-color:#fff +} +.org-org-document-info { + color:#191970 +} +.org-org-document-info-keyword { + color:#7f7f7f +} +.org-org-document-title { + color:#191970; + font-weight:700 +} +.org-org-done { + color:#228b22; + font-weight:700 +} +.org-org-drawer { + color:#00f +} +.org-org-ellipsis { + color:#b8860b; + text-decoration:underline +} +.org-org-footnote { + color:#a020f0; + text-decoration:underline +} +.org-org-formula { + color:#b22222 +} +.org-org-headline-done { + color:#bc8f8f +} +.org-org-hide { + color:#fff +} +.org-org-latex-and-related { + color:#8b4513 +} +.org-org-level-1 { + color:#00f +} +.org-org-level-2 { + color:sienna +} +.org-org-level-3 { + color:#a020f0 +} +.org-org-level-4 { + color:#b22222 +} +.org-org-level-5 { + color:#228b22 +} +.org-org-level-6 { + color:#008b8b +} +.org-org-level-7 { + color:#483d8b +} +.org-org-level-8 { + color:#8b2252 +} +.org-org-link { + color:#3a5fcd; + text-decoration:underline +} +.org-org-list-dt { + font-weight:700 +} +.org-org-macro { + color:#8b4513 +} +.org-org-meta-line { + color:#b22222 +} +.org-org-mode-line-clock { + color:#000; + background-color:#bfbfbf +} +.org-org-mode-line-clock-overrun { + color:#000; + background-color:red +} +.org-org-priority { + color:#a020f0 +} +.org-org-quote { + color:#7f7f7f +} +.org-org-scheduled { + color:#006400 +} +.org-org-scheduled-previously { + color:#b22222 +} +.org-org-scheduled-today { + color:#006400 +} +.org-org-sexp-date,.org-org-special-keyword { + color:#a020f0 +} +.org-org-table { + color:#00f +} +.org-org-tag,.org-org-tag-group { + font-weight:700 +} +.org-org-target { + text-decoration:underline +} +.org-org-time-grid { + color:#b8860b +} +.org-org-todo { + color:red; + font-weight:700 +} +.org-org-upcoming-deadline { + color:#b22222 +} +.org-org-verbatim,.org-org-verse { + color:#7f7f7f +} +.org-org-warning { + color:red; + font-weight:700 +} +.org-outline-1 { + color:#00f +} +.org-outline-2 { + color:sienna +} +.org-outline-3 { + color:#a020f0 +} +.org-outline-4 { + color:#b22222 +} +.org-outline-5 { + color:#228b22 +} +.org-outline-6 { + color:#008b8b +} +.org-outline-7 { + color:#483d8b +} +.org-outline-8 { + color:#8b2252 +} +.org-preprocessor { + color:#483d8b +} +.org-regexp-grouping-backslash,.org-regexp-grouping-construct { + font-weight:700 +} +.org-region { + background-color:gtk_selection_bg_color +} +.org-secondary-selection { + background-color:#ff0 +} +.org-shadow { + color:#7f7f7f +} +.org-show-paren-match { + background-color:#40e0d0 +} +.org-show-paren-mismatch { + color:#fff; + background-color:#a020f0 +} +.org-string { + color:#8b2252 +} +.org-success { + color:#228b22; + font-weight:700 +} +.org-table-cell { + color:#e5e5e5; + background-color:#00f +} +.org-tooltip { + color:#000; + background-color:#ffffe0 +} +.org-trailing-whitespace { + background-color:red +} +.org-type { + color:#228b22 +} +.org-underline { + text-decoration:underline +} +.org-variable-name { + color:sienna +} +.org-warning { + color:#ff8c00; + font-weight:700 +} +.org-warning-1 { + color:red; + font-weight:700 +} +body { + width:85%; + margin:2% auto; + font-size:14px; + line-height:1.4em; + font-fannnnnmily:Georgia,serif; + color:#333 +} +@media screen and (min-width:600px) { + body { + font-size:18px + } +} +@media screen and (min-width:1270px) { + body { + width:1200px + } +} +::-moz-selection { + background:#d6edff +} +::selection { + background:#d6edff +} +dl,ol,p,ul { + margin:0 auto +} +#content p { + margin: 1em auto; +} +.title { + margin:.8em auto; + color:gray; +} +.subtitle,.title { + text-align:center +} +.subtitle { + font-size:0.7em; + line-height:1.4; + font-weight:700; + margin:1em auto; + color: lightgray; +} +.abstract { + margin:auto; + width:80%; + font-style:italic +} +.abstract p:last-of-type:before { + content:" "; + white-space:pre +} +.status { + font-size:90%; + margin:2em auto +} +[class^=section-number-] { + margin-right:.5em +} +[id^=orgheadline] { + clear:both +} +#footnotes { + font-size:90% +} +.footpara { + display:inline; + margin:.2em auto +} +.footdef { + margin-bottom:1em +} +.footdef sup { + padding-right:.5em +} +li.on { + list-style: "β "; +} +li.off { + list-style: "β "; +} +a { + color:#527d9a; + text-decoration:none +} +a:hover { + color:#035; + border-bottom:2px solid; +} +figure { + padding:0; + margin:1em auto; + text-align:center +} +img { + max-width:100%; + vertical-align:middle +} +.MathJax_Display { + margin:0!important; + width:90%!important +} +h1,h2,h3,h4,h5,h6 { + font-family: var(--font-header); +} +h1 { + color: grey; +} +h2,h3,h4,h5,h6 { + color:#a5573e; + line-height:1em; + font-family:Helvetica,sans-serif +} +h1,h2,h3 { + line-height:1.4em +} +h4,h5,h6 { + font-size:1em +} +@media screen and (min-width:600px) { + h1 { + font-size:2em + } + h2 { + font-size:1.5em + } + h3 { + font-size:1.3em + } + h1,h2,h3 { + line-height:1.4em + } + h4,h5,h6 { + font-size:1.1em + } +} +dt { + font-weight:700 +} +table { + margin:1em auto; + border-top:2px solid; + border-collapse:collapse +} +table,thead { + border-bottom:2px solid +} +table td+td,table th+th { + border-left:1px solid gray +} +table tr { + border-top:1px solid #d3d3d3 +} +td,th { + padding:.3em .6em; + vertical-align:middle +} +caption.t-above { + caption-side:top +} +caption.t-bottom { + caption-side:bottom +} +caption { + margin-bottom:.3em +} +figcaption { + margin-top:.3em +} +th.org-center,th.org-left,th.org-right { + text-align:center +} +td.org-right { + text-align:right +} +td.org-left { + text-align:left +} +td.org-center { + text-align:center +} +blockquote { + margin:1em 2em; + padding-left:1em; + border-left:3px solid #ccc +} +kbd { + background-color:#f7f7f7; + font-size:80%; + margin:0 .1em; + padding:.1em .6em +} +.todo { + background-color:red +} +.done,.todo { + color:#fff; + padding:.1em .3em; + border-radius:3px; + background-clip:padding-box; + font-size:80%; + font-family:Lucida Console,monospace; + line-height:1 +} +.done { + background-color:green +} +.priority { + color:orange; + font-family:Lucida Console,monospace +} +#table-of-contents li { + clear:both +} +.tag { + font-family:Lucida Console,monospace; + font-size:.7em; + font-weight:400 +} +.tag span { + padding:.3em; + float:right; + margin-right:.5em; + border:1px solid #bbb; + border-radius:3px; + background-clip:padding-box; + color:#333; + background-color:#eee; + line-height:1 +} +.timestamp { + color:#bebebe; + font-size:90% +} +.timestamp-kwd { + color:#5f9ea0 +} +.org-right { + margin-left:auto; + margin-right:0; + text-align:right +} +.org-left { + margin-left:0; + 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% +} +:not(pre)>code { + padding:2px 5px; + margin:auto 1px; + border:1px solid #ddd; + border-radius:3px; + background-clip:padding-box; + color:#333; + font-size:80% +} +.org-src-container { + background-color: #FDFDFD; + border:1px solid #ccc; + box-shadow:3px 3px 3px #eee; + font-family:Lucida Console,monospace; + font-size:80%; + margin:1em auto; + padding:.1em .5em; + position:relative; + color: #000; +} +.org-src-container>pre { + overflow:auto +} +.org-src-container>pre:before { + display:block; + position:absolute; + background-color:#b3b3b3; + top:0; + right:0; + padding:0 .5em; + border-bottom-left-radius:8px; + border:0; + color:#fff; + font-size:80% +} +.org-src-container>pre.src-sh:before { + content:"sh" +} +.org-src-container>pre.src-bash:before { + content:"bash" +} +.org-src-container>pre.src-emacs-lisp:before { + content:"Emacs Lisp" +} +.org-src-container>pre.src-R:before { + content:"R" +} +.org-src-container>pre.src-cpp:before { + content:"C++" +} +.org-src-container>pre.src-c:before { + content:"C" +} +.org-src-container>pre.src-html:before { + content:"HTML" +} +.org-src-container>pre.src-javascript:before,.org-src-container>pre.src-js:before { + content:"Javascript" +} +// More languages 0% http://orgmode.org/worg/org-contrib/babel/languages.html .org-src-container>pre.src-abc:before { + content:"ABC" +} +.org-src-container>pre.src-asymptote:before { + content:"Asymptote" +} +.org-src-container>pre.src-awk:before { + content:"Awk" +} +.org-src-container>pre.src-C:before { + content:"C" +} +.org-src-container>pre.src-calc:before { + content:"Calc" +} +.org-src-container>pre.src-clojure:before { + content:"Clojure" +} +.org-src-container>pre.src-comint:before { + content:"comint" +} +.org-src-container>pre.src-css:before { + content:"CSS" +} +.org-src-container>pre.src-D:before { + content:"D" +} +.org-src-container>pre.src-ditaa:before { + content:"Ditaa" +} +.org-src-container>pre.src-dot:before { + content:"Dot" +} +.org-src-container>pre.src-ebnf:before { + content:"ebnf" +} +.org-src-container>pre.src-forth:before { + content:"Forth" +} +.org-src-container>pre.src-F90:before { + content:"Fortran" +} +.org-src-container>pre.src-gnuplot:before { + content:"Gnuplot" +} +.org-src-container>pre.src-haskell:before { + content:"Haskell" +} +.org-src-container>pre.src-io:before { + content:"Io" +} +.org-src-container>pre.src-java:before { + content:"Java" +} +.org-src-container>pre.src-latex:before { + content:"LaTeX" +} +.org-src-container>pre.src-ledger:before { + content:"Ledger" +} +.org-src-container>pre.src-ly:before { + content:"Lilypond" +} +.org-src-container>pre.src-lisp:before { + content:"Lisp" +} +.org-src-container>pre.src-makefile:before { + content:"Make" +} +.org-src-container>pre.src-matlab:before { + content:"Matlab" +} +.org-src-container>pre.src-max:before { + content:"Maxima" +} +.org-src-container>pre.src-mscgen:before { + content:"Mscgen" +} +.org-src-container>pre.src-Caml:before { + content:"Objective" +} +.org-src-container>pre.src-octave:before { + content:"Octave" +} +.org-src-container>pre.src-org:before { + content:"Org" +} +.org-src-container>pre.src-perl:before { + content:"Perl" +} +.org-src-container>pre.src-picolisp:before { + content:"Picolisp" +} +.org-src-container>pre.src-plantuml:before { + content:"PlantUML" +} +.org-src-container>pre.src-python:before { + content:"Python" +} +.org-src-container>pre.src-ruby:before { + content:"Ruby" +} +.org-src-container>pre.src-sass:before { + content:"Sass" +} +.org-src-container>pre.src-scala:before { + content:"Scala" +} +.org-src-container>pre.src-scheme:before { + content:"Scheme" +} +.org-src-container>pre.src-screen:before { + content:"Screen" +} +.org-src-container>pre.src-sed:before { + content:"Sed" +} +.org-src-container>pre.src-shell:before { + content:"shell" +} +.org-src-container>pre.src-shen:before { + content:"Shen" +} +.org-src-container>pre.src-sql:before { + content:"SQL" +} +.org-src-container>pre.src-sqlite:before { + content:"SQLite" +} +.org-src-container>pre.src-stan:before { + content:"Stan" +} +.org-src-container>pre.src-vala:before { + content:"Vala" +} +.org-src-container>pre.src-axiom:before { + content:"Axiom" +} +.org-src-container>pre.src-browser:before { + content:"HTML" +} +.org-src-container>pre.src-cypher:before { + content:"Neo4j" +} +.org-src-container>pre.src-elixir:before { + content:"Elixir" +} +.org-src-container>pre.src-request:before { + content:"http" +} +.org-src-container>pre.src-ipython:before { + content:"iPython" +} +.org-src-container>pre.src-kotlin:before { + content:"Kotlin" +} +.org-src-container>pre.src-Flavored Erlang lfe:before { + content:"Lisp" +} +.org-src-container>pre.src-mongo:before { + content:"MongoDB" +} +.org-src-container>pre.src-prolog:before { + content:"Prolog" +} +.org-src-container>pre.src-rec:before { + content:"rec" +} +.org-src-container>pre.src-ML sml:before { + content:"Standard" +} +.org-src-container>pre.src-Translate translate:before { + content:"Google" +} +.org-src-container>pre.src-typescript:before { + content:"Typescript" +} +.org-src-container>pre.src-rust:before { + content:"Rust" +} +.org-src-container>pre.src-go:before { + content:"Go" +} +.org-src-container>pre.src-http:before { + content:"HTTP" +} +.inlinetask { + background:#ffc; + border:2px solid gray; + margin:10px; + padding:10px +} +#org-div-home-and-up { + font-size:70%; + text-align:right; + white-space:nowrap +} +.linenr { + font-size:90% +} +.code-highlighted { + background-color:#ff0 +} +#bibliography { + font-size:90% +} +#bibliography table { + width:100% +} +.creator { + display:block +} +@media screen and (min-width:600px) { + .creator { + display:inline; + float:right + } +} + +div#nav ul li { + display: inline; +} + +div.drawer { + border:1px solid #ccc; + box-shadow:3px 3px 3px #eee; + font-size:85%; + margin:1em auto; + padding:.1em .5em; + position:relative +} +div.drawer h6 { + margin: 0; + padding: 0.1em; + color: #333; +} + +div.drawer.results { + font-family:monospace,monospace; + font-family: var(--font-mono); + background-color: #333; + color: #fff; +} +div.drawer p { + display: block; + unicode-bidi: embed; + white-space: pre; +} +div.drawer.results h6 { + color: #fff; +} + +.info { + border: 1px solid; + background-color: #BDE5F8; + color: #00529B; +} + +.tip { + border: 1px solid; + background-color: #DFF2BF; + color: #4F8A10; +} + +.note { + border: 1px solid; + background-color: #FFFCCB; + color: #9F6000; +} + +.warning { + border: 1px solid; + background-color: #FFBABA; + color: #D8000C; +} + +/* Set the colors in <pre> blocks from the Leuven theme */ +pre span.org-builtin {color:#006FE0;font-weight:bold;} +pre span.org-string {color:#008000;} +pre span.org-keyword {color:#0000FF;} +pre span.org-variable-name {color:#BA36A5;} +pre span.org-function-name {color:#006699;} +pre span.org-type {color:#6434A3;} +pre span.org-preprocessor {color:#808080;font-weight:bold;} +pre span.org-constant {color:#D0372D;} +pre span.org-comment-delimiter {color:#8D8D84;} +pre span.org-comment {color:#8D8D84;font-style:italic} +pre span.org-outshine-level-1 {color:#8D8D84;font-style:italic} +pre span.org-outshine-level-2 {color:#8D8D84;font-style:italic} +pre span.org-outshine-level-3 {color:#8D8D84;font-style:italic} +pre span.org-outshine-level-4 {color:#8D8D84;font-style:italic} +pre span.org-outshine-level-5 {color:#8D8D84;font-style:italic} +pre span.org-outshine-level-6 {color:#8D8D84;font-style:italic} +pre span.org-outshine-level-7 {color:#8D8D84;font-style:italic} +pre span.org-outshine-level-8 {color:#8D8D84;font-style:italic} +pre span.org-outshine-level-9 {color:#8D8D84;font-style:italic} +pre span.org-rainbow-delimiters-depth-1 {color:#707183;} +pre span.org-rainbow-delimiters-depth-2 {color:#7388d6;} +pre span.org-rainbow-delimiters-depth-3 {color:#909183;} +pre span.org-rainbow-delimiters-depth-4 {color:#709870;} +pre span.org-rainbow-delimiters-depth-5 {color:#907373;} +pre span.org-rainbow-delimiters-depth-6 {color:#6276ba;} +pre span.org-rainbow-delimiters-depth-7 {color:#858580;} +pre span.org-rainbow-delimiters-depth-8 {color:#80a880;} +pre span.org-rainbow-delimiters-depth-9 {color:#887070;} +pre span.org-sh-quoted-exec {color:#FF1493;} diff --git a/tmp/emacs-config/publish.org b/tmp/emacs-config/publish.org @@ -0,0 +1,230 @@ +#+TITLE: Publish dotemacs notes using Emacs org-mode +#+AUTHOR: Vincent Demeester +#+EMAIL: vincent@sbr.pm +#+EXPORT_EXCLUDE_TAGS: noexport +#+CREATOR: Emacs 27.0.90 (Org mode 9.3) +#+LANGUAGE: en +#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="./notes.css"/> +#+OPTIONS: html-style:nil + +This document is a literate version of my publishing /script/ on publishing my dotemacs +notes (that uses [[https://orgmode.org][=org-mode=]]). + +First let's import required libraries, which are =org= related. + +#+begin_src emacs-lisp :tangle yes +;; Add my personal libraries π +(add-to-list 'load-path (concat user-emacs-directory "lisp/")) + +(require 'org) +(require 'ox) +(require 'ox-publish) +(require 'ol-man) +(require 'ol-git-link) +(require 'ol-github) +(require 'ol-gitlab) +#+end_src + +To get syntax coloring on other mode than ~emacs-lisp~, we need to load them too[fn:1]. + +#+begin_src emacs-lisp :tangle yes + (require 'go-mode) + (require 'css-mode) + (require 'python-mode) + (require 'nix-mode) + (require 'ob-http) + (require 'yaml-mode) +#+end_src + +Now let's define variables to use later on. Those variables are where to find the project +we want to publish and where to publish theme. + +#+begin_src emacs-lisp :tangle yes + (setq site-directory "~/desktop/sites/") + + (setq org-default-publish-sbr (expand-file-name "sbr.pm" site-directory)) + (setq org-default-publish-dotemacs (expand-file-name "dotemacs" org-default-publish-sbr)) +#+end_src + +We want to republish everything every time β mainly to be used on CI. So we're telling +=org-mode= to disable the timestamp-based cache. + +#+begin_src emacs-lisp :tangle yes + (setq org-publish-use-timestamps-flag nil) +#+end_src + +Let's also customize a bit the /style/ of what =org-mode= will generate. + +- Set the default html coding system πΌ + #+begin_src emacs-lisp :tangle yes + (setq org-html-coding-system 'utf-8-unix) + #+end_src +- Let's disable the default script and style "includes". + #+begin_src emacs-lisp :tangle yes + (setq org-export-html-style-include-scripts nil + org-export-html-style-include-default nil) + #+end_src +- Let's also make sure the =#+begin_src= blocks are colorized, *but* using the css instead + of inlude style. + #+begin_src emacs-lisp :tangle yes + (setq org-src-fontify-natively t) + ;; (setq org-html-htmlize-output-type 'inline-css) ;; default + (setq org-html-htmlize-output-type 'css) + ;; (setq org-html-htmlize-font-prefix "") ;; default + (setq org-html-htmlize-font-prefix "org-") + #+end_src +- Customize how we export ~org-mode~ drawers + #+begin_src emacs-lisp :tangle yes + (defun my-org-export-format-drawer (name content) + (concat "<div class=\"drawer " (downcase name) "\">\n" + "<h6>" (capitalize name) "</h6>\n" + content + "\n</div>")) + (setq org-html-format-drawer-function 'my-org-export-format-drawer) + #+end_src +- And disable ~org-babel~ from trying to evaluate on export + #+begin_src emacs-lisp :tangle yes + (setq org-export-use-babel nil) + #+end_src + +I want [[https://writepermission.com/org-blogging-clickable-headlines.html][clickable headlines]], so let's define a ~html-format-headline-function~ for the +exporter to use. Not tangle currently as it doesn't work π. + +#+begin_src emacs-lisp :tangle no + (defun my-org-html-format-headline-function (todo todo-type priority text tags info) + "Format a headline with a link to itself." + (let* ((headline (get-text-property 0 :parent text)) + (id (or (org-element-property :CUSTOM_ID headline) + (org-export-get-reference headline info) + (org-element-property :ID headline))) + (link (if id + (format "<a href=\"#%s\">%s</a>" id text) + text))) + (org-html-format-headline-default-function todo todo-type priority link tags info))) + (setq org-html-format-headline-function 'my-org-html-format-headline-function) +#+end_src + +I also use some custom linksβ¦ First thing first, I want the =att:= link to be supporting +when exporting + +#+begin_src emacs-lisp :tangle yes +(require 'org-attach) +(setq org-link-abbrev-alist '(("att" . org-attach-expand-link))) +#+end_src + + +They are define in my [[https://github.com/vdemeester/emacs-config][emacs configuration]] repository : [[https://github.com/vdemeester/emacs-config/blob/master/lisp/setup-org.el][~setup-org.el~]]. + +#+begin_src emacs-lisp :tangle yes + (org-link-set-parameters "tag" + :follow #'endless/follow-tag-link) + (defun endless/follow-tag-link (tag) + "Display a list of TODO headlines with tag TAG. + With prefix argument, also display headlines without a TODO keyword." + (org-tags-view (null current-prefix-arg) tag)) + + (org-link-set-parameters "grep" + :follow #'vde/follow-grep-link + :face '(:foreground "DarkRed" :underline t)) + (defun vde/follow-grep-link (regexp) + "Run `rgrep' with REGEXP and FOLDER as argument, + like this : [[grep:REGEXP:FOLDER]]." + (setq expressions (split-string regexp ":")) + (setq exp (nth 0 expressions)) + (grep-compute-defaults) + (if (= (length expressions) 1) + (progn + (rgrep exp "*" (expand-file-name "./"))) + (progn + (setq folder (nth 1 expressions)) + (rgrep exp "*" (expand-file-name folder)))) + ) + + (org-link-set-parameters "rg" + :follow #'vde/follow-rg-link + :face '(:foreground "DarkGreen" :underline t)) + (defun vde/follow-rg-link (regexp) + "Run `ripgrep-regexp` with REXEP and FOLDER as argument, + like this : [[pt:REGEXP:FOLDER]]" + (setq expressions (split-string regexp ":")) + (setq exp (nth 0 expressions)) + (if (= (length expressions) 1) + (progn + (ripgrep-regexp exp (expand-file-name "./"))) + (progn + (setq folder (nth 1 expressions)) + (ripgrep-regexp exp (file-name-as-directory (expand-file-name folder))))) + ) + + (org-link-set-parameters + "org" + :complete (lambda () (+org-link-read-file "org" org-directory)) + :follow (lambda (link) (find-file (expand-file-name link org-directory))) + :face (lambda (link) + (if (file-exists-p (expand-file-name link org-directory)) + 'org-link + 'error))) + (defun +org-link-read-file (key dir) + (let ((file (read-file-name (format "%s: " (capitalize key)) dir))) + (format "%s:%s" + key + (file-relative-name file dir)))) +#+end_src + +Now, let's define projects. + +#+begin_src emacs-lisp :tangle yes + (setq org-publish-project-alist + `(("dotemacs-org" + :base-directory "." + :base-extension "org\\|txt" + :publishing-directory ,org-default-publish-dotemacs + :recursive t + :publishing-function org-html-publish-to-html + :headline-levels 4 + :auto-preamble t + :auto-sitemap t + :with-footnotes t + :with-toc nil + :with-drawers t + :exclude "_setup.org\\|sbr.pm\\|.extension\\|elpa\\|var" + :html-checkbox-type 'html + :html-preamble "<div id=\"nav\"> + <ul> + <li><a href=\"/\" class=\"home\">Home</a></li> + <li><a href=\"./\" class=\"index\">Index</a></li> + <li><a href=\"../\" class=\"up\">Up</a></li> + </ul> + </div>" + :html-postamble "<p class=\"creator\">%c</p><p class=\"postamble\">%a. Last Updated %C (exported %T).</p>") + ("dotemacs-static" + :base-directory "." + :base-extension "html\\|xml\\|css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|md\\|tar\\|gz\\|xz\\|zip\\|csv" + :exclude ".extension\\|elpa\\|var" + :publishing-directory ,org-default-publish-dotemacs + :recursive t + :publishing-function org-publish-attachment + ) + ("dotemacs" :components ("dotemacs-org" "dotemacs-static")) + )) +#+end_src + +I want the ~sites~ folder to be cleaned too, so let's define a function to be called that +will clean a folder and publish. + +#+begin_src emacs-lisp :tangle yes + (defun clean-and-publish () + "Clean the site folder and publish all projects" + (delete-directory org-default-publish-dotemacs t) + (org-publish-all)) +#+end_src + +Let's now create a ~Makefile~ so that I can just run ~make publish~ to automate that. + +#+INCLUDE: "Makefile" src makefile + +The rest is just /automation/ πΌ. The ~~/desktop/sites/~ folder is synced across a bunch +of my machines, including my servers (using [[https://syncthing.net/][syncthing]]). This means almost as soon as I run +this publish script, it will be available. + +[fn:1] Otherwise, emacs doesn't apply any syntax coloring.