commit ce33ac2b119ec3a8ef13471a5a295d9ec575a920
parent 5c4878d4d5cd40d20f8a7d2be4da452ad5bb1be8
Author: Lukas Henkel <lh@entf.net>
Date: Fri, 17 Nov 2023 22:24:48 +0100
Add diff-hl
Diffstat:
18 files changed, 3808 insertions(+), 1 deletion(-)
diff --git a/elpa/diff-hl-1.9.2.signed b/elpa/diff-hl-1.9.2.signed
@@ -0,0 +1,2 @@
+Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2023-02-19T11:05:02+0100 using RSA
+Good signature from 645357D2883A0966 GNU ELPA Signing Agent (2023) <elpasign@elpa.gnu.org> (trust undefined) created at 2023-02-19T11:05:02+0100 using EDDSA
+\ No newline at end of file
diff --git a/elpa/diff-hl-1.9.2/.dir-locals.el b/elpa/diff-hl-1.9.2/.dir-locals.el
@@ -0,0 +1,5 @@
+((nil . ((indent-tabs-mode . nil)
+ (fill-column . 80)
+ (sentence-end-double-space . t)
+ (emacs-lisp-docstring-fill-column . 75)))
+ (makefile-mode . ((indent-tabs-mode . t))))
diff --git a/elpa/diff-hl-1.9.2/.elpaignore b/elpa/diff-hl-1.9.2/.elpaignore
@@ -0,0 +1,2 @@
+README.md
+screenshot*
diff --git a/elpa/diff-hl-1.9.2/LICENSE b/elpa/diff-hl-1.9.2/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/elpa/diff-hl-1.9.2/Makefile b/elpa/diff-hl-1.9.2/Makefile
@@ -0,0 +1,26 @@
+EMACS ?= emacs
+SOURCES=diff-hl.el
+SOURCES+=diff-hl-amend.el
+SOURCES+=diff-hl-dired.el
+SOURCES+=diff-hl-flydiff.el
+SOURCES+=diff-hl-inline-popup.el
+SOURCES+=diff-hl-margin.el
+SOURCES+=diff-hl-show-hunk-posframe.el
+SOURCES+=diff-hl-show-hunk.el
+
+ARTIFACTS=$(patsubst %.el, %.elc, $(SOURCES))
+
+RM ?= rm -f
+
+all: compile test
+
+test:
+ $(EMACS) -batch -L . -l test/diff-hl-test.el -f diff-hl-run-tests
+
+compile:
+ $(EMACS) -batch -L . -f batch-byte-compile $(SOURCES)
+
+clean:
+ $(RM) $(ARTIFACTS)
+
+.PHONY: all test compile plain clean
diff --git a/elpa/diff-hl-1.9.2/diff-hl-amend.el b/elpa/diff-hl-1.9.2/diff-hl-amend.el
@@ -0,0 +1,69 @@
+;; Copyright (C) 2012-2013, 2020 Free Software Foundation, Inc. -*- lexical-binding: t -*-
+
+;; Author: Dmitry Gutov <dgutov@yandex.ru>
+;; URL: https://github.com/dgutov/diff-hl
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Toggle in the current buffer with `M-x diff-hl-amend-mode'.
+;; Toggle in all buffers with `M-x global-diff-hl-amend-mode'.
+
+;;; Code:
+
+(require 'diff-hl)
+
+;;;###autoload
+(define-minor-mode diff-hl-amend-mode
+ "Show changes against the second-last revision in `diff-hl-mode'.
+Most useful with backends that support rewriting local commits,
+and most importantly, \"amending\" the most recent one.
+Currently only supports Git, Mercurial and Bazaar."
+ :lighter " Amend"
+ (if diff-hl-amend-mode
+ (progn
+ (diff-hl-amend-setup)
+ (add-hook 'after-revert-hook 'diff-hl-amend-setup nil t))
+ (remove-hook 'after-revert-hook 'diff-hl-amend-setup t)
+ (kill-local-variable 'diff-hl-reference-revision))
+ (when diff-hl-mode
+ (diff-hl-update)))
+
+(defun diff-hl-amend-setup ()
+ (let ((backend (vc-backend buffer-file-name)))
+ (when backend
+ (setq-local diff-hl-reference-revision
+ (cl-case backend
+ (Git
+ "HEAD^")
+ (Hg
+ "-2")
+ (Bzr
+ "revno:-2"))))))
+
+;;;###autoload
+(define-globalized-minor-mode global-diff-hl-amend-mode diff-hl-amend-mode
+ turn-on-diff-hl-amend-mode
+ :group 'diff-hl)
+
+(defun turn-on-diff-hl-amend-mode ()
+ "Turn on `diff-hl-amend-mode' in a buffer if appropriate."
+ (and buffer-file-name (diff-hl-amend-mode 1)))
+
+(provide 'diff-hl-amend)
+
+;;; diff-hl-amend.el ends here
diff --git a/elpa/diff-hl-1.9.2/diff-hl-autoloads.el b/elpa/diff-hl-1.9.2/diff-hl-autoloads.el
@@ -0,0 +1,348 @@
+;;; diff-hl-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
+
+
+
+;;; Generated autoloads from diff-hl.el
+
+(autoload 'diff-hl-mode "diff-hl" "\
+Toggle VC diff highlighting.
+
+This is a minor mode. If called interactively, toggle the
+`Diff-Hl mode' mode. If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `diff-hl-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+(fn &optional ARG)" t)
+(autoload 'turn-on-diff-hl-mode "diff-hl" "\
+Turn on `diff-hl-mode' or `diff-hl-dir-mode' in a buffer if appropriate.")
+(autoload 'diff-hl--global-turn-on "diff-hl" "\
+Call `turn-on-diff-hl-mode' if the current major mode is applicable.")
+(autoload 'diff-hl-set-reference-rev "diff-hl" "\
+Set the reference revision globally to REV.
+When called interactively, REV read with completion.
+
+The default value chosen using one of methods below:
+
+- In a log view buffer, it uses the revision of current entry.
+Call `vc-print-log' or `vc-print-root-log' first to open a log
+view buffer.
+- In a VC annotate buffer, it uses the revision of current line.
+- In other situations, it uses the symbol at point.
+
+Notice that this sets the reference revision globally, so in
+files from other repositories, `diff-hl-mode' will not highlight
+changes correctly, until you run `diff-hl-reset-reference-rev'.
+
+Also notice that this will disable `diff-hl-amend-mode' in
+buffers that enables it, since `diff-hl-amend-mode' overrides its
+effect.
+
+(fn REV)" t)
+(autoload 'diff-hl-reset-reference-rev "diff-hl" "\
+Reset the reference revision globally to the most recent one." t)
+(put 'global-diff-hl-mode 'globalized-minor-mode t)
+(defvar global-diff-hl-mode nil "\
+Non-nil if Global Diff-Hl mode is enabled.
+See the `global-diff-hl-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-diff-hl-mode'.")
+(custom-autoload 'global-diff-hl-mode "diff-hl" nil)
+(autoload 'global-diff-hl-mode "diff-hl" "\
+Toggle Diff-Hl mode in all buffers.
+With prefix ARG, enable Global Diff-Hl mode if ARG is positive;
+otherwise, disable it.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.
+Enable the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+Diff-Hl mode is enabled in all buffers where `diff-hl--global-turn-on'
+would do it.
+
+See `diff-hl-mode' for more information on Diff-Hl mode.
+
+(fn &optional ARG)" t)
+(register-definition-prefixes "diff-hl" '("diff-hl-"))
+
+
+;;; Generated autoloads from diff-hl-amend.el
+
+(autoload 'diff-hl-amend-mode "diff-hl-amend" "\
+Show changes against the second-last revision in `diff-hl-mode'.
+
+Most useful with backends that support rewriting local commits,
+and most importantly, \"amending\" the most recent one.
+Currently only supports Git, Mercurial and Bazaar.
+
+This is a minor mode. If called interactively, toggle the
+`Diff-Hl-Amend mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `diff-hl-amend-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+(fn &optional ARG)" t)
+(put 'global-diff-hl-amend-mode 'globalized-minor-mode t)
+(defvar global-diff-hl-amend-mode nil "\
+Non-nil if Global Diff-Hl-Amend mode is enabled.
+See the `global-diff-hl-amend-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-diff-hl-amend-mode'.")
+(custom-autoload 'global-diff-hl-amend-mode "diff-hl-amend" nil)
+(autoload 'global-diff-hl-amend-mode "diff-hl-amend" "\
+Toggle Diff-Hl-Amend mode in all buffers.
+With prefix ARG, enable Global Diff-Hl-Amend mode if ARG is positive;
+otherwise, disable it.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.
+Enable the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+Diff-Hl-Amend mode is enabled in all buffers where
+`turn-on-diff-hl-amend-mode' would do it.
+
+See `diff-hl-amend-mode' for more information on Diff-Hl-Amend mode.
+
+(fn &optional ARG)" t)
+(register-definition-prefixes "diff-hl-amend" '("diff-hl-amend-setup" "turn-on-diff-hl-amend-mode"))
+
+
+;;; Generated autoloads from diff-hl-dired.el
+
+(autoload 'diff-hl-dired-mode "diff-hl-dired" "\
+Toggle VC diff highlighting on the side of a Dired window.
+
+This is a minor mode. If called interactively, toggle the
+`Diff-Hl-Dired mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `diff-hl-dired-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+(fn &optional ARG)" t)
+(autoload 'diff-hl-dired-mode-unless-remote "diff-hl-dired")
+(register-definition-prefixes "diff-hl-dired" '("diff-hl-dired-"))
+
+
+;;; Generated autoloads from diff-hl-flydiff.el
+
+(defvar diff-hl-flydiff-mode nil "\
+Non-nil if Diff-Hl-Flydiff mode is enabled.
+See the `diff-hl-flydiff-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `diff-hl-flydiff-mode'.")
+(custom-autoload 'diff-hl-flydiff-mode "diff-hl-flydiff" nil)
+(autoload 'diff-hl-flydiff-mode "diff-hl-flydiff" "\
+Perform highlighting on-the-fly.
+
+This is a global minor mode. It alters how `diff-hl-mode' works.
+
+This is a global minor mode. If called interactively, toggle the
+`Diff-Hl-Flydiff mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='diff-hl-flydiff-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+(fn &optional ARG)" t)
+(register-definition-prefixes "diff-hl-flydiff" '("diff-hl-flydiff"))
+
+
+;;; Generated autoloads from diff-hl-inline-popup.el
+
+(autoload 'diff-hl-inline-popup-hide "diff-hl-inline-popup" "\
+Hide the current inline popup." t)
+(autoload 'diff-hl-inline-popup-show "diff-hl-inline-popup" "\
+Create a phantom overlay to show the inline popup, with some
+content LINES, and a HEADER and a FOOTER, at POINT. KEYMAP is
+added to the current keymaps. CLOSE-HOOK is called when the popup
+is closed.
+
+(fn LINES &optional HEADER FOOTER KEYMAP CLOSE-HOOK POINT HEIGHT)")
+(register-definition-prefixes "diff-hl-inline-popup" '("diff-hl-inline-popup-"))
+
+
+;;; Generated autoloads from diff-hl-margin.el
+
+(defvar diff-hl-margin-mode nil "\
+Non-nil if Diff-Hl-Margin mode is enabled.
+See the `diff-hl-margin-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `diff-hl-margin-mode'.")
+(custom-autoload 'diff-hl-margin-mode "diff-hl-margin" nil)
+(autoload 'diff-hl-margin-mode "diff-hl-margin" "\
+Toggle displaying `diff-hl-mode' highlights on the margin.
+
+This is a global minor mode. If called interactively, toggle the
+`Diff-Hl-Margin mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='diff-hl-margin-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+(fn &optional ARG)" t)
+(autoload 'diff-hl-margin-local-mode "diff-hl-margin" "\
+Toggle displaying `diff-hl-mode' highlights on the margin locally.
+
+You probably shouldn't use this function directly.
+
+This is a minor mode. If called interactively, toggle the
+`Diff-Hl-Margin-Local mode' mode. If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable
+the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `diff-hl-margin-local-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+(fn &optional ARG)" t)
+(register-definition-prefixes "diff-hl-margin" '("diff-hl-"))
+
+
+;;; Generated autoloads from diff-hl-show-hunk.el
+
+(autoload 'diff-hl-show-hunk-inline-popup "diff-hl-show-hunk" "\
+Implementation to show the hunk in a inline popup.
+BUFFER is a buffer with the hunk.
+
+(fn BUFFER &optional IGNORED-LINE)")
+(autoload 'diff-hl-show-hunk-previous "diff-hl-show-hunk" "\
+Go to previous hunk/change and show it." t)
+(autoload 'diff-hl-show-hunk-next "diff-hl-show-hunk" "\
+Go to next hunk/change and show it." t)
+(autoload 'diff-hl-show-hunk "diff-hl-show-hunk" "\
+Show the VC diff hunk at point.
+The backend is determined by `diff-hl-show-hunk-function'." t)
+(autoload 'diff-hl-show-hunk-mouse-mode "diff-hl-show-hunk" "\
+Enables the margin and fringe to show a posframe/popup with vc diffs when clicked.
+
+By default, the popup shows only the current hunk, and
+the line of the hunk that matches the current position is
+highlighted. The face, border and other visual preferences are
+customizable. It can be also invoked with the command
+`diff-hl-show-hunk'
+\\{diff-hl-show-hunk-mouse-mode-map}
+
+This is a minor mode. If called interactively, toggle the
+`Diff-Hl-Show-Hunk-Mouse mode' mode. If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable
+the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `diff-hl-show-hunk-mouse-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+(fn &optional ARG)" t)
+(put 'global-diff-hl-show-hunk-mouse-mode 'globalized-minor-mode t)
+(defvar global-diff-hl-show-hunk-mouse-mode nil "\
+Non-nil if Global Diff-Hl-Show-Hunk-Mouse mode is enabled.
+See the `global-diff-hl-show-hunk-mouse-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-diff-hl-show-hunk-mouse-mode'.")
+(custom-autoload 'global-diff-hl-show-hunk-mouse-mode "diff-hl-show-hunk" nil)
+(autoload 'global-diff-hl-show-hunk-mouse-mode "diff-hl-show-hunk" "\
+Toggle Diff-Hl-Show-Hunk-Mouse mode in all buffers.
+With prefix ARG, enable Global Diff-Hl-Show-Hunk-Mouse mode if ARG is
+positive; otherwise, disable it.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.
+Enable the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+Diff-Hl-Show-Hunk-Mouse mode is enabled in all buffers where
+`diff-hl-show-hunk-mouse-mode' would do it.
+
+See `diff-hl-show-hunk-mouse-mode' for more information on
+Diff-Hl-Show-Hunk-Mouse mode.
+
+(fn &optional ARG)" t)
+(register-definition-prefixes "diff-hl-show-hunk" '("diff-hl-show-hunk-"))
+
+
+;;; Generated autoloads from diff-hl-show-hunk-posframe.el
+
+(autoload 'diff-hl-show-hunk-posframe "diff-hl-show-hunk-posframe" "\
+Implementation to show the hunk in a posframe.
+
+(fn BUFFER &optional LINE)")
+(register-definition-prefixes "diff-hl-show-hunk-posframe" '("diff-hl-show-hunk-"))
+
+;;; End of scraped data
+
+(provide 'diff-hl-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; no-native-compile: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; diff-hl-autoloads.el ends here
diff --git a/elpa/diff-hl-1.9.2/diff-hl-dired.el b/elpa/diff-hl-1.9.2/diff-hl-dired.el
@@ -0,0 +1,185 @@
+;;; diff-hl-dired.el --- Highlight changed files in Dired -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2017, 2023 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; To enable in all Dired buffers, add this to your init file:
+;;
+;; (add-hook 'dired-mode-hook 'diff-hl-dired-mode)
+;;
+;; or
+;;
+;; (add-hook 'dired-mode-hook 'diff-hl-dired-mode-unless-remote)
+;;
+;; to do it only in local Dired buffers.
+
+;;; Code:
+
+(require 'diff-hl)
+(require 'dired)
+(require 'vc-hooks)
+
+(defvar diff-hl-dired-process-buffer nil)
+
+(defgroup diff-hl-dired nil
+ "VC diff highlighting on the side of a Dired window."
+ :group 'diff-hl)
+
+(defface diff-hl-dired-insert
+ '((default :inherit diff-hl-insert))
+ "Face used to highlight added files.")
+
+(defface diff-hl-dired-delete
+ '((default :inherit diff-hl-delete))
+ "Face used to highlight directories with deleted files.")
+
+(defface diff-hl-dired-change
+ '((default :inherit diff-hl-change))
+ "Face used to highlight changed files.")
+
+(defface diff-hl-dired-unknown
+ '((default :inherit dired-ignored))
+ "Face used to highlight unregistered files.")
+
+(defface diff-hl-dired-ignored
+ '((default :inherit dired-ignored))
+ "Face used to highlight unregistered files.")
+
+(defcustom diff-hl-dired-extra-indicators t
+ "Non-nil to indicate ignored files."
+ :type 'boolean)
+
+(defcustom diff-hl-dired-ignored-backends '(RCS)
+ "VC backends to ignore.
+The directories registered to one of these backends won't have
+status indicators."
+ :type `(repeat (choice ,@(mapcar
+ (lambda (name)
+ `(const :tag ,(symbol-name name) ,name))
+ vc-handled-backends))))
+
+;;;###autoload
+(define-minor-mode diff-hl-dired-mode
+ "Toggle VC diff highlighting on the side of a Dired window."
+ :lighter ""
+ (if diff-hl-dired-mode
+ (progn
+ (diff-hl-maybe-define-bitmaps)
+ (set (make-local-variable 'diff-hl-dired-process-buffer) nil)
+ (add-hook 'dired-after-readin-hook 'diff-hl-dired-update nil t))
+ (remove-hook 'dired-after-readin-hook 'diff-hl-dired-update t)
+ (diff-hl-dired-clear)))
+
+(defun diff-hl-dired-update ()
+ "Highlight the Dired buffer."
+ (let ((backend (ignore-errors (vc-responsible-backend default-directory)))
+ (def-dir default-directory)
+ (buffer (current-buffer))
+ dirs-alist files-alist)
+ (when (and backend (not (memq backend diff-hl-dired-ignored-backends)))
+ (diff-hl-dired-clear)
+ (if (buffer-live-p diff-hl-dired-process-buffer)
+ (let ((proc (get-buffer-process diff-hl-dired-process-buffer)))
+ (when proc (kill-process proc)))
+ (setq diff-hl-dired-process-buffer
+ (generate-new-buffer " *diff-hl-dired* tmp status")))
+ (with-current-buffer diff-hl-dired-process-buffer
+ (setq default-directory (expand-file-name def-dir))
+ (erase-buffer)
+ (diff-hl-dired-status-files
+ backend def-dir
+ (when diff-hl-dired-extra-indicators
+ (cl-loop for file in (directory-files def-dir)
+ unless (member file '("." ".." ".hg"))
+ collect file))
+ (lambda (entries &optional more-to-come)
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (dolist (entry entries)
+ (cl-destructuring-bind (file state &rest r) entry
+ ;; Work around http://debbugs.gnu.org/18605
+ (setq file (replace-regexp-in-string "\\` " "" file))
+ (let ((type (plist-get
+ '( edited change added insert removed delete
+ unregistered unknown ignored ignored)
+ state)))
+ (if (string-match "\\`\\([^/]+\\)/" file)
+ (let* ((dir (match-string 1 file))
+ (value (cdr (assoc dir dirs-alist))))
+ (unless (eq value type)
+ (cond
+ ((eq state 'up-to-date))
+ ((null value)
+ (push (cons dir type) dirs-alist))
+ ((not (eq type 'ignored))
+ (setcdr (assoc dir dirs-alist) 'change)))))
+ (push (cons file type) files-alist)))))
+ (unless more-to-come
+ (diff-hl-dired-highlight-items
+ (append dirs-alist files-alist))))
+ (unless more-to-come
+ (kill-buffer diff-hl-dired-process-buffer))))
+ )))))
+
+(defun diff-hl-dired-status-files (backend dir files update-function)
+ "Using version control BACKEND, return list of (FILE STATE EXTRA) entries
+for DIR containing FILES. Call UPDATE-FUNCTION as entries are added."
+ (if (version< "25" emacs-version)
+ (vc-call-backend backend 'dir-status-files dir files update-function)
+ (vc-call-backend backend 'dir-status-files dir files nil update-function)))
+
+(when (version< emacs-version "24.4.51.5")
+ ;; Work around http://debbugs.gnu.org/19386
+ (defadvice vc-git-dir-status-goto-stage (around
+ diff-hl-dired-skip-up-to-date
+ (stage files update-function)
+ activate)
+ (when (eq stage 'ls-files-up-to-date)
+ (setq stage 'diff-index))
+ ad-do-it))
+
+(defun diff-hl-dired-highlight-items (alist)
+ "Highlight ALIST containing (FILE . TYPE) elements."
+ (dolist (pair alist)
+ (let ((file (car pair))
+ (type (cdr pair)))
+ (save-excursion
+ (goto-char (point-min))
+ (when (and type (dired-goto-file-1
+ file (expand-file-name file) nil))
+ (let* ((diff-hl-fringe-bmp-function 'diff-hl-fringe-bmp-from-type)
+ (diff-hl-fringe-face-function 'diff-hl-dired-face-from-type)
+ (o (diff-hl-add-highlighting type 'single)))
+ (overlay-put o 'modification-hooks '(diff-hl-overlay-modified))
+ (overlay-put o 'diff-hl-dired-type type)
+ ))))))
+
+(defun diff-hl-dired-face-from-type (type _pos)
+ (intern (format "diff-hl-dired-%s" type)))
+
+(defalias 'diff-hl-dired-clear 'diff-hl-remove-overlays)
+
+;;;###autoload
+(defun diff-hl-dired-mode-unless-remote ()
+ (unless (file-remote-p default-directory)
+ (diff-hl-dired-mode)))
+
+(provide 'diff-hl-dired)
+
+;;; diff-hl-dired.el ends here
diff --git a/elpa/diff-hl-1.9.2/diff-hl-flydiff.el b/elpa/diff-hl-1.9.2/diff-hl-flydiff.el
@@ -0,0 +1,83 @@
+;; Copyright (C) 2015-2021 Free Software Foundation, Inc. -*- lexical-binding: t -*-
+
+;; Author: Jonathan Hayase <PythonNut@gmail.com>
+;; URL: https://github.com/dgutov/diff-hl
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This mode enables diffing on-the-fly (i.e. without saving the buffer first)
+;; Toggle in all buffers with M-x diff-hl-flydiff-mode
+
+;;; Code:
+
+(require 'diff-hl)
+(require 'diff)
+
+(defgroup diff-hl-flydiff nil
+ "Highlight changes on the fly"
+ :group 'diff-hl)
+
+(defcustom diff-hl-flydiff-delay 0.3
+ "The idle delay in seconds before highlighting is updated."
+ :type 'number)
+
+(defvar diff-hl-flydiff-modified-tick nil)
+(defvar diff-hl-flydiff-timer nil)
+(make-variable-buffer-local 'diff-hl-flydiff-modified-tick)
+
+(defun diff-hl-flydiff-changes-buffer (file &optional backend)
+ (setq diff-hl-flydiff-modified-tick (buffer-chars-modified-tick))
+ (diff-hl-diff-buffer-with-reference file " *diff-hl-diff*" backend))
+
+(defun diff-hl-flydiff-update ()
+ (unless (or
+ (not diff-hl-mode)
+ (eq diff-hl-flydiff-modified-tick (buffer-chars-modified-tick))
+ (not buffer-file-name)
+ (file-remote-p default-directory)
+ (not (file-exists-p buffer-file-name)))
+ (diff-hl-update)))
+
+(defun diff-hl-flydiff/modified-p (_state)
+ (buffer-modified-p))
+
+;;;###autoload
+(define-minor-mode diff-hl-flydiff-mode
+ "Perform highlighting on-the-fly.
+This is a global minor mode. It alters how `diff-hl-mode' works."
+ :lighter "" :global t
+ (if diff-hl-flydiff-mode
+ (progn
+ (advice-add 'diff-hl-overlay-modified :override #'ignore)
+
+ (advice-add 'diff-hl-modified-p :before-until
+ #'diff-hl-flydiff/modified-p)
+ (advice-add 'diff-hl-changes-buffer :override
+ #'diff-hl-flydiff-changes-buffer)
+ (setq diff-hl-flydiff-timer
+ (run-with-idle-timer diff-hl-flydiff-delay t #'diff-hl-flydiff-update)))
+
+ (advice-remove 'diff-hl-overlay-modified #'ignore)
+
+ (advice-remove 'diff-hl-modified-p #'diff-hl-flydiff/modified-p)
+ (advice-remove 'diff-hl-changes-buffer #'diff-hl-flydiff-changes-buffer)
+
+ (and diff-hl-flydiff-timer
+ (cancel-timer diff-hl-flydiff-timer))))
+
+(provide 'diff-hl-flydiff)
diff --git a/elpa/diff-hl-1.9.2/diff-hl-inline-popup.el b/elpa/diff-hl-1.9.2/diff-hl-inline-popup.el
@@ -0,0 +1,284 @@
+;;; diff-hl-inline-popup.el --- inline popup using phantom overlays -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+;; Author: Álvaro González <alvarogonzalezsotillo@gmail.com>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Shows inline popups using phantom overlays. The lines of the popup
+;; can be scrolled.
+;;; Code:
+
+(require 'subr-x)
+
+(defvar diff-hl-inline-popup--current-popup nil "The overlay of the current inline popup.")
+(defvar diff-hl-inline-popup--current-lines nil "A list of the lines to show in the popup.")
+(defvar diff-hl-inline-popup--current-index nil "First line showed in popup.")
+(defvar diff-hl-inline-popup--invokinkg-command nil "Command that invoked the popup.")
+(defvar diff-hl-inline-popup--current-footer nil "String to be displayed in the footer.")
+(defvar diff-hl-inline-popup--current-header nil "String to be displayed in the header.")
+(defvar diff-hl-inline-popup--height nil "Height of the popup.")
+(defvar diff-hl-inline-popup--current-custom-keymap nil "Keymap to be added to the keymap of the inline popup.")
+(defvar diff-hl-inline-popup--close-hook nil "Function to be called when the popup closes.")
+
+(make-variable-buffer-local 'diff-hl-inline-popup--current-popup)
+(make-variable-buffer-local 'diff-hl-inline-popup--current-lines)
+(make-variable-buffer-local 'diff-hl-inline-popup--current-index)
+(make-variable-buffer-local 'diff-hl-inline-popup--current-header)
+(make-variable-buffer-local 'diff-hl-inline-popup--current-footer)
+(make-variable-buffer-local 'diff-hl-inline-popup--invokinkg-command)
+(make-variable-buffer-local 'diff-hl-inline-popup--current-custom-keymap)
+(make-variable-buffer-local 'diff-hl-inline-popup--height)
+(make-variable-buffer-local 'diff-hl-inline-popup--close-hook)
+
+(defun diff-hl-inline-popup--splice (list offset length)
+ "Compute a sublist of LIST starting at OFFSET, of LENGTH."
+ (butlast
+ (nthcdr offset list)
+ (- (length list) length offset)))
+
+(defun diff-hl-inline-popup--ensure-enough-lines (pos content-height)
+ "Ensure there is enough lines below POS to show the inline popup with CONTENT-HEIGHT height."
+ (let* ((line (line-number-at-pos pos))
+ (end (line-number-at-pos (window-end nil t)))
+ (height (+ 6 content-height))
+ (overflow (- (+ line height) end)))
+ (when (< 0 overflow)
+ (run-with-timer 0.1 nil #'scroll-up overflow))))
+
+(defun diff-hl-inline-popup--compute-content-height (&optional content-size)
+ "Compute the height of the inline popup.
+Default for CONTENT-SIZE is the size of the current lines"
+ (let ((content-size (or content-size (length diff-hl-inline-popup--current-lines)))
+ (max-size (- (/(window-height) 2) 3)))
+ (min content-size max-size)))
+
+(defun diff-hl-inline-popup--compute-content-lines (lines index window-size)
+ "Compute the lines to show in the popup, from LINES starting at INDEX with a WINDOW-SIZE."
+ (let* ((len (length lines))
+ (window-size (min window-size len))
+ (index (min index (- len window-size))))
+ (diff-hl-inline-popup--splice lines index window-size)))
+
+(defun diff-hl-inline-popup--compute-header (width &optional header)
+ "Compute the header of the popup, with some WIDTH, and some optional HEADER text."
+ (let* ((scroll-indicator (if (eq diff-hl-inline-popup--current-index 0) " " " ⬆ "))
+ (header (or header ""))
+ (new-width (- width (length header) (length scroll-indicator)))
+ (header (if (< new-width 0) "" header))
+ (new-width (- width (length header) (length scroll-indicator)))
+ (line (propertize (concat (diff-hl-inline-popup--separator new-width)
+ header scroll-indicator )
+ 'face '(:underline t))))
+ (concat line "\n") ))
+
+(defun diff-hl-inline-popup--compute-footer (width &optional footer)
+ "Compute the header of the popup, with some WIDTH, and some optional FOOTER text."
+ (let* ((scroll-indicator (if (>= diff-hl-inline-popup--current-index
+ (- (length diff-hl-inline-popup--current-lines)
+ diff-hl-inline-popup--height))
+ " "
+ " ⬇ "))
+ (footer (or footer ""))
+ (new-width (- width (length footer) (length scroll-indicator)))
+ (footer (if (< new-width 0) "" footer))
+ (new-width (- width (length footer) (length scroll-indicator)))
+ (blank-line (if (display-graphic-p)
+ ""
+ (concat "\n" (propertize (diff-hl-inline-popup--separator width)
+ 'face '(:underline t)))))
+ (line (propertize (concat (diff-hl-inline-popup--separator new-width)
+ footer scroll-indicator)
+ 'face '(:overline t))))
+ (concat blank-line "\n" line)))
+
+(defun diff-hl-inline-popup--separator (width &optional sep)
+ "Return the horizontal separator with character SEP and a WIDTH."
+ (let ((sep (or sep ?\s)))
+ (make-string width sep)))
+
+(defun diff-hl-inline-popup--available-width ()
+ "Compute the available width in chars."
+ (let ((magic-adjust 3))
+ (if (not (display-graphic-p))
+ (let* ((linumber-width (line-number-display-width nil))
+ (width (- (window-body-width) linumber-width magic-adjust)))
+ width)
+ (let* ((font-width (window-font-width))
+ (window-width (window-body-width nil t))
+ (linenumber-width (line-number-display-width t))
+ (available-pixels (- window-width linenumber-width))
+ (width (- (/ available-pixels font-width) magic-adjust)))
+
+ ;; https://emacs.stackexchange.com/questions/5495/how-can-i-determine-the-width-of-characters-on-the-screen
+ width))))
+
+(defun diff-hl-inline-popup--compute-popup-str (lines index window-size header footer)
+ "Compute the string that represents the popup.
+There are some content LINES starting at INDEX, with a WINDOW-SIZE. HEADER and
+FOOTER are showed at start and end."
+ (let* ((width (diff-hl-inline-popup--available-width))
+ (content-lines (diff-hl-inline-popup--compute-content-lines lines index window-size))
+ (header (diff-hl-inline-popup--compute-header width header))
+ (footer (diff-hl-inline-popup--compute-footer width footer)))
+ (concat header (string-join content-lines "\n") footer "\n")))
+
+(defun diff-hl-inline-popup-scroll-to (index)
+ "Scroll the inline popup to make visible the line at position INDEX."
+ (when diff-hl-inline-popup--current-popup
+ (setq diff-hl-inline-popup--current-index (max 0 (min index (- (length diff-hl-inline-popup--current-lines) diff-hl-inline-popup--height))))
+ (let* ((str (diff-hl-inline-popup--compute-popup-str
+ diff-hl-inline-popup--current-lines
+ diff-hl-inline-popup--current-index
+ diff-hl-inline-popup--height
+ diff-hl-inline-popup--current-header
+ diff-hl-inline-popup--current-footer)))
+ ;; https://debbugs.gnu.org/38563, `company--replacement-string'.
+ (add-face-text-property 0 (length str) 'default t str)
+ (overlay-put diff-hl-inline-popup--current-popup 'after-string str))))
+
+(defun diff-hl-inline-popup--popup-down()
+ "Scrolls one line down."
+ (interactive)
+ (diff-hl-inline-popup-scroll-to (1+ diff-hl-inline-popup--current-index) ))
+
+(defun diff-hl-inline-popup--popup-up()
+ "Scrolls one line up."
+ (interactive)
+ (diff-hl-inline-popup-scroll-to (1- diff-hl-inline-popup--current-index) ))
+
+(defun diff-hl-inline-popup--popup-pagedown()
+ "Scrolls one page down."
+ (interactive)
+ (diff-hl-inline-popup-scroll-to (+ diff-hl-inline-popup--current-index diff-hl-inline-popup--height) ))
+
+(defun diff-hl-inline-popup--popup-pageup()
+ "Scrolls one page up."
+ (interactive)
+ (diff-hl-inline-popup-scroll-to (- diff-hl-inline-popup--current-index diff-hl-inline-popup--height) ))
+
+(defvar diff-hl-inline-popup-transient-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "<prior>") #'diff-hl-inline-popup--popup-pageup)
+ (define-key map (kbd "M-v") #'diff-hl-inline-popup--popup-pageup)
+ (define-key map (kbd "<next>") #'diff-hl-inline-popup--popup-pagedown)
+ (define-key map (kbd "C-v") #'diff-hl-inline-popup--popup-pagedown)
+ (define-key map (kbd "<up>") #'diff-hl-inline-popup--popup-up)
+ (define-key map (kbd "C-p") #'diff-hl-inline-popup--popup-up)
+ (define-key map (kbd "<down>") #'diff-hl-inline-popup--popup-down)
+ (define-key map (kbd "C-n") #'diff-hl-inline-popup--popup-down)
+ (define-key map (kbd "C-g") #'diff-hl-inline-popup-hide)
+ (define-key map [escape] #'diff-hl-inline-popup-hide)
+ (define-key map (kbd "q") #'diff-hl-inline-popup-hide)
+ ;;http://ergoemacs.org/emacs/emacs_mouse_wheel_config.html
+ (define-key map (kbd "<mouse-4>") #'diff-hl-inline-popup--popup-up)
+ (define-key map (kbd "<wheel-up>") #'diff-hl-inline-popup--popup-up)
+ (define-key map (kbd "<mouse-5>") #'diff-hl-inline-popup--popup-down)
+ (define-key map (kbd "<wheel-down>") #'diff-hl-inline-popup--popup-down)
+ map)
+ "Keymap for command `diff-hl-inline-popup-transient-mode'.
+Capture all the vertical movement of the point, and converts it
+to scroll in the popup")
+
+(defun diff-hl-inline-popup--ignorable-command-p (command)
+ "Decide if COMMAND is a command allowed while showing an inline popup."
+ ;; https://emacs.stackexchange.com/questions/653/how-can-i-find-out-in-which-keymap-a-key-is-bound
+ (let ((keys (where-is-internal command (list diff-hl-inline-popup--current-custom-keymap
+ diff-hl-inline-popup-transient-mode-map ) t))
+ (invoking (eq command diff-hl-inline-popup--invokinkg-command)))
+ (or keys invoking)))
+
+(defun diff-hl-inline-popup--post-command-hook ()
+ "Called each time a command is executed."
+ (let ((allowed-command (or
+ (string-match-p "diff-hl-inline-popup-" (symbol-name this-command))
+ (diff-hl-inline-popup--ignorable-command-p this-command))))
+ (unless allowed-command
+ (diff-hl-inline-popup-hide))))
+
+(define-minor-mode diff-hl-inline-popup-transient-mode
+ "Temporal minor mode to control an inline popup"
+ :global nil
+ (remove-hook 'post-command-hook #'diff-hl-inline-popup--post-command-hook t)
+ (set-keymap-parent diff-hl-inline-popup-transient-mode-map nil)
+
+ (when diff-hl-inline-popup-transient-mode
+ (set-keymap-parent diff-hl-inline-popup-transient-mode-map
+ diff-hl-inline-popup--current-custom-keymap)
+ (add-hook 'post-command-hook #'diff-hl-inline-popup--post-command-hook 0 t)))
+
+;;;###autoload
+(defun diff-hl-inline-popup-hide()
+ "Hide the current inline popup."
+ (interactive)
+ (when diff-hl-inline-popup-transient-mode
+ (diff-hl-inline-popup-transient-mode -1))
+ (when diff-hl-inline-popup--close-hook
+ (funcall diff-hl-inline-popup--close-hook)
+ (setq diff-hl-inline-popup--close-hook nil))
+ (when diff-hl-inline-popup--current-popup
+ (delete-overlay diff-hl-inline-popup--current-popup)
+ (setq diff-hl-inline-popup--current-popup nil)))
+
+;;;###autoload
+(defun diff-hl-inline-popup-show (lines &optional header footer keymap close-hook point height)
+ "Create a phantom overlay to show the inline popup, with some
+content LINES, and a HEADER and a FOOTER, at POINT. KEYMAP is
+added to the current keymaps. CLOSE-HOOK is called when the popup
+is closed."
+ (when diff-hl-inline-popup--current-popup
+ (delete-overlay diff-hl-inline-popup--current-popup)
+ (setq diff-hl-inline-popup--current-popup nil))
+
+ (when (< (diff-hl-inline-popup--compute-content-height 99) 2)
+ (user-error "There is no enough vertical space to show the inline popup"))
+ (let* ((the-point (or point (line-end-position)))
+ (the-buffer (current-buffer))
+ (overlay (make-overlay the-point the-point the-buffer)))
+ (overlay-put overlay 'phantom t)
+ (overlay-put overlay 'diff-hl-inline-popup t)
+ (setq diff-hl-inline-popup--current-popup overlay)
+
+ (setq diff-hl-inline-popup--current-lines
+ (mapcar (lambda (s) (replace-regexp-in-string "\n" " " s)) lines))
+ (setq diff-hl-inline-popup--current-header header)
+ (setq diff-hl-inline-popup--current-footer footer)
+ (setq diff-hl-inline-popup--invokinkg-command this-command)
+ (setq diff-hl-inline-popup--current-custom-keymap keymap)
+ (setq diff-hl-inline-popup--close-hook close-hook)
+ (setq diff-hl-inline-popup--height (diff-hl-inline-popup--compute-content-height height))
+ (setq diff-hl-inline-popup--height (min diff-hl-inline-popup--height
+ (length diff-hl-inline-popup--current-lines)))
+ ;; (diff-hl-inline-popup--ensure-enough-lines point diff-hl-inline-popup--height)
+ (diff-hl-inline-popup-transient-mode 1)
+ (diff-hl-inline-popup-scroll-to 0)
+ overlay))
+
+(defun diff-hl-inline-popup--hide-all ()
+ "Testing purposes, use in case some inline popups get stuck in a buffer."
+ (interactive)
+ (when diff-hl-inline-popup-transient-mode
+ (diff-hl-inline-popup-transient-mode -1))
+ (setq diff-hl-inline-popup--current-popup nil)
+ (let* ((all-overlays (overlays-in (point-min) (point-max)))
+ (overlays (cl-remove-if-not (lambda (o)(overlay-get o 'diff-hl-inline-popup)) all-overlays)))
+ (dolist (o overlays)
+ (delete-overlay o))))
+
+(provide 'diff-hl-inline-popup)
+;;; diff-hl-inline-popup ends here
diff --git a/elpa/diff-hl-1.9.2/diff-hl-margin.el b/elpa/diff-hl-1.9.2/diff-hl-margin.el
@@ -0,0 +1,157 @@
+;;; diff-hl-margin.el --- Highlight buffer changes on margins -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2017 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This is a global mode, it modifies `diff-hl-mode' to use the margin
+;; instead of the fringe. To toggle, type `M-x diff-hl-margin-mode'.
+;;
+;; Compared to the default behavior, this makes `diff-hl-mode'
+;; indicators show up even when Emacs is running in a terminal.
+;;
+;; On the flip side, the indicators look simpler, and they are
+;; incompatible with `linum-mode' or any other mode that uses the
+;; margin.
+;;
+;; You might want to enable it conditionally in your init file
+;; depending on whether Emacs is running in graphical mode:
+;;
+;; (unless (window-system) (diff-hl-margin-mode))
+
+(require 'cl-lib)
+(require 'diff-hl)
+(require 'diff-hl-dired)
+
+(defvar diff-hl-margin-old-highlight-function nil)
+
+(defvar diff-hl-margin-old-width nil)
+
+(defgroup diff-hl-margin nil
+ "Highlight buffer changes on margin"
+ :group 'diff-hl)
+
+(defface diff-hl-margin-insert
+ '((default :inherit diff-hl-insert))
+ "Face used to highlight inserted lines on the margin.")
+
+(defface diff-hl-margin-delete
+ '((default :inherit diff-hl-delete))
+ "Face used to highlight deleted lines on the margin.")
+
+(defface diff-hl-margin-change
+ '((default :inherit diff-hl-change))
+ "Face used to highlight changed lines on the margin.")
+
+(defface diff-hl-margin-ignored
+ '((default :inherit dired-ignored))
+ "Face used to highlight changed lines on the margin.")
+
+(defface diff-hl-margin-unknown
+ '((default :inherit dired-ignored))
+ "Face used to highlight changed lines on the margin.")
+
+(defcustom diff-hl-margin-symbols-alist
+ '((insert . "+") (delete . "-") (change . "!")
+ (unknown . "?") (ignored . "i"))
+ "Associative list from symbols to strings."
+ :type '(alist :key-type symbol
+ :value-type string
+ :options (insert delete change unknown ignored))
+ :set (lambda (symbol value)
+ (defvar diff-hl-margin-spec-cache)
+ (set-default symbol value)
+ (setq diff-hl-margin-spec-cache nil)))
+
+;;;###autoload
+(define-minor-mode diff-hl-margin-mode
+ "Toggle displaying `diff-hl-mode' highlights on the margin."
+ :lighter "" :global t
+ (if diff-hl-margin-mode
+ (progn
+ (add-hook 'diff-hl-mode-on-hook 'diff-hl-margin-local-mode)
+ (add-hook 'diff-hl-mode-off-hook 'diff-hl-margin-local-mode-off)
+ (add-hook 'diff-hl-dired-mode-on-hook 'diff-hl-margin-local-mode)
+ (add-hook 'diff-hl-dired-mode-off-hook 'diff-hl-margin-local-mode-off))
+ (remove-hook 'diff-hl-mode-on-hook 'diff-hl-margin-local-mode)
+ (remove-hook 'diff-hl-mode-off-hook 'diff-hl-margin-local-mode-off)
+ (remove-hook 'diff-hl-dired-mode-on-hook 'diff-hl-margin-local-mode)
+ (remove-hook 'diff-hl-dired-mode-off-hook 'diff-hl-margin-local-mode-off))
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (cond
+ (diff-hl-mode
+ (diff-hl-margin-local-mode (if diff-hl-margin-mode 1 -1))
+ (diff-hl-update))
+ (diff-hl-dired-mode
+ (diff-hl-margin-local-mode (if diff-hl-margin-mode 1 -1))
+ (diff-hl-dired-update))))))
+
+;;;###autoload
+(define-minor-mode diff-hl-margin-local-mode
+ "Toggle displaying `diff-hl-mode' highlights on the margin locally.
+You probably shouldn't use this function directly."
+ :lighter ""
+ (let ((width-var (intern (format "%s-margin-width" diff-hl-side))))
+ (if diff-hl-margin-local-mode
+ (progn
+ (setq-local diff-hl-margin-old-highlight-function
+ diff-hl-highlight-function)
+ (setq-local diff-hl-highlight-function
+ #'diff-hl-highlight-on-margin)
+ (setq-local diff-hl-margin-old-width (symbol-value width-var))
+ (set width-var 1))
+ (when diff-hl-margin-old-highlight-function
+ (setq diff-hl-highlight-function diff-hl-margin-old-highlight-function
+ diff-hl-margin-old-highlight-function nil))
+ (set width-var diff-hl-margin-old-width)
+ (kill-local-variable 'diff-hl-margin-old-width)))
+ (dolist (win (get-buffer-window-list))
+ (set-window-buffer win (current-buffer))))
+
+(defun diff-hl-margin-local-mode-off ()
+ (diff-hl-margin-local-mode -1))
+
+(defvar diff-hl-margin-spec-cache nil)
+
+(defun diff-hl-margin-spec-cache ()
+ (or diff-hl-margin-spec-cache
+ (setq diff-hl-margin-spec-cache
+ (diff-hl-margin-build-spec-cache))))
+
+(defun diff-hl-margin-build-spec-cache ()
+ (cl-loop for (type . char) in diff-hl-margin-symbols-alist
+ nconc
+ (cl-loop for side in '(left right)
+ collect
+ (cons
+ (cons type side)
+ (propertize
+ " " 'display
+ `((margin ,(intern (format "%s-margin" side)))
+ ,(propertize char 'face
+ (intern (format "diff-hl-margin-%s" type)))))))))
+
+(defun diff-hl-highlight-on-margin (ovl type _shape)
+ (let ((spec (cdr (assoc (cons type diff-hl-side)
+ (diff-hl-margin-spec-cache)))))
+ (overlay-put ovl 'before-string spec)))
+
+(provide 'diff-hl-margin)
+
+;;; diff-hl-margin.el ends here
diff --git a/elpa/diff-hl-1.9.2/diff-hl-pkg.el b/elpa/diff-hl-1.9.2/diff-hl-pkg.el
@@ -0,0 +1,2 @@
+;; Generated package description from diff-hl.el -*- no-byte-compile: t -*-
+(define-package "diff-hl" "1.9.2" "Highlight uncommitted changes using VC" '((cl-lib "0.2") (emacs "25.1")) :commit "d20f16bf5eadd66e775f215e800f25caddae8cb5" :authors '(("Dmitry Gutov" . "dgutov@yandex.ru")) :maintainer '("Dmitry Gutov" . "dgutov@yandex.ru") :keywords '("vc" "diff") :url "https://github.com/dgutov/diff-hl")
diff --git a/elpa/diff-hl-1.9.2/diff-hl-show-hunk-posframe.el b/elpa/diff-hl-1.9.2/diff-hl-show-hunk-posframe.el
@@ -0,0 +1,238 @@
+;;; diff-hl-show-hunk-posframe.el --- posframe backend for diff-hl-show-hunk -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+;; Author: Álvaro González <alvarogonzalezsotillo@gmail.com>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This provides `diff-hl-show-hunk-posframe' than can be used as
+;; `diff-hl-show-hunk-function'. `posframe' is a runtime dependency,
+;; it is not required by this package, but it should be installed.
+;;
+;;; Code:
+
+(require 'diff-hl-show-hunk)
+
+;; This package uses some runtime dependencies, so we need to declare
+;; the external functions and variables
+(declare-function posframe-workable-p "posframe")
+(declare-function posframe-show "posframe")
+(defvar posframe-mouse-banish)
+
+(defgroup diff-hl-show-hunk-posframe nil
+ "Show vc diffs in a posframe."
+ :group 'diff-hl-show-hunk)
+
+(defcustom diff-hl-show-hunk-posframe-show-header-line t
+ "Show some useful buttons at the top of the diff-hl posframe."
+ :type 'boolean)
+
+(defcustom diff-hl-show-hunk-posframe-internal-border-width 2
+ "Internal border width of the posframe."
+ :type 'integer)
+
+(defcustom diff-hl-show-hunk-posframe-internal-border-color "#00ffff"
+ "Internal border color of the posframe."
+ :type 'color)
+
+(defcustom diff-hl-show-hunk-posframe-poshandler nil
+ "Poshandler of the posframe (see `posframe-show`)."
+ :type '(choice function
+ (const :tag "None" nil)))
+
+(defcustom diff-hl-show-hunk-posframe-parameters nil
+ "The frame parameters used by helm-posframe."
+ :type '(choice string
+ (const :tag "None" nil)))
+
+(defface diff-hl-show-hunk-posframe '((t nil))
+ "Face for the posframe buffer.
+Customize it to change the base properties of the text.")
+
+(defface diff-hl-show-hunk-posframe-button-face '((t . (:height 0.9)))
+ "Face for the posframe buttons" )
+
+(defvar diff-hl-show-hunk--frame nil "The postframe frame used in function `diff-hl-show-hunk-posframe'.")
+(defvar diff-hl-show-hunk--original-frame nil "The frame from which the hunk is shown.")
+
+(defun diff-hl-show-hunk--posframe-hide ()
+ "Hide the posframe and clean up buffer."
+ (interactive)
+ (diff-hl-show-hunk-posframe--transient-mode -1)
+ (when (frame-live-p diff-hl-show-hunk--frame)
+ (make-frame-invisible diff-hl-show-hunk--frame))
+ (when diff-hl-show-hunk--original-frame
+ (when (frame-live-p diff-hl-show-hunk--original-frame)
+ (let ((frame diff-hl-show-hunk--original-frame))
+ (select-frame-set-input-focus frame)
+ ;; In Gnome, sometimes the input focus is not restored to the
+ ;; original frame, so we try harder in a while
+ (run-with-timer 0.1 nil (lambda () (select-frame-set-input-focus frame)))))
+ (setq diff-hl-show-hunk--original-frame nil)))
+
+(defvar diff-hl-show-hunk-posframe--transient-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [escape] #'diff-hl-show-hunk-hide)
+ (define-key map (kbd "q") #'diff-hl-show-hunk-hide)
+ (define-key map (kbd "C-g") #'diff-hl-show-hunk-hide)
+ (set-keymap-parent map diff-hl-show-hunk-map)
+ map)
+ "Keymap for command `diff-hl-show-hunk-posframe--transient-mode'.")
+
+(define-minor-mode diff-hl-show-hunk-posframe--transient-mode
+ "Temporal minor mode to control diff-hl posframe."
+ :lighter ""
+ :global t
+ (if diff-hl-show-hunk-posframe--transient-mode
+ (add-hook 'post-command-hook #'diff-hl-show-hunk--posframe-post-command-hook nil)
+ (remove-hook 'post-command-hook #'diff-hl-show-hunk--posframe-post-command-hook nil)))
+
+(defun diff-hl-show-hunk--posframe-post-command-hook ()
+ "Called for each command while in `diff-hl-show-hunk-posframe--transient-mode."
+ (let* ((allowed-command (or
+ (diff-hl-show-hunk-ignorable-command-p this-command)
+ (and (symbolp this-command)
+ (string-match-p "diff-hl-" (symbol-name this-command)))))
+ (event-in-frame (eq last-event-frame diff-hl-show-hunk--frame))
+ (has-focus (and (frame-live-p diff-hl-show-hunk--frame)
+ (functionp 'frame-focus-state)
+ (eq (frame-focus-state diff-hl-show-hunk--frame) t)))
+ (still-visible (or event-in-frame allowed-command has-focus)))
+ (unless still-visible
+ (diff-hl-show-hunk--posframe-hide))))
+
+(defun diff-hl-show-hunk--posframe-button (text help-echo action)
+ "Make a string implementing a button with TEXT and a HELP-ECHO.
+The button calls an ACTION."
+ (concat
+ (propertize (concat " " text " ")
+ 'help-echo (if action help-echo "Not available")
+ 'face 'diff-hl-show-hunk-posframe-button-face
+ 'mouse-face (when action '(:box (:style released-button)))
+ 'keymap (when action
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "<header-line> <mouse-1>") action)
+ map)))
+ " "))
+
+(defun diff-hl-show-hunk-posframe--header-line ()
+ "Make the header line of the posframe."
+ (concat
+ (diff-hl-show-hunk--posframe-button
+ "⨯ Close"
+ "Close (\\[diff-hl-show-hunk-hide])"
+ #'diff-hl-show-hunk-hide)
+ (diff-hl-show-hunk--posframe-button
+ "⬆ Previous change"
+ "Previous change in hunk (\\[diff-hl-show-hunk-previous])"
+ #'diff-hl-show-hunk-previous)
+
+ (diff-hl-show-hunk--posframe-button
+ "⬇ Next change"
+ "Next change in hunk (\\[diff-hl-show-hunk-next])"
+ #'diff-hl-show-hunk-next)
+
+ (diff-hl-show-hunk--posframe-button
+ "⊚ Copy original"
+ "Copy original (\\[diff-hl-show-hunk-copy-original-text])"
+ #'diff-hl-show-hunk-copy-original-text)
+
+ (diff-hl-show-hunk--posframe-button
+ "♻ Revert hunk"
+ "Revert hunk (\\[diff-hl-show-hunk-revert-hunk])"
+ #'diff-hl-show-hunk-revert-hunk)
+
+ (unless diff-hl-show-staged-changes
+ (diff-hl-show-hunk--posframe-button
+ "⊕ Stage hunk"
+ "Stage hunk (\\[diff-hl-show-hunk-stage-hunk])"
+ #'diff-hl-show-hunk-stage-hunk))
+ ))
+
+;;;###autoload
+(defun diff-hl-show-hunk-posframe (buffer &optional _line)
+ "Implementation to show the hunk in a posframe."
+
+ (unless (require 'posframe nil t)
+ (user-error
+ (concat
+ "`diff-hl-show-hunk-posframe' requires the `posframe' package."
+ " Please install it or customize `diff-hl-show-hunk-function'.")))
+
+ (unless (posframe-workable-p)
+ (user-error
+ "Package `posframe' is not workable. Please customize diff-hl-show-hunk-function"))
+
+ (diff-hl-show-hunk--posframe-hide)
+ (setq diff-hl-show-hunk--hide-function #'diff-hl-show-hunk--posframe-hide)
+
+ ;; put an overlay to override read-only-mode keymap
+ (with-current-buffer buffer
+ ;; Change face size
+ (buffer-face-set 'diff-hl-show-hunk-posframe)
+
+ (let ((full-overlay (make-overlay 1 (1+ (buffer-size)))))
+ (overlay-put full-overlay
+ 'keymap diff-hl-show-hunk-posframe--transient-mode-map)))
+
+ (setq posframe-mouse-banish nil)
+ (setq diff-hl-show-hunk--original-frame last-event-frame)
+
+ (let* ((hunk-overlay diff-hl-show-hunk--original-overlay)
+ (position (overlay-end hunk-overlay)))
+ (setq
+ diff-hl-show-hunk--frame
+ (posframe-show buffer
+ :position position
+ :poshandler diff-hl-show-hunk-posframe-poshandler
+ :internal-border-width diff-hl-show-hunk-posframe-internal-border-width
+ :accept-focus t
+ ;; internal-border-color Doesn't always work, if not customize internal-border face
+ :internal-border-color diff-hl-show-hunk-posframe-internal-border-color
+ :hidehandler nil
+ ;; Sometimes, header-line is not taken into account, so put a min height and a min width
+ :min-height (when diff-hl-show-hunk-posframe-show-header-line 10)
+ :min-width (when diff-hl-show-hunk-posframe-show-header-line
+ (length (diff-hl-show-hunk-posframe--header-line)))
+ :respect-header-line diff-hl-show-hunk-posframe-show-header-line
+ :respect-tab-line nil
+ :respect-mode-line nil
+ :override-parameters diff-hl-show-hunk-posframe-parameters)))
+
+ (set-frame-parameter diff-hl-show-hunk--frame 'drag-internal-border t)
+ (set-frame-parameter diff-hl-show-hunk--frame 'drag-with-header-line t)
+
+ (with-selected-frame diff-hl-show-hunk--frame
+ (with-current-buffer buffer
+ (diff-hl-show-hunk-posframe--transient-mode 1)
+ (when diff-hl-show-hunk-posframe-show-header-line
+ (setq header-line-format (diff-hl-show-hunk-posframe--header-line)))
+ (goto-char (point-min))
+ (setq buffer-quit-function #'diff-hl-show-hunk--posframe-hide)
+ (select-window (window-main-window diff-hl-show-hunk--frame))
+
+ ;; Make cursor visible (mainly for selecting text in posframe)
+ (setq cursor-type 'box)
+
+ ;; Recenter arround point
+ (recenter)))
+ (select-frame-set-input-focus diff-hl-show-hunk--frame))
+
+(provide 'diff-hl-show-hunk-posframe)
+;;; diff-hl-show-hunk-posframe.el ends here
diff --git a/elpa/diff-hl-1.9.2/diff-hl-show-hunk.el b/elpa/diff-hl-1.9.2/diff-hl-show-hunk.el
@@ -0,0 +1,419 @@
+;;; diff-hl-show-hunk.el --- Integrate popup/posframe and diff-hl-diff-goto-hunk -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+;; Author: Álvaro González <alvarogonzalezsotillo@gmail.com>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; `diff-hl-show-hunk' shows a popup with the modification hunk at point.
+;; `diff-hl-show-hunk-function' points to the backend used to show the
+;; hunk. Its default value is `diff-hl-show-hunk-inline-popup', that
+;; shows diffs inline using overlay. There is another built-in backend:
+;; `diff-hl-show-hunk-posframe' (based on posframe).
+;;
+;; `diff-hl-show-hunk-mouse-mode' adds interaction on clicking in the
+;; margin or the fringe (shows the current hunk as well).
+;;
+;; To use it in all buffers:
+;;
+;; (global-diff-hl-show-hunk-mouse-mode)
+
+;;; Code:
+
+(require 'diff-hl-inline-popup)
+(require 'diff-hl)
+
+(defvar diff-hl-show-hunk-mouse-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "<left-margin> <mouse-1>") 'diff-hl-show-hunk--click)
+ (define-key map (kbd "<right-margin> <mouse-1>") 'diff-hl-show-hunk--click)
+ (define-key map (kbd "<left-fringe> <mouse-1>") 'diff-hl-show-hunk--click)
+ (define-key map (kbd "<right-fringe> <mouse-1>") 'diff-hl-show-hunk--click)
+ map)
+ "Keymap for command `diff-hl-show-hunk-mouse-mode'.")
+
+(defvar diff-hl-show-hunk-buffer-name "*diff-hl-show-hunk-buffer*"
+ "Name of the buffer used by diff-hl-show-hunk.")
+
+(defvar diff-hl-show-hunk-diff-buffer-name "*diff-hl-show-hunk-diff-buffer*"
+ "Name of the buffer used by diff-hl-show-hunk to show the diff.")
+
+(defvar diff-hl-show-hunk--original-window nil
+ "The vc window of which the hunk is shown.")
+
+(defvar diff-hl-show-hunk--original-buffer nil
+ "The vc buffer of which the hunk is shown.")
+
+(defvar diff-hl-show-hunk--original-content nil
+ "The original content of the hunk.")
+
+(defvar diff-hl-show-hunk--original-overlay nil
+ "Copy of the diff-hl hunk overlay.")
+
+(defgroup diff-hl-show-hunk nil
+ "Show vc diffs in a posframe or popup."
+ :group 'diff-hl)
+
+(defconst diff-hl-show-hunk-boundary "^@@.*@@")
+(defconst diff-hl-show-hunk--no-lines-removed-message (list "<<no lines removed>>"))
+
+(defcustom diff-hl-show-hunk-inline-popup-hide-hunk nil
+ "If t, inline-popup is shown over the hunk, hiding it."
+ :type 'boolean)
+
+(defcustom diff-hl-show-hunk-inline-popup-smart-lines t
+ "If t, inline-popup tries to show only the deleted lines of the
+hunk. The added lines are shown when scrolling the popup. If
+the hunk consist only on added lines, then
+`diff-hl-show-hunk--no-lines-removed-message' it is shown."
+ :type 'boolean)
+
+(defcustom diff-hl-show-hunk-function 'diff-hl-show-hunk-inline-popup
+ "The function used to render the hunk.
+The function receives as first parameter a buffer with the
+contents of the hunk, and as second parameter the line number
+corresponding to the clicked line in the original buffer."
+ :type '(choice
+ (const :tag "Show inline" diff-hl-show-hunk-inline-popup)
+ (const :tag "Show using posframe" diff-hl-show-hunk-posframe)))
+
+(defvar diff-hl-show-hunk--hide-function nil
+ "Function to call to close the shown hunk.")
+
+(defun diff-hl-show-hunk-hide ()
+ "Hide the current shown hunk."
+ (interactive)
+ (if (and diff-hl-show-hunk--original-window (window-live-p diff-hl-show-hunk--original-window))
+ (select-window diff-hl-show-hunk--original-window))
+ (setq diff-hl-show-hunk--original-window nil)
+ (if (buffer-live-p diff-hl-show-hunk--original-buffer)
+ (switch-to-buffer diff-hl-show-hunk--original-buffer))
+ (setq diff-hl-show-hunk--original-buffer nil)
+ (with-current-buffer (get-buffer-create diff-hl-show-hunk-buffer-name)
+ (read-only-mode -1)
+ (erase-buffer))
+ (bury-buffer diff-hl-show-hunk-buffer-name)
+ (when (get-buffer diff-hl-show-hunk-diff-buffer-name)
+ (bury-buffer diff-hl-show-hunk-diff-buffer-name))
+ (when diff-hl-show-hunk--hide-function
+ (let ((hidefunc diff-hl-show-hunk--hide-function))
+ (setq diff-hl-show-hunk--hide-function nil)
+ (funcall hidefunc)))
+ (when diff-hl-show-hunk--original-overlay
+ (diff-hl-show-hunk--goto-hunk-overlay diff-hl-show-hunk--original-overlay))
+ (when diff-hl-show-hunk--original-overlay
+ (delete-overlay diff-hl-show-hunk--original-overlay))
+ (setq diff-hl-show-hunk--original-overlay nil))
+
+(defun diff-hl-show-hunk-ignorable-command-p (command)
+ "Decide if COMMAND is a command allowed while showing the current hunk."
+ (member command '(ignore diff-hl-show-hunk handle-switch-frame diff-hl-show-hunk--click)))
+
+(defun diff-hl-show-hunk--compute-diffs ()
+ "Compute diffs using functions of diff-hl.
+Then put the differences inside a special buffer and set the
+point in that buffer to the corresponding line of the original
+buffer."
+ (defvar vc-sentinel-movepoint)
+ (let* ((buffer (or (buffer-base-buffer) (current-buffer)))
+ (line (line-number-at-pos))
+ (dest-buffer diff-hl-show-hunk-diff-buffer-name))
+ (with-current-buffer buffer
+ (diff-hl-diff-buffer-with-reference (buffer-file-name buffer) dest-buffer)
+ (switch-to-buffer dest-buffer)
+ (diff-hl-diff-skip-to line)
+ (setq vc-sentinel-movepoint (point)))
+ dest-buffer))
+
+(defun diff-hl-show-hunk--get-original-lines (content)
+ "Extracts the lines starting with '-' from CONTENT and save them."
+ (let* ((lines (split-string content "[\n\r]+" )))
+ (cl-remove-if-not (lambda (l) (string-match-p "^-.*" l)) lines)))
+
+(defun diff-hl-show-hunk--fill-original-content (content)
+ "Extracts the lines starting with '-' from CONTENT and save them."
+ (let* ((original-lines (diff-hl-show-hunk--get-original-lines content))
+ (original-lines (mapcar (lambda (l) (substring l 1)) original-lines))
+ (content (string-join original-lines "\n")))
+ (setq diff-hl-show-hunk--original-content content)))
+
+(defun diff-hl-show-hunk-buffer ()
+ "Create the buffer with the contents of the hunk at point.
+The buffer has the point in the corresponding line of the hunk.
+Returns a list with the buffer and the line number of the clicked line."
+ (let ((content)
+ (point-in-buffer)
+ (line)
+ (line-overlay)
+ ;; https://emacs.stackexchange.com/questions/35680/stop-emacs-from-updating-display
+ (inhibit-redisplay t)
+ (buffer (get-buffer-create diff-hl-show-hunk-buffer-name)))
+
+ ;; Get differences
+ (save-window-excursion
+ (save-excursion
+ (with-current-buffer (diff-hl-show-hunk--compute-diffs)
+ (setq content (buffer-substring-no-properties (point-min) (point-max)))
+ (setq point-in-buffer (point)))))
+
+ (with-current-buffer buffer
+ (read-only-mode -1)
+ (erase-buffer)
+ (insert content)
+
+ ;; Highlight the clicked line
+ (goto-char point-in-buffer)
+ (setq line-overlay (make-overlay (line-beginning-position)
+ (min (point-max)
+ (1+ (line-end-position)))))
+
+ ;; diff-mode
+ (diff-mode)
+ (read-only-mode 1)
+
+ ;; Find the hunk and narrow to it
+ (re-search-backward diff-hl-show-hunk-boundary nil 1)
+ (forward-line 1)
+ (let* ((start (point)))
+ (re-search-forward diff-hl-show-hunk-boundary nil 1)
+ (move-beginning-of-line nil)
+ (narrow-to-region start (point)))
+
+ ;; Store original content
+ (let ((content (buffer-string)))
+ (diff-hl-show-hunk--fill-original-content content))
+
+ ;; Come back to the clicked line
+ (goto-char (overlay-start line-overlay))
+ (setq line (line-number-at-pos)))
+
+ (list buffer line)))
+
+(defun diff-hl-show-hunk--click (event)
+ "Called when user clicks on margins. EVENT is click information."
+ (interactive "e")
+ ;; Go the click's position.
+ (posn-set-point (event-start event))
+ (diff-hl-show-hunk))
+
+(defvar diff-hl-show-hunk-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "p") #'diff-hl-show-hunk-previous)
+ (define-key map (kbd "n") #'diff-hl-show-hunk-next)
+ (define-key map (kbd "c") #'diff-hl-show-hunk-copy-original-text)
+ (define-key map (kbd "r") #'diff-hl-show-hunk-revert-hunk)
+ (define-key map (kbd "[") #'diff-hl-show-hunk-previous)
+ (define-key map (kbd "]") #'diff-hl-show-hunk-next)
+ (define-key map (kbd "{") #'diff-hl-show-hunk-previous)
+ (define-key map (kbd "}") #'diff-hl-show-hunk-next)
+ (define-key map (kbd "S") #'diff-hl-show-hunk-stage-hunk)
+ map))
+
+(defvar diff-hl-show-hunk--hide-function)
+
+;;;###autoload
+(defun diff-hl-show-hunk-inline-popup (buffer &optional _ignored-line)
+ "Implementation to show the hunk in a inline popup.
+BUFFER is a buffer with the hunk."
+ (diff-hl-inline-popup-hide)
+ (setq diff-hl-show-hunk--hide-function #'diff-hl-inline-popup-hide)
+ (let* ((lines (split-string (with-current-buffer buffer (buffer-string)) "[\n\r]+" ))
+ (smart-lines diff-hl-show-hunk-inline-popup-smart-lines)
+ (original-lines-number (cl-count-if (lambda (s) (string-prefix-p "-" s)) lines))
+ (lines (if (string= (car (last lines)) "" ) (butlast lines) lines))
+ (lines (if (and (eq original-lines-number 0) smart-lines)
+ diff-hl-show-hunk--no-lines-removed-message
+ lines))
+ (overlay diff-hl-show-hunk--original-overlay)
+ (type (overlay-get overlay 'diff-hl-hunk-type))
+ (point (if (eq type 'delete) (overlay-start overlay) (overlay-end overlay)))
+ (propertize-line (lambda (l)
+ (propertize l 'face
+ (cond ((string-prefix-p "+" l)
+ 'diff-added)
+ ((string-prefix-p "-" l)
+ 'diff-removed)))))
+ (propertized-lines (mapcar propertize-line lines)))
+
+ (save-excursion
+ ;; Save point in case the hunk is hidden, so next/previous works as expected
+ ;; If the hunk is delete type, then don't hide the hunk
+ ;; (because the hunk is located in a non deleted line)
+ (when (and diff-hl-show-hunk-inline-popup-hide-hunk
+ (not (eq type 'delete)))
+ (let* ((invisible-overlay (make-overlay (overlay-start overlay)
+ (overlay-end overlay))))
+ ;; Make new overlay, since the diff-hl overlay can be changed by diff-hl-flydiff
+ (overlay-put invisible-overlay 'invisible t)
+ ;; Change default hide popup function, to make the overlay visible
+ (setq diff-hl-show-hunk--hide-function
+ (lambda ()
+ (overlay-put invisible-overlay 'invisible nil)
+ (delete-overlay invisible-overlay)
+ (diff-hl-inline-popup-hide)))))
+ (diff-hl-show-hunk--goto-hunk-overlay overlay)
+ (let ((height
+ (when smart-lines
+ (when (not (eq 0 original-lines-number))
+ original-lines-number)))
+ (footer "(q)Quit (p)Previous (n)Next (r)Revert (c)Copy original"))
+ (unless diff-hl-show-staged-changes
+ (setq footer (concat footer " (S)Stage")))
+ (diff-hl-inline-popup-show
+ propertized-lines
+ (if (and (boundp 'diff-hl-reference-revision) diff-hl-reference-revision)
+ (concat "Diff with " diff-hl-reference-revision)
+ "Diff with HEAD")
+ footer
+ diff-hl-show-hunk-map
+ #'diff-hl-show-hunk-hide
+ point
+ height))
+ )))
+
+(defun diff-hl-show-hunk-copy-original-text ()
+ "Extracts all the lines from BUFFER starting with '-' to the kill ring."
+ (interactive)
+ (kill-new diff-hl-show-hunk--original-content)
+ (message "Original hunk content added to kill-ring"))
+
+(defun diff-hl-show-hunk-revert-hunk ()
+ "Dismiss the popup and revert the current diff hunk."
+ (interactive)
+ (diff-hl-show-hunk-hide)
+ (let (diff-hl-ask-before-revert-hunk)
+ (diff-hl-revert-hunk)))
+
+(defun diff-hl-show-hunk-stage-hunk ()
+ "Dismiss the popup and stage the current hunk."
+ (interactive)
+ (diff-hl-show-hunk-hide)
+ (diff-hl-stage-current-hunk))
+
+;;;###autoload
+(defun diff-hl-show-hunk-previous ()
+ "Go to previous hunk/change and show it."
+ (interactive)
+ (let* ((point (if diff-hl-show-hunk--original-overlay
+ (overlay-start diff-hl-show-hunk--original-overlay)
+ nil))
+ (previous-overlay (diff-hl-show-hunk--next-hunk t point)))
+ (if (not previous-overlay)
+ (message "There is no previous change")
+ (diff-hl-show-hunk-hide)
+ (diff-hl-show-hunk--goto-hunk-overlay previous-overlay)
+ (recenter)
+ (diff-hl-show-hunk))))
+
+(defun diff-hl-show-hunk--next-hunk (backward point)
+ "Same as `diff-hl-search-next-hunk', but in the current buffer
+of `diff-hl-show-hunk'."
+ (with-current-buffer (or diff-hl-show-hunk--original-buffer (current-buffer))
+ (diff-hl-search-next-hunk backward point)))
+
+(defun diff-hl-show-hunk--goto-hunk-overlay (overlay)
+ "Tries to display the whole overlay, and place the point at the
+end of the OVERLAY, so posframe/inline is placed below the hunk."
+ (when (and (overlayp overlay) (overlay-buffer overlay))
+ (let ((pt (point)))
+ (goto-char (overlay-start overlay))
+ (cond
+ ((< (point) (window-start))
+ (set-window-start nil (point)))
+ ((> (point) pt)
+ (redisplay))))
+ (goto-char (1- (overlay-end overlay)))))
+
+;;;###autoload
+(defun diff-hl-show-hunk-next ()
+ "Go to next hunk/change and show it."
+ (interactive)
+ (let* ((point (if diff-hl-show-hunk--original-overlay
+ (overlay-start diff-hl-show-hunk--original-overlay)
+ nil))
+ (next-overlay (diff-hl-show-hunk--next-hunk nil point)))
+ (if (not next-overlay)
+ (message "There is no next change")
+ (diff-hl-show-hunk-hide)
+ (diff-hl-show-hunk--goto-hunk-overlay next-overlay)
+ (recenter)
+ (diff-hl-show-hunk))))
+
+;;;###autoload
+(defun diff-hl-show-hunk ()
+ "Show the VC diff hunk at point.
+The backend is determined by `diff-hl-show-hunk-function'."
+ (interactive)
+
+ ;; Close any previous hunk
+ (save-excursion
+ (diff-hl-show-hunk-hide))
+
+ (unless (vc-backend buffer-file-name)
+ (user-error "The buffer is not under version control"))
+
+ (diff-hl-find-current-hunk)
+
+ (setq diff-hl-show-hunk--original-overlay nil)
+
+ ;; Store begining and end of hunk overlay
+ (let ((overlay (diff-hl-hunk-overlay-at (point))))
+ (when overlay
+ (let ((start (overlay-start overlay))
+ (end (overlay-end overlay))
+ (type (overlay-get overlay 'diff-hl-hunk-type)))
+ (setq diff-hl-show-hunk--original-overlay (make-overlay start end))
+ (overlay-put diff-hl-show-hunk--original-overlay 'diff-hl-hunk-type type)))
+
+ (unless overlay
+ (user-error "Not in a hunk")))
+
+ (cond
+ ((not diff-hl-show-hunk-function)
+ (message "Please configure `diff-hl-show-hunk-function'")
+ (diff-hl-diff-goto-hunk))
+ ((let ((buffer-and-line (diff-hl-show-hunk-buffer)))
+ (setq diff-hl-show-hunk--original-buffer (current-buffer))
+ (setq diff-hl-show-hunk--original-window (selected-window))
+ (apply diff-hl-show-hunk-function buffer-and-line))
+ ;; We could fall back to `diff-hl-diff-goto-hunk', but the
+ ;; current default should work in all environments (both GUI
+ ;; and terminal), and if something goes wrong we better show
+ ;; the error to the user.
+ )))
+
+;;;###autoload
+(define-minor-mode diff-hl-show-hunk-mouse-mode
+ "Enables the margin and fringe to show a posframe/popup with vc diffs when clicked.
+By default, the popup shows only the current hunk, and
+the line of the hunk that matches the current position is
+highlighted. The face, border and other visual preferences are
+customizable. It can be also invoked with the command
+`diff-hl-show-hunk'
+\\{diff-hl-show-hunk-mouse-mode-map}"
+ :group 'diff-hl-show-hunk
+ :lighter "")
+
+;;;###autoload
+(define-globalized-minor-mode global-diff-hl-show-hunk-mouse-mode
+ diff-hl-show-hunk-mouse-mode
+ diff-hl-show-hunk-mouse-mode)
+
+(provide 'diff-hl-show-hunk)
+;;; diff-hl-show-hunk.el ends here
diff --git a/elpa/diff-hl-1.9.2/diff-hl.el b/elpa/diff-hl-1.9.2/diff-hl.el
@@ -0,0 +1,1128 @@
+;;; diff-hl.el --- Highlight uncommitted changes using VC -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2023 Free Software Foundation, Inc.
+
+;; Author: Dmitry Gutov <dgutov@yandex.ru>
+;; URL: https://github.com/dgutov/diff-hl
+;; Keywords: vc, diff
+;; Version: 1.9.2
+;; Package-Requires: ((cl-lib "0.2") (emacs "25.1"))
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; `diff-hl-mode' highlights uncommitted changes on the side of the
+;; window (using the fringe, by default), allows you to jump between
+;; the hunks and revert them selectively.
+
+;; Provided commands:
+;;
+;; `diff-hl-diff-goto-hunk' C-x v =
+;; `diff-hl-revert-hunk' C-x v n
+;; `diff-hl-previous-hunk' C-x v [
+;; `diff-hl-next-hunk' C-x v ]
+;; `diff-hl-show-hunk' C-x v *
+;; `diff-hl-stage-current-hunk' C-x v S
+;; `diff-hl-set-reference-rev'
+;; `diff-hl-reset-reference-rev'
+;; `diff-hl-unstage-file'
+;;
+;; The mode takes advantage of `smartrep' if it is installed.
+;;
+;; Alternatively, it integrates with `repeat-mode' (Emacs 28+).
+
+;; Add either of the following to your init file.
+;;
+;; To use it in all buffers:
+;;
+;; (global-diff-hl-mode)
+;;
+;; Only in `prog-mode' buffers, with `vc-dir' integration:
+;;
+;; (add-hook 'prog-mode-hook 'turn-on-diff-hl-mode)
+;; (add-hook 'vc-dir-mode-hook 'turn-on-diff-hl-mode)
+
+;;; Code:
+
+(require 'fringe)
+(require 'diff-mode)
+(require 'vc)
+(require 'vc-dir)
+(require 'log-view)
+
+(eval-when-compile
+ (require 'cl-lib)
+ (require 'vc-git)
+ (require 'vc-hg)
+ (require 'face-remap)
+ (declare-function smartrep-define-key 'smartrep))
+
+(defgroup diff-hl nil
+ "VC diff highlighting on the side of a window"
+ :group 'vc)
+
+(defface diff-hl-insert
+ '((default :inherit diff-added)
+ (((class color)) :foreground "green4"))
+ "Face used to highlight inserted lines."
+ :group 'diff-hl)
+
+(defface diff-hl-delete
+ '((default :inherit diff-removed)
+ (((class color)) :foreground "red3"))
+ "Face used to highlight deleted lines."
+ :group 'diff-hl)
+
+(defface diff-hl-change
+ '((default :foreground "blue3")
+ (((class color) (min-colors 88) (background light))
+ :background "#ddddff")
+ (((class color) (min-colors 88) (background dark))
+ :background "#333355"))
+ "Face used to highlight changed lines."
+ :group 'diff-hl)
+
+(defcustom diff-hl-command-prefix (kbd "C-x v")
+ "The prefix for all `diff-hl' commands."
+ :group 'diff-hl
+ :type 'string)
+
+(defcustom diff-hl-draw-borders t
+ "Non-nil to draw borders around fringe indicators."
+ :group 'diff-hl
+ :type 'boolean)
+
+(defcustom diff-hl-disable-on-remote nil
+ "Non-nil will disable `diff-hl' in remote buffers."
+ :group 'diff-hl
+ :type 'boolean)
+
+(defcustom diff-hl-ask-before-revert-hunk t
+ "Non-nil to ask for confirmation before revert a hunk."
+ :group 'diff-hl
+ :type 'boolean)
+
+(defcustom diff-hl-highlight-function 'diff-hl-highlight-on-fringe
+ "Function to highlight the current line. Its arguments are
+ overlay, change type and position within a hunk."
+ :group 'diff-hl
+ :type 'function)
+
+(defcustom diff-hl-fringe-bmp-function 'diff-hl-fringe-bmp-from-pos
+ "Function to choose the fringe bitmap for a given change type
+ and position within a hunk. Should accept two arguments."
+ :group 'diff-hl
+ :type '(choice (const diff-hl-fringe-bmp-from-pos)
+ (const diff-hl-fringe-bmp-from-type)
+ function))
+
+(defcustom diff-hl-fringe-face-function 'diff-hl-fringe-face-from-type
+ "Function to choose the fringe face for a given change type
+ and position within a hunk. Should accept two arguments."
+ :group 'diff-hl
+ :type 'function)
+
+(defcustom diff-hl-side 'left
+ "Which side to use for indicators."
+ :type '(choice (const left)
+ (const right))
+ :initialize 'custom-initialize-default
+ :set (lambda (var value)
+ (let ((on (bound-and-true-p global-diff-hl-mode)))
+ (when on (global-diff-hl-mode -1))
+ (set-default var value)
+ (when on (global-diff-hl-mode 1)))))
+
+(defcustom diff-hl-highlight-revert-hunk-function
+ #'diff-hl-revert-narrow-to-hunk
+ "Function to emphasize the current hunk in `diff-hl-revert-hunk'.
+The function is called at the beginning of the hunk and is passed
+the end position as its only argument."
+ :type '(choice (const :tag "Do nothing" ignore)
+ (const :tag "Highlight the first column"
+ diff-hl-revert-highlight-first-column)
+ (const :tag "Narrow to the hunk"
+ diff-hl-revert-narrow-to-hunk)))
+
+(defcustom diff-hl-global-modes '(not image-mode)
+ "Modes for which `diff-hl-mode' is automagically turned on.
+This affects the behavior of `global-diff-hl-mode'.
+If nil, no modes have `diff-hl-mode' automatically turned on.
+If t, all modes have `diff-hl-mode' enabled.
+If a list, it should be a list of `major-mode' symbol names for
+which it should be automatically turned on. The sense of the list
+is negated if it begins with `not'. As such, the default value
+ (not image-mode)
+means that `diff-hl-mode' is turned on in all modes except for
+`image-mode' buffers. Previously, `diff-hl-mode' caused worse
+performance when viewing such files in certain conditions."
+ :type '(choice (const :tag "none" nil)
+ (const :tag "all" t)
+ (set :menu-tag "mode specific" :tag "modes"
+ :value (not)
+ (const :tag "Except" not)
+ (repeat :inline t (symbol :tag "mode"))))
+ :group 'diff-hl)
+
+(defcustom diff-hl-show-staged-changes t
+ "Whether to include staged changes in the indicators.
+Only affects Git, it's the only backend that has staging area."
+ :type 'boolean)
+
+(defcustom diff-hl-goto-hunk-old-revisions nil
+ "When non-nil, `diff-hl-diff-goto-hunk' will always try to
+navigate to the line in the diff that corresponds to the current
+line in the file buffer (or as close as it can get to it).
+
+When this variable is nil (default), `diff-hl-diff-goto-hunk'
+only does that when called without the prefix argument, or when
+the NEW revision is not specified (meaning, the diff is against
+the current version of the file)."
+ :type 'boolean)
+
+(defvar diff-hl-reference-revision nil
+ "Revision to diff against. nil means the most recent one.")
+
+(defun diff-hl-define-bitmaps ()
+ (let* ((scale (if (and (boundp 'text-scale-mode-amount)
+ (numberp text-scale-mode-amount))
+ (expt text-scale-mode-step text-scale-mode-amount)
+ 1))
+ (spacing (or (and (display-graphic-p) (default-value 'line-spacing)) 0))
+ (h (+ (ceiling (* (frame-char-height) scale))
+ (if (floatp spacing)
+ (truncate (* (frame-char-height) spacing))
+ spacing)))
+ (w (min (frame-parameter nil (intern (format "%s-fringe" diff-hl-side)))
+ 16))
+ (_ (when (zerop w) (setq w 16)))
+ (middle (make-vector h (expt 2 (1- w))))
+ (ones (1- (expt 2 w)))
+ (top (copy-sequence middle))
+ (bottom (copy-sequence middle))
+ (single (copy-sequence middle)))
+ (aset top 0 ones)
+ (aset bottom (1- h) ones)
+ (aset single 0 ones)
+ (aset single (1- h) ones)
+ (define-fringe-bitmap 'diff-hl-bmp-top top h w 'top)
+ (define-fringe-bitmap 'diff-hl-bmp-middle middle h w 'center)
+ (define-fringe-bitmap 'diff-hl-bmp-bottom bottom h w 'bottom)
+ (define-fringe-bitmap 'diff-hl-bmp-single single h w 'top)
+ (define-fringe-bitmap 'diff-hl-bmp-i [3 3 0 3 3 3 3 3 3 3] nil 2 'center)
+ (let* ((w2 (* (/ w 2) 2))
+ ;; When fringes are disabled, it's easier to fix up the width,
+ ;; instead of doing nothing (#20).
+ (w2 (if (zerop w2) 2 w2))
+ (delete-row (- (expt 2 (1- w2)) 2))
+ (middle-pos (1- (/ w2 2)))
+ (middle-bit (expt 2 middle-pos))
+ (insert-bmp (make-vector w2 (* 3 middle-bit))))
+ (define-fringe-bitmap 'diff-hl-bmp-delete (make-vector 2 delete-row) w2 w2)
+ (aset insert-bmp 0 0)
+ (aset insert-bmp middle-pos delete-row)
+ (aset insert-bmp (1+ middle-pos) delete-row)
+ (aset insert-bmp (1- w2) 0)
+ (define-fringe-bitmap 'diff-hl-bmp-insert insert-bmp w2 w2)
+ )))
+
+(defun diff-hl-maybe-define-bitmaps ()
+ (when (window-system) ;; No fringes in the console.
+ (unless (fringe-bitmap-p 'diff-hl-bmp-empty)
+ (diff-hl-define-bitmaps)
+ (define-fringe-bitmap 'diff-hl-bmp-empty [0] 1 1 'center))))
+
+(defun diff-hl-maybe-redefine-bitmaps ()
+ (when (window-system)
+ (diff-hl-define-bitmaps)))
+
+(defvar diff-hl-spec-cache (make-hash-table :test 'equal))
+
+(defun diff-hl-fringe-spec (type pos side)
+ (let* ((key (list type pos side
+ diff-hl-fringe-face-function
+ diff-hl-fringe-bmp-function))
+ (val (gethash key diff-hl-spec-cache)))
+ (unless val
+ (let* ((face-sym (funcall diff-hl-fringe-face-function type pos))
+ (bmp-sym (funcall diff-hl-fringe-bmp-function type pos)))
+ (setq val (propertize " " 'display `((,(intern (format "%s-fringe" side))
+ ,bmp-sym ,face-sym))))
+ (puthash key val diff-hl-spec-cache)))
+ val))
+
+(defun diff-hl-fringe-face-from-type (type _pos)
+ (intern (format "diff-hl-%s" type)))
+
+(defun diff-hl-fringe-bmp-from-pos (_type pos)
+ (intern (format "diff-hl-bmp-%s" pos)))
+
+(defun diff-hl-fringe-bmp-from-type (type _pos)
+ (cl-case type
+ (unknown 'question-mark)
+ (change 'exclamation-mark)
+ (ignored 'diff-hl-bmp-i)
+ (t (intern (format "diff-hl-bmp-%s" type)))))
+
+(defvar vc-svn-diff-switches)
+(defvar vc-fossil-diff-switches)
+
+(defmacro diff-hl-with-diff-switches (body)
+ `(let ((vc-git-diff-switches
+ ;; https://github.com/dgutov/diff-hl/issues/67
+ (cons "-U0"
+ ;; https://github.com/dgutov/diff-hl/issues/9
+ (and (boundp 'vc-git-diff-switches)
+ (listp vc-git-diff-switches)
+ (cl-remove-if-not
+ (lambda (arg)
+ (member arg '("--histogram" "--patience" "--minimal")))
+ vc-git-diff-switches))))
+ (vc-hg-diff-switches nil)
+ (vc-svn-diff-switches nil)
+ (vc-fossil-diff-switches '("-c" "0"))
+ (vc-diff-switches '("-U0"))
+ ,@(when (boundp 'vc-disable-async-diff)
+ '((vc-disable-async-diff t))))
+ ,body))
+
+(defun diff-hl-modified-p (state)
+ (or (memq state '(edited conflict))
+ (and (eq state 'up-to-date)
+ ;; VC state is stale in after-revert-hook.
+ (or revert-buffer-in-progress-p
+ ;; Diffing against an older revision.
+ diff-hl-reference-revision))))
+
+(declare-function vc-git-command "vc-git")
+
+(defun diff-hl-changes-buffer (file backend)
+ (diff-hl-with-diff-switches
+ (diff-hl-diff-against-reference file backend " *diff-hl* ")))
+
+(defun diff-hl-diff-against-reference (file backend buffer)
+ (if (and (eq backend 'Git)
+ (not diff-hl-reference-revision)
+ (not diff-hl-show-staged-changes))
+ (apply #'vc-git-command buffer 1
+ (list file)
+ "diff-files"
+ (cons "-p" (vc-switches 'git 'diff)))
+ (condition-case err
+ (vc-call-backend backend 'diff (list file)
+ diff-hl-reference-revision nil
+ buffer)
+ (error
+ ;; https://github.com/dgutov/diff-hl/issues/117
+ (when (string-match-p "\\`Failed (status 128)" (error-message-string err))
+ (vc-call-backend backend 'diff (list file)
+ "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
+ nil
+ buffer)))))
+ buffer)
+
+(defun diff-hl-changes ()
+ (let* ((file buffer-file-name)
+ (backend (vc-backend file)))
+ (when backend
+ (let ((state (vc-state file backend)))
+ (cond
+ ((diff-hl-modified-p state)
+ (diff-hl-changes-from-buffer
+ (diff-hl-changes-buffer file backend)))
+ ((eq state 'added)
+ `((1 ,(line-number-at-pos (point-max)) insert)))
+ ((eq state 'removed)
+ `((1 ,(line-number-at-pos (point-max)) delete))))))))
+
+(defun diff-hl-changes-from-buffer (buf)
+ (with-current-buffer buf
+ (let (res)
+ (goto-char (point-min))
+ (unless (eobp)
+ ;; TODO: When 27.1 is the minimum requirement, we can drop
+ ;; these bindings: that version, in addition to switching over
+ ;; to the diff-refine var, also added the
+ ;; called-interactively-p check, so refinement can't be
+ ;; triggered by code calling the navigation functions, only by
+ ;; direct interactive invocations.
+ (ignore-errors
+ (with-no-warnings
+ (let (diff-auto-refine-mode)
+ (diff-beginning-of-hunk t))))
+ (while (looking-at diff-hunk-header-re-unified)
+ (let ((line (string-to-number (match-string 3)))
+ (len (let ((m (match-string 4)))
+ (if m (string-to-number m) 1)))
+ (beg (point)))
+ (with-no-warnings
+ (let (diff-auto-refine-mode)
+ (diff-end-of-hunk)))
+ (let* ((inserts (diff-count-matches "^\\+" beg (point)))
+ (deletes (diff-count-matches "^-" beg (point)))
+ (type (cond ((zerop deletes) 'insert)
+ ((zerop inserts) 'delete)
+ (t 'change))))
+ (when (eq type 'delete)
+ (setq len 1)
+ (cl-incf line))
+ (push (list line len type) res)))))
+ (nreverse res))))
+
+(defun diff-hl-update ()
+ (let ((changes (diff-hl-changes))
+ (current-line 1))
+ (diff-hl-remove-overlays)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (dolist (c changes)
+ (cl-destructuring-bind (line len type) c
+ (forward-line (- line current-line))
+ (setq current-line line)
+ (let ((hunk-beg (point)))
+ (while (cl-plusp len)
+ (diff-hl-add-highlighting
+ type
+ (cond
+ ((not diff-hl-draw-borders) 'empty)
+ ((and (= len 1) (= line current-line)) 'single)
+ ((= len 1) 'bottom)
+ ((= line current-line) 'top)
+ (t 'middle)))
+ (forward-line 1)
+ (cl-incf current-line)
+ (cl-decf len))
+ (let ((h (make-overlay hunk-beg (point)))
+ (hook '(diff-hl-overlay-modified)))
+ (overlay-put h 'diff-hl t)
+ (overlay-put h 'diff-hl-hunk t)
+ (overlay-put h 'diff-hl-hunk-type type)
+ (overlay-put h 'modification-hooks hook)
+ (overlay-put h 'insert-in-front-hooks hook)
+ (overlay-put h 'insert-behind-hooks hook)))))))))
+
+(defvar-local diff-hl--modified-tick nil)
+
+(put 'diff-hl--modified-tick 'permanent-local t)
+
+(defun diff-hl-update-once ()
+ (unless (equal diff-hl--modified-tick (buffer-chars-modified-tick))
+ (diff-hl-update)
+ (setq diff-hl--modified-tick (buffer-chars-modified-tick))))
+
+(defun diff-hl-add-highlighting (type shape)
+ (let ((o (make-overlay (point) (point))))
+ (overlay-put o 'diff-hl t)
+ (funcall diff-hl-highlight-function o type shape)
+ o))
+
+(defun diff-hl-highlight-on-fringe (ovl type shape)
+ (overlay-put ovl 'before-string (diff-hl-fringe-spec type shape
+ diff-hl-side)))
+
+(defun diff-hl-remove-overlays (&optional beg end)
+ (save-restriction
+ (widen)
+ (dolist (o (overlays-in (or beg (point-min)) (or end (point-max))))
+ (when (overlay-get o 'diff-hl) (delete-overlay o)))))
+
+(defun diff-hl-overlay-modified (ov after-p _beg _end &optional _length)
+ "Delete the hunk overlay and all our line overlays inside it."
+ (unless after-p
+ (when (overlay-buffer ov)
+ (diff-hl-remove-overlays (overlay-start ov) (overlay-end ov))
+ (delete-overlay ov))))
+
+(defvar diff-hl-timer nil)
+
+(defun diff-hl-edit (_beg _end _len)
+ "DTRT when we've `undo'-ne the buffer into unmodified state."
+ (when undo-in-progress
+ (when diff-hl-timer
+ (cancel-timer diff-hl-timer))
+ (setq diff-hl-timer
+ (run-with-idle-timer 0.01 nil #'diff-hl-after-undo (current-buffer)))))
+
+(defun diff-hl-after-undo (buffer)
+ (with-current-buffer buffer
+ (unless (buffer-modified-p)
+ (diff-hl-update))))
+
+(defun diff-hl-after-revert ()
+ (defvar revert-buffer-preserve-modes)
+ (when revert-buffer-preserve-modes
+ (diff-hl-update)))
+
+(defun diff-hl-diff-goto-hunk-1 (historic)
+ (defvar vc-sentinel-movepoint)
+ (vc-buffer-sync)
+ (let* ((line (line-number-at-pos))
+ (buffer (current-buffer))
+ (rev1 diff-hl-reference-revision)
+ rev2)
+ (when historic
+ (let ((revs (diff-hl-diff-read-revisions rev1)))
+ (setq rev1 (car revs)
+ rev2 (cdr revs))))
+ (vc-diff-internal t (vc-deduce-fileset) rev1 rev2 t)
+ (vc-run-delayed (if (< (line-number-at-pos (point-max)) 3)
+ (with-current-buffer buffer (diff-hl-remove-overlays))
+ (when (or (not rev2) diff-hl-goto-hunk-old-revisions)
+ (diff-hl-diff-skip-to line))
+ (setq vc-sentinel-movepoint (point))))))
+
+(defun diff-hl-diff-goto-hunk (&optional historic)
+ "Run VC diff command and go to the line corresponding to the current."
+ (interactive (list current-prefix-arg))
+ (with-current-buffer (or (buffer-base-buffer) (current-buffer))
+ (diff-hl-diff-goto-hunk-1 historic)))
+
+(defun diff-hl-diff-read-revisions (rev1-default)
+ (let* ((file buffer-file-name)
+ (files (list file))
+ (backend (vc-backend file))
+ (rev2-default nil))
+ (cond
+ ;; if the file is not up-to-date, use working revision as older revision
+ ((not (vc-up-to-date-p file))
+ (setq rev1-default
+ (or rev1-default
+ (vc-working-revision file))))
+ ((not rev1-default)
+ (setq rev1-default (ignore-errors ;If `previous-revision' doesn't work.
+ (vc-call-backend backend 'previous-revision file
+ (vc-working-revision file))))
+ (when (string= rev1-default "") (setq rev1-default nil))))
+ ;; finally read the revisions
+ (let* ((rev1-prompt (if rev1-default
+ (concat "Older revision (default "
+ rev1-default "): ")
+ "Older revision: "))
+ (rev2-prompt (concat "Newer revision (default "
+ (or rev2-default "current source") "): "))
+ (rev1 (vc-read-revision rev1-prompt files backend rev1-default))
+ (rev2 (vc-read-revision rev2-prompt files backend rev2-default)))
+ (when (string= rev1 "") (setq rev1 nil))
+ (when (string= rev2 "") (setq rev2 nil))
+ (cons rev1 rev2))))
+
+(defun diff-hl-diff-skip-to (line)
+ "In `diff-mode', skip to the hunk and line corresponding to LINE
+in the source file, or the last line of the hunk above it."
+ (goto-char (point-min)) ; Counteract any similar behavior in diff-mode.
+ (diff-hunk-next)
+ (let (found)
+ (while (and (looking-at diff-hunk-header-re-unified) (not found))
+ (let ((hunk-line (string-to-number (match-string 3)))
+ (len (let ((m (match-string 4)))
+ (if m (string-to-number m) 1))))
+ (if (> line (+ hunk-line len))
+ (diff-hunk-next)
+ (setq found t)
+ (if (< line hunk-line)
+ ;; Retreat to the previous hunk.
+ (forward-line -1)
+ (let ((to-go (1+ (- line hunk-line))))
+ (while (cl-plusp to-go)
+ (forward-line 1)
+ (unless (looking-at "^-")
+ (cl-decf to-go))))))))))
+
+(defface diff-hl-reverted-hunk-highlight
+ '((default :inverse-video t))
+ "Face used to highlight the first column of the hunk to be reverted.")
+
+(defun diff-hl-revert-highlight-first-column (end)
+ (re-search-forward "^[+-]")
+ (forward-line 0)
+ (setq end (diff-hl-split-away-changes 0))
+ (let ((inhibit-read-only t))
+ (save-excursion
+ (while (< (point) end)
+ (font-lock-prepend-text-property (point) (1+ (point)) 'font-lock-face
+ 'diff-hl-reverted-hunk-highlight)
+ (forward-line 1)))))
+
+(defun diff-hl-revert-narrow-to-hunk (end)
+ (narrow-to-region (point) end))
+
+(defun diff-hl-revert-hunk-1 ()
+ (save-restriction
+ (widen)
+ (vc-buffer-sync)
+ (let* ((diff-buffer (get-buffer-create
+ (generate-new-buffer-name "*diff-hl*")))
+ (buffer (current-buffer))
+ (line (save-excursion
+ (diff-hl-find-current-hunk)
+ (line-number-at-pos)))
+ (file buffer-file-name)
+ (backend (vc-backend file)))
+ (unwind-protect
+ (progn
+ (vc-setup-buffer diff-buffer)
+ (diff-hl-diff-against-reference file backend diff-buffer)
+ (set-buffer diff-buffer)
+ (diff-mode)
+ (setq-local diff-vc-backend backend)
+ (setq-local diff-vc-revisions (list diff-hl-reference-revision nil))
+ (setq buffer-read-only t)
+ (pop-to-buffer diff-buffer)
+ (vc-run-delayed
+ (vc-diff-finish diff-buffer nil)
+ (let (beg-line end-line m-beg m-end)
+ (when (eobp)
+ (with-current-buffer buffer (diff-hl-remove-overlays))
+ (user-error "Buffer is up-to-date"))
+ (with-no-warnings
+ (let (diff-auto-refine-mode)
+ (diff-hl-diff-skip-to line)))
+ (setq m-end (diff-hl-split-away-changes 3))
+ (setq m-beg (point-marker))
+ (funcall diff-hl-highlight-revert-hunk-function m-end)
+ (setq beg-line (line-number-at-pos m-beg)
+ end-line (line-number-at-pos m-end))
+ (let ((wbh (window-body-height)))
+ (if (>= wbh (- end-line beg-line))
+ (recenter (/ (+ wbh (- beg-line end-line) 2) 2))
+ (recenter 1)))
+ (with-no-warnings
+ (when diff-auto-refine-mode
+ (diff-refine-hunk)))
+ (if diff-hl-ask-before-revert-hunk
+ (unless (yes-or-no-p (format "Revert current hunk in %s? "
+ file))
+ (user-error "Revert canceled")))
+ (let ((diff-advance-after-apply-hunk nil))
+ (save-window-excursion
+ (diff-apply-hunk t)))
+ (with-current-buffer buffer
+ (save-buffer))
+ (message "Hunk reverted"))))
+ (quit-windows-on diff-buffer t)))))
+
+(defun diff-hl-split-away-changes (max-context)
+ "Split away the minimal hunk at point from the rest of the hunk.
+
+The minimal hunk is the hunk a diff program would produce if
+asked for 0 lines of context. Add MAX-CONTEXT lines of context at
+most (stop when encounter another minimal hunk).
+
+Move point to the beginning of the delineated hunk and return
+its end position."
+ (let (end-marker)
+ (save-excursion
+ (while (looking-at "[-+]") (forward-line 1))
+ (dotimes (_i max-context)
+ (unless (looking-at "@\\|[-+]")
+ (forward-line 1)))
+ (setq end-marker (point-marker))
+ (unless (or (eobp)
+ (looking-at "@"))
+ (diff-split-hunk)))
+ (unless (looking-at "[-+]") (forward-line -1))
+ (while (looking-at "[-+]") (forward-line -1))
+ (dotimes (_i max-context)
+ (unless (looking-at "@\\|[-+]")
+ (forward-line -1)))
+ (unless (looking-at "@")
+ (forward-line 1)
+ (diff-split-hunk))
+ end-marker))
+
+(defun diff-hl-revert-hunk ()
+ "Revert the diff hunk with changes at or above the point."
+ (interactive)
+ (with-current-buffer (or (buffer-base-buffer) (current-buffer))
+ (diff-hl-revert-hunk-1)))
+
+(defun diff-hl-hunk-overlay-at (pos)
+ (cl-loop for o in (overlays-in pos (1+ pos))
+ when (overlay-get o 'diff-hl-hunk)
+ return o))
+
+(defun diff-hl-search-next-hunk (&optional backward point)
+ "Search the next hunk in the current buffer, or previous if BACKWARD."
+ (save-excursion
+ (when point
+ (goto-char point))
+ (catch 'found
+ (while (not (if backward (bobp) (eobp)))
+ (goto-char (if backward
+ (previous-overlay-change (point))
+ (next-overlay-change (point))))
+ (let ((o (diff-hl-hunk-overlay-at (point))))
+ (when (and o (= (overlay-start o) (point)))
+ (throw 'found o)))))))
+
+(defun diff-hl-next-hunk (&optional backward)
+ "Go to the beginning of the next hunk in the current buffer."
+ (interactive)
+ (let ((overlay (diff-hl-search-next-hunk backward)))
+ (if overlay
+ (goto-char (overlay-start overlay))
+ (user-error "No further hunks found"))))
+
+(defun diff-hl-previous-hunk ()
+ "Go to the beginning of the previous hunk in the current buffer."
+ (interactive)
+ (diff-hl-next-hunk t))
+
+(defun diff-hl-find-current-hunk ()
+ (let (o)
+ (cond
+ ((diff-hl-hunk-overlay-at (point)))
+ ((setq o (diff-hl-search-next-hunk t))
+ (goto-char (overlay-start o)))
+ (t
+ (diff-hl-next-hunk)))))
+
+(defun diff-hl-mark-hunk ()
+ (interactive)
+ (let ((hunk (diff-hl-hunk-overlay-at (point))))
+ (unless hunk
+ (user-error "No hunk at point"))
+ (goto-char (overlay-start hunk))
+ (push-mark (overlay-end hunk) nil t)))
+
+(defun diff-hl--ensure-staging-supported ()
+ (let ((backend (vc-backend buffer-file-name)))
+ (unless (eq backend 'Git)
+ (user-error "Only Git supports staging; this file is controlled by %s" backend))))
+
+(defun diff-hl-stage-current-hunk ()
+ "Stage the hunk at or near point.
+
+Only supported with Git."
+ (interactive)
+ (diff-hl--ensure-staging-supported)
+ (diff-hl-find-current-hunk)
+ (let* ((line (line-number-at-pos))
+ (file buffer-file-name)
+ (dest-buffer (get-buffer-create " *diff-hl-stage*"))
+ (orig-buffer (current-buffer))
+ (file-base (shell-quote-argument (file-name-nondirectory file)))
+ success)
+ (with-current-buffer dest-buffer
+ (let ((inhibit-read-only t))
+ (erase-buffer)))
+ (diff-hl-diff-buffer-with-reference file dest-buffer nil 3)
+ (with-current-buffer dest-buffer
+ (with-no-warnings
+ (let (diff-auto-refine-mode)
+ (diff-hl-diff-skip-to line)))
+ (let ((inhibit-read-only t))
+ (diff-hl-split-away-changes 3)
+ (save-excursion
+ (diff-end-of-hunk)
+ (delete-region (point) (point-max)))
+ (diff-beginning-of-hunk)
+ (delete-region (point-min) (point))
+ ;; diff-no-select creates a very ugly header; Git rejects it
+ (insert (format "diff a/%s b/%s\n" file-base file-base))
+ (insert (format "--- a/%s\n" file-base))
+ (insert (format "+++ b/%s\n" file-base)))
+ (let ((patchfile (make-temp-file "diff-hl-stage-patch")))
+ (write-region (point-min) (point-max) patchfile
+ nil 'silent)
+ (unwind-protect
+ (with-current-buffer orig-buffer
+ (with-output-to-string
+ (vc-git-command standard-output 0
+ patchfile
+ "apply" "--cached" ))
+ (setq success t))
+ (delete-file patchfile))))
+ (when success
+ (if diff-hl-show-staged-changes
+ (message (concat "Hunk staged; customize `diff-hl-show-staged-changes'"
+ " to highlight only unstages changes"))
+ (message "Hunk staged"))
+ (unless diff-hl-show-staged-changes
+ (diff-hl-update)))))
+
+(defun diff-hl-unstage-file ()
+ "Unstage all changes in the current file.
+
+Only supported with Git."
+ (interactive)
+ (unless buffer-file-name
+ (user-error "No current file"))
+ (diff-hl--ensure-staging-supported)
+ (vc-git-command nil 0 buffer-file-name "reset")
+ (message "Unstaged all")
+ (unless diff-hl-show-staged-changes
+ (diff-hl-update)))
+
+(defvar diff-hl-command-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "n" 'diff-hl-revert-hunk)
+ (define-key map "[" 'diff-hl-previous-hunk)
+ (define-key map "]" 'diff-hl-next-hunk)
+ (define-key map "*" 'diff-hl-show-hunk)
+ (define-key map "{" 'diff-hl-show-hunk-previous)
+ (define-key map "}" 'diff-hl-show-hunk-next)
+ (define-key map "S" 'diff-hl-stage-current-hunk)
+ map))
+(fset 'diff-hl-command-map diff-hl-command-map)
+
+(defvar diff-hl-lighter ""
+ "Mode line lighter for Diff Hl.
+
+The value of this variable is a mode line template as in
+`mode-line-format'.")
+
+;;;###autoload
+(define-minor-mode diff-hl-mode
+ "Toggle VC diff highlighting."
+ :lighter diff-hl-lighter
+ :keymap `(([remap vc-diff] . diff-hl-diff-goto-hunk)
+ (,diff-hl-command-prefix . diff-hl-command-map))
+ (if diff-hl-mode
+ (progn
+ (diff-hl-maybe-define-bitmaps)
+ (add-hook 'after-save-hook 'diff-hl-update nil t)
+ (add-hook 'after-change-functions 'diff-hl-edit nil t)
+ (add-hook (if vc-mode
+ ;; Defer until the end of this hook, so that its
+ ;; elements can modify the update behavior.
+ 'diff-hl-mode-on-hook
+ ;; If we're only opening the file now,
+ ;; `vc-find-file-hook' likely hasn't run yet, so
+ ;; let's wait until the state information is
+ ;; saved, in order not to fetch it twice.
+ 'find-file-hook)
+ 'diff-hl-update-once t t)
+ ;; Never removed because it acts globally.
+ (add-hook 'vc-checkin-hook 'diff-hl-after-checkin)
+ (add-hook 'after-revert-hook 'diff-hl-after-revert nil t)
+ ;; Magit does call `auto-revert-handler', but it usually
+ ;; doesn't do much, because `buffer-stale--default-function'
+ ;; doesn't care about changed VC state.
+ ;; https://github.com/magit/magit/issues/603
+ (add-hook 'magit-revert-buffer-hook 'diff-hl-update nil t)
+ ;; Magit versions 2.0-2.3 don't do the above and call this
+ ;; instead, but only when they don't call `revert-buffer':
+ (add-hook 'magit-not-reverted-hook 'diff-hl-update nil t)
+ (add-hook 'text-scale-mode-hook 'diff-hl-maybe-redefine-bitmaps nil t))
+ (remove-hook 'after-save-hook 'diff-hl-update t)
+ (remove-hook 'after-change-functions 'diff-hl-edit t)
+ (remove-hook 'find-file-hook 'diff-hl-update t)
+ (remove-hook 'after-revert-hook 'diff-hl-update t)
+ (remove-hook 'magit-revert-buffer-hook 'diff-hl-update t)
+ (remove-hook 'magit-not-reverted-hook 'diff-hl-update t)
+ (remove-hook 'text-scale-mode-hook 'diff-hl-maybe-redefine-bitmaps t)
+ (diff-hl-remove-overlays)))
+
+(defun diff-hl-after-checkin ()
+ (let ((fileset (vc-deduce-fileset t)))
+ (dolist (file (nth 1 fileset))
+ (let ((buf (find-buffer-visiting file)))
+ (when buf
+ (with-current-buffer buf
+ (when diff-hl-mode
+ (diff-hl-update))))))))
+
+(defvar diff-hl-repeat-exceptions '(diff-hl-show-hunk
+ diff-hl-show-hunk-previous
+ diff-hl-show-hunk-next))
+
+(when (require 'smartrep nil t)
+ (let (smart-keys)
+ (cl-labels ((scan (map)
+ (map-keymap
+ (lambda (event binding)
+ (if (consp binding)
+ (scan binding)
+ (when (and (characterp event)
+ (not (memq binding diff-hl-repeat-exceptions)))
+ (push (cons (string event) binding) smart-keys))))
+ map)))
+ (scan diff-hl-command-map)
+ (smartrep-define-key diff-hl-mode-map diff-hl-command-prefix smart-keys))))
+
+;; Integrate with `repeat-mode' in Emacs 28 (https://debbugs.gnu.org/47566)
+;;
+;; While smartrep feels solid, it looks kinda abandoned. And the
+;; chances of it being put into GNU ELPA are slim too.
+(map-keymap
+ (lambda (_key cmd)
+ (unless (memq cmd diff-hl-repeat-exceptions)
+ (put cmd 'repeat-map 'diff-hl-command-map)))
+ diff-hl-command-map)
+
+(declare-function magit-toplevel "magit-git")
+(declare-function magit-unstaged-files "magit-git")
+
+(defvar diff-hl--magit-unstaged-files nil)
+
+(defun diff-hl-magit-pre-refresh ()
+ (unless (and diff-hl-disable-on-remote
+ (file-remote-p default-directory))
+ (setq diff-hl--magit-unstaged-files (magit-unstaged-files t))))
+
+(defun diff-hl-magit-post-refresh ()
+ (unless (and diff-hl-disable-on-remote
+ (file-remote-p default-directory))
+ (let* ((topdir (magit-toplevel))
+ (modified-files
+ (mapcar (lambda (file) (expand-file-name file topdir))
+ (delete-consecutive-dups
+ (sort
+ (nconc (magit-unstaged-files t)
+ diff-hl--magit-unstaged-files)
+ #'string<))))
+ (unmodified-states '(up-to-date ignored unregistered)))
+ (setq diff-hl--magit-unstaged-files nil)
+ (dolist (buf (buffer-list))
+ (when (and (buffer-local-value 'diff-hl-mode buf)
+ (not (buffer-modified-p buf))
+ ;; Solve the "cloned indirect buffer" problem
+ ;; (diff-hl-mode could be non-nil there, even if
+ ;; buffer-file-name is nil):
+ (buffer-file-name buf)
+ (file-in-directory-p (buffer-file-name buf) topdir)
+ (file-exists-p (buffer-file-name buf)))
+ (with-current-buffer buf
+ (let* ((file buffer-file-name)
+ (backend (vc-backend file)))
+ (when backend
+ (cond
+ ((member file modified-files)
+ (when (memq (vc-state file) unmodified-states)
+ (vc-state-refresh file backend))
+ (diff-hl-update))
+ ((not (memq (vc-state file backend) unmodified-states))
+ (vc-state-refresh file backend)
+ (diff-hl-update)))))))))))
+
+(defun diff-hl-dir-update ()
+ (dolist (pair (if (vc-dir-marked-files)
+ (vc-dir-marked-only-files-and-states)
+ (vc-dir-child-files-and-states)))
+ (when (eq 'up-to-date (cdr pair))
+ (let ((buffer (find-buffer-visiting (car pair))))
+ (when buffer
+ (with-current-buffer buffer
+ (diff-hl-remove-overlays)))))))
+
+(define-minor-mode diff-hl-dir-mode
+ "Toggle `diff-hl-mode' integration in a `vc-dir-mode' buffer."
+ :lighter ""
+ (if diff-hl-dir-mode
+ (add-hook 'vc-checkin-hook 'diff-hl-dir-update t t)
+ (remove-hook 'vc-checkin-hook 'diff-hl-dir-update t)))
+
+(defun diff-hl-make-temp-file-name (file rev &optional manual)
+ "Return a backup file name for REV or the current version of FILE.
+If MANUAL is non-nil it means that a name for backups created by
+the user should be returned."
+ (let* ((auto-save-file-name-transforms
+ `((".*" ,temporary-file-directory t)))
+ (buffer-file-name file))
+ (expand-file-name
+ (concat (make-auto-save-file-name)
+ ".~" (subst-char-in-string
+ ?/ ?_ rev)
+ (unless manual ".") "~")
+ temporary-file-directory)))
+
+(defun diff-hl-create-revision (file revision)
+ "Read REVISION of FILE into a buffer and return the buffer."
+ (let ((automatic-backup (diff-hl-make-temp-file-name file revision))
+ (filebuf (get-file-buffer file))
+ (filename (diff-hl-make-temp-file-name file revision 'manual)))
+ (unless (file-exists-p filename)
+ (if (file-exists-p automatic-backup)
+ (rename-file automatic-backup filename nil)
+ (with-current-buffer filebuf
+ (let ((coding-system-for-read 'no-conversion)
+ (coding-system-for-write 'no-conversion))
+ (condition-case nil
+ (with-temp-file filename
+ (let ((outbuf (current-buffer)))
+ ;; Change buffer to get local value of
+ ;; vc-checkout-switches.
+ (with-current-buffer filebuf
+ (vc-call find-revision file revision outbuf))))
+ (error
+ (when (file-exists-p filename)
+ (delete-file filename))))))))
+ filename))
+
+(defun diff-hl-working-revision (file &optional backend)
+ "Like vc-working-revision, but always up-to-date"
+ (vc-file-setprop file 'vc-working-revision
+ (vc-call-backend (or backend (vc-backend file))
+ 'working-revision file)))
+
+(declare-function diff-no-select "diff")
+
+(defun diff-hl-diff-buffer-with-reference (file &optional dest-buffer backend context-lines)
+ "Compute the diff between the current buffer contents and reference in BACKEND.
+The diffs are computed in the buffer DEST-BUFFER. This requires
+the `diff-program' to be in your `exec-path'.
+CONTEXT-LINES is the size of the unified diff context, defaults to 0."
+ (require 'diff)
+ (vc-ensure-vc-buffer)
+ (save-current-buffer
+ (let* ((dest-buffer (or dest-buffer "*diff-hl-diff-buffer-with-reference*"))
+ (backend (or backend (vc-backend file)))
+ (temporary-file-directory
+ (if (file-directory-p "/dev/shm/")
+ "/dev/shm/"
+ temporary-file-directory))
+ (rev
+ (if (and (eq backend 'Git)
+ (not diff-hl-reference-revision)
+ (not diff-hl-show-staged-changes))
+ (diff-hl-git-index-revision
+ file
+ (diff-hl-git-index-object-name file))
+ (diff-hl-create-revision
+ file
+ (or diff-hl-reference-revision
+ (diff-hl-working-revision file backend)))))
+ (switches (format "-U %d --strip-trailing-cr" (or context-lines 0))))
+ (diff-no-select rev (current-buffer) switches 'noasync
+ (get-buffer-create dest-buffer))
+ (with-current-buffer dest-buffer
+ (let ((inhibit-read-only t))
+ ;; Function `diff-sentinel' adds a final line, so remove it
+ (delete-matching-lines "^Diff finished.*")))
+ (get-buffer-create dest-buffer))))
+
+;; TODO: Cache based on .git/index's mtime, maybe.
+(defun diff-hl-git-index-object-name (file)
+ (with-temp-buffer
+ (vc-git-command (current-buffer) 0 file "ls-files" "-s")
+ (and
+ (goto-char (point-min))
+ (re-search-forward "^[0-9]+ \\([0-9a-f]+\\)")
+ (match-string-no-properties 1))))
+
+(defun diff-hl-git-index-revision (file object-name)
+ (let ((filename (diff-hl-make-temp-file-name file
+ (concat ":" object-name)
+ 'manual))
+ (filebuf (get-file-buffer file)))
+ (unless (file-exists-p filename)
+ (with-current-buffer filebuf
+ (let ((coding-system-for-read 'no-conversion)
+ (coding-system-for-write 'no-conversion))
+ (condition-case nil
+ (with-temp-file filename
+ (let ((outbuf (current-buffer)))
+ ;; Change buffer to be inside the repo.
+ (with-current-buffer filebuf
+ (vc-git-command outbuf 0 nil
+ "cat-file" "blob" object-name))))
+ (error
+ (when (file-exists-p filename)
+ (delete-file filename)))))))
+ filename))
+
+;;;###autoload
+(defun turn-on-diff-hl-mode ()
+ "Turn on `diff-hl-mode' or `diff-hl-dir-mode' in a buffer if appropriate."
+ (cond
+ (buffer-file-name
+ (unless (and diff-hl-disable-on-remote
+ (file-remote-p buffer-file-name))
+ (diff-hl-mode 1)))
+ ((eq major-mode 'vc-dir-mode)
+ (diff-hl-dir-mode 1))))
+
+;;;###autoload
+(defun diff-hl--global-turn-on ()
+ "Call `turn-on-diff-hl-mode' if the current major mode is applicable."
+ (when (cond ((eq diff-hl-global-modes t)
+ t)
+ ((eq (car-safe diff-hl-global-modes) 'not)
+ (not (memq major-mode (cdr diff-hl-global-modes))))
+ (t (memq major-mode diff-hl-global-modes)))
+ (turn-on-diff-hl-mode)))
+
+(declare-function vc-annotate-extract-revision-at-line "vc-annotate")
+(declare-function diff-hl-amend-mode "diff-hl-amend")
+
+;;;###autoload
+(defun diff-hl-set-reference-rev (rev)
+ "Set the reference revision globally to REV.
+When called interactively, REV read with completion.
+
+The default value chosen using one of methods below:
+
+- In a log view buffer, it uses the revision of current entry.
+Call `vc-print-log' or `vc-print-root-log' first to open a log
+view buffer.
+- In a VC annotate buffer, it uses the revision of current line.
+- In other situations, it uses the symbol at point.
+
+Notice that this sets the reference revision globally, so in
+files from other repositories, `diff-hl-mode' will not highlight
+changes correctly, until you run `diff-hl-reset-reference-rev'.
+
+Also notice that this will disable `diff-hl-amend-mode' in
+buffers that enables it, since `diff-hl-amend-mode' overrides its
+effect."
+ (interactive
+ (let* ((def (or (and (equal major-mode 'vc-annotate-mode)
+ (car (vc-annotate-extract-revision-at-line)))
+ (log-view-current-tag)
+ (thing-at-point 'symbol t)))
+ (prompt (if def
+ (format "Reference revision (default %s): " def)
+ "Reference revision: ")))
+ (list (vc-read-revision prompt nil nil def))))
+ (if rev
+ (message "Set reference revision to %s" rev)
+ (user-error "No reference revision specified"))
+ (setq diff-hl-reference-revision rev)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when diff-hl-mode
+ (when (bound-and-true-p diff-hl-amend-mode)
+ (diff-hl-amend-mode -1))
+ (diff-hl-update)))))
+
+;;;###autoload
+(defun diff-hl-reset-reference-rev ()
+ "Reset the reference revision globally to the most recent one."
+ (interactive)
+ (setq diff-hl-reference-revision nil)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when diff-hl-mode
+ (diff-hl-update)))))
+
+;;;###autoload
+(define-globalized-minor-mode global-diff-hl-mode diff-hl-mode
+ diff-hl--global-turn-on :after-hook (diff-hl-global-mode-change))
+
+(defun diff-hl-global-mode-change ()
+ (unless global-diff-hl-mode
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when diff-hl-dir-mode
+ (diff-hl-dir-mode -1))))))
+
+(provide 'diff-hl)
+
+;;; diff-hl.el ends here
diff --git a/elpa/diff-hl-1.9.2/test/diff-hl-test.el b/elpa/diff-hl-1.9.2/test/diff-hl-test.el
@@ -0,0 +1,173 @@
+;;; diff-hl-test.el --- tests for diff-hl -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020, 2021 Free Software Foundation, Inc.
+
+;; Author: Nathan Moreau <nathan.moreau@m4x.org>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'diff-hl)
+(require 'subr-x) ;; string-trim
+(require 'ert)
+(require 'vc-git)
+
+(defvar diff-hl-test-source-file
+ (expand-file-name (concat (file-name-directory (locate-library "diff-hl"))
+ "test/empty")))
+
+(defvar diff-hl-test-initial-content nil)
+
+(defmacro diff-hl-test-in-source (&rest body)
+ `(save-window-excursion
+ (find-file diff-hl-test-source-file)
+ ,@body))
+(put 'diff-hl-test-in-source 'lisp-indent-function 0)
+
+(defun diff-hl-test-init ()
+ (diff-hl-test-in-source
+ (setq diff-hl-test-initial-content (buffer-string)))
+ t)
+
+(defun diff-hl-test-teardown ()
+ (diff-hl-test-in-source
+ (erase-buffer)
+ (insert diff-hl-test-initial-content)
+ (save-buffer)
+ (pcase (vc-backend buffer-file-name)
+ (`Git
+ (vc-git-command nil 0 buffer-file-name "reset"))
+ (`Hg
+ (vc-hg-command nil 0 buffer-file-name "revert")))))
+
+(defun diff-hl-test-compute-diff-lines ()
+ (diff-hl-test-in-source
+ (save-buffer)
+ (let ((vc-diff-switches "-w"))
+ (diff-hl-diff-goto-hunk))
+ (switch-to-buffer "*vc-diff*")
+ (let ((lines nil)
+ (previous-line (point-min)))
+ (goto-char (point-min))
+ (while (< (point) (point-max))
+ (forward-line 1)
+ (push (string-trim (buffer-substring-no-properties previous-line (point))) lines)
+ (setq previous-line (point)))
+ (delq nil (nreverse lines)))))
+
+(defmacro diff-hl-deftest (name &rest body)
+ `(ert-deftest ,name ()
+ (diff-hl-test-init)
+ (unwind-protect
+ (progn ,@body)
+ (diff-hl-test-teardown))))
+(put 'diff-hl-deftest 'lisp-indent-function 'defun)
+
+(diff-hl-deftest diff-hl-insert ()
+ (diff-hl-test-in-source
+ (goto-char (point-max))
+ (insert "added\n")
+ (should (equal "+added"
+ (car (last (diff-hl-test-compute-diff-lines)))))))
+
+(diff-hl-deftest diff-hl-remove ()
+ (diff-hl-test-in-source
+ (delete-region (point-min) (point-max))
+ (should (equal "-last line"
+ (car (last (diff-hl-test-compute-diff-lines)))))))
+
+(diff-hl-deftest diff-hl-indirect-buffer-insert ()
+ (diff-hl-test-in-source
+ (narrow-to-region (point-min) (point-max))
+ (goto-char (point-max))
+ (insert "added\n")
+ (should (equal "+added"
+ (car (last (diff-hl-test-compute-diff-lines)))))))
+
+(diff-hl-deftest diff-hl-indirect-buffer-remove ()
+ (diff-hl-test-in-source
+ (narrow-to-region (point-min) (point-max))
+ (goto-char (point-min))
+ (delete-region (point) (point-max))
+ (should (equal "-last line"
+ (car (last (diff-hl-test-compute-diff-lines)))))))
+
+(diff-hl-deftest diff-hl-indirect-buffer-move ()
+ (diff-hl-test-in-source
+ (narrow-to-region (point-min) (point-max))
+ (goto-char (point-min))
+ (kill-whole-line 3)
+ (goto-char (point-max))
+ (insert "added\n")
+ (save-buffer)
+ (diff-hl-mode 1)
+ (diff-hl-previous-hunk)
+ (should (looking-at "added"))
+ (diff-hl-previous-hunk)
+ (should (looking-at "function2"))
+ (should-error (diff-hl-previous-hunk) :type 'user-error)
+ (diff-hl-next-hunk)
+ (should (looking-at "added"))
+ (should-error (diff-hl-next-hunk) :type 'user-error)))
+
+(diff-hl-deftest diff-hl-can-ignore-staged-changes ()
+ (diff-hl-test-in-source
+ (goto-char (point-min))
+ (insert "new line 1\n")
+ (save-buffer)
+ (vc-git-command nil 0 buffer-file-name "add")
+ (goto-char (point-max))
+ (insert "new line 2\n")
+ (save-buffer)
+ (let ((diff-hl-show-staged-changes t))
+ (should
+ (equal (diff-hl-changes)
+ '((1 1 insert)
+ (12 1 insert)))))
+ (let ((diff-hl-show-staged-changes nil))
+ (should
+ (equal (diff-hl-changes)
+ '((12 1 insert)))))))
+
+(diff-hl-deftest diff-hl-flydiff-can-ignore-staged-changes ()
+ (diff-hl-test-in-source
+ (goto-char (point-min))
+ (insert "new line 1\n")
+ (save-buffer)
+ (vc-git-command nil 0 buffer-file-name "add")
+ (goto-char (point-max))
+ (insert "new line 2\n")
+ (let ((diff-hl-show-staged-changes t))
+ (should
+ (equal (diff-hl-changes-from-buffer
+ (diff-hl-diff-buffer-with-reference buffer-file-name))
+ '((1 1 insert)
+ (12 1 insert)))))
+ (let ((diff-hl-show-staged-changes nil))
+ (should
+ (equal (diff-hl-changes-from-buffer
+ (diff-hl-diff-buffer-with-reference buffer-file-name))
+ '((12 1 insert)))))))
+
+(defun diff-hl-run-tests ()
+ (ert-run-tests-batch))
+
+(provide 'diff-hl-test)
+
+;;; diff-hl-test.el ends here
diff --git a/elpa/diff-hl-1.9.2/test/empty b/elpa/diff-hl-1.9.2/test/empty
@@ -0,0 +1,10 @@
+function1 () {
+}
+
+function2 () {
+}
+
+function3 () {
+}
+
+last line
diff --git a/init.el b/init.el
@@ -330,6 +330,7 @@
'(global-auto-revert-mode t)
'(global-company-mode t)
'(global-corfu-mode t)
+ '(global-diff-hl-mode t)
'(help-window-select t)
'(ibuffer-mode-hook '(all-the-icons-ibuffer-mode))
'(ignored-local-variable-values '((sly-load-failed-fasl . ask)))
@@ -382,7 +383,7 @@
("melpa-stable" . "https://stable.melpa.org/packages/")
("melpa" . "https://melpa.org/packages/")))
'(package-selected-packages
- '(embark-consult embark all-the-icons-completion all-the-icons-ibuffer all-the-icons-dired sly-named-readtables sly-macrostep denote-refs denote-menu denote ox-epub ob-powershell powershell web-mode lexic editorconfig elfeed-tube-mpv elfeed-tube cider restclient-jq graphviz-dot-mode consult-eglot jq-mode ob-restclient restclient vterm deadgrep helpful pdf-tools paredit-menu paredit corfu sly eglot aggressive-indent project nov nhexl-mode elfeed magit yaml-mode json-mode lua-mode go-mode geiser-guile geiser org-contrib org ace-window expand-region consult marginalia uuidgen request diminish which-key))
+ '(diff-hl embark-consult embark all-the-icons-completion all-the-icons-ibuffer all-the-icons-dired sly-named-readtables sly-macrostep denote-refs denote-menu denote ox-epub ob-powershell powershell web-mode lexic editorconfig elfeed-tube-mpv elfeed-tube cider restclient-jq graphviz-dot-mode consult-eglot jq-mode ob-restclient restclient vterm deadgrep helpful pdf-tools paredit-menu paredit corfu sly eglot aggressive-indent project nov nhexl-mode elfeed magit yaml-mode json-mode lua-mode go-mode geiser-guile geiser org-contrib org ace-window expand-region consult marginalia uuidgen request diminish which-key))
'(pcomplete-ignore-case t t)
'(pixel-scroll-precision-mode t)
'(read-buffer-completion-ignore-case t)