commit 609df59bcffe42130f7355a4d32f5cb62cc1a42d Author: Wizzard Date: Thu Jan 25 19:32:08 2024 -0500 Added nvim & tmux diff --git a/dot_config/nvim/LICENSE b/dot_config/nvim/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/dot_config/nvim/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/dot_config/nvim/dot_git/HEAD b/dot_config/nvim/dot_git/HEAD new file mode 100644 index 0000000..c15bff2 --- /dev/null +++ b/dot_config/nvim/dot_git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/v2.0 diff --git a/dot_config/nvim/dot_git/config b/dot_config/nvim/dot_git/config new file mode 100644 index 0000000..a592f6d --- /dev/null +++ b/dot_config/nvim/dot_git/config @@ -0,0 +1,11 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[remote "origin"] + url = https://github.com/NvChad/NvChad + fetch = +refs/heads/v2.0:refs/remotes/origin/v2.0 +[branch "v2.0"] + remote = origin + merge = refs/heads/v2.0 diff --git a/dot_config/nvim/dot_git/description b/dot_config/nvim/dot_git/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/nvim/dot_git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/nvim/dot_git/hooks/executable_applypatch-msg.sample b/dot_config/nvim/dot_git/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/nvim/dot_git/hooks/executable_commit-msg.sample b/dot_config/nvim/dot_git/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/nvim/dot_git/hooks/executable_fsmonitor-watchman.sample b/dot_config/nvim/dot_git/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/nvim/dot_git/hooks/executable_post-update.sample b/dot_config/nvim/dot_git/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/nvim/dot_git/hooks/executable_pre-applypatch.sample b/dot_config/nvim/dot_git/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/nvim/dot_git/hooks/executable_pre-commit.sample b/dot_config/nvim/dot_git/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/nvim/dot_git/hooks/executable_pre-merge-commit.sample b/dot_config/nvim/dot_git/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/nvim/dot_git/hooks/executable_pre-push.sample b/dot_config/nvim/dot_git/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/nvim/dot_git/hooks/executable_pre-rebase.sample b/dot_config/nvim/dot_git/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/nvim/dot_git/hooks/executable_pre-receive.sample b/dot_config/nvim/dot_git/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/nvim/dot_git/hooks/executable_prepare-commit-msg.sample b/dot_config/nvim/dot_git/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/nvim/dot_git/hooks/executable_push-to-checkout.sample b/dot_config/nvim/dot_git/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/nvim/dot_git/hooks/executable_update.sample b/dot_config/nvim/dot_git/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/nvim/dot_git/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/nvim/dot_git/index b/dot_config/nvim/dot_git/index new file mode 100644 index 0000000..4e88a03 Binary files /dev/null and b/dot_config/nvim/dot_git/index differ diff --git a/dot_config/nvim/dot_git/info/exclude b/dot_config/nvim/dot_git/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/nvim/dot_git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/nvim/dot_git/logs/HEAD b/dot_config/nvim/dot_git/logs/HEAD new file mode 100644 index 0000000..6e547e7 --- /dev/null +++ b/dot_config/nvim/dot_git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 282a23f4469ee305e05ec7a108a728ee389d87fb Wizzard 1705825793 -0500 clone: from https://github.com/NvChad/NvChad diff --git a/dot_config/nvim/dot_git/logs/refs/heads/v2.0 b/dot_config/nvim/dot_git/logs/refs/heads/v2.0 new file mode 100644 index 0000000..6e547e7 --- /dev/null +++ b/dot_config/nvim/dot_git/logs/refs/heads/v2.0 @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 282a23f4469ee305e05ec7a108a728ee389d87fb Wizzard 1705825793 -0500 clone: from https://github.com/NvChad/NvChad diff --git a/dot_config/nvim/dot_git/logs/refs/remotes/origin/HEAD b/dot_config/nvim/dot_git/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..6e547e7 --- /dev/null +++ b/dot_config/nvim/dot_git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 282a23f4469ee305e05ec7a108a728ee389d87fb Wizzard 1705825793 -0500 clone: from https://github.com/NvChad/NvChad diff --git a/dot_config/nvim/dot_git/objects/pack/readonly_pack-ebb5cab3b48c90331e8f2aa1e427ecb95c54d2ad.idx b/dot_config/nvim/dot_git/objects/pack/readonly_pack-ebb5cab3b48c90331e8f2aa1e427ecb95c54d2ad.idx new file mode 100644 index 0000000..ab0e9a8 Binary files /dev/null and b/dot_config/nvim/dot_git/objects/pack/readonly_pack-ebb5cab3b48c90331e8f2aa1e427ecb95c54d2ad.idx differ diff --git a/dot_config/nvim/dot_git/objects/pack/readonly_pack-ebb5cab3b48c90331e8f2aa1e427ecb95c54d2ad.pack b/dot_config/nvim/dot_git/objects/pack/readonly_pack-ebb5cab3b48c90331e8f2aa1e427ecb95c54d2ad.pack new file mode 100644 index 0000000..d1642cb Binary files /dev/null and b/dot_config/nvim/dot_git/objects/pack/readonly_pack-ebb5cab3b48c90331e8f2aa1e427ecb95c54d2ad.pack differ diff --git a/dot_config/nvim/dot_git/objects/pack/readonly_pack-ebb5cab3b48c90331e8f2aa1e427ecb95c54d2ad.rev b/dot_config/nvim/dot_git/objects/pack/readonly_pack-ebb5cab3b48c90331e8f2aa1e427ecb95c54d2ad.rev new file mode 100644 index 0000000..5ac14ef Binary files /dev/null and b/dot_config/nvim/dot_git/objects/pack/readonly_pack-ebb5cab3b48c90331e8f2aa1e427ecb95c54d2ad.rev differ diff --git a/dot_config/nvim/dot_git/packed-refs b/dot_config/nvim/dot_git/packed-refs new file mode 100644 index 0000000..7f40181 --- /dev/null +++ b/dot_config/nvim/dot_git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +282a23f4469ee305e05ec7a108a728ee389d87fb refs/remotes/origin/v2.0 diff --git a/dot_config/nvim/dot_git/refs/heads/v2.0 b/dot_config/nvim/dot_git/refs/heads/v2.0 new file mode 100644 index 0000000..f977845 --- /dev/null +++ b/dot_config/nvim/dot_git/refs/heads/v2.0 @@ -0,0 +1 @@ +282a23f4469ee305e05ec7a108a728ee389d87fb diff --git a/dot_config/nvim/dot_git/refs/remotes/origin/HEAD b/dot_config/nvim/dot_git/refs/remotes/origin/HEAD new file mode 100644 index 0000000..1828ea8 --- /dev/null +++ b/dot_config/nvim/dot_git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/v2.0 diff --git a/dot_config/nvim/dot_git/shallow b/dot_config/nvim/dot_git/shallow new file mode 100644 index 0000000..f977845 --- /dev/null +++ b/dot_config/nvim/dot_git/shallow @@ -0,0 +1 @@ +282a23f4469ee305e05ec7a108a728ee389d87fb diff --git a/dot_config/nvim/dot_github/CONTRIBUTING.md b/dot_config/nvim/dot_github/CONTRIBUTING.md new file mode 100644 index 0000000..12d436d --- /dev/null +++ b/dot_config/nvim/dot_github/CONTRIBUTING.md @@ -0,0 +1,161 @@ +# [CONTRIBUTING](https://nvchad.github.io/contribute) + +## NvChad install for contributors + +If you wish to contribute to NvChad, you should: +1. [create a fork on GitHub](https://docs.github.com/en/get-started/quickstart/fork-a-repo) +2. clone your fork to your machine + - For ssh: + ```shell + $ git clone git@github.com:/NvChad.git ~/.config/nvim + ``` + - For https: + ```shell + $ git clone https://github.com//NvChad.git ~/.config/nvim + ``` +3. [add a new remote repo to track](https://www.atlassian.com/git/tutorials/git-forks-and-upstreams) + - this means you can push/pull as normal to your own repo, but also easily track & update from the NvChad repo + - for ssh: + ```shell + $ git remote add upstream git@github.com:NvChad/NvChad.git + ``` + - for https: + ```shell + $ git remote add upstream https://github.com/NvChad/NvChad.git + ``` +4. any time you create a branch to do some work, use + ```shell + $ git fetch upstream && git checkout -b dev-myFEAT upstream/main + ``` +5. only use the **--rebase** flag to update your dev branch + - this means that there are no `Merge NvChad/main into devBranch` commits, which are to be avoided + ```shell + $ git pull upstream --rebase + ``` + +## Things to know before contributing + +- When making a PR (pull request), please be very descriptive about what you've done! + +- PR titles should be formatted with 'fix', 'chore' or 'feat'. ex: `feat: add new plugin` + +- PRs should follow the pull request formats where applicable + +- We are open to all PRs, but may decline some for a myriad of reasons. Though don't be discouraged! We'll still be open to discussions. + +- PR's are always welcomed however NvChad aims to be less bloated. So PR's regarding existing plugin's enhancement and creating new features with existing plugins itself ( without adding a new plugin), bug fixes and corrections are more encouraged. + +- NvChad won't keep adding more and more features (like adding new plugins most likely) as requested if they feel unneeded and aren't usable by the majority!! If you think the plugin you want to be added is very useful and many NvChaders would find it useful, then such feature's PR is welcomed! + +- But adding specific features like adding config for [wakatime](https://github.com/wakatime/vim-wakatime) etc will be added in this [chad user configs](https://github.com/NvChad/NvChad/wiki/Chad-user-configs). This lets the user select the things only they want ( adding configs from extra configs ). + +## How to remove or edit commits from your PR +> You may have been directed here to remove a commit such as a merge commit: `Merge NvChad/main into devBranch` from your PR + +> As these commands edit your git history, you may need to **force push** with `git push origin --force` + +1. Run the following: + ``` + $ git rebase -i HEAD~ + ``` +
Example +

+ + ```shell + $ git rebase -i HEAD~4 + ``` + + ```shell + pick 28b2dcb statusline add lsp status + pick dad9a39 feat: Added lsp radial progress + pick 68f72f1 add clickable btn for exiting nvim + pick b281b53 avoid using q! for quitting vim + + # Rebase 52b655b..b281b53 onto 52b655b (4 commands) + # + # Commands: + # p, pick = use commit + # r, reword = use commit, but edit the commit message + # e, edit = use commit, but stop for amending + # s, squash = use commit, but meld into previous commit + # f, fixup = like "squash", but discard this commit's log message + # x, exec = run command (the rest of the line) using shell + # b, break = stop here (continue rebase later with 'git rebase --continue') + # d, drop = remove commit + # l, label

+
+ +2. Change the `pick` commands to whatever you wish, you may wish to `d` `drop` or `e` `edit` a commit. Then save & quit this git file to run it. + +
Example +

+ + ```shell {3,4} + pick 28b2dcb statusline add lsp status + pick dad9a39 feat: Added lsp radial progress + edit 68f72f1 add clickable btn for exiting nvim + d b281b53 avoid using q! for quitting vim + + # Rebase 52b655b..b281b53 onto 52b655b (4 commands) + # + # Commands: + # p, pick = use commit + # r, reword = use commit, but edit the commit message + # e, edit = use commit, but stop for amending + # s, squash = use commit, but meld into previous commit + # f, fixup = like "squash", but discard this commit's log message + # x, exec = run command (the rest of the line) using shell + # b, break = stop here (continue rebase later with 'git rebase --continue') + # d, drop = remove commit + # l, label

+
+ +3. If you picked `drop` you are done, if you picked `edit` then edit your files, then run: + ```shell + $ git add + ``` + +4. Once you have edited & added your files, run: + ```shell + $ git rebase --continue + ``` + +5. You will likely need to push using: + ```shell + $ git push origin --force + ``` + +## Help +For help with contributing and anything else nvChad related join the [discord](https://discord.gg/VyPxsGArXc) diff --git a/dot_config/nvim/dot_github/FUNDING.yml b/dot_config/nvim/dot_github/FUNDING.yml new file mode 100644 index 0000000..02611f2 --- /dev/null +++ b/dot_config/nvim/dot_github/FUNDING.yml @@ -0,0 +1,3 @@ +patreon: siduck +ko_fi: siduck +custom: ["https://www.buymeacoffee.com/siduck", "https://www.paypal.com/paypalme/siduck76"] diff --git a/dot_config/nvim/dot_github/ISSUE_TEMPLATE/bug_report.md b/dot_config/nvim/dot_github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..43b4ec0 --- /dev/null +++ b/dot_config/nvim/dot_github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,34 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + + + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - Operating System + - Terminal + - Version of Neovim + +**Additional context** +Add any other context about the problem here. diff --git a/dot_config/nvim/dot_github/ISSUE_TEMPLATE/config.yml b/dot_config/nvim/dot_github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3495e93 --- /dev/null +++ b/dot_config/nvim/dot_github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Wiki + url: https://github.com/siduck76/NvChad/wiki + about: "Walks you through how to use and Configure NvChad." + - name: Visit our gitter chat + url: https://gitter.im/neovim-dotfiles/community + about: "A place where we dicuss NvChad related stuff." diff --git a/dot_config/nvim/dot_github/ISSUE_TEMPLATE/feature_request.md b/dot_config/nvim/dot_github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..24d2f24 --- /dev/null +++ b/dot_config/nvim/dot_github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem was. + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. + +**Screenshot** +Maybe a screenshot of the feature diff --git a/dot_config/nvim/dot_github/PULL_REQUEST_TEMPLATE/feature.md b/dot_config/nvim/dot_github/PULL_REQUEST_TEMPLATE/feature.md new file mode 100644 index 0000000..a622846 --- /dev/null +++ b/dot_config/nvim/dot_github/PULL_REQUEST_TEMPLATE/feature.md @@ -0,0 +1,14 @@ + +Fixes Issue # (If it doesn't fix an issue then delete this line) + +Features Added: +- Plugin Name (Add links if possible too) + +Reasoning: +List why the feature is needed + +Speed (If applicable): +Show the impact on the speed of nvChad + +Other: +Anything else relevant goes here diff --git a/dot_config/nvim/dot_github/PULL_REQUEST_TEMPLATE/plugin.md b/dot_config/nvim/dot_github/PULL_REQUEST_TEMPLATE/plugin.md new file mode 100644 index 0000000..28ae8d3 --- /dev/null +++ b/dot_config/nvim/dot_github/PULL_REQUEST_TEMPLATE/plugin.md @@ -0,0 +1,16 @@ +(Make sure your title is either: 'fix', 'chore', or 'feat' then your title. ex: `fix: add new plugin`) + +Fixes Issue # (If it doesn't fix an issue then delete this line) + +Plugins Added: +- [Plugin Name](Plugin Link) +- [Plugin Name](Plugin Link) + +Reasoning: +List why the plugin(s) should be added + +Speed: +Show the impact on the speed of nvChad + +Other: +Anything else relevant goes here diff --git a/dot_config/nvim/dot_github/README.md b/dot_config/nvim/dot_github/README.md new file mode 100644 index 0000000..8f3ec47 --- /dev/null +++ b/dot_config/nvim/dot_github/README.md @@ -0,0 +1,122 @@ +

NvChad

+ +
+ Home + + Install + + Contribute + + Support + + Features +

+
+ +
+ +[![Neovim Minimum Version](https://img.shields.io/badge/Neovim-0.9.0-blueviolet.svg?style=flat-square&logo=Neovim&color=90E59A&logoColor=white)](https://github.com/neovim/neovim) +[![GitHub Issues](https://img.shields.io/github/issues/NvChad/NvChad.svg?style=flat-square&label=Issues&color=d77982)](https://github.com/NvChad/NvChad/issues) +[![Discord](https://img.shields.io/discord/869557815780470834?color=738adb&label=Discord&logo=discord&logoColor=white&style=flat-square)](https://discord.gg/gADmkJb9Fb) +[![Matrix](https://img.shields.io/badge/Matrix-40aa8b.svg?style=flat-square&logo=Matrix&logoColor=white)](https://matrix.to/#/#nvchad:matrix.org) +[![Telegram](https://img.shields.io/badge/Telegram-blue.svg?style=flat-square&logo=Telegram&logoColor=white)](https://t.me/DE_WM) + +
+ +## Showcase + + + + + + + +## What is it? + +- NvChad is a neovim config written in lua aiming to provide a base configuration with very beautiful UI and blazing fast startuptime (around 0.02 secs ~ 0.07 secs). We tweak UI plugins such as telescope, nvim-tree, bufferline etc well to provide an aesthetic UI experience. + +- Lazy loading is done 93% of the time meaning that plugins will not be loaded by default, they will be loaded only when required also at specific commands, events etc. This lowers the startuptime and it was like 0.07~ secs tested on an old pentium machine 1.4ghz + 4gb ram & HDD. + +- NvChad isn't a framework! It's supposed to be used as a "base" config, so users can tweak the defaults well, and also remove the things they don't like in the default config and build their config on top of it. Users can tweak the entire default config while staying in their custom config (lua/custom dir). This is the control center of the user's config and gitignored so the users can stay up-to-date with NvChad's latest config (main branch) while still controlling it with their chadrc (file that controls entire custom dir). + +## Theme Showcase + +
Images (Click to expand!) + +![4 themes](https://nvchad.com/screenshots/four_Themes.webp) +![radium 1](https://nvchad.com/screenshots/radium1.webp) +![radium 2](https://nvchad.com/screenshots/radium2.webp) +![radium 3](https://nvchad.com/screenshots/radium3.webp) + + +(Note: these are just 4-5 themes, NvChad has around 56 themes) +
+ +## UI related plugins used + +
Images (Click to expand!) + +

Nvim-tree.lua

+ +Fast file tree: + + + +

Telescope-nvim

+ +A fuzzy file finder, picker, sorter, previewer and much more: + + + +

Our own statusline written from scratch

+ +[NvChad UI](https://github.com/NvChad/ui) + + + +

Tabufline (our own pertab bufferline)

+ + +- Here's a [video](https://www.youtube.com/watch?v=V_9iJ96U_k8&ab_channel=siduck) that showcases it. + +

NvCheatsheet ( our UI Plugin )

+ + +
+ +## Plugins list + +- Many beautiful themes, theme toggler by our [base46 plugin](https://github.com/NvChad/base46) +- Inbuilt terminal toggling & management with [Nvterm](https://github.com/NvChad/nvterm) +- Lightweight & performant ui plugin with [NvChad UI](https://github.com/NvChad/ui) It provides statusline modules, tabufline ( tabs + buffer manager) , beautiful cheatsheets, NvChad updater, hide & unhide terminal buffers, theme switcher and much more! +- File navigation with [nvim-tree.lua](https://github.com/kyazdani42/nvim-tree.lua) +- Beautiful and configurable icons with [nvim-web-devicons](https://github.com/kyazdani42/nvim-web-devicons) +- Git diffs and more with [gitsigns.nvim](https://github.com/lewis6991/gitsigns.nvim) +- NeoVim Lsp configuration with [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) and [mason.nvim](https://github.com/williamboman/mason.nvim) +- Autocompletion with [nvim-cmp](https://github.com/hrsh7th/nvim-cmp) +- File searching, previewing image and text files and more with [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim). +- Syntax highlighting with [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) +- Autoclosing braces and html tags with [nvim-autopairs](https://github.com/windwp/nvim-autopairs) +- Indentlines with [indent-blankline.nvim](https://github.com/lukas-reineke/indent-blankline.nvim) +- Useful snippets with [friendly snippets](https://github.com/rafamadriz/friendly-snippets) + [LuaSnip](https://github.com/L3MON4D3/LuaSnip). +- Popup mappings keysheet [whichkey.nvim](https://github.com/folke/which-key.nvim) + +## History + +- I (@siduck i.e creator of NvChad) in my initial days of learning to program wanted a lightweight IDE for writing code, I had a very low end system which was like 1.4ghz pentium + 4gb ram & HDD. I was into web dev stuff so many suggested me to use vscode but that thing was very heavy on my system, It took more ram than my browser! ( minimal ungoogled chromium ) so I never tried it again, sublime text was nice but the fear of using proprietary software XD for a linux user bugged me a lot. Then I tried doom-emacs which looked pretty but it was slow and I was lost within its docs, I tried lunarvim but too lazy to read the docs. Doom-emacs and lunarvim inspired me to make a config which is the prettiest + very fast and simple. + +- I'm decent at ricing i.e customizing system and making it look pretty so I posted my neovim rice on [neovim subreddit](https://www.reddit.com/r/neovim/comments/m3xl4f/neovim_rice/), my neovim-dotfiles github repo blew up and then I had to come up with a name, I was amazed by the chad meme lol so I put NvChad as the name, the chad word in here doesnt literally mean the chad guy but in the sense such as chad linux vs windows i.e meaning superior, best etc. NvChad was made for my personal use but it gained some popularity which inspired me to make a public config i.e config usable by many and less hassle to update as everyone's going to use the same base config (NvChad) with their custom modifications (which are gitignored so that wont mess up), without the custom config stuff users would have to keep a track of every commit and copy paste git diffs to manually update nvchad. + +## :gift_heart: Support + +If you like NvChad and would like to support & appreciate it via donation then I'll gladly accept it. + +[![kofi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/siduck) +[![paypal](https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white)](https://paypal.me/siduck13) +[![buymeacoffee](https://img.shields.io/badge/Buy_Me_A_Coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/siduck) +[![patreon](https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white)](https://www.patreon.com/siduck) + +## Credits + +- [Elianiva](https://github.com/elianiva) helped me with NeoVim Lua related issues many times, NvChad wouldn't exist without his help at all as he helped me in my initial neovim journey! +- @lorvethe for making the beautiful NvChad logo. diff --git a/dot_config/nvim/dot_github/workflows/stale.yml b/dot_config/nvim/dot_github/workflows/stale.yml new file mode 100644 index 0000000..1f16ea2 --- /dev/null +++ b/dot_config/nvim/dot_github/workflows/stale.yml @@ -0,0 +1,22 @@ +name: 'Close stale issues and PRs' +on: + schedule: + - cron: '30 1 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.' + stale-pr-message: 'This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.' + close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.' + exempt-all-issue-assignees: true # doesn't close an issue if someone was assigned to it. + close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.' + exempt-all-pr-assignees: true # doesn't close a pr if someone was assigned to it. + days-before-issue-stale: 30 + days-before-pr-stale: 45 + days-before-issue-close: 5 + days-before-pr-close: 10 diff --git a/dot_config/nvim/dot_gitignore b/dot_config/nvim/dot_gitignore new file mode 100644 index 0000000..d8a93d9 --- /dev/null +++ b/dot_config/nvim/dot_gitignore @@ -0,0 +1,10 @@ +plugin +custom +spell +ftplugin +syntax +coc-settings.json +.luarc.json +lazy-lock.json +after +**/.DS_Store diff --git a/dot_config/nvim/dot_ignore b/dot_config/nvim/dot_ignore new file mode 100644 index 0000000..42677fb --- /dev/null +++ b/dot_config/nvim/dot_ignore @@ -0,0 +1 @@ +!/lua/custom/ diff --git a/dot_config/nvim/dot_stylua.toml b/dot_config/nvim/dot_stylua.toml new file mode 100644 index 0000000..ecb6dca --- /dev/null +++ b/dot_config/nvim/dot_stylua.toml @@ -0,0 +1,6 @@ +column_width = 120 +line_endings = "Unix" +indent_type = "Spaces" +indent_width = 2 +quote_style = "AutoPreferDouble" +call_parentheses = "None" diff --git a/dot_config/nvim/init.lua b/dot_config/nvim/init.lua new file mode 100644 index 0000000..21f0b6f --- /dev/null +++ b/dot_config/nvim/init.lua @@ -0,0 +1,21 @@ +require "core" + +local custom_init_path = vim.api.nvim_get_runtime_file("lua/custom/init.lua", false)[1] + +if custom_init_path then + dofile(custom_init_path) +end + +require("core.utils").load_mappings() + +local lazypath = vim.fn.stdpath "data" .. "/lazy/lazy.nvim" + +-- bootstrap lazy.nvim! +if not vim.loop.fs_stat(lazypath) then + require("core.bootstrap").gen_chadrc_template() + require("core.bootstrap").lazy(lazypath) +end + +dofile(vim.g.base46_cache .. "defaults") +vim.opt.rtp:prepend(lazypath) +require "plugins" diff --git a/dot_config/nvim/lazy-lock.json b/dot_config/nvim/lazy-lock.json new file mode 100644 index 0000000..f28c599 --- /dev/null +++ b/dot_config/nvim/lazy-lock.json @@ -0,0 +1,31 @@ +{ + "Comment.nvim": { "branch": "master", "commit": "0236521ea582747b58869cb72f70ccfa967d2e89" }, + "LuaSnip": { "branch": "master", "commit": "2dbef19461198630b3d7c39f414d09fb07d1fdd2" }, + "base46": { "branch": "v2.0", "commit": "3f2b658cbd6650ddaf2bae3233e143a41ca25b1a" }, + "better-escape.nvim": { "branch": "master", "commit": "d62cf3c04163a46f3895c70cc807f5ae68dd8ca1" }, + "cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" }, + "cmp-nvim-lsp": { "branch": "main", "commit": "5af77f54de1b16c34b23cba810150689a3a90312" }, + "cmp-nvim-lua": { "branch": "main", "commit": "f12408bdb54c39c23e67cab726264c10db33ada8" }, + "cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" }, + "cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" }, + "conform.nvim": { "branch": "master", "commit": "cbc5745bf7519acaf3a5cbaaa677fd556aa813d7" }, + "friendly-snippets": { "branch": "main", "commit": "69a2c1675b66e002799f5eef803b87a12f593049" }, + "gitsigns.nvim": { "branch": "main", "commit": "c5ff7628e19a47ec14d3657294cc074ecae27b99" }, + "indent-blankline.nvim": { "branch": "master", "commit": "b7aa0aed55887edfaece23f7b46ab22232fc8741" }, + "lazy.nvim": { "branch": "main", "commit": "96584866b9c5e998cbae300594d0ccfd0c464627" }, + "mason.nvim": { "branch": "main", "commit": "e110bc3be1a7309617cecd77bfe4bf86ba1b8134" }, + "minimap.vim": { "branch": "master", "commit": "701f4cf4b60a3e1685d2da484282f3a3d8bf9db6" }, + "nvim-autopairs": { "branch": "master", "commit": "eac31b4797ce4fa9dd546f7b98ec32305527b19e" }, + "nvim-cmp": { "branch": "main", "commit": "538e37ba87284942c1d76ed38dd497e54e65b891" }, + "nvim-colorizer.lua": { "branch": "master", "commit": "85855b38011114929f4058efc97af1059ab3e41d" }, + "nvim-lspconfig": { "branch": "master", "commit": "8917d2c830e04bf944a699b8c41f097621283828" }, + "nvim-tree.lua": { "branch": "master", "commit": "7bdb220d0fe604a77361e92cdbc7af1b8a412126" }, + "nvim-treesitter": { "branch": "master", "commit": "f197a15b0d1e8d555263af20add51450e5aaa1f0" }, + "nvim-web-devicons": { "branch": "master", "commit": "140edfcf25093e8b321d13e154cbce89ee868ca0" }, + "nvterm": { "branch": "main", "commit": "3e43be1d0ca60cc5e2dfc2d289b06577e7e57e98" }, + "plenary.nvim": { "branch": "master", "commit": "55d9fe89e33efd26f532ef20223e5f9430c8b0c0" }, + "telescope.nvim": { "branch": "master", "commit": "0902bb39ebaf76e655addc65130eb79b29abe6d2" }, + "ui": { "branch": "v2.0", "commit": "1737a2a98e18b635480756e817564b60ff31fc53" }, + "vim-tmux-navigator": { "branch": "master", "commit": "38b1d0402c4600543281dc85b3f51884205674b6" }, + "which-key.nvim": { "branch": "main", "commit": "4433e5ec9a507e5097571ed55c02ea9658fb268a" } +} \ No newline at end of file diff --git a/dot_config/nvim/lua/core/bootstrap.lua b/dot_config/nvim/lua/core/bootstrap.lua new file mode 100644 index 0000000..a5d5c68 --- /dev/null +++ b/dot_config/nvim/lua/core/bootstrap.lua @@ -0,0 +1,62 @@ +local M = {} +local fn = vim.fn + +M.echo = function(str) + vim.cmd "redraw" + vim.api.nvim_echo({ { str, "Bold" } }, true, {}) +end + +local function shell_call(args) + local output = fn.system(args) + assert(vim.v.shell_error == 0, "External call failed with error code: " .. vim.v.shell_error .. "\n" .. output) +end + +M.lazy = function(install_path) + ------------- base46 --------------- + local lazy_path = fn.stdpath "data" .. "/lazy/base46" + + M.echo " Compiling base46 theme to bytecode ..." + + local base46_repo = "https://github.com/NvChad/base46" + shell_call { "git", "clone", "--depth", "1", "-b", "v2.0", base46_repo, lazy_path } + vim.opt.rtp:prepend(lazy_path) + + require("base46").compile() + + --------- lazy.nvim --------------- + M.echo " Installing lazy.nvim & plugins ..." + local repo = "https://github.com/folke/lazy.nvim.git" + shell_call { "git", "clone", "--filter=blob:none", "--branch=stable", repo, install_path } + vim.opt.rtp:prepend(install_path) + + -- install plugins + require "plugins" + + -- mason packages & show post_bootstrap screen + require "nvchad.post_install"() +end + +M.gen_chadrc_template = function() + local path = fn.stdpath "config" .. "/lua/custom" + + if fn.isdirectory(path) ~= 1 then + local input = vim.env.NVCHAD_EXAMPLE_CONFIG or fn.input "Do you want to install example custom config? (y/N): " + + if input:lower() == "y" then + M.echo "Cloning example custom config repo..." + shell_call { "git", "clone", "--depth", "1", "https://github.com/NvChad/example_config", path } + fn.delete(path .. "/.git", "rf") + else + -- use very minimal chadrc + fn.mkdir(path, "p") + + local file = io.open(path .. "/chadrc.lua", "w") + if file then + file:write "---@type ChadrcConfig\nlocal M = {}\n\nM.ui = { theme = 'onedark' }\n\nreturn M" + file:close() + end + end + end +end + +return M diff --git a/dot_config/nvim/lua/core/default_config.lua b/dot_config/nvim/lua/core/default_config.lua new file mode 100644 index 0000000..639916a --- /dev/null +++ b/dot_config/nvim/lua/core/default_config.lua @@ -0,0 +1,92 @@ +local M = {} + +M.options = { + nvchad_branch = "v2.0", +} + +M.ui = { + ------------------------------- base46 ------------------------------------- + -- hl = highlights + hl_add = {}, + hl_override = {}, + changed_themes = {}, + theme_toggle = { "onedark", "one_light" }, + theme = "onedark", -- default theme + transparency = false, + lsp_semantic_tokens = false, -- needs nvim v0.9, just adds highlight groups for lsp semantic tokens + + -- https://github.com/NvChad/base46/tree/v2.0/lua/base46/extended_integrations + extended_integrations = {}, -- these aren't compiled by default, ex: "alpha", "notify" + + -- cmp themeing + cmp = { + icons = true, + lspkind_text = true, + style = "default", -- default/flat_light/flat_dark/atom/atom_colored + border_color = "grey_fg", -- only applicable for "default" style, use color names from base30 variables + selected_item_bg = "colored", -- colored / simple + }, + + telescope = { style = "borderless" }, -- borderless / bordered + + ------------------------------- nvchad_ui modules ----------------------------- + statusline = { + theme = "default", -- default/vscode/vscode_colored/minimal + -- default/round/block/arrow separators work only for default statusline theme + -- round and block will work for minimal theme only + separator_style = "default", + overriden_modules = nil, + }, + + -- lazyload it when there are 1+ buffers + tabufline = { + show_numbers = false, + enabled = true, + lazyload = true, + overriden_modules = nil, + }, + + -- nvdash (dashboard) + nvdash = { + load_on_startup = false, + + header = { + " ▄ ▄ ", + " ▄ ▄▄▄ ▄ ▄▄▄ ▄ ▄ ", + " █ ▄ █▄█ ▄▄▄ █ █▄█ █ █ ", + " ▄▄ █▄█▄▄▄█ █▄█▄█▄▄█▄▄█ █ ", + " ▄ █▄▄█ ▄ ▄▄ ▄█ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ", + " █▄▄▄▄ ▄▄▄ █ ▄ ▄▄▄ ▄ ▄▄▄ ▄ ▄ █ ▄", + "▄ █ █▄█ █▄█ █ █ █▄█ █ █▄█ ▄▄▄ █ █", + "█▄█ ▄ █▄▄█▄▄█ █ ▄▄█ █ ▄ █ █▄█▄█ █", + " █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ █▄█▄▄▄█ ", + }, + + buttons = { + { " Find File", "Spc f f", "Telescope find_files" }, + { "󰈚 Recent Files", "Spc f o", "Telescope oldfiles" }, + { "󰈭 Find Word", "Spc f w", "Telescope live_grep" }, + { " Bookmarks", "Spc m a", "Telescope marks" }, + { " Themes", "Spc t h", "Telescope themes" }, + { " Mappings", "Spc c h", "NvCheatsheet" }, + }, + }, + + cheatsheet = { theme = "grid" }, -- simple/grid + + lsp = { + -- show function signatures i.e args as you type + signature = { + disabled = false, + silent = true, -- silences 'no signature help available' message from appearing + }, + }, +} + +M.plugins = "" -- path i.e "custom.plugins", so make custom/plugins.lua file + +M.lazy_nvim = require "plugins.configs.lazy_nvim" -- config for lazy.nvim startup options + +M.mappings = require "core.mappings" + +return M diff --git a/dot_config/nvim/lua/core/init.lua b/dot_config/nvim/lua/core/init.lua new file mode 100644 index 0000000..19804e1 --- /dev/null +++ b/dot_config/nvim/lua/core/init.lua @@ -0,0 +1,115 @@ +local opt = vim.opt +local g = vim.g +local config = require("core.utils").load_config() + +-------------------------------------- globals ----------------------------------------- +g.nvchad_theme = config.ui.theme +g.base46_cache = vim.fn.stdpath "data" .. "/nvchad/base46/" +g.toggle_theme_icon = "  " +g.transparency = config.ui.transparency + +-------------------------------------- options ------------------------------------------ +opt.laststatus = 3 -- global statusline +opt.showmode = false + +opt.clipboard = "unnamedplus" +opt.cursorline = true + +-- Indenting +opt.expandtab = true +opt.shiftwidth = 2 +opt.smartindent = true +opt.tabstop = 2 +opt.softtabstop = 2 + +opt.fillchars = { eob = " " } +opt.ignorecase = true +opt.smartcase = true +opt.mouse = "a" + +-- Numbers +opt.number = true +opt.numberwidth = 2 +opt.ruler = false + +-- disable nvim intro +opt.shortmess:append "sI" + +opt.signcolumn = "yes" +opt.splitbelow = true +opt.splitright = true +opt.termguicolors = true +opt.timeoutlen = 400 +opt.undofile = true + +-- interval for writing swap file to disk, also used by gitsigns +opt.updatetime = 250 + +-- go to previous/next line with h,l,left arrow and right arrow +-- when cursor reaches end/beginning of line +opt.whichwrap:append "<>[]hl" + +g.mapleader = " " + +-- disable some default providers +for _, provider in ipairs { "node", "perl", "python3", "ruby" } do + vim.g["loaded_" .. provider .. "_provider"] = 0 +end + +-- add binaries installed by mason.nvim to path +local is_windows = vim.loop.os_uname().sysname == "Windows_NT" +vim.env.PATH = vim.fn.stdpath "data" .. "/mason/bin" .. (is_windows and ";" or ":") .. vim.env.PATH + +-------------------------------------- autocmds ------------------------------------------ +local autocmd = vim.api.nvim_create_autocmd + +-- dont list quickfix buffers +autocmd("FileType", { + pattern = "qf", + callback = function() + vim.opt_local.buflisted = false + end, +}) + +-- reload some chadrc options on-save +autocmd("BufWritePost", { + pattern = vim.tbl_map(function(path) + return vim.fs.normalize(vim.loop.fs_realpath(path)) + end, vim.fn.glob(vim.fn.stdpath "config" .. "/lua/custom/**/*.lua", true, true, true)), + group = vim.api.nvim_create_augroup("ReloadNvChad", {}), + + callback = function(opts) + local fp = vim.fn.fnamemodify(vim.fs.normalize(vim.api.nvim_buf_get_name(opts.buf)), ":r") --[[@as string]] + local app_name = vim.env.NVIM_APPNAME and vim.env.NVIM_APPNAME or "nvim" + local module = string.gsub(fp, "^.*/" .. app_name .. "/lua/", ""):gsub("/", ".") + + require("plenary.reload").reload_module "base46" + require("plenary.reload").reload_module(module) + require("plenary.reload").reload_module "custom.chadrc" + + config = require("core.utils").load_config() + + vim.g.nvchad_theme = config.ui.theme + vim.g.transparency = config.ui.transparency + + -- statusline + require("plenary.reload").reload_module("nvchad.statusline." .. config.ui.statusline.theme) + vim.opt.statusline = "%!v:lua.require('nvchad.statusline." .. config.ui.statusline.theme .. "').run()" + + -- tabufline + if config.ui.tabufline.enabled then + require("plenary.reload").reload_module "nvchad.tabufline.modules" + vim.opt.tabline = "%!v:lua.require('nvchad.tabufline.modules').run()" + end + + require("base46").load_all_highlights() + -- vim.cmd("redraw!") + end, +}) + +-------------------------------------- commands ------------------------------------------ +local new_cmd = vim.api.nvim_create_user_command + +new_cmd("NvChadUpdate", function() + require "nvchad.updater"() +end, {}) diff --git a/dot_config/nvim/lua/core/mappings.lua b/dot_config/nvim/lua/core/mappings.lua new file mode 100644 index 0000000..0a652a7 --- /dev/null +++ b/dot_config/nvim/lua/core/mappings.lua @@ -0,0 +1,468 @@ +-- n, v, i, t = mode names + +local M = {} + +M.general = { + i = { + -- go to beginning and end + [""] = { "^i", "Beginning of line" }, + [""] = { "", "End of line" }, + + -- navigate within insert mode + [""] = { "", "Move left" }, + [""] = { "", "Move right" }, + [""] = { "", "Move down" }, + [""] = { "", "Move up" }, + }, + + n = { + [""] = { " noh ", "Clear highlights" }, + -- switch between windows + [""] = { "h", "Window left" }, + [""] = { "l", "Window right" }, + [""] = { "j", "Window down" }, + [""] = { "k", "Window up" }, + + -- save + [""] = { " w ", "Save file" }, + + -- Copy all + [""] = { " %y+ ", "Copy whole file" }, + + -- line numbers + ["n"] = { " set nu! ", "Toggle line number" }, + ["rn"] = { " set rnu! ", "Toggle relative number" }, + + -- Allow moving the cursor through wrapped lines with j, k, and + -- http://www.reddit.com/r/vim/comments/2k4cbr/problem_with_gj_and_gk/ + -- empty mode is same as using :map + -- also don't use g[j|k] when in operator pending mode, so it doesn't alter d, y or c behaviour + ["j"] = { 'v:count || mode(1)[0:1] == "no" ? "j" : "gj"', "Move down", opts = { expr = true } }, + ["k"] = { 'v:count || mode(1)[0:1] == "no" ? "k" : "gk"', "Move up", opts = { expr = true } }, + [""] = { 'v:count || mode(1)[0:1] == "no" ? "k" : "gk"', "Move up", opts = { expr = true } }, + [""] = { 'v:count || mode(1)[0:1] == "no" ? "j" : "gj"', "Move down", opts = { expr = true } }, + + -- new buffer + ["b"] = { " enew ", "New buffer" }, + ["ch"] = { " NvCheatsheet ", "Mapping cheatsheet" }, + + ["fm"] = { + function() + vim.lsp.buf.format { async = true } + end, + "LSP formatting", + }, + }, + + t = { + [""] = { vim.api.nvim_replace_termcodes("", true, true, true), "Escape terminal mode" }, + }, + + v = { + [""] = { 'v:count || mode(1)[0:1] == "no" ? "k" : "gk"', "Move up", opts = { expr = true } }, + [""] = { 'v:count || mode(1)[0:1] == "no" ? "j" : "gj"', "Move down", opts = { expr = true } }, + ["<"] = { ""] = { ">gv", "Indent line" }, + }, + + x = { + ["j"] = { 'v:count || mode(1)[0:1] == "no" ? "j" : "gj"', "Move down", opts = { expr = true } }, + ["k"] = { 'v:count || mode(1)[0:1] == "no" ? "k" : "gk"', "Move up", opts = { expr = true } }, + -- Don't copy the replaced text after pasting in visual mode + -- https://vim.fandom.com/wiki/Replace_a_word_with_yanked_text#Alternative_mapping_for_paste + ["p"] = { 'p:let @+=@0:let @"=@0', "Dont copy replaced text", opts = { silent = true } }, + }, +} + +M.tabufline = { + plugin = true, + + n = { + -- cycle through buffers + [""] = { + function() + require("nvchad.tabufline").tabuflineNext() + end, + "Goto next buffer", + }, + + [""] = { + function() + require("nvchad.tabufline").tabuflinePrev() + end, + "Goto prev buffer", + }, + + -- close buffer + hide terminal buffer + ["x"] = { + function() + require("nvchad.tabufline").close_buffer() + end, + "Close buffer", + }, + }, +} + +M.comment = { + plugin = true, + + -- toggle comment in both modes + n = { + ["/"] = { + function() + require("Comment.api").toggle.linewise.current() + end, + "Toggle comment", + }, + }, + + v = { + ["/"] = { + "lua require('Comment.api').toggle.linewise(vim.fn.visualmode())", + "Toggle comment", + }, + }, +} + +M.lspconfig = { + plugin = true, + + -- See ` :help vim.lsp.*` for documentation on any of the below functions + + n = { + ["gD"] = { + function() + vim.lsp.buf.declaration() + end, + "LSP declaration", + }, + + ["gd"] = { + function() + vim.lsp.buf.definition() + end, + "LSP definition", + }, + + ["K"] = { + function() + vim.lsp.buf.hover() + end, + "LSP hover", + }, + + ["gi"] = { + function() + vim.lsp.buf.implementation() + end, + "LSP implementation", + }, + + ["ls"] = { + function() + vim.lsp.buf.signature_help() + end, + "LSP signature help", + }, + + ["D"] = { + function() + vim.lsp.buf.type_definition() + end, + "LSP definition type", + }, + + ["ra"] = { + function() + require("nvchad.renamer").open() + end, + "LSP rename", + }, + + ["ca"] = { + function() + vim.lsp.buf.code_action() + end, + "LSP code action", + }, + + ["gr"] = { + function() + vim.lsp.buf.references() + end, + "LSP references", + }, + + ["lf"] = { + function() + vim.diagnostic.open_float { border = "rounded" } + end, + "Floating diagnostic", + }, + + ["[d"] = { + function() + vim.diagnostic.goto_prev { float = { border = "rounded" } } + end, + "Goto prev", + }, + + ["]d"] = { + function() + vim.diagnostic.goto_next { float = { border = "rounded" } } + end, + "Goto next", + }, + + ["q"] = { + function() + vim.diagnostic.setloclist() + end, + "Diagnostic setloclist", + }, + + ["wa"] = { + function() + vim.lsp.buf.add_workspace_folder() + end, + "Add workspace folder", + }, + + ["wr"] = { + function() + vim.lsp.buf.remove_workspace_folder() + end, + "Remove workspace folder", + }, + + ["wl"] = { + function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, + "List workspace folders", + }, + }, + + v = { + ["ca"] = { + function() + vim.lsp.buf.code_action() + end, + "LSP code action", + }, + }, +} + +M.nvimtree = { + plugin = true, + + n = { + -- toggle + [""] = { " NvimTreeToggle ", "Toggle nvimtree" }, + + -- focus + ["e"] = { " NvimTreeFocus ", "Focus nvimtree" }, + }, +} + +M.telescope = { + plugin = true, + + n = { + -- find + ["ff"] = { " Telescope find_files ", "Find files" }, + ["fa"] = { " Telescope find_files follow=true no_ignore=true hidden=true ", "Find all" }, + ["fw"] = { " Telescope live_grep ", "Live grep" }, + ["fb"] = { " Telescope buffers ", "Find buffers" }, + ["fh"] = { " Telescope help_tags ", "Help page" }, + ["fo"] = { " Telescope oldfiles ", "Find oldfiles" }, + ["fz"] = { " Telescope current_buffer_fuzzy_find ", "Find in current buffer" }, + + -- git + ["cm"] = { " Telescope git_commits ", "Git commits" }, + ["gt"] = { " Telescope git_status ", "Git status" }, + + -- pick a hidden term + ["pt"] = { " Telescope terms ", "Pick hidden term" }, + + -- theme switcher + ["th"] = { " Telescope themes ", "Nvchad themes" }, + + ["ma"] = { " Telescope marks ", "telescope bookmarks" }, + }, +} + +M.nvterm = { + plugin = true, + + t = { + -- toggle in terminal mode + [""] = { + function() + require("nvterm.terminal").toggle "float" + end, + "Toggle floating term", + }, + + [""] = { + function() + require("nvterm.terminal").toggle "horizontal" + end, + "Toggle horizontal term", + }, + + [""] = { + function() + require("nvterm.terminal").toggle "vertical" + end, + "Toggle vertical term", + }, + }, + + n = { + -- toggle in normal mode + [""] = { + function() + require("nvterm.terminal").toggle "float" + end, + "Toggle floating term", + }, + + [""] = { + function() + require("nvterm.terminal").toggle "horizontal" + end, + "Toggle horizontal term", + }, + + [""] = { + function() + require("nvterm.terminal").toggle "vertical" + end, + "Toggle vertical term", + }, + + -- new + ["h"] = { + function() + require("nvterm.terminal").new "horizontal" + end, + "New horizontal term", + }, + + ["v"] = { + function() + require("nvterm.terminal").new "vertical" + end, + "New vertical term", + }, + }, +} + +M.whichkey = { + plugin = true, + + n = { + ["wK"] = { + function() + vim.cmd "WhichKey" + end, + "Which-key all keymaps", + }, + ["wk"] = { + function() + local input = vim.fn.input "WhichKey: " + vim.cmd("WhichKey " .. input) + end, + "Which-key query lookup", + }, + }, +} + +M.blankline = { + plugin = true, + + n = { + ["cc"] = { + function() + local ok, start = require("indent_blankline.utils").get_current_context( + vim.g.indent_blankline_context_patterns, + vim.g.indent_blankline_use_treesitter_scope + ) + + if ok then + vim.api.nvim_win_set_cursor(vim.api.nvim_get_current_win(), { start, 0 }) + vim.cmd [[normal! _]] + end + end, + + "Jump to current context", + }, + }, +} + +M.gitsigns = { + plugin = true, + + n = { + -- Navigation through hunks + ["]c"] = { + function() + if vim.wo.diff then + return "]c" + end + vim.schedule(function() + require("gitsigns").next_hunk() + end) + return "" + end, + "Jump to next hunk", + opts = { expr = true }, + }, + + ["[c"] = { + function() + if vim.wo.diff then + return "[c" + end + vim.schedule(function() + require("gitsigns").prev_hunk() + end) + return "" + end, + "Jump to prev hunk", + opts = { expr = true }, + }, + + -- Actions + ["rh"] = { + function() + require("gitsigns").reset_hunk() + end, + "Reset hunk", + }, + + ["ph"] = { + function() + require("gitsigns").preview_hunk() + end, + "Preview hunk", + }, + + ["gb"] = { + function() + package.loaded.gitsigns.blame_line() + end, + "Blame line", + }, + + ["td"] = { + function() + require("gitsigns").toggle_deleted() + end, + "Toggle deleted", + }, + }, +} + +return M diff --git a/dot_config/nvim/lua/core/utils.lua b/dot_config/nvim/lua/core/utils.lua new file mode 100644 index 0000000..8b2a03d --- /dev/null +++ b/dot_config/nvim/lua/core/utils.lua @@ -0,0 +1,118 @@ +local M = {} +local merge_tb = vim.tbl_deep_extend + +M.load_config = function() + local config = require "core.default_config" + local chadrc_path = vim.api.nvim_get_runtime_file("lua/custom/chadrc.lua", false)[1] + + if chadrc_path then + local chadrc = dofile(chadrc_path) + + config.mappings = M.remove_disabled_keys(chadrc.mappings, config.mappings) + config = merge_tb("force", config, chadrc) + config.mappings.disabled = nil + end + + return config +end + +M.remove_disabled_keys = function(chadrc_mappings, default_mappings) + if not chadrc_mappings then + return default_mappings + end + + -- store keys in a array with true value to compare + local keys_to_disable = {} + for _, mappings in pairs(chadrc_mappings) do + for mode, section_keys in pairs(mappings) do + if not keys_to_disable[mode] then + keys_to_disable[mode] = {} + end + section_keys = (type(section_keys) == "table" and section_keys) or {} + for k, _ in pairs(section_keys) do + keys_to_disable[mode][k] = true + end + end + end + + -- make a copy as we need to modify default_mappings + for section_name, section_mappings in pairs(default_mappings) do + for mode, mode_mappings in pairs(section_mappings) do + mode_mappings = (type(mode_mappings) == "table" and mode_mappings) or {} + for k, _ in pairs(mode_mappings) do + -- if key if found then remove from default_mappings + if keys_to_disable[mode] and keys_to_disable[mode][k] then + default_mappings[section_name][mode][k] = nil + end + end + end + end + + return default_mappings +end + +M.load_mappings = function(section, mapping_opt) + vim.schedule(function() + local function set_section_map(section_values) + if section_values.plugin then + return + end + + section_values.plugin = nil + + for mode, mode_values in pairs(section_values) do + local default_opts = merge_tb("force", { mode = mode }, mapping_opt or {}) + for keybind, mapping_info in pairs(mode_values) do + -- merge default + user opts + local opts = merge_tb("force", default_opts, mapping_info.opts or {}) + + mapping_info.opts, opts.mode = nil, nil + opts.desc = mapping_info[2] + + vim.keymap.set(mode, keybind, mapping_info[1], opts) + end + end + end + + local mappings = require("core.utils").load_config().mappings + + if type(section) == "string" then + mappings[section]["plugin"] = nil + mappings = { mappings[section] } + end + + for _, sect in pairs(mappings) do + set_section_map(sect) + end + end) +end + +M.lazy_load = function(plugin) + vim.api.nvim_create_autocmd({ "BufRead", "BufWinEnter", "BufNewFile" }, { + group = vim.api.nvim_create_augroup("BeLazyOnFileOpen" .. plugin, {}), + callback = function() + local file = vim.fn.expand "%" + local condition = file ~= "NvimTree_1" and file ~= "[lazy]" and file ~= "" + + if condition then + vim.api.nvim_del_augroup_by_name("BeLazyOnFileOpen" .. plugin) + + -- dont defer for treesitter as it will show slow highlighting + -- This deferring only happens only when we do "nvim filename" + if plugin ~= "nvim-treesitter" then + vim.schedule(function() + require("lazy").load { plugins = plugin } + + if plugin == "nvim-lspconfig" then + vim.cmd "silent! do FileType" + end + end, 0) + else + require("lazy").load { plugins = plugin } + end + end + end, + }) +end + +return M diff --git a/dot_config/nvim/lua/custom/README.md b/dot_config/nvim/lua/custom/README.md new file mode 100644 index 0000000..0cc616c --- /dev/null +++ b/dot_config/nvim/lua/custom/README.md @@ -0,0 +1,3 @@ +# Example_config + +This can be used as an example custom config for NvChad. Do check the https://github.com/NvChad/nvcommunity diff --git a/dot_config/nvim/lua/custom/chadrc.lua b/dot_config/nvim/lua/custom/chadrc.lua new file mode 100644 index 0000000..dd55730 --- /dev/null +++ b/dot_config/nvim/lua/custom/chadrc.lua @@ -0,0 +1,28 @@ +---@type ChadrcConfig +local M = {} + +-- Path to overriding theme and highlights files +local highlights = require "custom.highlights" + +M.ui = { + theme = "catppuccin", + theme_toggle = { "catppuccin", "one_light" }, + + hl_override = highlights.override, + hl_add = highlights.add, +} + +M.plugins = "custom.plugins" + +-- check core.mappings for table structure +M.mappings = require "custom.mappings" + +vim.api.nvim_create_autocmd("VimEnter", { + callback = function() + vim.defer_fn(function() + vim.cmd("NvimTreeToggle") + end, 100) + end +}) + +return M diff --git a/dot_config/nvim/lua/custom/configs/conform.lua b/dot_config/nvim/lua/custom/configs/conform.lua new file mode 100644 index 0000000..4b142bd --- /dev/null +++ b/dot_config/nvim/lua/custom/configs/conform.lua @@ -0,0 +1,24 @@ +local options = { + lsp_fallback = true, + + formatters_by_ft = { + lua = { "stylua" }, + + javascript = { "prettier" }, + css = { "prettier" }, + html = { "prettier" }, + + sh = { "shfmt" }, + }, + + -- adding same formatter for multiple filetypes can look too much work for some + -- instead of the above code you could just use a loop! the config is just a table after all! + + -- format_on_save = { + -- -- These options will be passed to conform.format() + -- timeout_ms = 500, + -- lsp_fallback = true, + -- }, +} + +require("conform").setup(options) diff --git a/dot_config/nvim/lua/custom/configs/lspconfig.lua b/dot_config/nvim/lua/custom/configs/lspconfig.lua new file mode 100644 index 0000000..d6f7f2b --- /dev/null +++ b/dot_config/nvim/lua/custom/configs/lspconfig.lua @@ -0,0 +1,17 @@ +local on_attach = require("plugins.configs.lspconfig").on_attach +local capabilities = require("plugins.configs.lspconfig").capabilities + +local lspconfig = require "lspconfig" + +-- if you just want default config for the servers then put them in a table +local servers = { "html", "cssls", "tsserver", "clangd" } + +for _, lsp in ipairs(servers) do + lspconfig[lsp].setup { + on_attach = on_attach, + capabilities = capabilities, + } +end + +-- +-- lspconfig.pyright.setup { blabla} diff --git a/dot_config/nvim/lua/custom/configs/overrides.lua b/dot_config/nvim/lua/custom/configs/overrides.lua new file mode 100644 index 0000000..c4cd2c7 --- /dev/null +++ b/dot_config/nvim/lua/custom/configs/overrides.lua @@ -0,0 +1,59 @@ +local M = {} + +M.treesitter = { + ensure_installed = { + "vim", + "lua", + "html", + "css", + "javascript", + "typescript", + "tsx", + "c", + "markdown", + "markdown_inline", + }, + indent = { + enable = true, + -- disable = { + -- "python" + -- }, + }, +} + +M.mason = { + ensure_installed = { + -- lua stuff + "lua-language-server", + "stylua", + + -- web dev stuff + "css-lsp", + "html-lsp", + "typescript-language-server", + "deno", + "prettier", + + -- c/cpp stuff + "clangd", + "clang-format", + }, +} + +-- git support in nvimtree +M.nvimtree = { + git = { + enable = true, + }, + + renderer = { + highlight_git = true, + icons = { + show = { + git = true, + }, + }, + }, +} + +return M diff --git a/dot_config/nvim/lua/custom/highlights.lua b/dot_config/nvim/lua/custom/highlights.lua new file mode 100644 index 0000000..ebf2dfb --- /dev/null +++ b/dot_config/nvim/lua/custom/highlights.lua @@ -0,0 +1,19 @@ +-- To find any highlight groups: " Telescope highlights" +-- Each highlight group can take a table with variables fg, bg, bold, italic, etc +-- base30 variable names can also be used as colors + +local M = {} + +---@type Base46HLGroupsList +M.override = { + Comment = { + italic = true, + }, +} + +---@type HLTable +M.add = { + NvimTreeOpenedFolderName = { fg = "green", bold = true }, +} + +return M diff --git a/dot_config/nvim/lua/custom/init.lua b/dot_config/nvim/lua/custom/init.lua new file mode 100644 index 0000000..608a8d9 --- /dev/null +++ b/dot_config/nvim/lua/custom/init.lua @@ -0,0 +1,7 @@ +-- local autocmd = vim.api.nvim_create_autocmd + +-- Auto resize panes when resizing nvim window +-- autocmd("VimResized", { +-- pattern = "*", +-- command = "tabdo wincmd =", +-- }) diff --git a/dot_config/nvim/lua/custom/mappings.lua b/dot_config/nvim/lua/custom/mappings.lua new file mode 100644 index 0000000..b9c8aa6 --- /dev/null +++ b/dot_config/nvim/lua/custom/mappings.lua @@ -0,0 +1,24 @@ +---@type MappingsTable +local M = {} + +M.general = { + n = { + [";"] = { ":", "enter command mode", opts = { nowait = true } }, + + -- format with conform + ["fm"] = { + function() + require("conform").format() + end, + "formatting", + } + + }, + v = { + [">"] = { ">gv", "indent"}, + }, +} + +-- more keybinds! + +return M diff --git a/dot_config/nvim/lua/custom/plugins.lua b/dot_config/nvim/lua/custom/plugins.lua new file mode 100644 index 0000000..a01791b --- /dev/null +++ b/dot_config/nvim/lua/custom/plugins.lua @@ -0,0 +1,74 @@ +local overrides = require("custom.configs.overrides") + +---@type NvPluginSpec[] +local plugins = { + + -- Override plugin definition options + { + "christoomey/vim-tmux-navigator", + lazy = false, + }, + + -- { + -- "wfxr/minimap.vim", + -- lazy = false, + -- }, + + { + "neovim/nvim-lspconfig", + config = function() + require "plugins.configs.lspconfig" + require "custom.configs.lspconfig" + end, -- Override to setup mason-lspconfig + }, + + -- override plugin configs + { + "williamboman/mason.nvim", + opts = overrides.mason + }, + + { + "nvim-treesitter/nvim-treesitter", + opts = overrides.treesitter, + }, + + { + "nvim-tree/nvim-tree.lua", + opts = overrides.nvimtree, + }, + + -- Install a plugin + { + "max397574/better-escape.nvim", + event = "InsertEnter", + config = function() + require("better_escape").setup() + end, + }, + + { + "stevearc/conform.nvim", + -- for users those who want auto-save conform + lazyloading! + -- event = "BufWritePre" + config = function() + require "custom.configs.conform" + end, + }, + + -- To make a plugin not be loaded + -- { + -- "NvChad/nvim-colorizer.lua", + -- enabled = false + -- }, + + -- All NvChad plugins are lazy-loaded by default + -- For a plugin to be loaded, you will need to set either `ft`, `cmd`, `keys`, `event`, or set `lazy = false` + -- If you want a plugin to load on startup, add `lazy = false` to a plugin spec, for example + -- { + -- "mg979/vim-visual-multi", + -- lazy = false, + -- } +} + +return plugins diff --git a/dot_config/nvim/lua/plugins/configs/cmp.lua b/dot_config/nvim/lua/plugins/configs/cmp.lua new file mode 100644 index 0000000..444da73 --- /dev/null +++ b/dot_config/nvim/lua/plugins/configs/cmp.lua @@ -0,0 +1,120 @@ +local cmp = require "cmp" + +dofile(vim.g.base46_cache .. "cmp") + +local cmp_ui = require("core.utils").load_config().ui.cmp +local cmp_style = cmp_ui.style + +local field_arrangement = { + atom = { "kind", "abbr", "menu" }, + atom_colored = { "kind", "abbr", "menu" }, +} + +local formatting_style = { + -- default fields order i.e completion word + item.kind + item.kind icons + fields = field_arrangement[cmp_style] or { "abbr", "kind", "menu" }, + + format = function(_, item) + local icons = require "nvchad.icons.lspkind" + local icon = (cmp_ui.icons and icons[item.kind]) or "" + + if cmp_style == "atom" or cmp_style == "atom_colored" then + icon = " " .. icon .. " " + item.menu = cmp_ui.lspkind_text and " (" .. item.kind .. ")" or "" + item.kind = icon + else + icon = cmp_ui.lspkind_text and (" " .. icon .. " ") or icon + item.kind = string.format("%s %s", icon, cmp_ui.lspkind_text and item.kind or "") + end + + return item + end, +} + +local function border(hl_name) + return { + { "╭", hl_name }, + { "─", hl_name }, + { "╮", hl_name }, + { "│", hl_name }, + { "╯", hl_name }, + { "─", hl_name }, + { "╰", hl_name }, + { "│", hl_name }, + } +end + +local options = { + completion = { + completeopt = "menu,menuone", + }, + + window = { + completion = { + side_padding = (cmp_style ~= "atom" and cmp_style ~= "atom_colored") and 1 or 0, + winhighlight = "Normal:CmpPmenu,CursorLine:CmpSel,Search:None", + scrollbar = false, + }, + documentation = { + border = border "CmpDocBorder", + winhighlight = "Normal:CmpDoc", + }, + }, + snippet = { + expand = function(args) + require("luasnip").lsp_expand(args.body) + end, + }, + + formatting = formatting_style, + + mapping = { + [""] = cmp.mapping.select_prev_item(), + [""] = cmp.mapping.select_next_item(), + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + [""] = cmp.mapping.complete(), + [""] = cmp.mapping.close(), + [""] = cmp.mapping.confirm { + behavior = cmp.ConfirmBehavior.Insert, + select = true, + }, + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif require("luasnip").expand_or_jumpable() then + vim.fn.feedkeys(vim.api.nvim_replace_termcodes("luasnip-expand-or-jump", true, true, true), "") + else + fallback() + end + end, { + "i", + "s", + }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif require("luasnip").jumpable(-1) then + vim.fn.feedkeys(vim.api.nvim_replace_termcodes("luasnip-jump-prev", true, true, true), "") + else + fallback() + end + end, { + "i", + "s", + }), + }, + sources = { + { name = "nvim_lsp" }, + { name = "luasnip" }, + { name = "buffer" }, + { name = "nvim_lua" }, + { name = "path" }, + }, +} + +if cmp_style ~= "atom" and cmp_style ~= "atom_colored" then + options.window.completion.border = border "CmpBorder" +end + +return options diff --git a/dot_config/nvim/lua/plugins/configs/lazy_nvim.lua b/dot_config/nvim/lua/plugins/configs/lazy_nvim.lua new file mode 100644 index 0000000..cd170bd --- /dev/null +++ b/dot_config/nvim/lua/plugins/configs/lazy_nvim.lua @@ -0,0 +1,47 @@ +return { + defaults = { lazy = true }, + install = { colorscheme = { "nvchad" } }, + + ui = { + icons = { + ft = "", + lazy = "󰂠 ", + loaded = "", + not_loaded = "", + }, + }, + + performance = { + rtp = { + disabled_plugins = { + "2html_plugin", + "tohtml", + "getscript", + "getscriptPlugin", + "gzip", + "logipat", + "netrw", + "netrwPlugin", + "netrwSettings", + "netrwFileHandlers", + "matchit", + "tar", + "tarPlugin", + "rrhelper", + "spellfile_plugin", + "vimball", + "vimballPlugin", + "zip", + "zipPlugin", + "tutor", + "rplugin", + "syntax", + "synmenu", + "optwin", + "compiler", + "bugreport", + "ftplugin", + }, + }, + }, +} diff --git a/dot_config/nvim/lua/plugins/configs/lspconfig.lua b/dot_config/nvim/lua/plugins/configs/lspconfig.lua new file mode 100644 index 0000000..f824aa0 --- /dev/null +++ b/dot_config/nvim/lua/plugins/configs/lspconfig.lua @@ -0,0 +1,64 @@ +dofile(vim.g.base46_cache .. "lsp") +require "nvchad.lsp" + +local M = {} +local utils = require "core.utils" + +-- export on_attach & capabilities for custom lspconfigs + +M.on_attach = function(client, bufnr) + utils.load_mappings("lspconfig", { buffer = bufnr }) + + if client.server_capabilities.signatureHelpProvider then + require("nvchad.signature").setup(client) + end + + if not utils.load_config().ui.lsp_semantic_tokens and client.supports_method "textDocument/semanticTokens" then + client.server_capabilities.semanticTokensProvider = nil + end +end + +M.capabilities = vim.lsp.protocol.make_client_capabilities() + +M.capabilities.textDocument.completion.completionItem = { + documentationFormat = { "markdown", "plaintext" }, + snippetSupport = true, + preselectSupport = true, + insertReplaceSupport = true, + labelDetailsSupport = true, + deprecatedSupport = true, + commitCharactersSupport = true, + tagSupport = { valueSet = { 1 } }, + resolveSupport = { + properties = { + "documentation", + "detail", + "additionalTextEdits", + }, + }, +} + +require("lspconfig").lua_ls.setup { + on_attach = M.on_attach, + capabilities = M.capabilities, + + settings = { + Lua = { + diagnostics = { + globals = { "vim" }, + }, + workspace = { + library = { + [vim.fn.expand "$VIMRUNTIME/lua"] = true, + [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true, + [vim.fn.stdpath "data" .. "/lazy/ui/nvchad_types"] = true, + [vim.fn.stdpath "data" .. "/lazy/lazy.nvim/lua/lazy"] = true, + }, + maxPreload = 100000, + preloadFileSize = 10000, + }, + }, + }, +} + +return M diff --git a/dot_config/nvim/lua/plugins/configs/mason.lua b/dot_config/nvim/lua/plugins/configs/mason.lua new file mode 100644 index 0000000..3692a15 --- /dev/null +++ b/dot_config/nvim/lua/plugins/configs/mason.lua @@ -0,0 +1,28 @@ +local options = { + ensure_installed = { "lua-language-server" }, -- not an option from mason.nvim + + PATH = "skip", + + ui = { + icons = { + package_pending = " ", + package_installed = "󰄳 ", + package_uninstalled = " 󰚌", + }, + + keymaps = { + toggle_server_expand = "", + install_server = "i", + update_server = "u", + check_server_version = "c", + update_all_servers = "U", + check_outdated_servers = "C", + uninstall_server = "X", + cancel_installation = "", + }, + }, + + max_concurrent_installers = 10, +} + +return options diff --git a/dot_config/nvim/lua/plugins/configs/nvimtree.lua b/dot_config/nvim/lua/plugins/configs/nvimtree.lua new file mode 100644 index 0000000..b4a8aee --- /dev/null +++ b/dot_config/nvim/lua/plugins/configs/nvimtree.lua @@ -0,0 +1,77 @@ +local options = { + filters = { + dotfiles = false, + exclude = { vim.fn.stdpath "config" .. "/lua/custom" }, + }, + disable_netrw = true, + hijack_netrw = true, + hijack_cursor = true, + hijack_unnamed_buffer_when_opening = false, + sync_root_with_cwd = true, + update_focused_file = { + enable = true, + update_root = false, + }, + view = { + adaptive_size = false, + side = "left", + width = 30, + preserve_window_proportions = true, + }, + git = { + enable = false, + ignore = true, + }, + filesystem_watchers = { + enable = true, + }, + actions = { + open_file = { + resize_window = true, + }, + }, + renderer = { + root_folder_label = false, + highlight_git = false, + highlight_opened_files = "none", + + indent_markers = { + enable = false, + }, + + icons = { + show = { + file = true, + folder = true, + folder_arrow = true, + git = false, + }, + + glyphs = { + default = "󰈚", + symlink = "", + folder = { + default = "", + empty = "", + empty_open = "", + open = "", + symlink = "", + symlink_open = "", + arrow_open = "", + arrow_closed = "", + }, + git = { + unstaged = "✗", + staged = "✓", + unmerged = "", + renamed = "➜", + untracked = "★", + deleted = "", + ignored = "◌", + }, + }, + }, + }, +} + +return options diff --git a/dot_config/nvim/lua/plugins/configs/others.lua b/dot_config/nvim/lua/plugins/configs/others.lua new file mode 100644 index 0000000..dafd5a4 --- /dev/null +++ b/dot_config/nvim/lua/plugins/configs/others.lua @@ -0,0 +1,66 @@ +local M = {} +local utils = require "core.utils" + +M.blankline = { + indentLine_enabled = 1, + filetype_exclude = { + "help", + "terminal", + "lazy", + "lspinfo", + "TelescopePrompt", + "TelescopeResults", + "mason", + "nvdash", + "nvcheatsheet", + "", + }, + buftype_exclude = { "terminal" }, + show_trailing_blankline_indent = false, + show_first_indent_level = false, + show_current_context = true, + show_current_context_start = true, +} + +M.luasnip = function(opts) + require("luasnip").config.set_config(opts) + + -- vscode format + require("luasnip.loaders.from_vscode").lazy_load() + require("luasnip.loaders.from_vscode").lazy_load { paths = vim.g.vscode_snippets_path or "" } + + -- snipmate format + require("luasnip.loaders.from_snipmate").load() + require("luasnip.loaders.from_snipmate").lazy_load { paths = vim.g.snipmate_snippets_path or "" } + + -- lua format + require("luasnip.loaders.from_lua").load() + require("luasnip.loaders.from_lua").lazy_load { paths = vim.g.lua_snippets_path or "" } + + vim.api.nvim_create_autocmd("InsertLeave", { + callback = function() + if + require("luasnip").session.current_nodes[vim.api.nvim_get_current_buf()] + and not require("luasnip").session.jump_active + then + require("luasnip").unlink_current() + end + end, + }) +end + +M.gitsigns = { + signs = { + add = { text = "│" }, + change = { text = "│" }, + delete = { text = "󰍵" }, + topdelete = { text = "‾" }, + changedelete = { text = "~" }, + untracked = { text = "│" }, + }, + on_attach = function(bufnr) + utils.load_mappings("gitsigns", { buffer = bufnr }) + end, +} + +return M diff --git a/dot_config/nvim/lua/plugins/configs/telescope.lua b/dot_config/nvim/lua/plugins/configs/telescope.lua new file mode 100644 index 0000000..784fb19 --- /dev/null +++ b/dot_config/nvim/lua/plugins/configs/telescope.lua @@ -0,0 +1,55 @@ +local options = { + defaults = { + vimgrep_arguments = { + "rg", + "-L", + "--color=never", + "--no-heading", + "--with-filename", + "--line-number", + "--column", + "--smart-case", + }, + prompt_prefix = "  ", + selection_caret = " ", + entry_prefix = " ", + initial_mode = "insert", + selection_strategy = "reset", + sorting_strategy = "ascending", + layout_strategy = "horizontal", + layout_config = { + horizontal = { + prompt_position = "top", + preview_width = 0.55, + results_width = 0.8, + }, + vertical = { + mirror = false, + }, + width = 0.87, + height = 0.80, + preview_cutoff = 120, + }, + file_sorter = require("telescope.sorters").get_fuzzy_file, + file_ignore_patterns = { "node_modules" }, + generic_sorter = require("telescope.sorters").get_generic_fuzzy_sorter, + path_display = { "truncate" }, + winblend = 0, + border = {}, + borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" }, + color_devicons = true, + set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil, + file_previewer = require("telescope.previewers").vim_buffer_cat.new, + grep_previewer = require("telescope.previewers").vim_buffer_vimgrep.new, + qflist_previewer = require("telescope.previewers").vim_buffer_qflist.new, + -- Developer configurations: Not meant for general override + buffer_previewer_maker = require("telescope.previewers").buffer_previewer_maker, + mappings = { + n = { ["q"] = require("telescope.actions").close }, + }, + }, + + extensions_list = { "themes", "terms" }, +} + +return options diff --git a/dot_config/nvim/lua/plugins/configs/treesitter.lua b/dot_config/nvim/lua/plugins/configs/treesitter.lua new file mode 100644 index 0000000..b21b55d --- /dev/null +++ b/dot_config/nvim/lua/plugins/configs/treesitter.lua @@ -0,0 +1,12 @@ +local options = { + ensure_installed = { "lua" }, + + highlight = { + enable = true, + use_languagetree = true, + }, + + indent = { enable = true }, +} + +return options diff --git a/dot_config/nvim/lua/plugins/init.lua b/dot_config/nvim/lua/plugins/init.lua new file mode 100644 index 0000000..27d9e7f --- /dev/null +++ b/dot_config/nvim/lua/plugins/init.lua @@ -0,0 +1,281 @@ +-- All plugins have lazy=true by default,to load a plugin on startup just lazy=false +-- List of all default plugins & their definitions +local default_plugins = { + + "nvim-lua/plenary.nvim", + + { + "NvChad/base46", + branch = "v2.0", + build = function() + require("base46").load_all_highlights() + end, + }, + + { + "NvChad/ui", + branch = "v2.0", + lazy = false, + }, + + { + "NvChad/nvterm", + init = function() + require("core.utils").load_mappings "nvterm" + end, + config = function(_, opts) + require "base46.term" + require("nvterm").setup(opts) + end, + }, + + { + "NvChad/nvim-colorizer.lua", + init = function() + require("core.utils").lazy_load "nvim-colorizer.lua" + end, + config = function(_, opts) + require("colorizer").setup(opts) + + -- execute colorizer as soon as possible + vim.defer_fn(function() + require("colorizer").attach_to_buffer(0) + end, 0) + end, + }, + + { + "nvim-tree/nvim-web-devicons", + opts = function() + return { override = require "nvchad.icons.devicons" } + end, + config = function(_, opts) + dofile(vim.g.base46_cache .. "devicons") + require("nvim-web-devicons").setup(opts) + end, + }, + + { + "lukas-reineke/indent-blankline.nvim", + version = "2.20.7", + init = function() + require("core.utils").lazy_load "indent-blankline.nvim" + end, + opts = function() + return require("plugins.configs.others").blankline + end, + config = function(_, opts) + require("core.utils").load_mappings "blankline" + dofile(vim.g.base46_cache .. "blankline") + require("indent_blankline").setup(opts) + end, + }, + + { + "nvim-treesitter/nvim-treesitter", + tag = "v0.9.2", + init = function() + require("core.utils").lazy_load "nvim-treesitter" + end, + cmd = { "TSInstall", "TSBufEnable", "TSBufDisable", "TSModuleInfo" }, + build = ":TSUpdate", + opts = function() + return require "plugins.configs.treesitter" + end, + config = function(_, opts) + dofile(vim.g.base46_cache .. "syntax") + require("nvim-treesitter.configs").setup(opts) + end, + }, + + -- git stuff + { + "lewis6991/gitsigns.nvim", + ft = { "gitcommit", "diff" }, + init = function() + -- load gitsigns only when a git file is opened + vim.api.nvim_create_autocmd({ "BufRead" }, { + group = vim.api.nvim_create_augroup("GitSignsLazyLoad", { clear = true }), + callback = function() + vim.fn.jobstart({"git", "-C", vim.loop.cwd(), "rev-parse"}, + { + on_exit = function(_, return_code) + if return_code == 0 then + vim.api.nvim_del_augroup_by_name "GitSignsLazyLoad" + vim.schedule(function() + require("lazy").load { plugins = { "gitsigns.nvim" } } + end) + end + end + } + ) + end, + }) + end, + opts = function() + return require("plugins.configs.others").gitsigns + end, + config = function(_, opts) + dofile(vim.g.base46_cache .. "git") + require("gitsigns").setup(opts) + end, + }, + + -- lsp stuff + { + "williamboman/mason.nvim", + cmd = { "Mason", "MasonInstall", "MasonInstallAll", "MasonUpdate" }, + opts = function() + return require "plugins.configs.mason" + end, + config = function(_, opts) + dofile(vim.g.base46_cache .. "mason") + require("mason").setup(opts) + + -- custom nvchad cmd to install all mason binaries listed + vim.api.nvim_create_user_command("MasonInstallAll", function() + if opts.ensure_installed and #opts.ensure_installed > 0 then + vim.cmd("MasonInstall " .. table.concat(opts.ensure_installed, " ")) + end + end, {}) + + vim.g.mason_binaries_list = opts.ensure_installed + end, + }, + + { + "neovim/nvim-lspconfig", + init = function() + require("core.utils").lazy_load "nvim-lspconfig" + end, + config = function() + require "plugins.configs.lspconfig" + end, + }, + + -- load luasnips + cmp related in insert mode only + { + "hrsh7th/nvim-cmp", + event = "InsertEnter", + dependencies = { + { + -- snippet plugin + "L3MON4D3/LuaSnip", + dependencies = "rafamadriz/friendly-snippets", + opts = { history = true, updateevents = "TextChanged,TextChangedI" }, + config = function(_, opts) + require("plugins.configs.others").luasnip(opts) + end, + }, + + -- autopairing of (){}[] etc + { + "windwp/nvim-autopairs", + opts = { + fast_wrap = {}, + disable_filetype = { "TelescopePrompt", "vim" }, + }, + config = function(_, opts) + require("nvim-autopairs").setup(opts) + + -- setup cmp for autopairs + local cmp_autopairs = require "nvim-autopairs.completion.cmp" + require("cmp").event:on("confirm_done", cmp_autopairs.on_confirm_done()) + end, + }, + + -- cmp sources plugins + { + "saadparwaiz1/cmp_luasnip", + "hrsh7th/cmp-nvim-lua", + "hrsh7th/cmp-nvim-lsp", + "hrsh7th/cmp-buffer", + "hrsh7th/cmp-path", + }, + }, + opts = function() + return require "plugins.configs.cmp" + end, + config = function(_, opts) + require("cmp").setup(opts) + end, + }, + + { + "numToStr/Comment.nvim", + keys = { + { "gcc", mode = "n", desc = "Comment toggle current line" }, + { "gc", mode = { "n", "o" }, desc = "Comment toggle linewise" }, + { "gc", mode = "x", desc = "Comment toggle linewise (visual)" }, + { "gbc", mode = "n", desc = "Comment toggle current block" }, + { "gb", mode = { "n", "o" }, desc = "Comment toggle blockwise" }, + { "gb", mode = "x", desc = "Comment toggle blockwise (visual)" }, + }, + init = function() + require("core.utils").load_mappings "comment" + end, + config = function(_, opts) + require("Comment").setup(opts) + end, + }, + + -- file managing , picker etc + { + "nvim-tree/nvim-tree.lua", + cmd = { "NvimTreeToggle", "NvimTreeFocus" }, + init = function() + require("core.utils").load_mappings "nvimtree" + end, + opts = function() + return require "plugins.configs.nvimtree" + end, + config = function(_, opts) + dofile(vim.g.base46_cache .. "nvimtree") + require("nvim-tree").setup(opts) + end, + }, + + { + "nvim-telescope/telescope.nvim", + dependencies = { "nvim-treesitter/nvim-treesitter" }, + cmd = "Telescope", + init = function() + require("core.utils").load_mappings "telescope" + end, + opts = function() + return require "plugins.configs.telescope" + end, + config = function(_, opts) + dofile(vim.g.base46_cache .. "telescope") + local telescope = require "telescope" + telescope.setup(opts) + + -- load extensions + for _, ext in ipairs(opts.extensions_list) do + telescope.load_extension(ext) + end + end, + }, + + -- Only load whichkey after all the gui + { + "folke/which-key.nvim", + keys = { "", "", "", '"', "'", "`", "c", "v", "g" }, + init = function() + require("core.utils").load_mappings "whichkey" + end, + cmd = "WhichKey", + config = function(_, opts) + dofile(vim.g.base46_cache .. "whichkey") + require("which-key").setup(opts) + end, + }, +} + +local config = require("core.utils").load_config() + +if #config.plugins > 0 then + table.insert(default_plugins, { import = config.plugins }) +end + +require("lazy").setup(default_plugins, config.lazy_nvim) diff --git a/dot_config/tmux/plugins/catppuccin-tmux/LICENSE b/dot_config/tmux/plugins/catppuccin-tmux/LICENSE new file mode 100644 index 0000000..006383b --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Catppuccin + +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. diff --git a/dot_config/tmux/plugins/catppuccin-tmux/README.md b/dot_config/tmux/plugins/catppuccin-tmux/README.md new file mode 100644 index 0000000..8106ae2 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/README.md @@ -0,0 +1,117 @@ +

+ Logo
+ + Catppuccin for Tmux + +

+ +

+ + + +

+ +

+ +

+ +## Themes + +- 🌻 [Latte](./catppuccin-latte.tmuxtheme) +- 🪴 [Frappé](./catppuccin-frappe.tmuxtheme) +- 🌺 [Macchiato](./catppuccin-macchiato.tmuxtheme) +- 🌿 [Mocha](./catppuccin-mocha.tmuxtheme) + +## Usage + +### TPM + +1. Install [TPM](https://github.com/tmux-plugins/tpm) +2. Add the Catppuccin plugin: + +```bash +set -g @plugin 'catppuccin/tmux' +# ...alongside +set -g @plugin 'tmux-plugins/tpm' +``` + +3. (Optional) Set your preferred flavour, it defaults to `"mocha"`: + +```bash +set -g @catppuccin_flavour 'latte' # or frappe, macchiato, mocha +``` + +### Manual + +1. Copy your desired theme's configuration contents into your Tmux config (usually stored at `~/.tmux.conf`) +2. Reload Tmux by either restarting the session or reloading it with `tmux source-file ~/.tmux.conf` + +#### Configuration options + +All flavours support certain levels of customization that match our [Catppuccin +Style Guide][style-guide]. To add these customizations, add any of the following +options to your Tmux configuration. + +In order to have the correct icons displayed please use your favorite nerd fonts patched font. + +##### Enable window tabs + +By default, the theme places the `window-status` in the `status-right`. With +`@catppuccin_window_tabs_enabled` set to `on`, the theme will place the +directory within the `status-right` and move the window names to the +`window-status` format variables. + +```sh +set -g @catppuccin_window_tabs_enabled on # or off to disable window_tabs +``` + +##### Configure separator + +By default, the theme will use a round separator for left and right. +To overwrite it use `@catppuccin_left_separator` and `@catppuccin_right_separator` + +```sh +set -g @catppuccin_left_separator "█" +set -g @catppuccin_right_separator "█" +``` + +##### Enable DateTime + +By default, the `date_time` componenet is set to off. +It can be enabled by specifing any tmux date and time format. + +```sh +set -g @catppuccin_date_time "%Y-%m-%d %H:%M" +``` + +##### Enable User + +By default, the `user` componenet is set to off. +It can be enabled by toggoling it on. + +```sh +set -g @catppuccin_user "on" +``` + +##### Enable Host + +By default, the `host` componenet is set to off. +It can be enabled by toggoling it on. + +```sh +set -g @catppuccin_host "on" +``` + +[style-guide]: https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md + +## 💝 Thanks to + +- [Pocco81](https://github.com/catppuccin) +- [vinnyA3](https://github.com/vinnyA3) +- [rogeruiz](https://github.com/rogeruiz) + +  + +

+

Copyright © 2021-present Catppuccin Org +

diff --git a/dot_config/tmux/plugins/catppuccin-tmux/assets/frappe.webp b/dot_config/tmux/plugins/catppuccin-tmux/assets/frappe.webp new file mode 100644 index 0000000..64c14f8 Binary files /dev/null and b/dot_config/tmux/plugins/catppuccin-tmux/assets/frappe.webp differ diff --git a/dot_config/tmux/plugins/catppuccin-tmux/assets/latte.webp b/dot_config/tmux/plugins/catppuccin-tmux/assets/latte.webp new file mode 100644 index 0000000..6e48ac9 Binary files /dev/null and b/dot_config/tmux/plugins/catppuccin-tmux/assets/latte.webp differ diff --git a/dot_config/tmux/plugins/catppuccin-tmux/assets/macchiato.webp b/dot_config/tmux/plugins/catppuccin-tmux/assets/macchiato.webp new file mode 100644 index 0000000..df3aa04 Binary files /dev/null and b/dot_config/tmux/plugins/catppuccin-tmux/assets/macchiato.webp differ diff --git a/dot_config/tmux/plugins/catppuccin-tmux/assets/mocha.webp b/dot_config/tmux/plugins/catppuccin-tmux/assets/mocha.webp new file mode 100644 index 0000000..d9ee469 Binary files /dev/null and b/dot_config/tmux/plugins/catppuccin-tmux/assets/mocha.webp differ diff --git a/dot_config/tmux/plugins/catppuccin-tmux/assets/preview.webp b/dot_config/tmux/plugins/catppuccin-tmux/assets/preview.webp new file mode 100644 index 0000000..3224dc1 Binary files /dev/null and b/dot_config/tmux/plugins/catppuccin-tmux/assets/preview.webp differ diff --git a/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-frappe.tmuxtheme b/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-frappe.tmuxtheme new file mode 100644 index 0000000..a38a73f --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-frappe.tmuxtheme @@ -0,0 +1,17 @@ +# NOTE: you can use vars with $ and ${} as long as the str is double quoted: "" +# WARNING: hex colors can't contain capital letters + +# --> Catppuccin (Frappe) +thm_bg="#303446" +thm_fg="#c6d0f5" +thm_cyan="#99d1db" +thm_black="#292c3c" +thm_gray="#414559" +thm_magenta="#ca9ee6" +thm_pink="#f4b8e4" +thm_red="#e78284" +thm_green="#a6d189" +thm_yellow="#e5c890" +thm_blue="#8caaee" +thm_orange="#ef9f76" +thm_black4="#626880" diff --git a/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-latte.tmuxtheme b/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-latte.tmuxtheme new file mode 100644 index 0000000..16f078f --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-latte.tmuxtheme @@ -0,0 +1,17 @@ +# NOTE: you can use vars with $ and ${} as long as the str is double quoted: "" +# WARNING: hex colors can't contain capital letters + +# --> Catppuccin (Latte) +thm_bg="#dce0e8" +thm_fg="#4c4f69" +thm_cyan="#179299" +thm_black="#e6e9ef" +thm_gray="#bcc0cc" +thm_magenta="#ea76cb" +thm_pink="#8839ef" +thm_red="#d20f39" +thm_green="#40a02b" +thm_yellow="#df8e1d" +thm_blue="#1e66f5" +thm_orange="#fe640b" +thm_black4="#acb0be" diff --git a/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-macchiato.tmuxtheme b/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-macchiato.tmuxtheme new file mode 100644 index 0000000..c90bf76 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-macchiato.tmuxtheme @@ -0,0 +1,17 @@ +# NOTE: you can use vars with $ and ${} as long as the str is double quoted: "" +# WARNING: hex colors can't contain capital letters + +# --> Catppuccin (Macchiato) +thm_bg="#24273a" +thm_fg="#cad3f5" +thm_cyan="#91d7e3" +thm_black="#1e2030" +thm_gray="#363a4f" +thm_magenta="#c6a0f6" +thm_pink="#f5bde6" +thm_red="#ed8796" +thm_green="#a6da95" +thm_yellow="#eed49f" +thm_blue="#8aadf4" +thm_orange="#f5a97f" +thm_black4="#5b6078" diff --git a/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-mocha.tmuxtheme b/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-mocha.tmuxtheme new file mode 100644 index 0000000..41e6369 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/catppuccin-mocha.tmuxtheme @@ -0,0 +1,17 @@ +# NOTE: you can use vars with $ and ${} as long as the str is double quoted: "" +# WARNING: hex colors can't contain capital letters + +# --> Catppuccin (Mocha) +thm_bg="#1e1e2e" +thm_fg="#cdd6f4" +thm_cyan="#89dceb" +thm_black="#181825" +thm_gray="#313244" +thm_magenta="#cba6f7" +thm_pink="#f5c2e7" +thm_red="#f38ba8" +thm_green="#a6e3a1" +thm_yellow="#f9e2af" +thm_blue="#89b4fa" +thm_orange="#fab387" +thm_black4="#585b70" diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_editorconfig b/dot_config/tmux/plugins/catppuccin-tmux/dot_editorconfig new file mode 100644 index 0000000..d86ac02 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_editorconfig @@ -0,0 +1,34 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# EditorConfig is awesome: https://EditorConfig.org + +root = true + +[*] +charset = utf-8 +indent_size = 2 +indent_style = space +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +# go +[*.go] +indent_style = tab +indent_size = 4 + +# python +[*.{ini,py,py.tpl,rst}] +indent_size = 4 + +# rust +[*.rs] +indent_size = 4 + +# documentation, utils +[*.{md,mdx,diff}] +trim_trailing_whitespace = false + +# windows shell scripts +[*.{cmd,bat,ps1}] +end_of_line = crlf diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/HEAD b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/HEAD new file mode 100644 index 0000000..b870d82 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/config b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/config new file mode 100644 index 0000000..93aa7a2 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/config @@ -0,0 +1,13 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[submodule] + active = . +[remote "origin"] + url = https://git::@github.com/dreamsofcode-io/catppuccin-tmux + fetch = +refs/heads/main:refs/remotes/origin/main +[branch "main"] + remote = origin + merge = refs/heads/main diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/description b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_applypatch-msg.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_commit-msg.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_fsmonitor-watchman.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_post-update.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-applypatch.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-commit.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-merge-commit.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-push.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-rebase.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-receive.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_prepare-commit-msg.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_push-to-checkout.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_update.sample b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/index b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/index new file mode 100644 index 0000000..b43e5e8 Binary files /dev/null and b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/index differ diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/info/exclude b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/logs/HEAD b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/logs/HEAD new file mode 100644 index 0000000..b2d55db --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 b4e0715356f820fc72ea8e8baf34f0f60e891718 Wizzard 1705878653 -0500 clone: from https://github.com/dreamsofcode-io/catppuccin-tmux diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/logs/refs/heads/main b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/logs/refs/heads/main new file mode 100644 index 0000000..b2d55db --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/logs/refs/heads/main @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 b4e0715356f820fc72ea8e8baf34f0f60e891718 Wizzard 1705878653 -0500 clone: from https://github.com/dreamsofcode-io/catppuccin-tmux diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/logs/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..b2d55db --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 b4e0715356f820fc72ea8e8baf34f0f60e891718 Wizzard 1705878653 -0500 clone: from https://github.com/dreamsofcode-io/catppuccin-tmux diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/objects/pack/readonly_pack-7ec9d5280771851939be7b87b903b1b41a252ff5.idx b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/objects/pack/readonly_pack-7ec9d5280771851939be7b87b903b1b41a252ff5.idx new file mode 100644 index 0000000..44bc61e Binary files /dev/null and b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/objects/pack/readonly_pack-7ec9d5280771851939be7b87b903b1b41a252ff5.idx differ diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/objects/pack/readonly_pack-7ec9d5280771851939be7b87b903b1b41a252ff5.pack b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/objects/pack/readonly_pack-7ec9d5280771851939be7b87b903b1b41a252ff5.pack new file mode 100644 index 0000000..b8d8fc7 Binary files /dev/null and b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/objects/pack/readonly_pack-7ec9d5280771851939be7b87b903b1b41a252ff5.pack differ diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/objects/pack/readonly_pack-7ec9d5280771851939be7b87b903b1b41a252ff5.rev b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/objects/pack/readonly_pack-7ec9d5280771851939be7b87b903b1b41a252ff5.rev new file mode 100644 index 0000000..168d3f0 Binary files /dev/null and b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/objects/pack/readonly_pack-7ec9d5280771851939be7b87b903b1b41a252ff5.rev differ diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/packed-refs b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/packed-refs new file mode 100644 index 0000000..c960ad5 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +b4e0715356f820fc72ea8e8baf34f0f60e891718 refs/remotes/origin/main diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/refs/heads/main b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/refs/heads/main new file mode 100644 index 0000000..3d1d1ee --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/refs/heads/main @@ -0,0 +1 @@ +b4e0715356f820fc72ea8e8baf34f0f60e891718 diff --git a/dot_config/tmux/plugins/catppuccin-tmux/dot_git/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/refs/remotes/origin/HEAD new file mode 100644 index 0000000..4b0a875 --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/dot_git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/main diff --git a/dot_config/tmux/plugins/catppuccin-tmux/empty_dot_gitignore b/dot_config/tmux/plugins/catppuccin-tmux/empty_dot_gitignore new file mode 100644 index 0000000..e69de29 diff --git a/dot_config/tmux/plugins/catppuccin-tmux/executable_catppuccin.tmux b/dot_config/tmux/plugins/catppuccin-tmux/executable_catppuccin.tmux new file mode 100644 index 0000000..ebd3c8a --- /dev/null +++ b/dot_config/tmux/plugins/catppuccin-tmux/executable_catppuccin.tmux @@ -0,0 +1,168 @@ +#!/usr/bin/env bash +PLUGIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +get_tmux_option() { + local option value default + option="$1" + default="$2" + value="$(tmux show-option -gqv "$option")" + + if [ -n "$value" ]; then + echo "$value" + else + echo "$default" + fi +} + +set() { + local option=$1 + local value=$2 + tmux_commands+=(set-option -gq "$option" "$value" ";") +} + +setw() { + local option=$1 + local value=$2 + tmux_commands+=(set-window-option -gq "$option" "$value" ";") +} + +main() { + local theme + theme="$(get_tmux_option "@catppuccin_flavour" "mocha")" + + # Aggregate all commands in one array + local tmux_commands=() + + # NOTE: Pulling in the selected theme by the theme that's being set as local + # variables. + # shellcheck source=catppuccin-frappe.tmuxtheme + source /dev/stdin <<<"$(sed -e "/^[^#].*=/s/^/local /" "${PLUGIN_DIR}/catppuccin-${theme}.tmuxtheme")" + + # status + set status "on" + set status-bg "${thm_bg}" + set status-justify "left" + set status-left-length "100" + set status-right-length "100" + + # messages + set message-style "fg=${thm_cyan},bg=${thm_gray},align=centre" + set message-command-style "fg=${thm_cyan},bg=${thm_gray},align=centre" + + # panes + set pane-border-style "fg=${thm_gray}" + set pane-active-border-style "fg=${thm_blue}" + + # windows + setw window-status-activity-style "fg=${thm_fg},bg=${thm_bg},none" + setw window-status-separator "" + setw window-status-style "fg=${thm_fg},bg=${thm_bg},none" + + # --------=== Statusline + + # NOTE: Checking for the value of @catppuccin_window_tabs_enabled + local wt_enabled + wt_enabled="$(get_tmux_option "@catppuccin_window_tabs_enabled" "off")" + readonly wt_enabled + + local right_separator + right_separator="$(get_tmux_option "@catppuccin_right_separator" "")" + readonly right_separator + + local left_separator + left_separator="$(get_tmux_option "@catppuccin_left_separator" "")" + readonly left_separator + + local user + user="$(get_tmux_option "@catppuccin_user" "off")" + readonly user + + local host + host="$(get_tmux_option "@catppuccin_host" "off")" + readonly host + + local date_time + date_time="$(get_tmux_option "@catppuccin_date_time" "off")" + readonly date_time + + # These variables are the defaults so that the setw and set calls are easier to parse. + local show_directory + readonly show_directory="#[fg=$thm_pink,bg=$thm_bg,nobold,nounderscore,noitalics]$right_separator#[fg=$thm_bg,bg=$thm_pink,nobold,nounderscore,noitalics] #[fg=$thm_fg,bg=$thm_gray] #{b:pane_current_path} #{?client_prefix,#[fg=$thm_red]" + + local show_window + readonly show_window="#[fg=$thm_pink,bg=$thm_bg,nobold,nounderscore,noitalics]$right_separator#[fg=$thm_bg,bg=$thm_pink,nobold,nounderscore,noitalics] #[fg=$thm_fg,bg=$thm_gray] #W #{?client_prefix,#[fg=$thm_red]" + + local show_session + readonly show_session="#[fg=$thm_green]}#[bg=$thm_gray]$right_separator#{?client_prefix,#[bg=$thm_red],#[bg=$thm_green]}#[fg=$thm_bg] #[fg=$thm_fg,bg=$thm_gray] #S " + + local show_directory_in_window_status + #readonly show_directory_in_window_status="#[fg=$thm_bg,bg=$thm_blue] #I #[fg=$thm_fg,bg=$thm_gray] #{b:pane_current_path} " + readonly show_directory_in_window_status="#[fg=$thm_bg,bg=$thm_blue] #I #[fg=$thm_fg,bg=$thm_gray] #W " + + local show_directory_in_window_status_current + #readonly show_directory_in_window_status_current="#[fg=$thm_bg,bg=$thm_orange] #I #[fg=$thm_fg,bg=$thm_bg] #{b:pane_current_path} " + readonly show_directory_in_window_status_current="#[fg=colour232,bg=$thm_orange] #I #[fg=colour255,bg=colour237] #(echo '#{pane_current_path}' | rev | cut -d'/' -f-2 | rev) " + + local show_window_in_window_status + readonly show_window_in_window_status="#[fg=$thm_fg,bg=$thm_bg] #W #[fg=$thm_bg,bg=$thm_blue] #I#[fg=$thm_blue,bg=$thm_bg]$left_separator#[fg=$thm_fg,bg=$thm_bg,nobold,nounderscore,noitalics] " + + local show_window_in_window_status_current + readonly show_window_in_window_status_current="#[fg=$thm_fg,bg=$thm_gray] #W #[fg=$thm_bg,bg=$thm_orange] #I#[fg=$thm_orange,bg=$thm_bg]$left_separator#[fg=$thm_fg,bg=$thm_bg,nobold,nounderscore,noitalics] " + #setw -g window-status-current-format "#[fg=colour232,bg=$thm_orange] #I #[fg=colour255,bg=colour237] #(echo '#{pane_current_path}' | rev | cut -d'/' -f-2 | rev) " + + + local show_user + readonly show_user="#[fg=$thm_blue,bg=$thm_gray]$right_separator#[fg=$thm_bg,bg=$thm_blue] #[fg=$thm_fg,bg=$thm_gray] #(whoami) " + + local show_host + readonly show_host="#[fg=$thm_blue,bg=$thm_gray]$right_separator#[fg=$thm_bg,bg=$thm_blue]󰒋 #[fg=$thm_fg,bg=$thm_gray] #H " + + local show_date_time + readonly show_date_time="#[fg=$thm_blue,bg=$thm_gray]$right_separator#[fg=$thm_bg,bg=$thm_blue] #[fg=$thm_fg,bg=$thm_gray] $date_time " + + # Right column 1 by default shows the Window name. + local right_column1=$show_window + + # Right column 2 by default shows the current Session name. + local right_column2=$show_session + + # Window status by default shows the current directory basename. + local window_status_format=$show_directory_in_window_status + local window_status_current_format=$show_directory_in_window_status_current + + # NOTE: With the @catppuccin_window_tabs_enabled set to on, we're going to + # update the right_column1 and the window_status_* variables. + if [[ "${wt_enabled}" == "on" ]]; then + right_column1=$show_directory + window_status_format=$show_window_in_window_status + window_status_current_format=$show_window_in_window_status_current + fi + + if [[ "${user}" == "on" ]]; then + right_column2=$right_column2$show_user + fi + + if [[ "${host}" == "on" ]]; then + right_column2=$right_column2$show_host + fi + + if [[ "${date_time}" != "off" ]]; then + right_column2=$right_column2$show_date_time + fi + + set status-left "" + + set status-right "${right_column1},${right_column2}" + + setw window-status-format "${window_status_format}" + setw window-status-current-format "${window_status_current_format}" + + # --------=== Modes + # + setw clock-mode-colour "${thm_blue}" + setw mode-style "fg=${thm_pink} bg=${thm_black4} bold" + + tmux "${tmux_commands[@]}" +} + +main "$@" diff --git a/dot_config/tmux/plugins/tmux-sensible/CHANGELOG.md b/dot_config/tmux/plugins/tmux-sensible/CHANGELOG.md new file mode 100644 index 0000000..579c0db --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/CHANGELOG.md @@ -0,0 +1,43 @@ +# Changelog + +### master +- remove `detach-on-destroy` +- do not set `aggressive-resize` on iTerm terminal +- disable `detach-on-destroy` + +### v3.0.0, 2015-06-24 +- remove 'almost sensible' feature + +### v2.3.0, 2015-06-24 +- update to support \*THE\* latest tmux version +- bugfix for `prefix + R` key binding +- fix for tmux 2.0 `default-terminal` option (thanks @kwbr) + +### v2.2.0, 2015-02-10 +- bugfix in `key_binding_not_set`: the regex is now properly detecting key + bindings with `-r` flag. +- enable `aggressive-resize` + +### v2.1.0, 2014-12-12 +- check before binding `prefix + prefix` (@m1foley) +- enable `focus-events` +- deprecate 'almost sensible' feature. The reason for this is to focus the + plugin on doing just one thing. + +### v2.0.0, 2014-10-03 +- bugfix: prevent exiting tmux if 'reattach-to-user-namespace' is not installed +- remove all mouse-related options +- introduce 'almost sensible' setting and options + +### v1.1.0, 2014-08-30 +- bugfix: determine the default shell from the $SHELL env var on OS X +- set `mode-mouse on` by default +- do not make any decision about the prefix, just enhance it +- update `README.md`. List options set in the plugin. +- do *not* set `mode-mouse on` by default because some users don't like it +- if a user changes default prefix but binds `C-b` to something else, do not + unbind `C-b` + +### v1.0.0, 2014-07-30 +- initial work on the plugin +- add readme diff --git a/dot_config/tmux/plugins/tmux-sensible/LICENSE.md b/dot_config/tmux/plugins/tmux-sensible/LICENSE.md new file mode 100644 index 0000000..40f6ddd --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (C) 2014 Bruno Sutic + +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. diff --git a/dot_config/tmux/plugins/tmux-sensible/README.md b/dot_config/tmux/plugins/tmux-sensible/README.md new file mode 100644 index 0000000..fff34fa --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/README.md @@ -0,0 +1,122 @@ +# Tmux sensible + +A set of tmux options that should be acceptable to everyone. + +Inspired by [vim-sensible](https://github.com/tpope/vim-sensible). + +Tested and working on Linux, OSX and Cygwin. + +### Principles + +- `tmux-sensible` options should be acceptable to **every** tmux user!
+ If any of the options bothers you, please open an issue and it will probably + be updated (or removed). +- if you think a new option should be added, feel free to open a pull request. +- **no overriding** of user defined settings.
+ Your existing `.tmux.conf` settings are respected and they won't be changed. + That way you can use `tmux-sensible` if you have a few specific options. + +### Goals + +- group standard tmux community options in one place +- remove clutter from your `.tmux.conf` +- educate new tmux users about basic options + +### Options + +```tmux +# Address vim mode switching delay (http://superuser.com/a/252717/65504) +set -s escape-time 0 + +# Increase scrollback buffer size from 2000 to 50000 lines +set -g history-limit 50000 + +# Increase tmux messages display duration from 750ms to 4s +set -g display-time 4000 + +# Refresh 'status-left' and 'status-right' more often, from every 15s to 5s +set -g status-interval 5 + +# (OS X) Fix pbcopy/pbpaste for old tmux versions (pre 2.6) +set -g default-command "reattach-to-user-namespace -l $SHELL" + +# Upgrade $TERM +set -g default-terminal "screen-256color" + +# Emacs key bindings in tmux command prompt (prefix + :) are better than +# vi keys, even for vim users +set -g status-keys emacs + +# Focus events enabled for terminals that support them +set -g focus-events on + +# Super useful when using "grouped sessions" and multi-monitor setup +setw -g aggressive-resize on +``` + +### Key bindings + +```tmux +# Easier and faster switching between next/prev window +bind C-p previous-window +bind C-n next-window +``` + +Above bindings enhance the default `prefix + p` and `prefix + n` bindings by +allowing you to hold `Ctrl` and repeat `a + p`/`a + n` (if your prefix is +`C-a`), which is a lot quicker. + +```tmux +# Source .tmux.conf as suggested in `man tmux` +bind R source-file '~/.tmux.conf' +``` + +"Adaptable" key bindings that build upon your `prefix` value: + +```tmux +# If prefix is 'C-a' +bind C-a send-prefix +bind a last-window +``` + +If prefix is `C-b`, above keys will be `C-b` and `b`.
+If prefix is `C-z`, above keys will be `C-z` and `z`... you get the idea. + +### Installation with [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) (recommended) + +Add plugin to the list of TPM plugins in `.tmux.conf`: + +```tmux +set -g @plugin 'tmux-plugins/tmux-sensible' +``` + +Hit `prefix + I` to fetch the plugin and source it. That's it! + +### Manual Installation + +Clone the repo: + + $ git clone https://github.com/tmux-plugins/tmux-sensible ~/clone/path + +Add this line to the bottom of `.tmux.conf`: + +```tmux +run-shell ~/clone/path/sensible.tmux +``` + +Reload TMUX environment with `$ tmux source-file ~/.tmux.conf`, and that's it. + +### Other goodies + +You might also find these useful: + +- [copycat](https://github.com/tmux-plugins/tmux-copycat) + improve tmux search and reduce mouse usage +- [pain control](https://github.com/tmux-plugins/tmux-pain-control) + useful standard bindings for controlling panes +- [resurrect](https://github.com/tmux-plugins/tmux-resurrect) + persists tmux environment across system restarts + +### License + +[MIT](LICENSE.md) diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/HEAD b/dot_config/tmux/plugins/tmux-sensible/dot_git/HEAD new file mode 100644 index 0000000..cb089cd --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/config b/dot_config/tmux/plugins/tmux-sensible/dot_git/config new file mode 100644 index 0000000..d3eb0d4 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/config @@ -0,0 +1,13 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[submodule] + active = . +[remote "origin"] + url = https://git::@github.com/tmux-plugins/tmux-sensible + fetch = +refs/heads/master:refs/remotes/origin/master +[branch "master"] + remote = origin + merge = refs/heads/master diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/description b/dot_config/tmux/plugins/tmux-sensible/dot_git/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_applypatch-msg.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_commit-msg.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_fsmonitor-watchman.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_post-update.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-applypatch.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-commit.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-merge-commit.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-push.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-rebase.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-receive.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_prepare-commit-msg.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_push-to-checkout.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_update.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/index b/dot_config/tmux/plugins/tmux-sensible/dot_git/index new file mode 100644 index 0000000..9152bd3 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-sensible/dot_git/index differ diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/info/exclude b/dot_config/tmux/plugins/tmux-sensible/dot_git/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/HEAD b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/HEAD new file mode 100644 index 0000000..d122a12 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 25cb91f42d020f675bb0a2ce3fbd3a5d96119efa Wizzard 1705878652 -0500 clone: from https://github.com/tmux-plugins/tmux-sensible diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/heads/master b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/heads/master new file mode 100644 index 0000000..d122a12 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 25cb91f42d020f675bb0a2ce3fbd3a5d96119efa Wizzard 1705878652 -0500 clone: from https://github.com/tmux-plugins/tmux-sensible diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..d122a12 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 25cb91f42d020f675bb0a2ce3fbd3a5d96119efa Wizzard 1705878652 -0500 clone: from https://github.com/tmux-plugins/tmux-sensible diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.idx b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.idx new file mode 100644 index 0000000..2cdcae9 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.idx differ diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.pack b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.pack new file mode 100644 index 0000000..adb25e1 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.pack differ diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.rev b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.rev new file mode 100644 index 0000000..a2745c4 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.rev differ diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/packed-refs b/dot_config/tmux/plugins/tmux-sensible/dot_git/packed-refs new file mode 100644 index 0000000..aa00119 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +25cb91f42d020f675bb0a2ce3fbd3a5d96119efa refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/heads/master b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/heads/master new file mode 100644 index 0000000..61072b5 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/heads/master @@ -0,0 +1 @@ +25cb91f42d020f675bb0a2ce3fbd3a5d96119efa diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/remotes/origin/HEAD new file mode 100644 index 0000000..6efe28f --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.0.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.0.0 new file mode 100644 index 0000000..f9c2582 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.0.0 @@ -0,0 +1 @@ +bb7593b2c5c6c76a2872981f837d16e6ddbeff53 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.1.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.1.0 new file mode 100644 index 0000000..9a414ff --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.1.0 @@ -0,0 +1 @@ +dfea8c551c6c6b5e03873476360a732cc798f3a5 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.0.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.0.0 new file mode 100644 index 0000000..58a2b6e --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.0.0 @@ -0,0 +1 @@ +8478e668197b78c46e2fe934ea2b582587731be9 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.1.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.1.0 new file mode 100644 index 0000000..9e5cf7a --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.1.0 @@ -0,0 +1 @@ +992141db12089e0a1cc9fac1e425788fdc34173c diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.2.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.2.0 new file mode 100644 index 0000000..ddb030e --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.2.0 @@ -0,0 +1 @@ +f896d2af916d3185616d498287515b3d43449aa1 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.3.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.3.0 new file mode 100644 index 0000000..39a28a4 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.3.0 @@ -0,0 +1 @@ +a4f9a791e09178abcb7a9625cfea9e210f14210e diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v3.0.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v3.0.0 new file mode 100644 index 0000000..631584b --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v3.0.0 @@ -0,0 +1 @@ +ccb68a6b1cf9b75818b93240240d6d266f2f12c4 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_gitattributes b/dot_config/tmux/plugins/tmux-sensible/dot_gitattributes new file mode 100644 index 0000000..4cde323 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_gitattributes @@ -0,0 +1,2 @@ +# Force text files to have unix eols, so Windows/Cygwin does not break them +*.* eol=lf diff --git a/dot_config/tmux/plugins/tmux-sensible/executable_sensible.tmux b/dot_config/tmux/plugins/tmux-sensible/executable_sensible.tmux new file mode 100644 index 0000000..66db3c1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/executable_sensible.tmux @@ -0,0 +1,168 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# used to match output from `tmux list-keys` +KEY_BINDING_REGEX="bind-key[[:space:]]\+\(-r[[:space:]]\+\)\?\(-T prefix[[:space:]]\+\)\?" + +is_osx() { + local platform=$(uname) + [ "$platform" == "Darwin" ] +} + +iterm_terminal() { + [[ "${TERM_PROGRAM}" =~ ^iTerm || "${LC_TERMINAL}" =~ ^iTerm ]] +} + +command_exists() { + local command="$1" + type "$command" >/dev/null 2>&1 +} + +# returns prefix key, e.g. 'C-a' +prefix() { + tmux show-option -gv prefix +} + +# if prefix is 'C-a', this function returns 'a' +prefix_without_ctrl() { + local prefix="$(prefix)" + echo "$prefix" | cut -d '-' -f2 +} + +option_value_not_changed() { + local option="$1" + local default_value="$2" + local option_value=$(tmux show-option -gv "$option") + [ "$option_value" == "$default_value" ] +} + +server_option_value_not_changed() { + local option="$1" + local default_value="$2" + local option_value=$(tmux show-option -sv "$option") + [ "$option_value" == "$default_value" ] +} + +key_binding_not_set() { + local key="${1//\\/\\\\}" + if $(tmux list-keys | grep -q "${KEY_BINDING_REGEX}${key}[[:space:]]"); then + return 1 + else + return 0 + fi +} + +key_binding_not_changed() { + local key="$1" + local default_value="$2" + if $(tmux list-keys | grep -q "${KEY_BINDING_REGEX}${key}[[:space:]]\+${default_value}"); then + # key still has the default binding + return 0 + else + return 1 + fi +} + +get_tmux_config() { + local tmux_config_xdg="${XDG_CONFIG_HOME:-$HOME/.config}/tmux/tmux.conf" + local tmux_config="$HOME/.tmux.conf" + + if [ -f "${tmux_config_xdg}" ]; then + echo "${tmux_config_xdg}" + else + echo ${tmux_config} + fi +} + +main() { + # OPTIONS + + # address vim mode switching delay (http://superuser.com/a/252717/65504) + if server_option_value_not_changed "escape-time" "500"; then + tmux set-option -s escape-time 0 + fi + + # increase scrollback buffer size + if option_value_not_changed "history-limit" "2000"; then + tmux set-option -g history-limit 50000 + fi + + # tmux messages are displayed for 4 seconds + if option_value_not_changed "display-time" "750"; then + tmux set-option -g display-time 4000 + fi + + # refresh 'status-left' and 'status-right' more often + if option_value_not_changed "status-interval" "15"; then + tmux set-option -g status-interval 5 + fi + + # required (only) on OS X + if is_osx && command_exists "reattach-to-user-namespace" && option_value_not_changed "default-command" ""; then + tmux set-option -g default-command "reattach-to-user-namespace -l $SHELL" + fi + + # upgrade $TERM, tmux 1.9 + if option_value_not_changed "default-terminal" "screen"; then + tmux set-option -g default-terminal "screen-256color" + fi + # upgrade $TERM, tmux 2.0+ + if server_option_value_not_changed "default-terminal" "screen"; then + tmux set-option -s default-terminal "screen-256color" + fi + + # emacs key bindings in tmux command prompt (prefix + :) are better than + # vi keys, even for vim users + tmux set-option -g status-keys emacs + + # focus events enabled for terminals that support them + tmux set-option -g focus-events on + + # super useful when using "grouped sessions" and multi-monitor setup + if ! iterm_terminal; then + tmux set-window-option -g aggressive-resize on + fi + + # DEFAULT KEY BINDINGS + + local prefix="$(prefix)" + local prefix_without_ctrl="$(prefix_without_ctrl)" + + # if C-b is not prefix + if [ $prefix != "C-b" ]; then + # unbind obsolete default binding + if key_binding_not_changed "C-b" "send-prefix"; then + tmux unbind-key C-b + fi + + # pressing `prefix + prefix` sends to the shell + if key_binding_not_set "$prefix"; then + tmux bind-key "$prefix" send-prefix + fi + fi + + # If Ctrl-a is prefix then `Ctrl-a + a` switches between alternate windows. + # Works for any prefix character. + if key_binding_not_set "$prefix_without_ctrl"; then + tmux bind-key "$prefix_without_ctrl" last-window + fi + + # easier switching between next/prev window + if key_binding_not_set "C-p"; then + tmux bind-key C-p previous-window + fi + if key_binding_not_set "C-n"; then + tmux bind-key C-n next-window + fi + + # source `.tmux.conf` file - as suggested in `man tmux` + if key_binding_not_set "R"; then + local tmux_config=$(get_tmux_config) + + tmux bind-key R run-shell " \ + tmux source-file ${tmux_config} > /dev/null; \ + tmux display-message 'Sourced ${tmux_config}!'" + fi +} +main diff --git a/dot_config/tmux/plugins/tmux-yank/CHANGELOG.md b/dot_config/tmux/plugins/tmux-yank/CHANGELOG.md new file mode 100644 index 0000000..ca1740c --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/CHANGELOG.md @@ -0,0 +1,132 @@ +Change Log +========== + +[master] +-------- + +### Added + +- Mouse support, controlled by `yank_with_mouse` and `yank_selection_mouse` + (@keidax) + +[v2.3.0] 2018-02-01 +------------------- + +### Added + +- Tmux 2.4 support (@docwhat, @edi9999) +- Windows Subsystem for Linux (WSL) support via `clip.exe` (@lukewang1024) +- "copy pane current directory" feature (@bruno-) +- `yank_line` and `yank_pane_pwd` fork to prevent xclip from hanging Tmux (@leoalekseyev) +* `yank_line` no longer cares if you use emacs or vi in copy-mode. + +### Fixed + +- Detect git builds of tmux version ≥ 2.4 (@maximbaz PR#89) + +[v2.2.0] 2015-10-12 +------------------- + +### Added + +- Support for custom copy command (if `xclip` and others aren't + accessible, and you want to have your custom copy command) +- Cygwin support via `putclip` command + +[v2.1.0] 2015-06-17 +------------------- + +### Added + +- Add support for `xsel` on Linux (@ctjhoa) +- Support for shell `vi` mode (@xnaveira) + +### Updated + +- Make `reattach-to-user-namespace` on OS X optional (@bosr) +- Deprecate Alty + +[v2.0.0] 2014-12-06 +------------------- + +### Fixed + +- Change copy mode "put selection" key binding to Y so that vi + mode Controly is not overridden. + +[v1.0.0] 2014-12-06 +------------------- + +### Added + +- Show error message if plugin dependencies aren't installed. +- Vagrant setup for manually testing Linux. + +### Updated + +- `README` + - Related plugin list + - Instructions on updating `xclip` for Linux. + +### Removed + +- The screen-cast is moved into `screencast` branch. + +[v0.0.4] 2014-07-29 +------------------- + +### Updated + +- `README` documentation; including a screen-cast. + +[v0.0.3] 2014-06-29 +------------------- + +### Added + +- Wait when doing "yank line" when using a remote shell (`ssh`, `mosh`) to + ensure screen is updated. + +### Fixed + +- Handle `yank-line` when used on the last line of buffer: copy multiple + lines. +- `yank-line` never yanks 'newline' char for multiple-line commands in + shell (this is actually tmux/bash bug). + +### Updated + +- Code cleanup. + +[v0.0.2] 2014-06-25 +------------------- + +### Updated + + - `README` + +### Added + + - In OS X: Check if `reattach-to-user-namespace` is installed. + - "copy current command line" feature. + +[v0.0.1] 2014-06-24 +------------------- + +- First working version. + +Notes +----- + +This change log is kept in format. + + [master]: https://github.com/tmux-plugins/tmux-yank/compare/v2.3.0...HEAD + [v2.3.0]: https://github.com/tmux-plugins/tmux-yank/compare/v2.2.0...v2.3.0 + [v2.2.0]: https://github.com/tmux-plugins/tmux-yank/compare/v2.1.0...v2.2.0 + [v2.1.0]: https://github.com/tmux-plugins/tmux-yank/compare/v2.0.0...v2.1.0 + [v2.0.0]: https://github.com/tmux-plugins/tmux-yank/compare/v1.0.0...v2.0.0 + [v1.0.0]: https://github.com/tmux-plugins/tmux-yank/compare/v0.0.4...v1.0.0 + [v0.0.4]: https://github.com/tmux-plugins/tmux-yank/compare/v0.0.3...v0.0.4 + [v0.0.3]: https://github.com/tmux-plugins/tmux-yank/compare/v0.0.2...v0.0.3 + [v0.0.2]: https://github.com/tmux-plugins/tmux-yank/compare/v0.0.1...v0.0.2 + [v0.0.1]: https://github.com/tmux-plugins/tmux-yank/commits/v0.0.1 diff --git a/dot_config/tmux/plugins/tmux-yank/LICENSE.md b/dot_config/tmux/plugins/tmux-yank/LICENSE.md new file mode 100644 index 0000000..a898835 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (C) 2014, 2017 Bruno Sutic +Copyright (C) 2017 Christian Höltje + +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. diff --git a/dot_config/tmux/plugins/tmux-yank/README.md b/dot_config/tmux/plugins/tmux-yank/README.md new file mode 100644 index 0000000..cfe5a79 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/README.md @@ -0,0 +1,290 @@ +[![Build +Status](https://travis-ci.org/tmux-plugins/tmux-yank.svg?branch=master)](https://travis-ci.org/tmux-plugins/tmux-yank) +[![GitHub +release](https://img.shields.io/github/release/tmux-plugins/tmux-yank.svg)](https://github.com/tmux-plugins/tmux-yank/releases) +[![GitHub +issues](https://img.shields.io/github/issues/tmux-plugins/tmux-yank.svg)](https://github.com/tmux-plugins/tmux-yank/issues) + +tmux-yank +========= + +Copy to the system clipboard in [`tmux`](https://tmux.github.io/). + +Supports: + +- Linux +- macOS +- Cygwin +- Windows Subsystem for Linux (WSL) + +Installing +---------- + +### Via TPM (recommended) + +The easiest way to install `tmux-yank` is via the [Tmux Plugin +Manager](https://github.com/tmux-plugins/tpm). + +1. Add plugin to the list of TPM plugins in `.tmux.conf`: + + ``` tmux + set -g @plugin 'tmux-plugins/tmux-yank' + ``` + +2. Use prefixI install `tmux-yank`. You should now + be able to `tmux-yank` immediately. +3. When you want to update `tmux-yank` use prefixU. + +### Manual Installation + +1. Clone the repository + + ``` sh + $ git clone https://github.com/tmux-plugins/tmux-yank ~/clone/path + ``` + +2. Add this line to the bottom of `.tmux.conf` + + ``` tmux + run-shell ~/clone/path/yank.tmux + ``` + +3. Reload the `tmux` environment + + ``` sh + # type this inside tmux + $ tmux source-file ~/.tmux.conf + ``` + +You should now be able to use `tmux-yank` immediately. + +Requirements +------------ + +In order for `tmux-yank` to work, there must be a program that store data in +the system clipboard. + +### macOS + +- [`reattach-to-user-namespace`](https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard) + +**Note**: Some versions of macOS (aka OS X) have been reported to work +without `reattach-to-user-namespace`. It doesn't hurt to have it installed. + +- OS X 10.8: Mountain Lion – *required* +- OS X 10.9: Mavericks – *required* +- OS X 10.10: Yosemite – *not required* +- OS X 10.11: El Capitan – *not required* +- macOS 10.12: Sierra – *required* +- macOS 10.14: Mojave - *required* +- macOS 10.15: Catalina - *not required* + +The easiest way to use `reattach-to-user-namespace` with `tmux` is use to +use the [`tmux-sensible`](https://github.com/tmux-plugins/tmux-sensible) +plugin. + +To use it manually, use: + +``` tmux +# ~/.tmux.conf +set-option -g default-command "reattach-to-user-namespace -l $SHELL" +``` + +If you have `tmux` 1.5 or newer and are using +[iTerm2](https://www.iterm2.com/) version 3 or newer then the y +in `copy-mode` and mouse selection will work without `tmux-yank`. + +To enable this: + +1. Go into iTerm2's preferences. +2. Go to the "General" tab. +3. Check "Applications in terminal may access clipboard" +4. In `tmux`, ensure `set-clipboard` is turned on: + + ``` sh + $ tmux show-options -g -s set-clipboard + set-clipboard on + ``` + +#### [HomeBrew](https://brew.sh/) (recommended) + +``` sh +$ brew install reattach-to-user-namespace +``` + +#### MacPorts + +``` sh +$ sudo port install tmux-pasteboard +``` + +### Linux + +- `xsel` (recommended) or `xclip` (for X). +- `wl-copy` from [wl-clipboard](https://github.com/bugaevc/wl-clipboard) (for Wayland) + +If you have `tmux` 1.5 or newer and are using `xterm`, the y in +`copy-mode` and mouse selection will work without `tmux-yank`. See the +`tmux(1)` man page entry for the `set-clipboard` option. + +#### Debian & Ubuntu + +``` sh +$ sudo apt-get install xsel # or xclip +``` + +#### RedHat & CentOS + +``` sh +$ sudo yum install xsel # or xclip +``` + +### Cygwin + +- (*optional*) `putclip` which is part of the `cygutils-extra` package. + +### Windows Subsystem for Linux (WSL) + +- `clip.exe` is shipped with Windows Subsystem for Linux. + +Configuration +------------- + +### Key bindings + +- Normal Mode + - prefixy — copies text from the command line + to the clipboard. + + Works with all popular shells/repls. Tested with: + + - shells: `bash`, `zsh` (with `bindkey -e`), `tcsh` + - repls: `irb`, `pry`, `node`, `psql`, `python`, `php -a`, + `coffee` + - remote shells: `ssh`, [mosh](http://mosh.mit.edu/) + - vim/neovim command line (requires + [vim-husk](https://github.com/bruno-/vim-husk) or + [vim-rsi](https://github.com/tpope/vim-rsi) plugin) + + - prefixY — copy the current pane's current + working directory to the clipboard. + +- Copy Mode + - y — copy selection to system clipboard. + - Y (shift-y) — "put" selection. Equivalent to copying a + selection, and pasting it to the command line. + + +### Default and Preferred Clipboard Programs + +tmux-yank does its best to detect a reasonable choice for a clipboard +program on your OS. + +If tmux-yank can't detect a known clipboard program then it uses the +`@custom_copy_command` tmux option as your clipboard program if set. + +If you need to always override tmux-yank's choice for a clipboard program, +then you can set `@override_copy_command` to force tmux-yank to use whatever +you want. + +Note that both programs _must_ accept `STDIN` for the text to be copied. + +An example of setting `@override_copy_command`: + +``` tmux +# ~/.tmux.conf + +set -g @custom_copy_command 'my-clipboard-copy --some-arg' +# or +set -g @override_copy_command 'my-clipboard-copy --some-arg' +``` + +### Linux Clipboards + +Linux has several cut-and-paste clipboards: `primary`, `secondary`, and +`clipboard` (default in tmux-yank is `clipboard`). + +You can change this by setting `@yank_selection`: + +``` tmux +# ~/.tmux.conf + +set -g @yank_selection 'primary' # or 'secondary' or 'clipboard' +``` + +With mouse support turned on (see below) the default clipboard for mouse +selections is `primary`. + +You can change this by setting `@yank_selection_mouse`: + +``` tmux +# ~/.tmux.conf + +set -g @yank_selection_mouse 'clipboard' # or 'primary' or 'secondary' +``` + +### Controlling Yank Behavior + +By default, `tmux-yank` will exit copy mode after yanking text. If you wish to +remain in copy mode, you can set `@yank_action`: + +``` tmux +# ~/.tmux.conf + +set -g @yank_action 'copy-pipe' # or 'copy-pipe-and-cancel' for the default +``` + +### Mouse Support + +`tmux-yank` has mouse support enabled by default. It will only work if `tmux`'s +built-in mouse support is also enabled (with `mouse on` since `tmux` 2.1, or +`mode-mouse on` in older versions). + +To yank with the mouse, click and drag with the primary button to begin +selection, and release to yank. + +If you would prefer to disable this behavior, or provide your own bindings for +the `MouseDragEnd1Pane` event, you can do so with: + +``` tmux +# ~/.tmux.conf + +set -g @yank_with_mouse off # or 'on' +``` + +If you want to remain in copy mode after making a mouse selection, set +`@yank_action` as described above. + +### vi mode support + +If using `tmux` 2.3 or older *and* using vi keys then you'll have add the +following configuration setting: + +``` tmux +# ~/.tmux.conf + +set -g @shell_mode 'vi' +``` + +This isn't needed with `tmux` 2.4 or newer. + +### Screen-cast + +[![screencast +screenshot](/video/screencast_img.png)](https://vimeo.com/102039099) + +**Note**: The screen-cast uses Controly for +"put selection". Use Y in `v2.0.0` and later. + +### Other tmux plugins + +- [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) - a plugin + for regular expression searches in tmux and fast match selection +- [tmux-open](https://github.com/tmux-plugins/tmux-open) - a plugin for + quickly opening highlighted file or a URL +- [tmux-continuum](https://github.com/tmux-plugins/tmux-continuum) - + automatic restoring and continuous saving of tmux environment. + +### License + +[MIT](LICENSE.md) diff --git a/dot_config/tmux/plugins/tmux-yank/Vagrantfile b/dot_config/tmux/plugins/tmux-yank/Vagrantfile new file mode 100644 index 0000000..778b77a --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/Vagrantfile @@ -0,0 +1,10 @@ +VAGRANTFILE_API_VERSION = '2' + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + config.vm.box = 'precise32' + config.vm.box_url = 'http://files.vagrantup.com/precise32.box' + + config.vm.provision 'shell', path: 'vagrant_provisioning.sh' + + config.ssh.forward_x11 = true +end diff --git a/dot_config/tmux/plugins/tmux-yank/_config.yml b/dot_config/tmux/plugins/tmux-yank/_config.yml new file mode 100644 index 0000000..c741881 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-slate \ No newline at end of file diff --git a/dot_config/tmux/plugins/tmux-yank/dot_editorconfig b/dot_config/tmux/plugins/tmux-yank/dot_editorconfig new file mode 100644 index 0000000..d65b947 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_editorconfig @@ -0,0 +1,24 @@ +# EditorConfig: http://EditorConfig.org + +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 + +[*.md] +max_line_length = 76 +indent_size = 4 +trim_trailing_whitespace = true + +[Vagrantfile] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + + +[{*.sh,*.tmux}] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/HEAD b/dot_config/tmux/plugins/tmux-yank/dot_git/HEAD new file mode 100644 index 0000000..cb089cd --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/config b/dot_config/tmux/plugins/tmux-yank/dot_git/config new file mode 100644 index 0000000..c715f37 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/config @@ -0,0 +1,13 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[submodule] + active = . +[remote "origin"] + url = https://git::@github.com/tmux-plugins/tmux-yank + fetch = +refs/heads/master:refs/remotes/origin/master +[branch "master"] + remote = origin + merge = refs/heads/master diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/description b/dot_config/tmux/plugins/tmux-yank/dot_git/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_applypatch-msg.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_commit-msg.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_fsmonitor-watchman.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_post-update.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-applypatch.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-commit.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-merge-commit.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-push.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-rebase.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-receive.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_prepare-commit-msg.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_push-to-checkout.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_update.sample b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/index b/dot_config/tmux/plugins/tmux-yank/dot_git/index new file mode 100644 index 0000000..2e84289 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-yank/dot_git/index differ diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/info/exclude b/dot_config/tmux/plugins/tmux-yank/dot_git/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/logs/HEAD b/dot_config/tmux/plugins/tmux-yank/dot_git/logs/HEAD new file mode 100644 index 0000000..a14d9e9 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 acfd36e4fcba99f8310a7dfb432111c242fe7392 Wizzard 1705878654 -0500 clone: from https://github.com/tmux-plugins/tmux-yank diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/logs/refs/heads/master b/dot_config/tmux/plugins/tmux-yank/dot_git/logs/refs/heads/master new file mode 100644 index 0000000..a14d9e9 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 acfd36e4fcba99f8310a7dfb432111c242fe7392 Wizzard 1705878654 -0500 clone: from https://github.com/tmux-plugins/tmux-yank diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/logs/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tmux-yank/dot_git/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..a14d9e9 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 acfd36e4fcba99f8310a7dfb432111c242fe7392 Wizzard 1705878654 -0500 clone: from https://github.com/tmux-plugins/tmux-yank diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/objects/pack/readonly_pack-9589e7095e8016290060123bf3cc10e133b790ba.idx b/dot_config/tmux/plugins/tmux-yank/dot_git/objects/pack/readonly_pack-9589e7095e8016290060123bf3cc10e133b790ba.idx new file mode 100644 index 0000000..761058b Binary files /dev/null and b/dot_config/tmux/plugins/tmux-yank/dot_git/objects/pack/readonly_pack-9589e7095e8016290060123bf3cc10e133b790ba.idx differ diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/objects/pack/readonly_pack-9589e7095e8016290060123bf3cc10e133b790ba.pack b/dot_config/tmux/plugins/tmux-yank/dot_git/objects/pack/readonly_pack-9589e7095e8016290060123bf3cc10e133b790ba.pack new file mode 100644 index 0000000..a86c0a2 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-yank/dot_git/objects/pack/readonly_pack-9589e7095e8016290060123bf3cc10e133b790ba.pack differ diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/objects/pack/readonly_pack-9589e7095e8016290060123bf3cc10e133b790ba.rev b/dot_config/tmux/plugins/tmux-yank/dot_git/objects/pack/readonly_pack-9589e7095e8016290060123bf3cc10e133b790ba.rev new file mode 100644 index 0000000..5a64f01 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-yank/dot_git/objects/pack/readonly_pack-9589e7095e8016290060123bf3cc10e133b790ba.rev differ diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/packed-refs b/dot_config/tmux/plugins/tmux-yank/dot_git/packed-refs new file mode 100644 index 0000000..3c66c70 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +acfd36e4fcba99f8310a7dfb432111c242fe7392 refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/heads/master b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/heads/master new file mode 100644 index 0000000..443e2c8 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/heads/master @@ -0,0 +1 @@ +acfd36e4fcba99f8310a7dfb432111c242fe7392 diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/remotes/origin/HEAD new file mode 100644 index 0000000..6efe28f --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.1 b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.1 new file mode 100644 index 0000000..244d228 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.1 @@ -0,0 +1 @@ +34a97e02dbf7cde9e461f477c5b7a9f15efdfa48 diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.2 b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.2 new file mode 100644 index 0000000..826199a --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.2 @@ -0,0 +1 @@ +260c29505bbdd90511d467bfb117db29c1c94659 diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.3 b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.3 new file mode 100644 index 0000000..9ef4315 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.3 @@ -0,0 +1 @@ +76a5c8485f00acdecdad6372afe7a97ef1fd2236 diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.4 b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.4 new file mode 100644 index 0000000..b7478b5 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v0.0.4 @@ -0,0 +1 @@ +f633618cdd55caec59b63ce69bdd13924f67ec91 diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v1.0.0 b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v1.0.0 new file mode 100644 index 0000000..81c2f18 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v1.0.0 @@ -0,0 +1 @@ +c879f38dbcc2740b3ad64eb27c6ea7e9c4ba5d65 diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.0.0 b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.0.0 new file mode 100644 index 0000000..4058041 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.0.0 @@ -0,0 +1 @@ +c3262f748883c8324a66d4df5bfe74e25bd3a882 diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.1.0 b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.1.0 new file mode 100644 index 0000000..e7fd9d4 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.1.0 @@ -0,0 +1 @@ +3d479d92d01c3360d371c820102d5b00f3cf505b diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.2.0 b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.2.0 new file mode 100644 index 0000000..4d0c37a --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.2.0 @@ -0,0 +1 @@ +82e65a84dddd072b642bda322bffac246fafe26b diff --git a/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.3.0 b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.3.0 new file mode 100644 index 0000000..d02e288 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_git/refs/tags/v2.3.0 @@ -0,0 +1 @@ +fd8000238b324005389076486a2e6e03dba1c64f diff --git a/dot_config/tmux/plugins/tmux-yank/dot_gitattributes b/dot_config/tmux/plugins/tmux-yank/dot_gitattributes new file mode 100644 index 0000000..07c6d8e --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_gitattributes @@ -0,0 +1,11 @@ +# The linguist directives are for https://github.com/github/linguist + +*.md text eol=lf whitespace=blank-at-eol +*.sh text eol=lf whitespace=blank-at-eol diff=php +*.tmux text eol=lf whitespace=blank-at-eol diff=php + +Vagrantfile text eol=lf linguist-vendored +video/* linguist-documentation + +# Binary Types +*.png binary diff --git a/dot_config/tmux/plugins/tmux-yank/dot_gitignore b/dot_config/tmux/plugins/tmux-yank/dot_gitignore new file mode 100644 index 0000000..a977916 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_gitignore @@ -0,0 +1 @@ +.vagrant/ diff --git a/dot_config/tmux/plugins/tmux-yank/dot_travis.yml b/dot_config/tmux/plugins/tmux-yank/dot_travis.yml new file mode 100644 index 0000000..cc4b3ac --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/dot_travis.yml @@ -0,0 +1,17 @@ +sudo: required +language: bash +services: + - docker + +script: +- "./citest" + +notifications: + email: false + pushover: + on_success: change + on_failure: always + api_key: + secure: gWoqAqGyBbO6mcKbHkt29jJZ7ElOfct2C5WPfliBARl8ImCE0HE6CEGdK25i29mjfIxXWp3HITsRawuauZDN8nCZ9srO+0wr7OWAcZuhDW6mDmKNLX2y4eR4lK21MsMpLIHqA48hYXkHVKSHR7TDG88A/0MRXoTb5gcuPDJMqPk= + users: + secure: dIUBBbi8R7cOcwBQ8guLsq+M8vBXcSAu9vKUVEqToSHoWap4fTl4QSZpyhzxLy6uSNRwg1u20xVSlEAPee2Z+efzZQtA0I9bRTkcAMbzH65+sWKgMsEMJoHrqlCr7FvX4c+UMW9sWlRLoH52oN3ilCQNy2beI8mWqE4gAGxD4aA= diff --git a/dot_config/tmux/plugins/tmux-yank/executable_citest b/dot_config/tmux/plugins/tmux-yank/executable_citest new file mode 100644 index 0000000..f8e17f5 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/executable_citest @@ -0,0 +1,30 @@ +#!/bin/bash + +set -euo pipefail + +cd "$(dirname "$0")" + +bash_scripts=( + yank.tmux + scripts/*.sh +) + +set -x +docker run \ + --rm \ + --volume="${PWD}:/mnt:ro" \ + --workdir="/mnt" \ + bash:latest \ + bash -Dn "${bash_scripts[@]}" + +docker run \ + --rm \ + --volume="${PWD}:/mnt:ro" \ + --workdir="/mnt" \ + koalaman/shellcheck:stable \ + --shell=bash \ + --external-sources \ + --color=always \ + "${bash_scripts[@]}" + +# EOF diff --git a/dot_config/tmux/plugins/tmux-yank/executable_yank.tmux b/dot_config/tmux/plugins/tmux-yank/executable_yank.tmux new file mode 100644 index 0000000..3003974 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/executable_yank.tmux @@ -0,0 +1,92 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SCRIPTS_DIR="${CURRENT_DIR}/scripts" +HELPERS_DIR="${CURRENT_DIR}/scripts" + +# shellcheck source=scripts/helpers.sh +source "${HELPERS_DIR}/helpers.sh" + +clipboard_copy_without_newline_command() { + local copy_command="$1" + printf "tr -d '\\n' | %s" "$copy_command" +} + +set_error_bindings() { + local key_bindings key + key_bindings="$(yank_key) $(put_key) $(yank_put_key)" + for key in $key_bindings; do + if tmux_is_at_least 2.4; then + tmux bind-key -T copy-mode-vi "$key" send-keys -X copy-pipe-and-cancel "tmux display-message 'Error! tmux-yank dependencies not installed!'" + tmux bind-key -T copy-mode "$key" send-keys -X copy-pipe-and-cancel "tmux display-message 'Error! tmux-yank dependencies not installed!'" + else + tmux bind-key -t vi-copy "$key" copy-pipe "tmux display-message 'Error! tmux-yank dependencies not installed!'" + tmux bind-key -t emacs-copy "$key" copy-pipe "tmux display-message 'Error! tmux-yank dependencies not installed!'" + fi + done +} + +error_handling_if_command_not_present() { + local copy_command="$1" + if [ -z "$copy_command" ]; then + set_error_bindings + exit 0 + fi +} + +# `yank_without_newline` binding isn't intended to be used by the user. It is +# a helper for `copy_line` command. +set_copy_mode_bindings() { + local copy_command="$1" + local copy_wo_newline_command + copy_wo_newline_command="$(clipboard_copy_without_newline_command "$copy_command")" + local copy_command_mouse + copy_command_mouse="$(clipboard_copy_command "true")" + if tmux_is_at_least 2.4; then + tmux bind-key -T copy-mode-vi "$(yank_key)" send-keys -X "$(yank_action)" "$copy_command" + tmux bind-key -T copy-mode-vi "$(put_key)" send-keys -X copy-pipe-and-cancel "tmux paste-buffer -p" + tmux bind-key -T copy-mode-vi "$(yank_put_key)" send-keys -X copy-pipe-and-cancel "$copy_command; tmux paste-buffer -p" + tmux bind-key -T copy-mode-vi "$(yank_wo_newline_key)" send-keys -X "$(yank_action)" "$copy_wo_newline_command" + if [[ "$(yank_with_mouse)" == "on" ]]; then + tmux bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X "$(yank_action)" "$copy_command_mouse" + fi + + tmux bind-key -T copy-mode "$(yank_key)" send-keys -X "$(yank_action)" "$copy_command" + tmux bind-key -T copy-mode "$(put_key)" send-keys -X copy-pipe-and-cancel "tmux paste-buffer -p" + tmux bind-key -T copy-mode "$(yank_put_key)" send-keys -X copy-pipe-and-cancel "$copy_command; tmux paste-buffer -p" + tmux bind-key -T copy-mode "$(yank_wo_newline_key)" send-keys -X "$(yank_action)" "$copy_wo_newline_command" + if [[ "$(yank_with_mouse)" == "on" ]]; then + tmux bind-key -T copy-mode MouseDragEnd1Pane send-keys -X "$(yank_action)" "$copy_command_mouse" + fi + else + tmux bind-key -t vi-copy "$(yank_key)" copy-pipe "$copy_command" + tmux bind-key -t vi-copy "$(put_key)" copy-pipe "tmux paste-buffer -p" + tmux bind-key -t vi-copy "$(yank_put_key)" copy-pipe "$copy_command; tmux paste-buffer -p" + tmux bind-key -t vi-copy "$(yank_wo_newline_key)" copy-pipe "$copy_wo_newline_command" + if [[ "$(yank_with_mouse)" == "on" ]]; then + tmux bind-key -t vi-copy MouseDragEnd1Pane copy-pipe "$copy_command_mouse" + fi + + tmux bind-key -t emacs-copy "$(yank_key)" copy-pipe "$copy_command" + tmux bind-key -t emacs-copy "$(put_key)" copy-pipe "tmux paste-buffer -p" + tmux bind-key -t emacs-copy "$(yank_put_key)" copy-pipe "$copy_command; tmux paste-buffer -p" + tmux bind-key -t emacs-copy "$(yank_wo_newline_key)" copy-pipe "$copy_wo_newline_command" + if [[ "$(yank_with_mouse)" == "on" ]]; then + tmux bind-key -t emacs-copy MouseDragEnd1Pane copy-pipe "$copy_command_mouse" + fi + fi +} + +set_normal_bindings() { + tmux bind-key "$(yank_line_key)" run-shell -b "$SCRIPTS_DIR/copy_line.sh" + tmux bind-key "$(yank_pane_pwd_key)" run-shell -b "$SCRIPTS_DIR/copy_pane_pwd.sh" +} + +main() { + local copy_command + copy_command="$(clipboard_copy_command)" + error_handling_if_command_not_present "$copy_command" + set_copy_mode_bindings "$copy_command" + set_normal_bindings +} +main diff --git a/dot_config/tmux/plugins/tmux-yank/scripts/executable_copy_line.sh b/dot_config/tmux/plugins/tmux-yank/scripts/executable_copy_line.sh new file mode 100644 index 0000000..20a70e1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/scripts/executable_copy_line.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +HELPERS_DIR="$CURRENT_DIR" +TMUX_COPY_MODE="" + +REMOTE_SHELL_WAIT_TIME="0.4" + +# shellcheck source=scripts/helpers.sh +source "${HELPERS_DIR}/helpers.sh" + +# sets a TMUX_COPY_MODE that is used as a global variable +get_tmux_copy_mode() { + TMUX_COPY_MODE="$(tmux show-option -gwv mode-keys)" +} + +# The command when on ssh with latency. To make it work in this case too, +# sleep is added. +add_sleep_for_remote_shells() { + local pane_command + pane_command="$(tmux display-message -p '#{pane_current_command}')" + if [[ $pane_command =~ (ssh|mosh) ]]; then + sleep "$REMOTE_SHELL_WAIT_TIME" + fi +} + +go_to_the_beginning_of_current_line() { + if [ "$(shell_mode)" == "emacs" ]; then + tmux send-key 'C-a' + else + tmux send-key 'Escape' '0' + fi +} + +enter_tmux_copy_mode() { + tmux copy-mode +} + +start_tmux_selection() { + if tmux_is_at_least 2.4; then + tmux send -X begin-selection + elif [ "$TMUX_COPY_MODE" == "vi" ]; then + # vi copy mode + tmux send-key 'Space' + else + # emacs copy mode + tmux send-key 'C-Space' + fi +} + +# works when command spans accross multiple lines +end_of_line_in_copy_mode() { + if tmux_is_at_least 2.4; then + tmux send -X -N 150 'cursor-down' # 'down' key. 'vi' mode is faster so we're + # jumping more lines than emacs. + tmux send -X 'end-of-line' # End of line (just in case we are already at the last line). + tmux send -X 'previous-word' # Beginning of the previous word. + tmux send -X 'next-word-end' # End of next word. + elif [ "$TMUX_COPY_MODE" == "vi" ]; then + # vi copy mode + # This sequence of keys consistently selects multiple lines + tmux send-key '150' # Go to the bottom of scrollback buffer by using + tmux send-key 'j' # 'down' key. 'vi' mode is faster so we're + # jumping more lines than emacs. + tmux send-key '$' # End of line (just in case we are already at the last line). + tmux send-key 'b' # Beginning of the previous word. + tmux send-key 'e' # End of next word. + else + # emacs copy mode + for ((c = 1; c <= '30'; c++)); do # go to the bottom of scrollback buffer + tmux send-key 'C-n' + done + tmux send-key 'C-e' + tmux send-key 'M-b' + tmux send-key 'M-f' + fi +} + +yank_to_clipboard() { + if tmux_is_at_least 2.4; then + # shellcheck disable=SC2119 + tmux send -X copy-pipe-and-cancel "$(clipboard_copy_command)" + else + tmux send-key "$(yank_wo_newline_key)" + fi +} + +go_to_the_end_of_current_line() { + if [ "$(shell_mode)" == "emacs" ]; then + tmux send-keys 'C-e' + else + tmux send-keys '$' 'a' + fi +} + +yank_current_line() { + go_to_the_beginning_of_current_line + add_sleep_for_remote_shells + enter_tmux_copy_mode + start_tmux_selection + end_of_line_in_copy_mode + yank_to_clipboard + go_to_the_end_of_current_line + display_message 'Line copied to clipboard!' +} + +main() { + get_tmux_copy_mode + yank_current_line +} +main diff --git a/dot_config/tmux/plugins/tmux-yank/scripts/executable_copy_pane_pwd.sh b/dot_config/tmux/plugins/tmux-yank/scripts/executable_copy_pane_pwd.sh new file mode 100644 index 0000000..1db321f --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/scripts/executable_copy_pane_pwd.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +HELPERS_DIR="$CURRENT_DIR" + +# shellcheck source=scripts/helpers.sh +source "${HELPERS_DIR}/helpers.sh" + +pane_current_path() { + tmux display -p -F "#{pane_current_path}" +} + +display_notice() { + display_message 'PWD copied to clipboard!' +} + +main() { + local copy_command + local payload + # shellcheck disable=SC2119 + copy_command="$(clipboard_copy_command)" + payload="$(pane_current_path | tr -d '\n')" + # $copy_command below should not be quoted + echo "$payload" | $copy_command + tmux set-buffer "$payload" + display_notice +} +main diff --git a/dot_config/tmux/plugins/tmux-yank/scripts/helpers.sh b/dot_config/tmux/plugins/tmux-yank/scripts/helpers.sh new file mode 100644 index 0000000..66beeec --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/scripts/helpers.sh @@ -0,0 +1,208 @@ +#!bash +# shellcheck disable=SC2239 + +yank_line="y" +yank_line_option="@yank_line" + +yank_pane_pwd="Y" +yank_pane_pwd_option="@yank_pane_pwd" + +yank_default="y" +yank_option="@copy_mode_yank" + +put_default="Y" +put_option="@copy_mode_put" + +yank_put_default="M-y" +yank_put_option="@copy_mode_yank_put" + +yank_wo_newline_default="!" +yank_wo_newline_option="@copy_mode_yank_wo_newline" + +yank_selection_default="clipboard" +yank_selection_option="@yank_selection" + +yank_selection_mouse_default="primary" +yank_selection_mouse_option="@yank_selection_mouse" + +yank_with_mouse_default="on" +yank_with_mouse_option="@yank_with_mouse" + +yank_action_default="copy-pipe-and-cancel" +yank_action_option="@yank_action" + +shell_mode_default="emacs" +shell_mode_option="@shell_mode" + +custom_copy_command_default="" +custom_copy_command_option="@custom_copy_command" + +override_copy_command_default="" +override_copy_command_option="@override_copy_command" + +# helper functions +get_tmux_option() { + local option="$1" + local default_value="$2" + local option_value + option_value=$(tmux show-option -gqv "$option") + if [ -z "$option_value" ]; then + echo "$default_value" + else + echo "$option_value" + fi +} + +yank_line_key() { + get_tmux_option "$yank_line_option" "$yank_line" +} + +yank_pane_pwd_key() { + get_tmux_option "$yank_pane_pwd_option" "$yank_pane_pwd" +} + +yank_key() { + get_tmux_option "$yank_option" "$yank_default" +} + +put_key() { + get_tmux_option "$put_option" "$put_default" +} + +yank_put_key() { + get_tmux_option "$yank_put_option" "$yank_put_default" +} + +yank_wo_newline_key() { + get_tmux_option "$yank_wo_newline_option" "$yank_wo_newline_default" +} + +yank_selection() { + get_tmux_option "$yank_selection_option" "$yank_selection_default" +} + +yank_selection_mouse() { + get_tmux_option "$yank_selection_mouse_option" "$yank_selection_mouse_default" +} + +yank_with_mouse() { + get_tmux_option "$yank_with_mouse_option" "$yank_with_mouse_default" +} + +yank_action() { + get_tmux_option "$yank_action_option" "$yank_action_default" +} + +shell_mode() { + get_tmux_option "$shell_mode_option" "$shell_mode_default" +} + +custom_copy_command() { + get_tmux_option "$custom_copy_command_option" "$custom_copy_command_default" +} + +override_copy_command() { + get_tmux_option "$override_copy_command_option" "$override_copy_command_default" +} +# Ensures a message is displayed for 5 seconds in tmux prompt. +# Does not override the 'display-time' tmux option. +display_message() { + local message="$1" + + # display_duration defaults to 5 seconds, if not passed as an argument + if [ "$#" -eq 2 ]; then + local display_duration="$2" + else + local display_duration="5000" + fi + + # saves user-set 'display-time' option + local saved_display_time + saved_display_time=$(get_tmux_option "display-time" "750") + + # sets message display time to 5 seconds + tmux set-option -gq display-time "$display_duration" + + # displays message + tmux display-message "$message" + + # restores original 'display-time' value + tmux set-option -gq display-time "$saved_display_time" +} + +command_exists() { + local command="$1" + type "$command" >/dev/null 2>&1 +} + +clipboard_copy_command() { + local mouse="${1:-false}" + # installing reattach-to-user-namespace is recommended on OS X + if [ -n "$(override_copy_command)" ]; then + override_copy_command + elif command_exists "pbcopy"; then + if command_exists "reattach-to-user-namespace"; then + echo "reattach-to-user-namespace pbcopy" + else + echo "pbcopy" + fi + elif command_exists "clip.exe"; then # WSL clipboard command + echo "cat | clip.exe" + elif command_exists "wl-copy"; then # wl-clipboard: Wayland clipboard utilities + echo "wl-copy" + elif command_exists "xsel"; then + local xsel_selection + if [[ $mouse == "true" ]]; then + xsel_selection="$(yank_selection_mouse)" + else + xsel_selection="$(yank_selection)" + fi + echo "xsel -i --$xsel_selection" + elif command_exists "xclip"; then + local xclip_selection + if [[ $mouse == "true" ]]; then + xclip_selection="$(yank_selection_mouse)" + else + xclip_selection="$(yank_selection)" + fi + echo "xclip -selection $xclip_selection" + elif command_exists "putclip"; then # cygwin clipboard command + echo "putclip" + elif [ -n "$(custom_copy_command)" ]; then + custom_copy_command + fi +} + +# Cache the TMUX version for speed. +tmux_version="$(tmux -V | cut -d ' ' -f 2 | sed 's/next-//')" + +tmux_is_at_least() { + if [[ $tmux_version == "$1" ]] || [[ $tmux_version == master ]]; then + return 0 + fi + + local i + local -a current_version wanted_version + IFS='.' read -ra current_version <<<"$tmux_version" + IFS='.' read -ra wanted_version <<<"$1" + + # fill empty fields in current_version with zeros + for ((i = ${#current_version[@]}; i < ${#wanted_version[@]}; i++)); do + current_version[i]=0 + done + + # fill empty fields in wanted_version with zeros + for ((i = ${#wanted_version[@]}; i < ${#current_version[@]}; i++)); do + wanted_version[i]=0 + done + + for ((i = 0; i < ${#current_version[@]}; i++)); do + if ((10#${current_version[i]} < 10#${wanted_version[i]})); then + return 1 + fi + if ((10#${current_version[i]} > 10#${wanted_version[i]})); then + return 0 + fi + done + return 0 +} diff --git a/dot_config/tmux/plugins/tmux-yank/vagrant_provisioning.sh b/dot_config/tmux/plugins/tmux-yank/vagrant_provisioning.sh new file mode 100644 index 0000000..c093d29 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/vagrant_provisioning.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +sudo apt-get update +sudo apt-get install -y git-core expect vim xclip +sudo apt-get install -y python-software-properties software-properties-common + +# install latest Tmux 1.9a +sudo add-apt-repository -y ppa:pi-rho/dev +sudo apt-get update +sudo apt-get install -y tmux=1.9a-1~ppa1~p + +# configure X11 for xclip testing +echo "export DISPLAY='IP:0.0'" >>/home/vagrant/.bashrc diff --git a/dot_config/tmux/plugins/tmux-yank/video/README.md b/dot_config/tmux/plugins/tmux-yank/video/README.md new file mode 100644 index 0000000..97f3056 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/video/README.md @@ -0,0 +1,7 @@ +## Tmux yank screencast + +This directory contains docs used for creating +[tmux yank screencast](https://vimeo.com/102039099). + +- `script.md` - this file contains a script and a voiceover used to produce the + screencast diff --git a/dot_config/tmux/plugins/tmux-yank/video/screencast_img.png b/dot_config/tmux/plugins/tmux-yank/video/screencast_img.png new file mode 100644 index 0000000..3bbedd2 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-yank/video/screencast_img.png differ diff --git a/dot_config/tmux/plugins/tmux-yank/video/script.md b/dot_config/tmux/plugins/tmux-yank/video/script.md new file mode 100644 index 0000000..e401aa4 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-yank/video/script.md @@ -0,0 +1,204 @@ +# Tmux yank screencast script + +1 - Intro - what's the plugin about +=================================== +Actions +------- +- none, just clear screen + +Script +------ +In this screencast we'll demo a tmux yank plugin. + +This plugin enables you to copy some text from tmux to the system clipboard, +along with some extra functionality we'll show. +It was made to complement tmux copycat plugin which we'll also be using for +selection in this screencast. + +2 - problems with vanilla tmux and `y` +============================== +Actions +------- +- $ echo 'example url https://github.com/tmux-plugins/tmux-yank' +- highlight url +- enter +- paste url + +- remove url +- highlight url again +- 'y' +- paste with cmd + v + +Script +------ +Let's show a problem scenario you might be having with tmux. + +I'll generate some example output with a url in the terminal. + +Okay, now I want to copy that url and open it in the browser. +By using tmux copycat saved search I'll quickly select the url. + +I'll press enter, a "bajnding" for copy. +I can now paste it in tmux by pressing prefix + right angle bracket. + +That works, but there's a problem. Tmux paste works only within tmux. Pressing +prefix + right angle bracket won't work in the browser where I actually want the +above url to be. + + +Ideally, when I copy some text in tmux, I want it to be available for paste +anywhere on the system with control-v or command-v if I'm on a Mac. + +Enter tmux-yank which enables just that. +I'll select the url again. + +Tmux-yank provides a convenient "bajnding" so that pressing 'y' in copy mode +copies the text and makes it available in system clipboard. + +I'm on a mac so I'll press command-v and there you have you have it. +It goes without saying that this paste will work in the browser. + + +Personally, I use tmux-yank copying all the time so I don't have to think in +terms of being in tmux versus working with the rest of the system. + +And also, this way I can avoid tmux default paste binding 'prefix + right angle +bracket' because it is a bit clunky and unintuitive. + +3 - showing 'ctrl-y' +==================== +Actions +------- +- git status -sb (file1.txt, file2.txt, file3.txt) +- git add +- highlight last file +- y +- paste and enter to git add a file + +- clear screen +- git status -sb +- git add +- highlight last file +- ctrl-y and git add a file + +- cmd - v + +Script +------ +Let's show another feature. + +I'll invoke git status command for the project I'm in. +Now I want to git add only the last file. + +I'll select the last file, yank and paste. + +Do you think we can optimize this? + +Often with tmux there's a need to copy a selection, and paste it to the command +line immediately. + +Tmux-yank provides a so called 'put selection' command. Let's demo it. + +I'll highlight another git status file and press control-y. +The selection is immediately 'put' to the command line. That's one step, instead +of two. + + +A nice side-effect of 'put selection' command is that it preserves the system +clipboard content. +If I press command-v now you'll see that the clipboard still contains the +previous entry. 'put selection' command didn't overwrite it. + +4. show 'line yank' +=================== +Actions +------- +- clear pane scrollback +- split window +- echo 'some command' +- ctrl-p to show the last command +- prefix + y + +- go the the pane on the right +- cmd - v + +Script +------ +The last tmux-yank feature I'd like to show is 'line yank'. + +It enables you to quickly copy the current command line to system clipoard. +The nice thing is, it also works for commands that strech multiple lines. + +But here's the basic example. I'll write a simple command. + +Okay, that works. Now, I want to execute that same command in the pane on the +right. I could of course type the command again, but that's tedious and I could +make a typo. + +Another solution is mouse selection, but that's just slow and lame. + + +I'll use the 'line yank' feature. +I'll press prefix + 'y' and the command is copied. Notice there were no changes +to the command itself - it is intact. + +In the second pane on the right I can paste the line with command - v. + +5. show 'line yank' with the production server +============================================== +Actions +------- +- left pane - local psql console +- right pane - psql console on developsta +- prepared create_table command on the left +- execute the command, it's ok +- show the command again +- show that mouse selection is innefective +- prefix + y + +- switch to right pane +- paste +- enter + +Script +------ +One scenario where I find line yank feature really useful is when I have to +execute a command on the production server. + +Here I have the local environment in the left pane, and I'm connected to +the production server in the right pane. + +The task I want to perform is creating a database table on the +production server. +Frankly, I feel hesitatnt to type that command straight on production. + +I'd rather first try and debug it locally, and then execute it on production. + +Let's do that then. I'll open a database console locally and type the command. + + +Oh, it looks like I have a typo. It's good I tried this locally first. + +Ok, the command works and is now ready. How do I now run in on production? +Typing this again, with the possibility of making a typo is not an option. +Let's try mouse selection. + +Hm, that won't work either. It seems I can't scope mouse +selection to the left pane. + +Let's now try line yank with prefix + 'y'. +Notice we're copying a multi-line command. + +I'll paste it in the right pane. + +That looks ok, so I'll execute it.. and it's good. + +6. Outro +======== +Actions +------- +- just a blank screen + +Script +------ +That's it for this screencast. I hope you'll find tmux-yank useful. diff --git a/dot_config/tmux/plugins/tpm/CHANGELOG.md b/dot_config/tmux/plugins/tpm/CHANGELOG.md new file mode 100644 index 0000000..a9ce81e --- /dev/null +++ b/dot_config/tmux/plugins/tpm/CHANGELOG.md @@ -0,0 +1,86 @@ +# Changelog + +### master + +### v3.1.0, 2023-01-03 +- upgrade to new version of `tmux-test` +- bug: when using `emacs` copy mode, Enter does not quit screen after tpm + installation/update. Fix by making `Escape` the key for emacs mode. +- add a doc with troubleshooting instructions +- add `.gitattributes` file that forces linefeed characters (classic `\n`) as + line endings - helps with misconfigured git on windows/cygwin +- readme update: announce Cygwin support +- un-deprecate old plugin definition syntax: `set -g @tpm_plugins` +- More stuff, check `git log`. + +### v3.0.0, 2015-08-03 +- refactor `shared_set_tpm_path_constant` function +- move all instructions to `docs/` dir +- add `bin/install_plugins` cli executable script +- improved test runner function +- switch to using [tmux-test](https://github.com/tmux-plugins/tmux-test) + framework +- add `bin/update_plugins` cli executable script +- refactor test `expect` scripts, make them simpler and ensure they properly + assert expectations +- refactor code that sets 'TMUX_PLUGIN_MANAGER_PATH' global env var +- stop using global variable for 'tpm path' +- support defining plugins via `set -g @plugin` in sourced files as well + +### v2.0.0, 2015-07-07 +- enable overriding default key bindings +- start using `C-c` to clear screen +- add uninstall/clean procedure and keybinding (prefix+alt+u) (@chilicuil) +- add new `set @plugin 'repo'` plugin definition syntax (@chilicuil) +- revert back to using `-g` flag in new plugin definition syntax +- permit leading whitespace with new plugin definition syntax (thanks @chilicuil) +- make sure `TMUX_PLUGIN_MANAGER_PATH` always has trailng slash +- ensure old/deprecated plugin syntax `set -g @tpm_plugins` works alongside new + `set -g @plugin` syntax + +### v1.2.2, 2015-02-08 +- set GIT_TERMINAL_PROMPT=0 when doing `git clone`, `pull` or `submodule update` + to ensure git does not prompt for username/password in any case + +### v1.2.1, 2014-11-21 +- change the way plugin name is expanded. It now uses the http username + and password by default, like this: `https://git::@github.com/`. This prevents + username and password prompt (and subsequently tmux install hanging) with old + git versions. Fixes #7. + +### v1.2.0, 2014-11-20 +- refactor tests so they can be used on travis +- add travis.yml, add travis badge to the readme + +### v1.1.0, 2014-11-19 +- if the plugin is not downloaded do not source it +- remove `PLUGINS.md`, an obsolete list of plugins +- update readme with instructions about uninstalling plugins +- tilde char and `$HOME` in `TMUX_SHARED_MANAGER_PATH` couldn't be used because + they are just plain strings. Fixing the problem by manually expanding them. +- bugfix: fragile `*.tmux` file globbing (@majutsushi) + +### v1.0.0, 2014-08-05 +- update readme because of github organization change to + [tmux-plugins](https://github.com/tmux-plugins) +- update tests to pass +- update README to suggest different first plugin +- update list of plugins in the README +- remove README 'about' section +- move key binding to the main file. Delete `key_binding.sh`. +- rename `display_message` -> `echo_message` +- installing plugins installs just new plugins. Already installed plugins aren't + updated. +- add 'update plugin' binding and functionality +- add test for updating a plugin + +### v0.0.2, 2014-07-17 +- run all *.tmux plugin files as executables +- fix all redirects to /dev/null +- fix bug: TPM shared path is created before sync (cloning plugins from github + is done) +- add test suite running in Vagrant +- add Tmux version check. `TPM` won't run if Tmux version is less than 1.9. + +### v0.0.1, 2014-05-21 +- get TPM up and running diff --git a/dot_config/tmux/plugins/tpm/HOW_TO_PLUGIN.md b/dot_config/tmux/plugins/tpm/HOW_TO_PLUGIN.md new file mode 100644 index 0000000..9901619 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/HOW_TO_PLUGIN.md @@ -0,0 +1,2 @@ +Instructions moved to +[docs/how_to_create_plugin.md](docs/how_to_create_plugin.md). diff --git a/dot_config/tmux/plugins/tpm/LICENSE.md b/dot_config/tmux/plugins/tpm/LICENSE.md new file mode 100644 index 0000000..1222865 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/LICENSE.md @@ -0,0 +1,20 @@ +MIT license +Copyright (C) 2014 Bruno Sutic + +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. diff --git a/dot_config/tmux/plugins/tpm/README.md b/dot_config/tmux/plugins/tpm/README.md new file mode 100644 index 0000000..2371863 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/README.md @@ -0,0 +1,101 @@ +# Tmux Plugin Manager + +[![Build Status](https://travis-ci.org/tmux-plugins/tpm.svg?branch=master)](https://travis-ci.org/tmux-plugins/tpm) + +Installs and loads `tmux` plugins. + +Tested and working on Linux, OSX, and Cygwin. + +See list of plugins [here](https://github.com/tmux-plugins/list). + +### Installation + +Requirements: `tmux` version 1.9 (or higher), `git`, `bash`. + +Clone TPM: + +```bash +git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm +``` + +Put this at the bottom of `~/.tmux.conf` (`$XDG_CONFIG_HOME/tmux/tmux.conf` +works too): + +```bash +# List of plugins +set -g @plugin 'tmux-plugins/tpm' +set -g @plugin 'tmux-plugins/tmux-sensible' + +# Other examples: +# set -g @plugin 'github_username/plugin_name' +# set -g @plugin 'github_username/plugin_name#branch' +# set -g @plugin 'git@github.com:user/plugin' +# set -g @plugin 'git@bitbucket.com:user/plugin' + +# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) +run '~/.tmux/plugins/tpm/tpm' +``` + +Reload TMUX environment so TPM is sourced: + +```bash +# type this in terminal if tmux is already running +tmux source ~/.tmux.conf +``` + +That's it! + +### Installing plugins + +1. Add new plugin to `~/.tmux.conf` with `set -g @plugin '...'` +2. Press `prefix` + I (capital i, as in **I**nstall) to fetch the plugin. + +You're good to go! The plugin was cloned to `~/.tmux/plugins/` dir and sourced. + +### Uninstalling plugins + +1. Remove (or comment out) plugin from the list. +2. Press `prefix` + alt + u (lowercase u as in **u**ninstall) to remove the plugin. + +All the plugins are installed to `~/.tmux/plugins/` so alternatively you can +find plugin directory there and remove it. + +### Key bindings + +`prefix` + I +- Installs new plugins from GitHub or any other git repository +- Refreshes TMUX environment + +`prefix` + U +- updates plugin(s) + +`prefix` + alt + u +- remove/uninstall plugins not on the plugin list + +### Docs + +- [Help, tpm not working](docs/tpm_not_working.md) - problem solutions + +More advanced features and instructions, regular users probably do not need +this: + +- [How to create a plugin](docs/how_to_create_plugin.md). It's easy. +- [Managing plugins via the command line](docs/managing_plugins_via_cmd_line.md) +- [Changing plugins install dir](docs/changing_plugins_install_dir.md) +- [Automatic TPM installation on a new machine](docs/automatic_tpm_installation.md) + +### Tests + +Tests for this project run on [Travis CI](https://travis-ci.org/tmux-plugins/tpm). + +When run locally, [vagrant](https://www.vagrantup.com/) is required. +Run tests with: + +```bash +# within project directory +./run_tests +``` + +### License + +[MIT](LICENSE.md) diff --git a/dot_config/tmux/plugins/tpm/bin/executable_clean_plugins b/dot_config/tmux/plugins/tpm/bin/executable_clean_plugins new file mode 100644 index 0000000..12f8730 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bin/executable_clean_plugins @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Script intended for use via the command line. +# +# `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, +# but does not need to be started in order to run this script. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" + +main() { + "$SCRIPTS_DIR/clean_plugins.sh" # has correct exit code +} +main diff --git a/dot_config/tmux/plugins/tpm/bin/executable_install_plugins b/dot_config/tmux/plugins/tpm/bin/executable_install_plugins new file mode 100644 index 0000000..c66b15b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bin/executable_install_plugins @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Script intended for use via the command line. +# +# `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, +# but does not need to be started in order to run this script. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" + +main() { + "$SCRIPTS_DIR/install_plugins.sh" # has correct exit code +} +main diff --git a/dot_config/tmux/plugins/tpm/bin/executable_update_plugins b/dot_config/tmux/plugins/tpm/bin/executable_update_plugins new file mode 100644 index 0000000..30a5646 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bin/executable_update_plugins @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Script intended for use via the command line. +# +# `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, +# but does not need to be started in order to run this script. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +PROGRAM_NAME="$0" + +if [ $# -eq 0 ]; then + echo "usage:" + echo " $PROGRAM_NAME all update all plugins" + echo " $PROGRAM_NAME tmux-foo update plugin 'tmux-foo'" + echo " $PROGRAM_NAME tmux-bar tmux-baz update multiple plugins" + exit 1 +fi + +main() { + "$SCRIPTS_DIR/update_plugin.sh" --shell-echo "$*" # has correct exit code +} +main "$*" + diff --git a/dot_config/tmux/plugins/tpm/bindings/executable_clean_plugins b/dot_config/tmux/plugins/tpm/bindings/executable_clean_plugins new file mode 100644 index 0000000..9a0d5d7 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bindings/executable_clean_plugins @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Tmux key-binding script. +# Scripts intended to be used via the command line are in `bin/` directory. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +HELPERS_DIR="$SCRIPTS_DIR/helpers" + +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +main() { + reload_tmux_environment + "$SCRIPTS_DIR/clean_plugins.sh" --tmux-echo >/dev/null 2>&1 + reload_tmux_environment + end_message +} +main diff --git a/dot_config/tmux/plugins/tpm/bindings/executable_install_plugins b/dot_config/tmux/plugins/tpm/bindings/executable_install_plugins new file mode 100644 index 0000000..3ade3c4 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bindings/executable_install_plugins @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Tmux key-binding script. +# Scripts intended to be used via the command line are in `bin/` directory. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +HELPERS_DIR="$SCRIPTS_DIR/helpers" + +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +main() { + reload_tmux_environment + "$SCRIPTS_DIR/install_plugins.sh" --tmux-echo >/dev/null 2>&1 + reload_tmux_environment + end_message +} +main diff --git a/dot_config/tmux/plugins/tpm/bindings/executable_update_plugins b/dot_config/tmux/plugins/tpm/bindings/executable_update_plugins new file mode 100644 index 0000000..28cc281 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bindings/executable_update_plugins @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Tmux key-binding script. +# Scripts intended to be used via the command line are in `bin/` directory. + +# This script: +# - shows a list of installed plugins +# - starts a prompt to enter the name of the plugin that will be updated + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +HELPERS_DIR="$SCRIPTS_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +display_plugin_update_list() { + local plugins="$(tpm_plugins_list_helper)" + tmux_echo "Installed plugins:" + tmux_echo "" + + for plugin in $plugins; do + # displaying only installed plugins + if plugin_already_installed "$plugin"; then + local plugin_name="$(plugin_name_helper "$plugin")" + tmux_echo " $plugin_name" + fi + done + + tmux_echo "" + tmux_echo "Type plugin name to update it." + tmux_echo "" + tmux_echo "- \"all\" - updates all plugins" + tmux_echo "- ENTER - cancels" +} + +update_plugin_prompt() { + tmux command-prompt -p 'plugin update:' " \ + send-keys C-c; \ + run-shell '$SCRIPTS_DIR/update_plugin_prompt_handler.sh %1'" +} + +main() { + reload_tmux_environment + display_plugin_update_list + update_plugin_prompt +} +main diff --git a/dot_config/tmux/plugins/tpm/docs/automatic_tpm_installation.md b/dot_config/tmux/plugins/tpm/docs/automatic_tpm_installation.md new file mode 100644 index 0000000..630573f --- /dev/null +++ b/dot_config/tmux/plugins/tpm/docs/automatic_tpm_installation.md @@ -0,0 +1,12 @@ +# Automatic tpm installation + +One of the first things we do on a new machine is cloning our dotfiles. Not everything comes with them though, so for example `tpm` most likely won't be installed. + +If you want to install `tpm` and plugins automatically when tmux is started, put the following snippet in `.tmux.conf` before the final `run '~/.tmux/plugins/tpm/tpm'`: + +``` +if "test ! -d ~/.tmux/plugins/tpm" \ + "run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm && ~/.tmux/plugins/tpm/bin/install_plugins'" +``` + +This useful tip was submitted by @acr4 and narfman0. diff --git a/dot_config/tmux/plugins/tpm/docs/changing_plugins_install_dir.md b/dot_config/tmux/plugins/tpm/docs/changing_plugins_install_dir.md new file mode 100644 index 0000000..27de96d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/docs/changing_plugins_install_dir.md @@ -0,0 +1,16 @@ +# Changing plugins install dir + +By default, TPM installs plugins in a subfolder named `plugins/` inside +`$XDG_CONFIG_HOME/tmux/` if a `tmux.conf` file was found at that location, or +inside `~/.tmux/` otherwise. + +You can change the install path by putting this in `.tmux.conf`: + + set-environment -g TMUX_PLUGIN_MANAGER_PATH '/some/other/path/' + +Tmux plugin manager initialization in `.tmux.conf` should also be updated: + + # initializes TMUX plugin manager in a new path + run /some/other/path/tpm/tpm + +Please make sure that the `run` line is at the very bottom of `.tmux.conf`. diff --git a/dot_config/tmux/plugins/tpm/docs/how_to_create_plugin.md b/dot_config/tmux/plugins/tpm/docs/how_to_create_plugin.md new file mode 100644 index 0000000..f7d9c13 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/docs/how_to_create_plugin.md @@ -0,0 +1,108 @@ +# How to create Tmux plugins + +Creating a new plugin is easy. + +For demonstration purposes we'll create a simple plugin that lists all +installed TPM plugins. Yes, a plugin that lists plugins :) We'll bind that to +`prefix + T`. + +The source code for this example plugin can be found +[here](https://github.com/tmux-plugins/tmux-example-plugin). + +### 1. create a new git project + +TPM depends on git for downloading and updating plugins. + +To create a new git project: + + $ mkdir tmux_my_plugin + $ cd tmux_my_plugin + $ git init + +### 2. create a `*.tmux` plugin run file + +When it sources a plugin, TPM executes all `*.tmux` files in your plugins' +directory. That's how plugins are run. + +Create a plugin run file in plugin directory: + + $ touch my_plugin.tmux + $ chmod u+x my_plugin.tmux + +You can have more than one `*.tmux` file, and all will get executed. However, usually +you'll need just one. + +### 3. create a plugin key binding + +We want the behavior of the plugin to trigger when a user hits `prefix + T`. + +Key `T` is chosen because: + - it's "kind of" a mnemonic for `TPM` + - the key is not used by Tmux natively. Tmux man page, KEY BINDINGS section + contains a list of all the bindings Tmux uses. There's plenty of unused keys + and we don't want to override any of Tmux default key bindings. + +Open the plugin run file in your favorite text editor: + + $ vim my_plugin.tmux + # or + $ subl my_plugin.tmux + +Put the following content in the file: + + #!/usr/bin/env bash + + CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + tmux bind-key T run-shell "$CURRENT_DIR/scripts/tmux_list_plugins.sh" + +As you can see, plugin run file is a simple bash script that sets up the binding. + +When pressed, `prefix + T` will execute another shell script: +`tmux_list_plugins.sh`. That script should be in `scripts/` directory - +relative to the plugin run file. + + +### 4. listing plugins + +Now that we have the binding, let's create a script that's invoked with +`prefix + T`. + + $ mkdir scripts + $ touch scripts/tmux_list_plugins.sh + $ chmod u+x scripts/tmux_list_plugins.sh + +And here's the script content: + + #!/usr/bin/env bash + + # fetching the directory where plugins are installed + plugin_path="$(tmux show-env -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)" + + # listing installed plugins + ls -1 "$plugin_path" + +### 5. try it out + +To see if this works, execute the plugin run file: + + $ ./my_plugin.tmux + +That should set up the key binding. Now hit `prefix + T` and see if it works. + +### 6. publish the plugin + +When everything is ready, push the plugin to an online git repository, +preferably GitHub. + +Other users can install your plugin by just adding plugin git URL to the +`@plugin` list in their `.tmux.conf`. + +If the plugin is on GitHub, your users will be able to use the shorthand of +`github_username/repository`. + +### Conclusion + +Hopefully, that was easy. As you can see, it's mostly shell scripting. + +You can use other scripting languages (ruby, python etc) but plain old shell +is preferred because of portability. diff --git a/dot_config/tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md b/dot_config/tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md new file mode 100644 index 0000000..7aefd7d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md @@ -0,0 +1,36 @@ +# Managing plugins via the command line + +Aside from tmux key bindings, TPM provides shell interface for managing plugins +via scripts located in [bin/](../bin/) directory. + +Tmux does not need to be started in order to run scripts (but it's okay if it +is). If you [changed tpm install dir](../docs/changing_plugins_install_dir.md) +in `.tmux.conf` that should work fine too. + +Prerequisites: + +- tmux installed on the system (doh) +- `.tmux.conf` set up for TPM + +### Installing plugins + +As usual, plugins need to be specified in `.tmux.conf`. Run the following +command to install plugins: + + ~/.tmux/plugins/tpm/bin/install_plugins + +### Updating plugins + +To update all installed plugins: + + ~/.tmux/plugins/tpm/bin/update_plugins all + +or update a single plugin: + + ~/.tmux/plugins/tpm/bin/update_plugins tmux-sensible + +### Removing plugins + +To remove plugins not on the plugin list: + + ~/.tmux/plugins/tpm/bin/clean_plugins diff --git a/dot_config/tmux/plugins/tpm/docs/tpm_not_working.md b/dot_config/tmux/plugins/tpm/docs/tpm_not_working.md new file mode 100644 index 0000000..6680291 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/docs/tpm_not_working.md @@ -0,0 +1,102 @@ +# Help, tpm not working! + +Here's the list of issues users had with `tpm`: + +
+ +> Nothing works. `tpm` key bindings `prefix + I`, `prefix + U` not even + defined. + +Related [issue #22](https://github.com/tmux-plugins/tpm/issues/22) + +- Do you have required `tmux` version to run `tpm`?
+ Check `tmux` version with `$ tmux -V` command and make sure it's higher or + equal to the required version for `tpm` as stated in the readme. + +- ZSH tmux plugin might be causing issues.
+ If you have it installed, try disabling it and see if `tpm` works then. + +
+ +> Help, I'm using custom config file with `tmux -f /path/to/my_tmux.conf` +to start Tmux and for some reason plugins aren't loaded!? + +Related [issue #57](https://github.com/tmux-plugins/tpm/issues/57) + +`tpm` has a known issue when using custom config file with `-f` option. +The solution is to use alternative plugin definition syntax. Here are the steps +to make it work: + +1. remove all `set -g @plugin` lines from tmux config file +2. in the config file define the plugins in the following way: + + # List of plugins + set -g @tpm_plugins ' \ + tmux-plugins/tpm \ + tmux-plugins/tmux-sensible \ + tmux-plugins/tmux-resurrect \ + ' + + # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) + run '~/.tmux/plugins/tpm/tpm' + +3. Reload TMUX environment so TPM is sourced: `$ tmux source /path/to/my_tmux.conf` + +The plugins should now be working. + +
+ +> Weird sequence of characters show up when installing or updating plugins + +Related: [issue #25](https://github.com/tmux-plugins/tpm/issues/25) + +- This could be caused by [tmuxline.vim](https://github.com/edkolev/tmuxline.vim) + plugin. Uninstall it and see if things work. + +
+ +> "failed to connect to server" error when sourcing .tmux.conf + +Related: [issue #48](https://github.com/tmux-plugins/tpm/issues/48) + +- Make sure `tmux source ~/.tmux.conf` command is ran from inside `tmux`. + +
+ +> tpm not working: '~/.tmux/plugins/tpm/tpm' returned 2 (Windows / Cygwin) + +Related: [issue #81](https://github.com/tmux-plugins/tpm/issues/81) + +This issue is most likely caused by Windows line endings. For example, if you +have git's `core.autocrlf` option set to `true`, git will automatically convert +all the files to Windows line endings which might cause a problem. + +The solution is to convert all line ending to Unix newline characters. This +command handles that for all files under `.tmux/` dir (skips `.git` +subdirectories): + +```bash +find ~/.tmux -type d -name '.git*' -prune -o -type f -print0 | xargs -0 dos2unix +``` + +
+ +> '~/.tmux/plugins/tpm/tpm' returned 127 (on macOS, w/ tmux installed using brew) + +Related: [issue #67](https://github.com/tmux-plugins/tpm/issues/67) + +This problem is because tmux's `run-shell` command runs a shell which doesn't read from user configs, thus tmux installed in a brew prefix (e.g. `/usr/local/bin`) will not be found. + +The solution is to find your brew prefix + +```sh +> echo "$(brew --prefix)/bin" +/opt/homebrew/bin +``` + +And prepend it to the `PATH` environment variable +``` +set-environment -g PATH "/opt/homebrew/bin:/bin:/usr/bin" +``` + +before any `run-shell`/`run` commands in `~/.tmux.conf`. diff --git a/dot_config/tmux/plugins/tpm/dot_git/HEAD b/dot_config/tmux/plugins/tpm/dot_git/HEAD new file mode 100644 index 0000000..cb089cd --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/config b/dot_config/tmux/plugins/tpm/dot_git/config new file mode 100644 index 0000000..ea5d8f7 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/config @@ -0,0 +1,15 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[submodule] + active = . +[remote "origin"] + url = https://git::@github.com/tmux-plugins/tpm + fetch = +refs/heads/master:refs/remotes/origin/master +[branch "master"] + remote = origin + merge = refs/heads/master +[submodule "lib/tmux-test"] + url = https://github.com/tmux-plugins/tmux-test.git diff --git a/dot_config/tmux/plugins/tpm/dot_git/description b/dot_config/tmux/plugins/tpm/dot_git/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_applypatch-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_commit-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_fsmonitor-watchman.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_post-update.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-applypatch.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-commit.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-merge-commit.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-push.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-rebase.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-receive.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_prepare-commit-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_push-to-checkout.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_update.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/tmux/plugins/tpm/dot_git/index b/dot_config/tmux/plugins/tpm/dot_git/index new file mode 100644 index 0000000..579da09 Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/index differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/info/exclude b/dot_config/tmux/plugins/tpm/dot_git/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/tmux/plugins/tpm/dot_git/logs/HEAD b/dot_config/tmux/plugins/tpm/dot_git/logs/HEAD new file mode 100644 index 0000000..01ebb28 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 99469c4a9b1ccf77fade25842dc7bafbc8ce9946 Wizzard 1705878651 -0500 clone: from https://github.com/tmux-plugins/tpm diff --git a/dot_config/tmux/plugins/tpm/dot_git/logs/refs/heads/master b/dot_config/tmux/plugins/tpm/dot_git/logs/refs/heads/master new file mode 100644 index 0000000..01ebb28 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 99469c4a9b1ccf77fade25842dc7bafbc8ce9946 Wizzard 1705878651 -0500 clone: from https://github.com/tmux-plugins/tpm diff --git a/dot_config/tmux/plugins/tpm/dot_git/logs/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tpm/dot_git/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..01ebb28 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 99469c4a9b1ccf77fade25842dc7bafbc8ce9946 Wizzard 1705878651 -0500 clone: from https://github.com/tmux-plugins/tpm diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/HEAD b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/HEAD new file mode 100644 index 0000000..b36919d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/HEAD @@ -0,0 +1 @@ +33fa65fbfb72ba6dd106c21bf5ee6cc353ecdbb6 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/config b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/config new file mode 100644 index 0000000..a228840 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/config @@ -0,0 +1,12 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + worktree = ../../../../lib/tmux-test +[remote "origin"] + url = https://github.com/tmux-plugins/tmux-test.git + fetch = +refs/heads/master:refs/remotes/origin/master +[branch "master"] + remote = origin + merge = refs/heads/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/description b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_applypatch-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_commit-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_fsmonitor-watchman.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_post-update.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-applypatch.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-commit.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-merge-commit.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-push.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-rebase.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-receive.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_prepare-commit-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_push-to-checkout.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_update.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/index b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/index new file mode 100644 index 0000000..ea18887 Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/index differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/info/exclude b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/HEAD b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/HEAD new file mode 100644 index 0000000..862e630 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/HEAD @@ -0,0 +1,2 @@ +0000000000000000000000000000000000000000 cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 Wizzard 1705878651 -0500 clone: from https://github.com/tmux-plugins/tmux-test.git +cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 33fa65fbfb72ba6dd106c21bf5ee6cc353ecdbb6 Wizzard 1705878651 -0500 checkout: moving from master to 33fa65fbfb72ba6dd106c21bf5ee6cc353ecdbb6 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/heads/master b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/heads/master new file mode 100644 index 0000000..3c62fb3 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 Wizzard 1705878651 -0500 clone: from https://github.com/tmux-plugins/tmux-test.git diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..3c62fb3 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 Wizzard 1705878651 -0500 clone: from https://github.com/tmux-plugins/tmux-test.git diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.idx b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.idx new file mode 100644 index 0000000..dc77dab Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.idx differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.pack b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.pack new file mode 100644 index 0000000..3d0f6c1 Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.pack differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.rev b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.rev new file mode 100644 index 0000000..3b016b7 Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.rev differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/packed-refs b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/packed-refs new file mode 100644 index 0000000..c115c69 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/heads/master b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/heads/master new file mode 100644 index 0000000..4a94ccf --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/heads/master @@ -0,0 +1 @@ +cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/remotes/origin/HEAD new file mode 100644 index 0000000..6efe28f --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.0.1 b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.0.1 new file mode 100644 index 0000000..6e54b81 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.0.1 @@ -0,0 +1 @@ +53f50f99968c5d111dd8b1c9c2d220d818bc5b75 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.1.0 b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.1.0 new file mode 100644 index 0000000..bb34893 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.1.0 @@ -0,0 +1 @@ +0ea93e8287d81626e21a7c5d7a04bc60fb83034e diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.2.0 b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.2.0 new file mode 100644 index 0000000..b8cf1e2 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.2.0 @@ -0,0 +1 @@ +f9e3edd4d3855b76f676c885349e598c1b71d471 diff --git a/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.idx b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.idx new file mode 100644 index 0000000..5791428 Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.idx differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.pack b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.pack new file mode 100644 index 0000000..40beeff Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.pack differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.rev b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.rev new file mode 100644 index 0000000..ec09ecf Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.rev differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/packed-refs b/dot_config/tmux/plugins/tpm/dot_git/packed-refs new file mode 100644 index 0000000..51e3419 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +99469c4a9b1ccf77fade25842dc7bafbc8ce9946 refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/heads/master b/dot_config/tmux/plugins/tpm/dot_git/refs/heads/master new file mode 100644 index 0000000..e69d6dc --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/heads/master @@ -0,0 +1 @@ +99469c4a9b1ccf77fade25842dc7bafbc8ce9946 diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tpm/dot_git/refs/remotes/origin/HEAD new file mode 100644 index 0000000..6efe28f --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.1 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.1 new file mode 100644 index 0000000..3c28b9e --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.1 @@ -0,0 +1 @@ +aee1fbc949e1f68db3d8da7ac1b9bee5b4ac1595 diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.2 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.2 new file mode 100644 index 0000000..2a3fd81 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.2 @@ -0,0 +1 @@ +e29045e1db9ad6e1e9cf72ab59b78f0ec72cafb8 diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.0.0 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.0.0 new file mode 100644 index 0000000..761fd8d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.0.0 @@ -0,0 +1 @@ +d520c6a47a40dc1ab0e7799d95514c5aab000a8f diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.1.0 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.1.0 new file mode 100644 index 0000000..3c31de9 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.1.0 @@ -0,0 +1 @@ +0794614b55ea7c9b7c07306e64a09b8ac1207a2e diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.0 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.0 new file mode 100644 index 0000000..f811427 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.0 @@ -0,0 +1 @@ +1e65a591ab5972ff9072f2c07608ee1dd0b88eb7 diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.1 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.1 new file mode 100644 index 0000000..737c3e9 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.1 @@ -0,0 +1 @@ +92ba10978b6e9a7a767ed2ddb9c7190f9956789a diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.2 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.2 new file mode 100644 index 0000000..c48d270 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.2 @@ -0,0 +1 @@ +5957fe6b4644e75ba0740a94faf97307eb31046d diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v2.0.0 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v2.0.0 new file mode 100644 index 0000000..c9292df --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v2.0.0 @@ -0,0 +1 @@ +79c45e42bf525de25a12689f3770ff1f1d30a1aa diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v3.0.0 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v3.0.0 new file mode 100644 index 0000000..2c56969 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v3.0.0 @@ -0,0 +1 @@ +234002ad1c58e04b4e74853c7f1698874f69da60 diff --git a/dot_config/tmux/plugins/tpm/dot_gitattributes b/dot_config/tmux/plugins/tpm/dot_gitattributes new file mode 100644 index 0000000..80772e4 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_gitattributes @@ -0,0 +1,9 @@ +# Force text files to have unix eols, so Windows/Cygwin does not break them +*.* eol=lf + +# These files are unfortunately not recognized as text files so +# explicitly listing them here +tpm eol=lf +bin/* eol=lf +bindings/* eol=lf +tests/* eol=lf diff --git a/dot_config/tmux/plugins/tpm/dot_gitignore b/dot_config/tmux/plugins/tpm/dot_gitignore new file mode 100644 index 0000000..8a94156 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_gitignore @@ -0,0 +1,4 @@ +**/.vagrant/ +run_tests +tests/run_tests_in_isolation +tests/helpers/helpers.sh diff --git a/dot_config/tmux/plugins/tpm/dot_gitmodules b/dot_config/tmux/plugins/tpm/dot_gitmodules new file mode 100644 index 0000000..5e44e3c --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/tmux-test"] + path = lib/tmux-test + url = https://github.com/tmux-plugins/tmux-test.git diff --git a/dot_config/tmux/plugins/tpm/dot_travis.yml b/dot_config/tmux/plugins/tpm/dot_travis.yml new file mode 100644 index 0000000..ac45d8b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_travis.yml @@ -0,0 +1,19 @@ +# generic packages and tmux +before_install: + - sudo apt-get update + - sudo apt-get install -y git-core expect + - sudo apt-get install -y python-software-properties software-properties-common + - sudo apt-get install -y libevent-dev libncurses-dev + - git clone https://github.com/tmux/tmux.git + - cd tmux + - git checkout 2.0 + - sh autogen.sh + - ./configure && make && sudo make install + +install: + - git fetch --unshallow --recurse-submodules || git fetch --recurse-submodules + # manual `git clone` required for testing `tmux-test` plugin itself + - git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test; true + - lib/tmux-test/setup + +script: ./tests/run_tests_in_isolation diff --git a/dot_config/tmux/plugins/tpm/executable_tpm b/dot_config/tmux/plugins/tpm/executable_tpm new file mode 100644 index 0000000..7ad4b99 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/executable_tpm @@ -0,0 +1,81 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BINDINGS_DIR="$CURRENT_DIR/bindings" +SCRIPTS_DIR="$CURRENT_DIR/scripts" + +source "$SCRIPTS_DIR/variables.sh" + +get_tmux_option() { + local option="$1" + local default_value="$2" + local option_value="$(tmux show-option -gqv "$option")" + if [ -z "$option_value" ]; then + echo "$default_value" + else + echo "$option_value" + fi +} + +tpm_path_set() { + tmux show-environment -g "$DEFAULT_TPM_ENV_VAR_NAME" >/dev/null 2>&1 +} + +# Check if configuration file exists at an XDG-compatible location, if so use +# that directory for TMUX_PLUGIN_MANAGER_PATH. Otherwise use $DEFAULT_TPM_PATH. +set_default_tpm_path() { + local xdg_tmux_path="${XDG_CONFIG_HOME:-$HOME/.config}/tmux" + local tpm_path="$DEFAULT_TPM_PATH" + + if [ -f "$xdg_tmux_path/tmux.conf" ]; then + tpm_path="$xdg_tmux_path/plugins/" + fi + + tmux set-environment -g "$DEFAULT_TPM_ENV_VAR_NAME" "$tpm_path" +} + +# Ensures TMUX_PLUGIN_MANAGER_PATH global env variable is set. +# +# Put this in `.tmux.conf` to override the default: +# `set-environment -g TMUX_PLUGIN_MANAGER_PATH "/some/other/path/"` +set_tpm_path() { + if ! tpm_path_set; then + set_default_tpm_path + fi +} + +# 1. Fetches plugin names from `@plugin` variables +# 2. Creates full plugin path +# 3. Sources all *.tmux files from each of the plugin directories +# - no errors raised if directory does not exist +# Files are sourced as tmux config files, not as shell scripts! +source_plugins() { + "$SCRIPTS_DIR/source_plugins.sh" >/dev/null 2>&1 +} + +# prefix + I - downloads TPM plugins and reloads TMUX environment +# prefix + U - updates a plugin (or all of them) and reloads TMUX environment +# prefix + alt + u - remove unused TPM plugins and reloads TMUX environment +set_tpm_key_bindings() { + local install_key="$(get_tmux_option "$install_key_option" "$default_install_key")" + tmux bind-key "$install_key" run-shell "$BINDINGS_DIR/install_plugins" + + local update_key="$(get_tmux_option "$update_key_option" "$default_update_key")" + tmux bind-key "$update_key" run-shell "$BINDINGS_DIR/update_plugins" + + local clean_key="$(get_tmux_option "$clean_key_option" "$default_clean_key")" + tmux bind-key "$clean_key" run-shell "$BINDINGS_DIR/clean_plugins" +} + +supported_tmux_version_ok() { + "$SCRIPTS_DIR/check_tmux_version.sh" "$SUPPORTED_TMUX_VERSION" +} + +main() { + if supported_tmux_version_ok; then + set_tpm_path + set_tpm_key_bindings + source_plugins + fi +} +main diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/CHANGELOG.md b/dot_config/tmux/plugins/tpm/lib/tmux-test/CHANGELOG.md new file mode 100644 index 0000000..e6b9c79 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/CHANGELOG.md @@ -0,0 +1,45 @@ +# Changelog + +### master +- move `setup` task to `.travis.yml` for travis tests +- "merge" travis.yml and travis_for_plugins.yml files (no need to keep em + separate) +- add more useful helper functions +- remove tmux-test repo as a submodule from self, this causes issues with + `$ git submodule update --recursive --init` command that some users use for + managing other plugins +- add new helper `teardown_helper` +- add `run_tests` helper +- change CLI syntax for choosing vagrant machine to run the tests on +- enable running just a single test via `run_tests` cli interface +- add `--keep-running` cli option to continue running vagrant after the tests + are done executing +- start using tmux 2.0 for tests + +### v0.2.0, 2015-02-22 +- `setup` script gitignores `tests/helpers.sh` +- move `tests/helpers.sh` to `tests/helpers/helpers.sh` +- `setup` undo removes added lines from gitignore file + +### v0.1.0, 2015-02-22 +- changes so that 'tmux-test' can be included with tmux plugins +- do not gitignore submodules directory +- add installation and usage instructions +- copy `.travis.yml` to the project root when running `setup` script +- add a brief mention of travis CI to the readme +- add test helpers +- `setup` script symlinks helpers file to `tests/` directory +- `setup` script can undo most of its actions +- add a tmux scripting test +- `tmux-test` uses `tmux-test` to test itself +- update `tmux-test` submodule +- a different `travis.yml` for `tmux-test` and for plugins + +### v0.0.1, 2015-02-21 +- git init +- add vagrant provisioning scripts for ubuntu and debian +- add a ".travis.yml" file +- generic "run_tests" script +- "run_tests_in_isolation" script +- add "Vagrantfile" +- enable passing VM names as arguments to "run_tests" script diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/LICENSE.md b/dot_config/tmux/plugins/tpm/lib/tmux-test/LICENSE.md new file mode 100644 index 0000000..e6e7350 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (C) Bruno Sutic + +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. diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/README.md b/dot_config/tmux/plugins/tpm/lib/tmux-test/README.md new file mode 100644 index 0000000..27dccc9 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/README.md @@ -0,0 +1,134 @@ +# tmux-test + +[![Build Status](https://travis-ci.org/tmux-plugins/tmux-test.png?branch=master)](https://travis-ci.org/tmux-plugins/tmux-test) + +A small framework for isolated testing of tmux plugins. Isolation is achieved by +running the tests in `Vagrant`. Works on [travis](travis-ci.org) too. + +Extracted from [tmux plugin manager](https://github.com/tmux-plugins/tpm) and +[tmux-copycat](https://github.com/tmux-plugins/tmux-copycat). + +Dependencies: `Vagrant` (no required when running on travis). + +### Setup + +Let's say you made tmux plugin with the following file hierarchy: + +```text +/tmux-plugin +|-- plugin.tmux +`-- scripts + `-- plugin_script.sh +``` + +From your project root directory (tmux-plugin/) execute the following shell +command to fetch `tmux-test` and add it as a submodule: + + $ git submodule add https://github.com/tmux-plugins/tmux-test.git lib/tmux-test + +Run the `setup` script: + + $ lib/tmux-test/setup + +The project directory will now look like this (additions have comments): + +```text +/tmux-plugin +|-- plugin.tmux +|-- run_tests # symlink, gitignored +|-- .gitignore # 2 lines appended to gitignore +|-- .travis.yml # added +|-- lib/tmux-test/ # git submodule +|-- scripts +| `-- plugin_script.sh +`-- tests # dir to put the tests in + `-- run_tests_in_isolation.sh # symlink, gitignored + `-- helpers + `-- helpers.sh # symlinked bash helpers, gitignored +``` + +`tmux-test` is now set up. You are ok to commit the additions to the repo. + +### Writing and running tests + +A test is any executable with a name starting with `test_` in `tests/` +directory. + +Now that you installed `tmux-test` let's create an example test. + +- create a `tests/test_example.sh` file with the following content (it's a + `bash` script but it can be any executable): + + #/usr/bin/env bash + + CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + + # bash helpers provided by 'tmux-test' + source $CURRENT_DIR/helpers/helpers.sh + + # installs plugin from current repo in Vagrant (or on Travis) + install_tmux_plugin_under_test_helper + + # start tmux in background (plugin under test is sourced) + tmux new -d + + # get first session name + session_name="$(tmux list-sessions -F "#{session_name}")" + + # fail the test if first session name is not "0" + if [ "$session_name" == "0" ]; then + # fail_helper is also provided by 'tmux-test' + fail_helper "First session name is not '0' by default" + fi + + # sets the right script exit code ('tmux-test' helper) + exit_helper + +- make the test file executable with `$ chmod +x tests/test_example.sh` +- run the test by executing `./run_tests` from the project root directory +- the first invocation might take some time because Vagrant's ubuntu virtual + machine is downloading. You should see `Success, tests pass!` message when it's + done. + +Check out more example test scripts in this project's [tests/ directory](tests/). + +### Continuous integration + +The setup script (`lib/tmux-test/setup`) added a `.travis.yml` file to the +project root. To setup continuous integration, just add/enable the project on +[travis](travis-ci.org). + +### Notes + +- The `tests/` directory for tests and `lib/tmux-test/` for cloning `tmux-test` + into cannot be changed currently +- Don't run `tests/run_tests_in_isolation` script on your local development + environment. That's an internal test runner meant to be executed in an + isolated environment like `vagrant` or `travis`.
+ Use `./run_tests` script. +- You can use `KEEP_RUNNING=true ./run_tests` for faster test running cycle. + If this case `Vagrant` will keep running even after the tests are done. +- You can use `VAGRANT_CWD=lib/tmux-text/ vagrant ssh ubuntu` for ssh login to + `Vagrant`. + +### Running `tmux-test` framework tests + +`tmux-test` uses itself to test itself. To run framework tests: + +- clone this project `$ git clone git@github.com:tmux-plugins/tmux-test.git` +- `$ cd tmux-test` +- run `$ ./run_framework_tests` + +### Other goodies + +- [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) - a plugin for + regex searches in tmux and fast match selection +- [tmux-continuum](https://github.com/tmux-plugins/tmux-continuum) - automatic + restoring and continuous saving of tmux env + +You might want to follow [@brunosutic](https://twitter.com/brunosutic) on +twitter if you want to hear about new tmux plugins or feature updates. + +### License + +[MIT](LICENSE.md) diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/Vagrantfile b/dot_config/tmux/plugins/tpm/lib/tmux-test/Vagrantfile new file mode 100644 index 0000000..04b3eba --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/Vagrantfile @@ -0,0 +1,17 @@ +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + + config.vm.synced_folder "../../", "/vagrant" + + config.vm.define :ubuntu do |ubuntu| + ubuntu.vm.box = "hashicorp/precise64" + ubuntu.vm.provision "shell", path: "vagrant_ubuntu_provisioning.sh" + end + + config.vm.define :centos do |centos| + centos.vm.box = "chef/centos-6.5" + centos.vm.provision "shell", path: "vagrant_centos_provisioning.sh" + end + +end diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_git b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_git new file mode 100644 index 0000000..71808e5 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_git @@ -0,0 +1 @@ +gitdir: ../../.git/modules/lib/tmux-test diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_gitignore b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_gitignore new file mode 100644 index 0000000..27281b5 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_gitignore @@ -0,0 +1,2 @@ +.vagrant/ +lib/ diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_travis.yml b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_travis.yml new file mode 100644 index 0000000..ac45d8b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_travis.yml @@ -0,0 +1,19 @@ +# generic packages and tmux +before_install: + - sudo apt-get update + - sudo apt-get install -y git-core expect + - sudo apt-get install -y python-software-properties software-properties-common + - sudo apt-get install -y libevent-dev libncurses-dev + - git clone https://github.com/tmux/tmux.git + - cd tmux + - git checkout 2.0 + - sh autogen.sh + - ./configure && make && sudo make install + +install: + - git fetch --unshallow --recurse-submodules || git fetch --recurse-submodules + # manual `git clone` required for testing `tmux-test` plugin itself + - git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test; true + - lib/tmux-test/setup + +script: ./tests/run_tests_in_isolation diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_framework_tests b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_framework_tests new file mode 100644 index 0000000..ed7f634 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_framework_tests @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# This file is used to run "tmux-test" framework tests. + +# "setup" script is needed to run the tests, but it overrides some working dir +# files. To address that, "setup" is run before the tests and it's actions are +# undone after. + +main() { + git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test + lib/tmux-test/setup + ./run_tests + local exit_value=$? + lib/tmux-test/setup "undo" + exit "$exit_value" +} +main diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_tests b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_tests new file mode 100644 index 0000000..eeeef28 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_tests @@ -0,0 +1,145 @@ +#!/usr/bin/env bash + +# This file is a symlink from 'tmux-test' plugin. +# You probably don't want to edit it. + +# Run this script when running a test suite. + +# For each virtual machine where tests run, this script performs the following: +# - starts VM +# - starts the test suite witin a VM +# - stops the VM after the test suite is done + +export BOXES="" +export FILES="" +export KEEP_RUNNING="" + +# global variable for script exit value +export EXIT_VALUE=0 + +display_help() { + echo "Usage:" + echo " ./run_tests # runs tests on default VM ubuntu" + echo " ./run_tests -m ubuntu # runs tests on ubuntu VM" + echo " ./run_tests -m ubuntu -m centos # runs tests on ubuntu and cents VMs" + echo " ./run_tests tests/some_test # run a single test file" + echo " ./run_tests --keep-running # don't stop vagrant after the tests are done" +} + +parse_arguments() { + while : + do + case "$1" in + -m | --machine) + local machine="$2" + if [ "$machine" == "ubuntu" ] || [ "$machine" == "centos" ]; then + BOXES="$BOXES $machine" + else + echo "Unknown machine '$machine'" + echo "" + display_help + exit 1 + fi + shift 2 + ;; + + -k | --keep-running) + KEEP_RUNNING="true" + shift + ;; + + -h | --help) + display_help + exit 0 + ;; + + --) # End of all options + shift + FILES="$*" + break + ;; + + -* ) + echo "Error: Unknown option: $1" >&2 + echo "" + display_help + exit 1 + ;; + + *) # No more options + FILES="$*" + break + ;; + esac + done + + # default options + if [ -z "$BOXES" ]; then + BOXES="ubuntu" + fi +} + +register_failing_tests() { + EXIT_VALUE=1 +} + +run_vagrant() { + local box="$1" + VAGRANT_CWD=lib/tmux-test/ vagrant up "$box" +} + +# Halt vagrant after tests are done running, unless `--keep-running` +# option is given +stop_vagrant() { + local box="$1" + if [ -z "$KEEP_RUNNING" ]; then + VAGRANT_CWD=lib/tmux-test/ vagrant halt "$box" + else + echo + echo "--keep-running option set, Vagrant not halted" + fi +} + +run_tests() { + local box="$1" + local test_file="/vagrant/tests/run_tests_in_isolation" + echo "Running test suite on $box from: $test_file" + echo + VAGRANT_CWD=lib/tmux-test/ vagrant ssh "$box" -c "cd /vagrant; $test_file $FILES" +} + +exit_message() { + local exit_val="$1" + echo + if [ "$exit_val" == 0 ]; then + echo "Success, tests pass!" + else + echo "Tests failed!" 1>&2 + fi +} + +run_tests_on_vm() { + local vm="$1" + run_vagrant "$vm" + run_tests "$vm" + local tests_exit_value="$?" + stop_vagrant "$vm" + if [ "$tests_exit_value" -gt 0 ]; then + register_failing_tests + fi +} + +run_tests_on_virtual_machines() { + local box + for box in $BOXES; do + run_tests_on_vm "$box" + done +} + +main() { + parse_arguments "$@" + run_tests_on_virtual_machines + exit_message "$EXIT_VALUE" + exit "$EXIT_VALUE" +} +main "$@" diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_setup b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_setup new file mode 100644 index 0000000..575a8a3 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_setup @@ -0,0 +1,93 @@ +#!/usr/bin/env bash + +# invoke this script from your projects root directory + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# pass "undo" as a script arg to undo most of the setup actions +UNDO_SETUP="$1" +undo() { + [ "$UNDO_SETUP" == "undo" ] +} + +restore() { + local file="$1" + rm -f "$file" + git checkout -- "$file" 2>/dev/null +} + +gitignore() { + local file="$1" + grep -q "^${file}$" .gitignore 2>/dev/null || echo "$file" >> .gitignore +} + +remove_from_gitignore() { + local file="$1" + local escaped_filename="$(echo "$file" | sed "s,/,\\\/,g")" + sed -i"" "/^${escaped_filename}$/d" .gitignore +} + +add_files_to_gitignore() { + if ! undo; then + gitignore "run_tests" + gitignore "tests/run_tests_in_isolation" + gitignore "tests/helpers/helpers.sh" + else + remove_from_gitignore "run_tests" + remove_from_gitignore "tests/run_tests_in_isolation" + remove_from_gitignore "tests/helpers/helpers.sh" + fi +} + +symlink_user_test_runner() { + local file="run_tests" + if ! undo; then + ln -sf "lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +create_directory_for_tests() { + if ! undo; then + mkdir -p tests/helpers/ + fi +} + +symlink_internal_test_runner() { + local file="tests/run_tests_in_isolation" + if ! undo; then + ln -sf "../lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +symlink_test_helpers() { + local file="tests/helpers/helpers.sh" + if ! undo; then + ln -sf "../../lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +copy_travis_yml() { + local file=".travis.yml" + if ! undo; then + cp "lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +main() { + add_files_to_gitignore + symlink_user_test_runner + create_directory_for_tests + symlink_internal_test_runner + symlink_test_helpers + copy_travis_yml +} +main + diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_literal_run_tests_in_isolation b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_literal_run_tests_in_isolation new file mode 100644 index 0000000..fa39ebe --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_literal_run_tests_in_isolation @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +# This file is a symlink from 'tmux-test' plugin. +# You probably don't want to edit it. + +# This script should be run within an isolated enviroment (Vagrant, travis). +# Depending on what the tests do, it might NOT be safe to run this script +# directly on the development machine. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +EXIT_VALUE=0 # running a test suite is successful by default + +all_test_files() { + ls -1 "$CURRENT_DIR" | # test files are in the current dir + \grep -i "^test" | # test file names start with "test" + xargs # file names in a single line +} + +set_exit_val_to_false() { + EXIT_VALUE=1 +} + +run_tests() { + local test_file tests_files + if [ "$#" -gt 0 ]; then + test_files="${@//tests\//}" # remove 'tests/' directory prefix + else + test_files="$(all_test_files)" + fi + for test_file in $test_files; do + echo "Running test: $test_file" + "${CURRENT_DIR}/${test_file}" + + # handling exit value + local test_exit_value="$?" + if [ "$test_exit_value" -ne 0 ]; then + set_exit_val_to_false + fi + done +} + +main() { + run_tests "$@" + exit "$EXIT_VALUE" +} +main "$@" diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_basic_script_execution.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_basic_script_execution.sh new file mode 100644 index 0000000..0fdcf09 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_basic_script_execution.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +exit 0 diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_default_session_name.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_default_session_name.sh new file mode 100644 index 0000000..c761b93 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_default_session_name.sh @@ -0,0 +1,24 @@ +#/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# bash helpers provided by 'tmux-test' +source $CURRENT_DIR/helpers/helpers.sh + +# installs plugin from current repo in Vagrant (or on Travis) +install_tmux_plugin_under_test_helper + +# start tmux in background (plugin under test is sourced) +tmux new -d + +# get first session name +session_name="$(tmux list-sessions -F "#{session_name}")" + +# fail the test if first session name is not "0" +if ! [ "$session_name" == "0" ]; then + # fail_helper is also provided by 'tmux-test' + fail_helper "First session name is not '0' by default" +fi + +# sets the right script exit code ('tmux-test' helper) +exit_helper diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_tmux_scripting.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_tmux_scripting.sh new file mode 100644 index 0000000..3b4bece --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_tmux_scripting.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source $CURRENT_DIR/helpers/helpers.sh + +number_of_windows() { + tmux list-windows | + wc -l | + sed "s/ //g" +} + +main() { + # start tmux in the background + tmux new -d + tmux new-window + + local number_of_windows="$(number_of_windows)" + if ! [ "$number_of_windows" -eq 2 ]; then + fail_helper "Incorrect number of windows. Expected 2, got $number_of_windows" + fi + exit_helper +} +main diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/helpers/helpers.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/helpers/helpers.sh new file mode 100644 index 0000000..32b1ee4 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/helpers/helpers.sh @@ -0,0 +1,68 @@ +# This file is a symlink from 'tmux-test' plugin. +# You probably don't want to edit it. + + +# Global variable that keeps the value of test status (success/fail). +# Suggested usage is via `fail_helper` and `exit_helper` functions. +TEST_STATUS="success" + +# PRIVATE FUNCTIONS + +_clone_the_plugin() { + local plugin_path="${HOME}/.tmux/plugins/tmux-plugin-under-test/" + rm -rf "$plugin_path" + git clone --recursive "${CURRENT_DIR}/../" "$plugin_path" >/dev/null 2>&1 +} + +_add_plugin_to_tmux_conf() { + set_tmux_conf_helper<<-HERE + run-shell '~/.tmux/plugins/tmux-plugin-under-test/*.tmux' + HERE +} + +# PUBLIC HELPER FUNCTIONS + +teardown_helper() { + rm -f ~/.tmux.conf + rm -rf ~/.tmux/ + tmux kill-server >/dev/null 2>&1 +} + +set_tmux_conf_helper() { + > ~/.tmux.conf # empty tmux.conf file + while read line; do + echo "$line" >> ~/.tmux.conf + done +} + +fail_helper() { + local message="$1" + echo "$message" >&2 + TEST_STATUS="fail" +} + +exit_helper() { + teardown_helper + if [ "$TEST_STATUS" == "fail" ]; then + echo "FAIL!" + echo + exit 1 + else + echo "SUCCESS" + echo + exit 0 + fi +} + +install_tmux_plugin_under_test_helper() { + _clone_the_plugin + _add_plugin_to_tmux_conf +} + +run_tests() { + # get all the functions starting with 'test_' and invoke them + for test in $(compgen -A function | grep "^test_"); do + "$test" + done + exit_helper +} diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_centos_provisioning.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_centos_provisioning.sh new file mode 100644 index 0000000..20a282b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_centos_provisioning.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# libevent2 installation instructions from here +# https://gist.github.com/rschuman/6168833 + +sudo su - + +yum -y install gcc kernel-devel make automake autoconf ncurses-devel +yum -y install git-core expect vim ruby ruby-devel ruby-irb + +# install libevent2 from source +curl http://sourceforge.net/projects/levent/files/latest/download?source=files -L -o libevent2.tar.gz -w 'Last URL was: %{url_effective}' +cd ~/downloads +tar zxvf libevent2.tar.gz +cd ./libevent-* +./configure --prefix=/usr/local +make +make install + +# compile tmux +git clone https://github.com/tmux/tmux.git ~/tmux_source +cd ~/tmux_source +git checkout 2.0 +sh autogen.sh +LDFLAGS="-L/usr/local/lib -Wl,-rpath=/usr/local/lib" ./configure --prefix=/usr/local +make && sudo make install diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_ubuntu_provisioning.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_ubuntu_provisioning.sh new file mode 100644 index 0000000..63a60ea --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_ubuntu_provisioning.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +sudo apt-get update +sudo apt-get install -y git-core expect vim +sudo apt-get install -y python-software-properties software-properties-common +sudo apt-get install -y build-essential libtool autotools-dev autoconf +sudo apt-get install -y pkg-config libevent-dev libncurses-dev + +# install tmux 2.0 +git clone https://github.com/tmux/tmux.git ~/tmux_source +cd ~/tmux_source +git checkout 2.0 +sh autogen.sh +./configure && make && sudo make install diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_check_tmux_version.sh b/dot_config/tmux/plugins/tpm/scripts/executable_check_tmux_version.sh new file mode 100644 index 0000000..b0aedec --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_check_tmux_version.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +VERSION="$1" +UNSUPPORTED_MSG="$2" + +get_tmux_option() { + local option=$1 + local default_value=$2 + local option_value=$(tmux show-option -gqv "$option") + if [ -z "$option_value" ]; then + echo "$default_value" + else + echo "$option_value" + fi +} + +# Ensures a message is displayed for 5 seconds in tmux prompt. +# Does not override the 'display-time' tmux option. +display_message() { + local message="$1" + + # display_duration defaults to 5 seconds, if not passed as an argument + if [ "$#" -eq 2 ]; then + local display_duration="$2" + else + local display_duration="5000" + fi + + # saves user-set 'display-time' option + local saved_display_time=$(get_tmux_option "display-time" "750") + + # sets message display time to 5 seconds + tmux set-option -gq display-time "$display_duration" + + # displays message + tmux display-message "$message" + + # restores original 'display-time' value + tmux set-option -gq display-time "$saved_display_time" +} + +# this is used to get "clean" integer version number. Examples: +# `tmux 1.9` => `19` +# `1.9a` => `19` +get_digits_from_string() { + local string="$1" + local only_digits="$(echo "$string" | tr -dC '[:digit:]')" + echo "$only_digits" +} + +tmux_version_int() { + local tmux_version_string=$(tmux -V) + echo "$(get_digits_from_string "$tmux_version_string")" +} + +unsupported_version_message() { + if [ -n "$UNSUPPORTED_MSG" ]; then + echo "$UNSUPPORTED_MSG" + else + echo "Error, Tmux version unsupported! Please install Tmux version $VERSION or greater!" + fi +} + +exit_if_unsupported_version() { + local current_version="$1" + local supported_version="$2" + if [ "$current_version" -lt "$supported_version" ]; then + display_message "$(unsupported_version_message)" + exit 1 + fi +} + +main() { + local supported_version_int="$(get_digits_from_string "$VERSION")" + local current_version_int="$(tmux_version_int)" + exit_if_unsupported_version "$current_version_int" "$supported_version_int" +} +main diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_clean_plugins.sh b/dot_config/tmux/plugins/tpm/scripts/executable_clean_plugins.sh new file mode 100644 index 0000000..a025524 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_clean_plugins.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/utility.sh" + +if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions + source "$HELPERS_DIR/tmux_echo_functions.sh" +else # shell output functions + source "$HELPERS_DIR/shell_echo_functions.sh" +fi + +clean_plugins() { + local plugins plugin plugin_directory + plugins="$(tpm_plugins_list_helper)" + + for plugin_directory in "$(tpm_path)"/*; do + [ -d "${plugin_directory}" ] || continue + plugin="$(plugin_name_helper "${plugin_directory}")" + case "${plugins}" in + *"${plugin}"*) : ;; + *) + [ "${plugin}" = "tpm" ] && continue + echo_ok "Removing \"$plugin\"" + rm -rf "${plugin_directory}" >/dev/null 2>&1 + [ -d "${plugin_directory}" ] && + echo_err " \"$plugin\" clean fail" || + echo_ok " \"$plugin\" clean success" + ;; + esac + done +} + +main() { + ensure_tpm_path_exists + clean_plugins + exit_value_helper +} +main diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_install_plugins.sh b/dot_config/tmux/plugins/tpm/scripts/executable_install_plugins.sh new file mode 100644 index 0000000..e2450ac --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_install_plugins.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/utility.sh" + +if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions + source "$HELPERS_DIR/tmux_echo_functions.sh" +else # shell output functions + source "$HELPERS_DIR/shell_echo_functions.sh" +fi + +clone() { + local plugin="$1" + local branch="$2" + if [ -n "$branch" ]; then + cd "$(tpm_path)" && + GIT_TERMINAL_PROMPT=0 git clone -b "$branch" --single-branch --recursive "$plugin" >/dev/null 2>&1 + else + cd "$(tpm_path)" && + GIT_TERMINAL_PROMPT=0 git clone --single-branch --recursive "$plugin" >/dev/null 2>&1 + fi +} + +# tries cloning: +# 1. plugin name directly - works if it's a valid git url +# 2. expands the plugin name to point to a GitHub repo and tries cloning again +clone_plugin() { + local plugin="$1" + local branch="$2" + clone "$plugin" "$branch" || + clone "https://git::@github.com/$plugin" "$branch" +} + +# clone plugin and produce output +install_plugin() { + local plugin="$1" + local branch="$2" + local plugin_name="$(plugin_name_helper "$plugin")" + + if plugin_already_installed "$plugin"; then + echo_ok "Already installed \"$plugin_name\"" + else + echo_ok "Installing \"$plugin_name\"" + clone_plugin "$plugin" "$branch" && + echo_ok " \"$plugin_name\" download success" || + echo_err " \"$plugin_name\" download fail" + fi +} + +install_plugins() { + local plugins="$(tpm_plugins_list_helper)" + for plugin in $plugins; do + IFS='#' read -ra plugin <<< "$plugin" + install_plugin "${plugin[0]}" "${plugin[1]}" + done +} + +verify_tpm_path_permissions() { + local path="$(tpm_path)" + # check the write permission flag for all users to ensure + # that we have proper access + [ -w "$path" ] || + echo_err "$path is not writable!" +} + +main() { + ensure_tpm_path_exists + verify_tpm_path_permissions + install_plugins + exit_value_helper +} +main diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_source_plugins.sh b/dot_config/tmux/plugins/tpm/scripts/executable_source_plugins.sh new file mode 100644 index 0000000..6381d54 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_source_plugins.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" + +plugin_dir_exists() { + [ -d "$1" ] +} + +# Runs all *.tmux files from the plugin directory. +# Files are ran as executables. +# No errors if the plugin dir does not exist. +silently_source_all_tmux_files() { + local plugin_path="$1" + local plugin_tmux_files="$plugin_path*.tmux" + if plugin_dir_exists "$plugin_path"; then + for tmux_file in $plugin_tmux_files; do + # if the glob didn't find any files this will be the + # unexpanded glob which obviously doesn't exist + [ -f "$tmux_file" ] || continue + # runs *.tmux file as an executable + $tmux_file >/dev/null 2>&1 + done + fi +} + +source_plugins() { + local plugin plugin_path + local plugins="$(tpm_plugins_list_helper)" + for plugin in $plugins; do + IFS='#' read -ra plugin <<< "$plugin" + plugin_path="$(plugin_path_helper "${plugin[0]}")" + silently_source_all_tmux_files "$plugin_path" + done +} + +main() { + source_plugins +} +main diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin.sh b/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin.sh new file mode 100644 index 0000000..e533664 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +# this script handles core logic of updating plugins + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/utility.sh" + +if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions + source "$HELPERS_DIR/tmux_echo_functions.sh" +else # shell output functions + source "$HELPERS_DIR/shell_echo_functions.sh" +fi + +# from now on ignore first script argument +shift + +pull_changes() { + local plugin="$1" + local plugin_path="$(plugin_path_helper "$plugin")" + cd "$plugin_path" && + GIT_TERMINAL_PROMPT=0 git pull && + GIT_TERMINAL_PROMPT=0 git submodule update --init --recursive +} + +update() { + local plugin="$1" output + output=$(pull_changes "$plugin" 2>&1) + if (( $? == 0 )); then + echo_ok " \"$plugin\" update success" + echo_ok "$(echo "$output" | sed -e 's/^/ | /')" + else + echo_err " \"$plugin\" update fail" + echo_err "$(echo "$output" | sed -e 's/^/ | /')" + fi +} + +update_all() { + echo_ok "Updating all plugins!" + echo_ok "" + local plugins="$(tpm_plugins_list_helper)" + for plugin in $plugins; do + IFS='#' read -ra plugin <<< "$plugin" + local plugin_name="$(plugin_name_helper "${plugin[0]}")" + # updating only installed plugins + if plugin_already_installed "$plugin_name"; then + update "$plugin_name" & + fi + done + wait +} + +update_plugins() { + local plugins="$*" + for plugin in $plugins; do + IFS='#' read -ra plugin <<< "$plugin" + local plugin_name="$(plugin_name_helper "${plugin[0]}")" + if plugin_already_installed "$plugin_name"; then + update "$plugin_name" & + else + echo_err "$plugin_name not installed!" & + fi + done + wait +} + +main() { + ensure_tpm_path_exists + if [ "$1" == "all" ]; then + update_all + else + update_plugins "$*" + fi + exit_value_helper +} +main "$*" diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin_prompt_handler.sh b/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin_prompt_handler.sh new file mode 100644 index 0000000..5e1f7d9 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin_prompt_handler.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +if [ $# -eq 0 ]; then + exit 0 +fi + +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +main() { + "$CURRENT_DIR/update_plugin.sh" --tmux-echo "$*" + reload_tmux_environment + end_message +} +main "$*" diff --git a/dot_config/tmux/plugins/tpm/scripts/helpers/plugin_functions.sh b/dot_config/tmux/plugins/tpm/scripts/helpers/plugin_functions.sh new file mode 100644 index 0000000..f33d215 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/helpers/plugin_functions.sh @@ -0,0 +1,104 @@ +# using @tpm_plugins is now deprecated in favor of using @plugin syntax +tpm_plugins_variable_name="@tpm_plugins" + +# manually expanding tilde char or `$HOME` variable. +_manual_expansion() { + local path="$1" + local expanded_tilde="${path/#\~/$HOME}" + echo "${expanded_tilde/#\$HOME/$HOME}" +} + +_tpm_path() { + local string_path="$(tmux start-server\; show-environment -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)/" + _manual_expansion "$string_path" +} + +_CACHED_TPM_PATH="$(_tpm_path)" + +# Get the absolute path to the users configuration file of TMux. +# This includes a prioritized search on different locations. +# +_get_user_tmux_conf() { + # Define the different possible locations. + xdg_location="${XDG_CONFIG_HOME:-$HOME/.config}/tmux/tmux.conf" + default_location="$HOME/.tmux.conf" + + # Search for the correct configuration file by priority. + if [ -f "$xdg_location" ]; then + echo "$xdg_location" + + else + echo "$default_location" + fi +} + +_tmux_conf_contents() { + user_config=$(_get_user_tmux_conf) + cat /etc/tmux.conf "$user_config" 2>/dev/null + if [ "$1" == "full" ]; then # also output content from sourced files + local file + for file in $(_sourced_files); do + cat $(_manual_expansion "$file") 2>/dev/null + done + fi +} + +# return files sourced from tmux config files +_sourced_files() { + _tmux_conf_contents | + sed -E -n -e "s/^[[:space:]]*source(-file)?[[:space:]]+(-q+[[:space:]]+)?['\"]?([^'\"]+)['\"]?/\3/p" +} + +# Want to be able to abort in certain cases +trap "exit 1" TERM +export TOP_PID=$$ + +_fatal_error_abort() { + echo >&2 "Aborting." + kill -s TERM $TOP_PID +} + +# PUBLIC FUNCTIONS BELOW + +tpm_path() { + if [ "$_CACHED_TPM_PATH" == "/" ]; then + echo >&2 "FATAL: Tmux Plugin Manager not configured in tmux.conf" + _fatal_error_abort + fi + echo "$_CACHED_TPM_PATH" +} + +tpm_plugins_list_helper() { + # lists plugins from @tpm_plugins option + echo "$(tmux start-server\; show-option -gqv "$tpm_plugins_variable_name")" + + # read set -g @plugin "tmux-plugins/tmux-example-plugin" entries + _tmux_conf_contents "full" | + awk '/^[ \t]*set(-option)? +-g +@plugin/ { gsub(/'\''/,""); gsub(/'\"'/,""); print $4 }' +} + +# Allowed plugin name formats: +# 1. "git://github.com/user/plugin_name.git" +# 2. "user/plugin_name" +plugin_name_helper() { + local plugin="$1" + # get only the part after the last slash, e.g. "plugin_name.git" + local plugin_basename="$(basename "$plugin")" + # remove ".git" extension (if it exists) to get only "plugin_name" + local plugin_name="${plugin_basename%.git}" + echo "$plugin_name" +} + +plugin_path_helper() { + local plugin="$1" + local plugin_name="$(plugin_name_helper "$plugin")" + echo "$(tpm_path)${plugin_name}/" +} + +plugin_already_installed() { + local plugin="$1" + local plugin_path="$(plugin_path_helper "$plugin")" + [ -d "$plugin_path" ] && + cd "$plugin_path" && + git remote >/dev/null 2>&1 +} diff --git a/dot_config/tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh b/dot_config/tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh new file mode 100644 index 0000000..ecaa37e --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh @@ -0,0 +1,7 @@ +echo_ok() { + echo "$*" +} + +echo_err() { + fail_helper "$*" +} diff --git a/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh b/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh new file mode 100644 index 0000000..7a6ef0a --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh @@ -0,0 +1,28 @@ +_has_emacs_mode_keys() { + $(tmux show -gw mode-keys | grep -q emacs) +} + +tmux_echo() { + local message="$1" + tmux run-shell "echo '$message'" +} + +echo_ok() { + tmux_echo "$*" +} + +echo_err() { + tmux_echo "$*" +} + +end_message() { + if _has_emacs_mode_keys; then + local continue_key="ESCAPE" + else + local continue_key="ENTER" + fi + tmux_echo "" + tmux_echo "TMUX environment reloaded." + tmux_echo "" + tmux_echo "Done, press $continue_key to continue." +} diff --git a/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_utils.sh b/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_utils.sh new file mode 100644 index 0000000..238952d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_utils.sh @@ -0,0 +1,6 @@ +HELPERS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$HELPERS_DIR/plugin_functions.sh" + +reload_tmux_environment() { + tmux source-file $(_get_user_tmux_conf) >/dev/null 2>&1 +} diff --git a/dot_config/tmux/plugins/tpm/scripts/helpers/utility.sh b/dot_config/tmux/plugins/tpm/scripts/helpers/utility.sh new file mode 100644 index 0000000..de6eb35 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/helpers/utility.sh @@ -0,0 +1,17 @@ +ensure_tpm_path_exists() { + mkdir -p "$(tpm_path)" +} + +fail_helper() { + local message="$1" + echo "$message" >&2 + FAIL="true" +} + +exit_value_helper() { + if [ "$FAIL" == "true" ]; then + exit 1 + else + exit 0 + fi +} diff --git a/dot_config/tmux/plugins/tpm/scripts/variables.sh b/dot_config/tmux/plugins/tpm/scripts/variables.sh new file mode 100644 index 0000000..5601a86 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/variables.sh @@ -0,0 +1,13 @@ +install_key_option="@tpm-install" +default_install_key="I" + +update_key_option="@tpm-update" +default_update_key="U" + +clean_key_option="@tpm-clean" +default_clean_key="M-u" + +SUPPORTED_TMUX_VERSION="1.9" + +DEFAULT_TPM_ENV_VAR_NAME="TMUX_PLUGIN_MANAGER_PATH" +DEFAULT_TPM_PATH="$HOME/.tmux/plugins/" diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_failed_plugin_download b/dot_config/tmux/plugins/tpm/tests/executable_expect_failed_plugin_download new file mode 100644 index 0000000..b970477 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_failed_plugin_download @@ -0,0 +1,36 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + I +send "I" + +# cloning might take a while +set timeout 20 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installing \"non-existing-plugin\"" +} + +expect { + "\"non-existing-plugin\" download fail" +} + +expect { + "Done, press ENTER to continue" { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_clean_plugins b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_clean_plugins new file mode 100644 index 0000000..987c49d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_clean_plugins @@ -0,0 +1,35 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + alt + u +send "u" + +set timeout 5 + +expect_after { + timeout { exit 1 } +} + +expect { + "Removing \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" clean success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_multiple_plugins_download b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_multiple_plugins_download new file mode 100644 index 0000000..cc87a26 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_multiple_plugins_download @@ -0,0 +1,44 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + I +send "I" + +# cloning might take a while +set timeout 15 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installing \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" download success" +} + +expect { + "Installing \"tmux-copycat\"" +} + +expect { + "\"tmux-copycat\" download success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_plugin_download b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_plugin_download new file mode 100644 index 0000000..388f05d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_plugin_download @@ -0,0 +1,50 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + I +send "I" + +# cloning might take a while +set timeout 15 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installing \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" download success" +} + +expect { + "Done, press ENTER to continue" { + send " " + } +} + +sleep 1 +# this is tmux prefix + I +send "I" + +expect { + "Already installed \"tmux-example-plugin\"" +} + +expect { + "Done, press ENTER to continue" { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_a_single_plugin b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_a_single_plugin new file mode 100644 index 0000000..bcd64fe --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_a_single_plugin @@ -0,0 +1,55 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + U +send "U" + +set timeout 15 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installed plugins" +} + +expect { + "tmux-example-plugin" +} + +expect { + "\"all\" - updates all plugins" +} + +expect { + "ENTER - cancels" +} + +# wait for tmux to display prompt before sending characters +sleep 1 +send "tmux-example-plugin\r" + +expect { + "Updating \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" update success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_all_plugins b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_all_plugins new file mode 100644 index 0000000..4f3a4a3 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_all_plugins @@ -0,0 +1,59 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + U +send "U" + +set timeout 5 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installed plugins" +} + +expect { + "tmux-example-plugin" +} + +expect { + "\"all\" - updates all plugins" +} + +expect { + "ENTER - cancels" +} + +# wait for tmux to display prompt before sending characters +sleep 1 +send "all\r" + +expect { + "Updating all plugins!" +} + +expect { + "Updating \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" update success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_clean.sh b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_clean.sh new file mode 100644 index 0000000..d36c468 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_clean.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TPM_DIR="$PWD" +PLUGINS_DIR="$HOME/.tmux/plugins" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +manually_install_the_plugin() { + rm -rf "$PLUGINS_DIR" + mkdir -p "$PLUGINS_DIR" + cd "$PLUGINS_DIR" + git clone --quiet https://github.com/tmux-plugins/tmux-example-plugin +} + +# TMUX KEY-BINDING TESTS + +test_plugin_uninstallation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + "$CURRENT_DIR/expect_successful_clean_plugins" || + fail_helper "[key-binding] clean fails" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_uninstallation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + script_run_helper "$TPM_DIR/bin/clean_plugins" '"tmux-example-plugin" clean success' || + fail_helper "[script] plugin cleaning fails" + + teardown_helper +} + +test_unsuccessful_plugin_uninstallation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + chmod 000 "$PLUGINS_DIR/tmux-example-plugin" # disable directory deletion + + local expected_exit_code=1 + script_run_helper "$TPM_DIR/bin/clean_plugins" '"tmux-example-plugin" clean fail' "$expected_exit_code" || + fail_helper "[script] unsuccessful plugin cleaning doesn't fail" + + chmod 755 "$PLUGINS_DIR/tmux-example-plugin" # enable directory deletion + + teardown_helper +} + +run_tests diff --git a/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation.sh b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation.sh new file mode 100644 index 0000000..94fb674 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation.sh @@ -0,0 +1,284 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PLUGINS_DIR="$HOME/.tmux/plugins" +TPM_DIR="$PWD" + +CUSTOM_PLUGINS_DIR="$HOME/foo/plugins" +ADDITIONAL_CONFIG_FILE_1="$HOME/.tmux/additional_config_file_1" +ADDITIONAL_CONFIG_FILE_2="$HOME/.tmux/additional_config_file_2" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +# TMUX KEY-BINDING TESTS + +test_plugin_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_plugin_download" || + fail_helper "[key-binding] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails" + + teardown_helper +} + +test_plugin_installation_via_tmux_key_binding_set_option() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-option -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_plugin_download" || + fail_helper "[key-binding][set-option] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][set-option] plugin download fails" + + teardown_helper +} + +test_plugin_installation_custom_dir_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR' + + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_plugin_download" || + fail_helper "[key-binding][custom dir] plugin installation fails" + + check_dir_exists_helper "$CUSTOM_PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][custom dir] plugin download fails" + + teardown_helper + rm -rf "$CUSTOM_PLUGINS_DIR" +} + +test_non_existing_plugin_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/non-existing-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_failed_plugin_download" || + fail_helper "[key-binding] non existing plugin installation doesn't fail" + + teardown_helper +} + +test_multiple_plugins_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + \ \ set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_multiple_plugins_download" || + fail_helper "[key-binding] multiple plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding] plugin download fails (tmux-copycat)" + + teardown_helper +} + +test_plugins_installation_from_sourced_file_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + source '$ADDITIONAL_CONFIG_FILE_1' + set -g @plugin 'tmux-plugins/tmux-example-plugin' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo "set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1" + + "$CURRENT_DIR/expect_successful_multiple_plugins_download" || + fail_helper "[key-binding][sourced file] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][sourced file] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding][sourced file] plugin download fails (tmux-copycat)" + + teardown_helper +} + +test_plugins_installation_from_multiple_sourced_files_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + \ \ source '$ADDITIONAL_CONFIG_FILE_1' + source-file '$ADDITIONAL_CONFIG_FILE_2' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo "set -g @plugin 'tmux-plugins/tmux-example-plugin'" > "$ADDITIONAL_CONFIG_FILE_1" + echo " set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_2" + + "$CURRENT_DIR/expect_successful_multiple_plugins_download" || + fail_helper "[key-binding][multiple sourced files] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][multiple sourced files] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding][multiple sourced files] plugin download fails (tmux-copycat)" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' || + fail_helper "[script] plugin already installed message fail" + + teardown_helper +} + +test_plugin_installation_custom_dir_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR' + + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script][custom dir] plugin installation fails" + + check_dir_exists_helper "$CUSTOM_PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script][custom dir] plugin download fails" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' || + fail_helper "[script][custom dir] plugin already installed message fail" + + teardown_helper + rm -rf "$CUSTOM_PLUGINS_DIR" +} + +test_non_existing_plugin_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/non-existing-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + local expected_exit_code=1 + script_run_helper "$TPM_DIR/bin/install_plugins" '"non-existing-plugin" download fail' "$expected_exit_code" || + fail_helper "[script] non existing plugin installation doesn't fail" + + teardown_helper +} + +test_multiple_plugins_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + \ \ set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] multiple plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script] plugin download fails (tmux-copycat)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' || + fail_helper "[script] multiple plugins already installed message fail" + + teardown_helper +} + +test_plugins_installation_from_sourced_file_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + source '$ADDITIONAL_CONFIG_FILE_1' + set -g @plugin 'tmux-plugins/tmux-example-plugin' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo "set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1" + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-copycat" download success' || + fail_helper "[script][sourced file] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script][sourced file] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script][sourced file] plugin download fails (tmux-copycat)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' || + fail_helper "[script][sourced file] plugins already installed message fail" + + teardown_helper +} + +test_plugins_installation_from_multiple_sourced_files_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + \ \ source '$ADDITIONAL_CONFIG_FILE_1' + source-file '$ADDITIONAL_CONFIG_FILE_2' + set -g @plugin 'tmux-plugins/tmux-example-plugin' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo " set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1" + echo "set -g @plugin 'tmux-plugins/tmux-sensible'" > "$ADDITIONAL_CONFIG_FILE_2" + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-sensible" download success' || + fail_helper "[script][multiple sourced files] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script][multiple sourced files] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script][multiple sourced files] plugin download fails (tmux-copycat)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-sensible/" || + fail_helper "[script][multiple sourced files] plugin download fails (tmux-sensible)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-sensible"' || + fail_helper "[script][multiple sourced files] plugins already installed message fail" + + teardown_helper +} + +run_tests diff --git a/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation_legacy.sh b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation_legacy.sh new file mode 100644 index 0000000..b1d0cf6 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation_legacy.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PLUGINS_DIR="$HOME/.tmux/plugins" +TPM_DIR="$PWD" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +# TMUX KEY-BINDING TESTS + +test_plugin_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + # opens tmux and test it with `expect` + $CURRENT_DIR/expect_successful_plugin_download || + fail_helper "[key-binding] plugin installation fails" + + # check plugin dir exists after download + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails" + + teardown_helper +} + +test_legacy_and_new_syntax_for_plugin_installation_work_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins " \ + tmux-plugins/tmux-example-plugin \ + " + set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + # opens tmux and test it with `expect` + "$CURRENT_DIR"/expect_successful_multiple_plugins_download || + fail_helper "[key-binding] multiple plugins installation fails" + + # check plugin dir exists after download + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding] plugin download fails (tmux-copycat)" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' || + fail_helper "[script] plugin already installed message fail" + + teardown_helper +} + +test_legacy_and_new_syntax_for_plugin_installation_work_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins " \ + tmux-plugins/tmux-example-plugin \ + " + set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] multiple plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script] plugin download fails (tmux-copycat)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' || + fail_helper "[script] multiple plugins already installed message fail" + + teardown_helper +} + +run_tests diff --git a/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_sourcing.sh b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_sourcing.sh new file mode 100644 index 0000000..c06f1fe --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_sourcing.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TPM_DIR="$PWD" +PLUGINS_DIR="$HOME/.tmux/plugins" + +CUSTOM_PLUGINS_DIR="$HOME/foo/plugins" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +check_binding_defined() { + local binding="$1" + tmux list-keys | grep -q "$binding" +} + +create_test_plugin_helper() { + local plugin_path="$PLUGINS_DIR/tmux_test_plugin/" + rm -rf "$plugin_path" + mkdir -p "$plugin_path" + + while read line; do + echo "$line" >> "$plugin_path/test_plugin.tmux" + done + chmod +x "$plugin_path/test_plugin.tmux" +} + +check_tpm_path() { + local correct_tpm_path="$1" + local tpm_path="$(tmux start-server\; show-environment -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)" + [ "$correct_tpm_path" == "$tpm_path" ] +} + +test_plugin_sourcing() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "doesnt_matter/tmux_test_plugin" + run-shell "$TPM_DIR/tpm" + HERE + + # manually creates a local tmux plugin + create_test_plugin_helper <<- HERE + tmux bind-key R run-shell foo_command + HERE + + tmux new-session -d # tmux starts detached + check_binding_defined "R run-shell foo_command" || + fail_helper "Plugin sourcing fails" + + teardown_helper +} + +test_default_tpm_path() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + check_tpm_path "${PLUGINS_DIR}/" || + fail_helper "Default TPM path not correct" + + teardown_helper +} + +test_custom_tpm_path() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR' + run-shell "$TPM_DIR/tpm" + HERE + + check_tpm_path "$CUSTOM_PLUGINS_DIR" || + fail_helper "Custom TPM path not correct" + + teardown_helper +} + +run_tests diff --git a/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_update.sh b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_update.sh new file mode 100644 index 0000000..4924d16 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_update.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TPM_DIR="$PWD" +PLUGINS_DIR="$HOME/.tmux/plugins" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +manually_install_the_plugin() { + mkdir -p "$PLUGINS_DIR" + cd "$PLUGINS_DIR" + git clone --quiet https://github.com/tmux-plugins/tmux-example-plugin +} + +# TMUX KEY-BINDING TESTS + +test_plugin_update_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + "$CURRENT_DIR/expect_successful_update_of_all_plugins" || + fail_helper "[key-binding] 'update all plugins' fails" + + "$CURRENT_DIR/expect_successful_update_of_a_single_plugin" || + fail_helper "[key-binding] 'update single plugin' fails" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_update_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + local expected_exit_code=1 + script_run_helper "$TPM_DIR/bin/update_plugins" 'usage' "$expected_exit_code" || + fail_helper "[script] running update plugins without args should fail" + + script_run_helper "$TPM_DIR/bin/update_plugins tmux-example-plugin" '"tmux-example-plugin" update success' || + fail_helper "[script] plugin update fails" + + script_run_helper "$TPM_DIR/bin/update_plugins all" '"tmux-example-plugin" update success' || + fail_helper "[script] update all plugins fails" + + teardown_helper +} + +run_tests diff --git a/dot_config/tmux/plugins/tpm/tests/helpers/tpm.sh b/dot_config/tmux/plugins/tpm/tests/helpers/tpm.sh new file mode 100644 index 0000000..1594afb --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/helpers/tpm.sh @@ -0,0 +1,13 @@ +check_dir_exists_helper() { + [ -d "$1" ] +} + +# runs the scripts and asserts it has the correct output and exit code +script_run_helper() { + local script="$1" + local expected_output="$2" + local expected_exit_code="${3:-0}" + $script 2>&1 | + grep "$expected_output" >/dev/null 2>&1 && # grep -q flag quits the script early + [ "${PIPESTATUS[0]}" -eq "$expected_exit_code" ] +} diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/License.md b/dot_config/tmux/plugins/vim-tmux-navigator/License.md new file mode 100644 index 0000000..046c81d --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/License.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Chris Toomey + +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. diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/README.md b/dot_config/tmux/plugins/vim-tmux-navigator/README.md new file mode 100644 index 0000000..a45f310 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/README.md @@ -0,0 +1,461 @@ +Vim Tmux Navigator +================== + +This plugin is a repackaging of [Mislav Marohnić's](https://mislav.net/) tmux-navigator +configuration described in [this gist][]. When combined with a set of tmux +key bindings, the plugin will allow you to navigate seamlessly between +vim and tmux splits using a consistent set of hotkeys. + +**NOTE**: This requires tmux v1.8 or higher. + +Usage +----- + +This plugin provides the following mappings which allow you to move between +Vim panes and tmux splits seamlessly. + +- `` => Left +- `` => Down +- `` => Up +- `` => Right +- `` => Previous split + +**Note** - you don't need to use your tmux `prefix` key sequence before using +the mappings. + +If you want to use alternate key mappings, see the [configuration section +below][]. + +Installation +------------ + +### Vim + +If you don't have a preferred installation method, I recommend using [Vundle][]. +Assuming you have Vundle installed and configured, the following steps will +install the plugin: + +Add the following line to your `~/.vimrc` file + +``` vim +Plugin 'christoomey/vim-tmux-navigator' +``` + +Then run + +``` +:PluginInstall +``` + +If you are using Vim 8+, you don't need any plugin manager. Simply clone this repository inside `~/.vim/pack/plugin/start/` directory and restart Vim. + +``` +git clone git@github.com:christoomey/vim-tmux-navigator.git ~/.vim/pack/plugins/start/vim-tmux-navigator +``` + +### lazy.nvim + +If you are using [lazy.nvim](https://github.com/folke/lazy.nvim). Add the following plugin to your configuration. + +```lua +{ + "christoomey/vim-tmux-navigator", + cmd = { + "TmuxNavigateLeft", + "TmuxNavigateDown", + "TmuxNavigateUp", + "TmuxNavigateRight", + "TmuxNavigatePrevious", + }, + keys = { + { "", "TmuxNavigateLeft" }, + { "", "TmuxNavigateDown" }, + { "", "TmuxNavigateUp" }, + { "", "TmuxNavigateRight" }, + { "", "TmuxNavigatePrevious" }, + }, +} +``` + +Then, restart Neovim and lazy.nvim will automatically install the plugin and configure the keybindings. + +### tmux + +To configure the tmux side of this customization there are two options: + +#### Add a snippet + +Add the following to your `~/.tmux.conf` file: + +``` tmux +# Smart pane switching with awareness of Vim splits. +# See: https://github.com/christoomey/vim-tmux-navigator +is_vim="ps -o state= -o comm= -t '#{pane_tty}' \ + | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'" +bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L' +bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' 'select-pane -D' +bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' 'select-pane -U' +bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R' +tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")' +if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \ + "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\' 'select-pane -l'" +if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \ + "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\' 'select-pane -l'" + +bind-key -T copy-mode-vi 'C-h' select-pane -L +bind-key -T copy-mode-vi 'C-j' select-pane -D +bind-key -T copy-mode-vi 'C-k' select-pane -U +bind-key -T copy-mode-vi 'C-l' select-pane -R +bind-key -T copy-mode-vi 'C-\' select-pane -l +``` + +#### TPM + +If you'd prefer, you can use the Tmux Plugin Manager ([TPM][]) instead of +copying the snippet. +When using TPM, add the following lines to your ~/.tmux.conf: + +``` tmux +set -g @plugin 'christoomey/vim-tmux-navigator' +run '~/.tmux/plugins/tpm/tpm' +``` + +Thanks to Christopher Sexton who provided the updated tmux configuration in +[this blog post][]. + +Configuration +------------- + +### Custom Key Bindings + +If you don't want the plugin to create any mappings, you can use the five +provided functions to define your own custom maps. You will need to define +custom mappings in your `~/.vimrc` as well as update the bindings in tmux to +match. + +#### Vim + +Add the following to your `~/.vimrc` to define your custom maps: + +``` vim +let g:tmux_navigator_no_mappings = 1 + +noremap {Left-Mapping} :TmuxNavigateLeft +noremap {Down-Mapping} :TmuxNavigateDown +noremap {Up-Mapping} :TmuxNavigateUp +noremap {Right-Mapping} :TmuxNavigateRight +noremap {Previous-Mapping} :TmuxNavigatePrevious +``` + +*Note* Each instance of `{Left-Mapping}` or `{Down-Mapping}` must be replaced +in the above code with the desired mapping. Ie, the mapping for `` => +Left would be created with `noremap :TmuxNavigateLeft`. + +##### Autosave on leave + +You can configure the plugin to write the current buffer, or all buffers, when +navigating from Vim to tmux. This functionality is exposed via the +`g:tmux_navigator_save_on_switch` variable, which can have either of the +following values: + +Value | Behavior +------ | ------ +1 | `:update` (write the current buffer, but only if changed) +2 | `:wall` (write all buffers) + +To enable this, add the following (with the desired value) to your ~/.vimrc: + +```vim +" Write all buffers before navigating from Vim to tmux pane +let g:tmux_navigator_save_on_switch = 2 +``` + +##### Disable While Zoomed + +By default, if you zoom the tmux pane running Vim and then attempt to navigate +"past" the edge of the Vim session, tmux will unzoom the pane. This is the +default tmux behavior, but may be confusing if you've become accustomed to +navigation "wrapping" around the sides due to this plugin. + +We provide an option, `g:tmux_navigator_disable_when_zoomed`, which can be used +to disable this unzooming behavior, keeping all navigation within Vim until the +tmux pane is explicitly unzoomed. + +To disable navigation when zoomed, add the following to your ~/.vimrc: + +```vim +" Disable tmux navigator when zooming the Vim pane +let g:tmux_navigator_disable_when_zoomed = 1 +``` + +##### Preserve Zoom + +As noted above, navigating from a Vim pane to another tmux pane normally causes +the window to be unzoomed. Some users may prefer the behavior of tmux's `-Z` +option to `select-pane`, which keeps the window zoomed if it was zoomed. To +enable this behavior, set the `g:tmux_navigator_preserve_zoom` option to `1`: + +```vim +" If the tmux window is zoomed, keep it zoomed when moving from Vim to another pane +let g:tmux_navigator_preserve_zoom = 1 +``` + +Naturally, if `g:tmux_navigator_disable_when_zoomed` is enabled, this option +will have no effect. + +#### Tmux + +Alter each of the five lines of the tmux configuration listed above to use your +custom mappings. **Note** each line contains two references to the desired +mapping. + +### Additional Customization + +#### Ignoring programs that use Ctrl+hjkl movement + +In interactive programs such as FZF, Ctrl+hjkl can be used instead of the arrow keys to move the selection up and down. If vim-tmux-navigator is getting in your way trying to change the active window instead, you can make it be ignored and work as if this plugin were not enabled. Just modify the `is_vim` variable(that you have either on the snipped you pasted on `~/.tmux.conf` or on the `vim-tmux-navigator.tmux` file). For example, to add the program `foobar`: + +```diff +- is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'" ++ is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf|foobar)(diff)?$'" +``` + +#### Restoring Clear Screen (C-l) + +The default key bindings include `` which is the readline key binding +for clearing the screen. The following binding can be added to your `~/.tmux.conf` file to provide an alternate mapping to `clear-screen`. + +``` tmux +bind C-l send-keys 'C-l' +``` + +With this enabled you can use ` C-l` to clear the screen. + +Thanks to [Brian Hogan][] for the tip on how to re-map the clear screen binding. + +#### Restoring SIGQUIT (C-\\) + +The default key bindings also include `` which is the default method of +sending SIGQUIT to a foreground process. Similar to "Clear Screen" above, a key +binding can be created to replicate SIGQUIT in the prefix table. + +``` tmux +bind C-\\ send-keys 'C-\' +``` + +Alternatively, you can exclude the previous pane key binding from your `~/.tmux.conf`. If using TPM, the following line can be used to unbind the previous pane binding set by the plugin. + +``` tmux +unbind -n C-\\ +``` + +#### Disable Wrapping + +By default, if you try to move past the edge of the screen, tmux/vim will +"wrap" around to the opposite side. To disable this, you'll need to +configure both tmux and vim: + +For vim, you only need to enable this option: +```vim +let g:tmux_navigator_no_wrap = 1 +``` + +Tmux doesn't have an option, so whatever key bindings you have need to be set +to conditionally wrap based on position on screen: + +```tmux +is_vim="ps -o state= -o comm= -t '#{pane_tty}' \ + | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'" +bind-key -n 'C-h' if-shell "$is_vim" { send-keys C-h } { if-shell -F '#{pane_at_left}' {} { select-pane -L } } +bind-key -n 'C-j' if-shell "$is_vim" { send-keys C-j } { if-shell -F '#{pane_at_bottom}' {} { select-pane -D } } +bind-key -n 'C-k' if-shell "$is_vim" { send-keys C-k } { if-shell -F '#{pane_at_top}' {} { select-pane -U } } +bind-key -n 'C-l' if-shell "$is_vim" { send-keys C-l } { if-shell -F '#{pane_at_right}' {} { select-pane -R } } + +bind-key -T copy-mode-vi 'C-h' if-shell -F '#{pane_at_left}' {} { select-pane -L } +bind-key -T copy-mode-vi 'C-j' if-shell -F '#{pane_at_bottom}' {} { select-pane -D } +bind-key -T copy-mode-vi 'C-k' if-shell -F '#{pane_at_top}' {} { select-pane -U } +bind-key -T copy-mode-vi 'C-l' if-shell -F '#{pane_at_right}' {} { select-pane -R } +``` + +#### Nesting +If you like to nest your tmux sessions, this plugin is not going to work +properly. It probably never will, as it would require detecting when Tmux would +wrap from one outermost pane to another and propagating that to the outer +session. + +By default this plugin works on the outermost tmux session and the vim +sessions it contains, but you can customize the behaviour by adding more +commands to the expression used by the grep command. + +When nesting tmux sessions via ssh or mosh, you could extend it to look like +`'(^|\/)g?(view|vim|ssh|mosh?)(diff)?$'`, which makes this plugin work within +the innermost tmux session and the vim sessions within that one. This works +better than the default behaviour if you use the outer Tmux sessions as relays +to different hosts and have all instances of vim on remote hosts. + +Similarly, if you like to nest tmux locally, add `|tmux` to the expression. + +This behaviour means that you can't leave the innermost session with Ctrl-hjkl +directly. These following fallback mappings can be targeted to the right Tmux +session by escaping the prefix (Tmux' `send-prefix` command). + +``` tmux +bind -r C-h run "tmux select-pane -L" +bind -r C-j run "tmux select-pane -D" +bind -r C-k run "tmux select-pane -U" +bind -r C-l run "tmux select-pane -R" +bind -r C-\ run "tmux select-pane -l" +``` + +Another workaround is to configure tmux on the outer machine to send keys to +the inner tmux session: + +``` +bind-key -n 'M-h' 'send-keys c-h' +bind-key -n 'M-j' 'send-keys c-j' +bind-key -n 'M-k' 'send-keys c-k' +bind-key -n 'M-l' 'send-keys c-l' +``` + +Here we bind "meta" key (aka "alt" or "option" key) combinations for each of +the four directions and send those along to the innermost session via +`send-keys`. You use the normal `C-h,j,k,l` while in the outermost session and +the alternative bindings to navigate the innermost session. Note that if you +use the example above on a Mac, you may need to configure your terminal app to +get the option key to work like a normal meta key. Consult your terminal app's +manual for details. + +A third possible solution is to manually prevent the outermost tmux session +from intercepting the navigation keystrokes by disabling the prefix table: + +``` +set -g pane-active-border-style 'fg=#000000,bg=#ffff00' +bind -T root F12 \ + set prefix None \;\ + set key-table off \;\ + if -F '#{pane_in_mode}' 'send-keys -X cancel' \;\ + set -g pane-active-border-style 'fg=#000000,bg=#00ff00' + refresh-client -S \;\ + +bind -T off F12 \ + set -u prefix \;\ + set -u key-table \;\ + set -g pane-active-border-style 'fg=#000000,bg=#ffff00' + refresh-client -S +``` + +This code, added to the machine running the outermost tmux session, toggles the +outermost prefix table on and off with the `F12` key. When off, the active +pane's border changes to green to indicate that the inner session receives +navigation keystrokes. When toggled back on, the border returns to yellow and +normal operation resumes and the outermost responds to the nav keystrokes. + +The code example above also toggles the prefix key (ctrl-b by default) for the +outer session so that same prefix can be temporarily used on the inner session +instead of having to use a different prefix (ctrl-a by default) which you may +find convenient. If not, simply remove the lines that set/unset the prefix key +from the code example above. + + +Troubleshooting +--------------- + +### Vim -> Tmux doesn't work! + +This is likely due to conflicting key mappings in your `~/.vimrc`. You can use +the following search pattern to find conflicting mappings +`\v(nore)?map\s+\`. Any matching lines should be deleted or +altered to avoid conflicting with the mappings from the plugin. + +Another option is that the pattern matching included in the `.tmux.conf` is +not recognizing that Vim is active. To check that tmux is properly recognizing +Vim, use the provided Vim command `:TmuxNavigatorProcessList`. The output of +that command should be a list like: + +``` +Ss -zsh +S+ vim +S+ tmux +``` + +If you encounter a different output please [open an issue][] with as much info +about your OS, Vim version, and tmux version as possible. + +[open an issue]: https://github.com/christoomey/vim-tmux-navigator/issues/new + +### Tmux Can't Tell if Vim Is Active + +This functionality requires tmux version 1.8 or higher. You can check your +version to confirm with this shell command: + +``` bash +tmux -V # should return 'tmux 1.8' +``` + +### Switching out of Vim Is Slow + +If you find that navigation within Vim (from split to split) is fine, but Vim +to a non-Vim tmux pane is delayed, it might be due to a slow shell startup. +Consider moving code from your shell's non-interactive rc file (e.g., +`~/.zshenv`) into the interactive startup file (e.g., `~/.zshrc`) as Vim only +sources the non-interactive config. + +### It doesn't work in Vim's `terminal` mode + +Terminal mode is currently unsupported as adding this plugin's mappings there +causes conflict with movement mappings for FZF (it also uses terminal mode). +There's a conversation about this in https://github.com/christoomey/vim-tmux-navigator/pull/172 + +### It Doesn't Work in tmate + +[tmate][] is a tmux fork that aids in setting up remote pair programming +sessions. It is designed to run alongside tmux without issue, but occasionally +there are hiccups. Specifically, if the versions of tmux and tmate don't match, +you can have issues. See [this +issue](https://github.com/christoomey/vim-tmux-navigator/issues/27) for more +detail. + +[tmate]: http://tmate.io/ + +### Switching between host panes doesn't work when docker is running + +Images built from minimalist OSes may not have the `ps` command or have a +simpler version of the command that is not compatible with this plugin. +Try installing the `procps` package using the appropriate package manager +command. For Alpine, you would do `apk add procps`. + +If this doesn't solve your problem, you can also try the following: + +Replace the `is_vim` variable in your `~/.tmux.conf` file with: +```tmux +if-shell '[ -f /.dockerenv ]' \ + "is_vim=\"ps -o state=,comm= -t '#{pane_tty}' \ + | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?)(diff)?$'\"" + # Filter out docker instances of nvim from the host system to prevent + # host from thinking nvim is running in a pseudoterminal when its not. + "is_vim=\"ps -o state=,comm=,cgroup= -t '#{pane_tty}' \ + | grep -ivE '^.+ +.+ +.+\\/docker\\/.+$' \ + | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?)(diff)? +'\"" +``` + +Details: The output of the ps command on the host system includes processes +running within containers, but containers have their own instances of +/dev/pts/\*. vim-tmux-navigator relies on /dev/pts/\* to determine if vim is +running, so if vim is running in say /dev/pts/ in a container and there is a +tmux pane (not running vim) in /dev/pts/ on the host system, then without +the patch above vim-tmux-navigator will think vim is running when its not. + +### It Still Doesn't Work!!! + +The tmux configuration uses an inlined grep pattern match to help determine if +the current pane is running Vim. If you run into any issues with the navigation +not happening as expected, you can try using [Mislav's original external +script][] which has a more robust check. + +[Brian Hogan]: https://twitter.com/bphogan +[Mislav's original external script]: https://github.com/mislav/dotfiles/blob/master/bin/tmux-vim-select-pane +[Vundle]: https://github.com/gmarik/vundle +[TPM]: https://github.com/tmux-plugins/tpm +[configuration section below]: #custom-key-bindings +[this blog post]: http://www.codeography.com/2013/06/19/navigating-vim-and-tmux-splits +[this gist]: https://gist.github.com/mislav/5189704 diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/doc/tmux-navigator.txt b/dot_config/tmux/plugins/vim-tmux-navigator/doc/tmux-navigator.txt new file mode 100644 index 0000000..d4ae0ad --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/doc/tmux-navigator.txt @@ -0,0 +1,39 @@ +*tmux-navigator.txt* Plugin to allow seamless navigation between tmux and vim + +============================================================================== +CONTENTS *tmux-navigator-contents* + + +============================================================================== +INTRODUCTION *tmux-navigator* + +Vim-tmux-navigator is a little plugin which enables seamless navigation +between tmux panes and vim splits. This plugin is a repackaging of Mislav +Marohinc's tmux=navigator configuration. When combined with a set of tmux key +bindings, the plugin will allow you to navigate seamlessly between vim and +tmux splits using a consistent set of hotkeys. + +NOTE: This requires tmux v1.8 or higher. + +============================================================================== +CONFIGURATION *tmux-navigator-configuration* + +* Activate autoupdate on exit + let g:tmux_navigator_save_on_switch = 1 + +* Disable vim->tmux navigation when the Vim pane is zoomed in tmux + let g:tmux_navigator_disable_when_zoomed = 1 + +* If the Vim pane is zoomed, stay zoomed when moving to another tmux pane + let g:tmux_navigator_preserve_zoom = 1 + +* Custom Key Bindings + let g:tmux_navigator_no_mappings = 1 + + noremap {Left-mapping} :TmuxNavigateLeft + noremap {Down-Mapping} :TmuxNavigateDown + noremap {Up-Mapping} :TmuxNavigateUp + noremap {Right-Mapping} :TmuxNavigateRight + noremap {Previous-Mapping} :TmuxNavigatePrevious + + vim:tw=78:ts=8:ft=help:norl: diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/HEAD b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/HEAD new file mode 100644 index 0000000..cb089cd --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/config b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/config new file mode 100644 index 0000000..96d0c84 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/config @@ -0,0 +1,13 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[submodule] + active = . +[remote "origin"] + url = https://git::@github.com/christoomey/vim-tmux-navigator + fetch = +refs/heads/master:refs/remotes/origin/master +[branch "master"] + remote = origin + merge = refs/heads/master diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/description b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_applypatch-msg.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_commit-msg.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_fsmonitor-watchman.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_post-update.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-applypatch.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-commit.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-merge-commit.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-push.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-rebase.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-receive.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_prepare-commit-msg.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_push-to-checkout.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_update.sample b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/index b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/index new file mode 100644 index 0000000..28a8d0f Binary files /dev/null and b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/index differ diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/info/exclude b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/logs/HEAD b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/logs/HEAD new file mode 100644 index 0000000..d76a3cd --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 38b1d0402c4600543281dc85b3f51884205674b6 Wizzard 1705878652 -0500 clone: from https://github.com/christoomey/vim-tmux-navigator diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/logs/refs/heads/master b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/logs/refs/heads/master new file mode 100644 index 0000000..d76a3cd --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 38b1d0402c4600543281dc85b3f51884205674b6 Wizzard 1705878652 -0500 clone: from https://github.com/christoomey/vim-tmux-navigator diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/logs/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..d76a3cd --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 38b1d0402c4600543281dc85b3f51884205674b6 Wizzard 1705878652 -0500 clone: from https://github.com/christoomey/vim-tmux-navigator diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/objects/pack/readonly_pack-749cbadf260e94d6f7c5509699b0d48e2cd5b41f.idx b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/objects/pack/readonly_pack-749cbadf260e94d6f7c5509699b0d48e2cd5b41f.idx new file mode 100644 index 0000000..014a475 Binary files /dev/null and b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/objects/pack/readonly_pack-749cbadf260e94d6f7c5509699b0d48e2cd5b41f.idx differ diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/objects/pack/readonly_pack-749cbadf260e94d6f7c5509699b0d48e2cd5b41f.pack b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/objects/pack/readonly_pack-749cbadf260e94d6f7c5509699b0d48e2cd5b41f.pack new file mode 100644 index 0000000..7572669 Binary files /dev/null and b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/objects/pack/readonly_pack-749cbadf260e94d6f7c5509699b0d48e2cd5b41f.pack differ diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/objects/pack/readonly_pack-749cbadf260e94d6f7c5509699b0d48e2cd5b41f.rev b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/objects/pack/readonly_pack-749cbadf260e94d6f7c5509699b0d48e2cd5b41f.rev new file mode 100644 index 0000000..dc2a876 Binary files /dev/null and b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/objects/pack/readonly_pack-749cbadf260e94d6f7c5509699b0d48e2cd5b41f.rev differ diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/packed-refs b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/packed-refs new file mode 100644 index 0000000..932638a --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +38b1d0402c4600543281dc85b3f51884205674b6 refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/refs/heads/master b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/refs/heads/master new file mode 100644 index 0000000..1c43155 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/refs/heads/master @@ -0,0 +1 @@ +38b1d0402c4600543281dc85b3f51884205674b6 diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/refs/remotes/origin/HEAD new file mode 100644 index 0000000..6efe28f --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/refs/tags/v1.0 b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/refs/tags/v1.0 new file mode 100644 index 0000000..75bd634 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_git/refs/tags/v1.0 @@ -0,0 +1 @@ +22734100c02990ff090f3544319620ef3f516dea diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/dot_gitignore b/dot_config/tmux/plugins/vim-tmux-navigator/dot_gitignore new file mode 100644 index 0000000..926ccaa --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/dot_gitignore @@ -0,0 +1 @@ +doc/tags diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/executable_vim-tmux-navigator.tmux b/dot_config/tmux/plugins/vim-tmux-navigator/executable_vim-tmux-navigator.tmux new file mode 100644 index 0000000..e23d902 --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/executable_vim-tmux-navigator.tmux @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +version_pat='s/^tmux[^0-9]*([.0-9]+).*/\1/p' + +is_vim="ps -o state= -o comm= -t '#{pane_tty}' \ + | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'" +tmux bind-key -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L" +tmux bind-key -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D" +tmux bind-key -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U" +tmux bind-key -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R" +tmux_version="$(tmux -V | sed -En "$version_pat")" +tmux setenv -g tmux_version "$tmux_version" + +#echo "{'version' : '${tmux_version}', 'sed_pat' : '${version_pat}' }" > ~/.tmux_version.json + +tmux if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \ + "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\' 'select-pane -l'" +tmux if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \ + "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\' 'select-pane -l'" + +tmux bind-key -T copy-mode-vi C-h select-pane -L +tmux bind-key -T copy-mode-vi C-j select-pane -D +tmux bind-key -T copy-mode-vi C-k select-pane -U +tmux bind-key -T copy-mode-vi C-l select-pane -R +tmux bind-key -T copy-mode-vi C-\\ select-pane -l diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/pattern-check b/dot_config/tmux/plugins/vim-tmux-navigator/pattern-check new file mode 100644 index 0000000..bfcda8b --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/pattern-check @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# +# Collection of various test strings that could be the output of the tmux +# 'pane_current_comamnd' message. Included as regression test for updates to +# the inline grep pattern used in the `.tmux.conf` configuration + +set -e + +RED=$(tput setaf 1) +GREEN=$(tput setaf 2) +YELLOW=$(tput setaf 3) +NORMAL=$(tput sgr0) + +vim_pattern='(^|\/)g?(view|l?n?vim?x?|fzf)(diff)?$' +match_tests=(vim Vim VIM vimdiff lvim /usr/local/bin/vim vi gvim view gview nvim vimx fzf) +no_match_tests=( /Users/christoomey/.vim/thing /usr/local/bin/start-vim ) + +display_matches() { + for process_name in "$@"; do + printf "%s %s\n" "$(matches_vim_pattern $process_name)" "$process_name" + done +} + +matches_vim_pattern() { + if echo "$1" | grep -iqE "$vim_pattern"; then + echo "${GREEN}match${NORMAL}" + else + echo "${RED}fail${NORMAL}" + fi +} + +main() { + echo "Testing against pattern: ${YELLOW}$vim_pattern${NORMAL}\n" + + echo "These should all ${GREEN}match${NORMAL}\n----------------------" + display_matches "${match_tests[@]}" + + echo "\nThese should all ${RED}fail${NORMAL}\n---------------------" + display_matches "${no_match_tests[@]}" +} + +main diff --git a/dot_config/tmux/plugins/vim-tmux-navigator/plugin/tmux_navigator.vim b/dot_config/tmux/plugins/vim-tmux-navigator/plugin/tmux_navigator.vim new file mode 100644 index 0000000..81a593a --- /dev/null +++ b/dot_config/tmux/plugins/vim-tmux-navigator/plugin/tmux_navigator.vim @@ -0,0 +1,140 @@ +" Maps to switch vim splits in the given direction. If there are +" no more windows in that direction, forwards the operation to tmux. +" Additionally, toggles between last active vim splits/tmux panes. + +if exists("g:loaded_tmux_navigator") || &cp || v:version < 700 + finish +endif +let g:loaded_tmux_navigator = 1 + +function! s:VimNavigate(direction) + try + execute 'wincmd ' . a:direction + catch + echohl ErrorMsg | echo 'E11: Invalid in command-line window; executes, CTRL-C quits: wincmd k' | echohl None + endtry +endfunction + +if !get(g:, 'tmux_navigator_no_mappings', 0) + noremap :TmuxNavigateLeft + noremap :TmuxNavigateDown + noremap :TmuxNavigateUp + noremap :TmuxNavigateRight + noremap :TmuxNavigatePrevious +endif + +if empty($TMUX) + command! TmuxNavigateLeft call s:VimNavigate('h') + command! TmuxNavigateDown call s:VimNavigate('j') + command! TmuxNavigateUp call s:VimNavigate('k') + command! TmuxNavigateRight call s:VimNavigate('l') + command! TmuxNavigatePrevious call s:VimNavigate('p') + finish +endif + +command! TmuxNavigateLeft call s:TmuxAwareNavigate('h') +command! TmuxNavigateDown call s:TmuxAwareNavigate('j') +command! TmuxNavigateUp call s:TmuxAwareNavigate('k') +command! TmuxNavigateRight call s:TmuxAwareNavigate('l') +command! TmuxNavigatePrevious call s:TmuxAwareNavigate('p') + +if !exists("g:tmux_navigator_save_on_switch") + let g:tmux_navigator_save_on_switch = 0 +endif + +if !exists("g:tmux_navigator_disable_when_zoomed") + let g:tmux_navigator_disable_when_zoomed = 0 +endif + +if !exists("g:tmux_navigator_preserve_zoom") + let g:tmux_navigator_preserve_zoom = 0 +endif + +if !exists("g:tmux_navigator_no_wrap") + let g:tmux_navigator_no_wrap = 0 +endif + +let s:pane_position_from_direction = {'h': 'left', 'j': 'bottom', 'k': 'top', 'l': 'right'} + +function! s:TmuxOrTmateExecutable() + return (match($TMUX, 'tmate') != -1 ? 'tmate' : 'tmux') +endfunction + +function! s:TmuxVimPaneIsZoomed() + return s:TmuxCommand("display-message -p '#{window_zoomed_flag}'") == 1 +endfunction + +function! s:TmuxSocket() + " The socket path is the first value in the comma-separated list of $TMUX. + return split($TMUX, ',')[0] +endfunction + +function! s:TmuxCommand(args) + let cmd = s:TmuxOrTmateExecutable() . ' -S ' . s:TmuxSocket() . ' ' . a:args + let l:x=&shellcmdflag + let &shellcmdflag='-c' + let retval=system(cmd) + let &shellcmdflag=l:x + return retval +endfunction + +function! s:TmuxNavigatorProcessList() + echo s:TmuxCommand("run-shell 'ps -o state= -o comm= -t ''''#{pane_tty}'''''") +endfunction +command! TmuxNavigatorProcessList call s:TmuxNavigatorProcessList() + +let s:tmux_is_last_pane = 0 +augroup tmux_navigator + au! + autocmd WinEnter * let s:tmux_is_last_pane = 0 +augroup END + +function! s:NeedsVitalityRedraw() + return exists('g:loaded_vitality') && v:version < 704 && !has("patch481") +endfunction + +function! s:ShouldForwardNavigationBackToTmux(tmux_last_pane, at_tab_page_edge) + if g:tmux_navigator_disable_when_zoomed && s:TmuxVimPaneIsZoomed() + return 0 + endif + return a:tmux_last_pane || a:at_tab_page_edge +endfunction + +function! s:TmuxAwareNavigate(direction) + let nr = winnr() + let tmux_last_pane = (a:direction == 'p' && s:tmux_is_last_pane) + if !tmux_last_pane + call s:VimNavigate(a:direction) + endif + let at_tab_page_edge = (nr == winnr()) + " Forward the switch panes command to tmux if: + " a) we're toggling between the last tmux pane; + " b) we tried switching windows in vim but it didn't have effect. + if s:ShouldForwardNavigationBackToTmux(tmux_last_pane, at_tab_page_edge) + if g:tmux_navigator_save_on_switch == 1 + try + update " save the active buffer. See :help update + catch /^Vim\%((\a\+)\)\=:E32/ " catches the no file name error + endtry + elseif g:tmux_navigator_save_on_switch == 2 + try + wall " save all the buffers. See :help wall + catch /^Vim\%((\a\+)\)\=:E141/ " catches the no file name error + endtry + endif + let args = 'select-pane -t ' . shellescape($TMUX_PANE) . ' -' . tr(a:direction, 'phjkl', 'lLDUR') + if g:tmux_navigator_preserve_zoom == 1 + let l:args .= ' -Z' + endif + if g:tmux_navigator_no_wrap == 1 + let args = 'if -F "#{pane_at_' . s:pane_position_from_direction[a:direction] . '}" "" "' . args . '"' + endif + silent call s:TmuxCommand(args) + if s:NeedsVitalityRedraw() + redraw! + endif + let s:tmux_is_last_pane = 1 + else + let s:tmux_is_last_pane = 0 + endif +endfunction diff --git a/dot_config/tmux/tmux.conf b/dot_config/tmux/tmux.conf new file mode 100644 index 0000000..1af9e6a --- /dev/null +++ b/dot_config/tmux/tmux.conf @@ -0,0 +1,62 @@ +#set-option -sa terminal-overrides ",xterm*:Tc" + +set -g default-terminal "screen-256color" +set -ag terminal-overrides ",screen-256color:RGB" + +set -g status-bg '#191828' # Dark background color for the status bar +set -g status-fg '#82B7E2' # The text color extracted from your image + +set -g mouse on + +#unbind C-b +#set -g prefix C-Space +#bind C-Space send-prefix + +# Vim style pane selection +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R + +# Start windows and panes at 1, not 0 +set -g base-index 1 +set -g pane-base-index 1 +set-window-option -g pane-base-index 1 +set-option -g renumber-windows on + +# Use Alt-arrow keys without prefix key to switch panes +bind -n M-Left select-pane -L +bind -n M-Right select-pane -R +bind -n M-Up select-pane -U +bind -n M-Down select-pane -D + +# Shift arrow to switch windows +bind -n S-Left previous-window +bind -n S-Right next-window + +# Shift Alt vim keys to switch windows +bind -n M-H previous-window +bind -n M-L next-window + +set -g @catppuccin_flavour 'mocha' + +set -g @plugin 'tmux-plugins/tpm' +set -g @plugin 'tmux-plugins/tmux-sensible' +set -g @plugin 'christoomey/vim-tmux-navigator' +set -g @plugin 'dreamsofcode-io/catppuccin-tmux' +set -g @plugin 'tmux-plugins/tmux-yank' + + + +run '~/.tmux/plugins/tpm/tpm' + +# set vi-mode +set-window-option -g mode-keys vi +# keybindings +bind-key -T copy-mode-vi v send-keys -X begin-selection +bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle +bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard" +# bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel + +bind '"' split-window -v -c "#{pane_current_path}" +bind % split-window -h -c "#{pane_current_path}"