34 changed files with 5678 additions and 10 deletions
@ -1 +1 @@ |
|||||
Subproject commit 84ec18dfc503bebd863ddce108ee4503c334b615 |
Subproject commit 0b075cf5e6ef05584ef6377e116e8d0fe1f8f788 |
||||
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
@ -0,0 +1 @@ |
|||||
|
doc/tags |
||||
@ -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>. |
||||
@ -0,0 +1,88 @@ |
|||||
|
# LaTeX-BoX |
||||
|
 |
||||
|
|
||||
|
## This plugin provides: |
||||
|
- Background compilation using latexmk. |
||||
|
- Completion for commands, environments, labels, bibtex entries, and inline maths. |
||||
|
- A simple table of contents improving the navigation of large files. |
||||
|
- Smart indentation. |
||||
|
- Highlight matching \begin/\end and \left\right pairs. |
||||
|
- Motion between \begin/\end and \left\right pairs with the % key. |
||||
|
- Motion through brackets/braces (with user-defined keys). |
||||
|
- Environment objects (e.g., select environement with "vie" or "vae"). |
||||
|
- Inline math objects (e.g., select inline math with "vi$" or "va$"). |
||||
|
- Folding of parts (part/chapter/section/etc) and environments. |
||||
|
- OmniCompletion for bibliography entries respects BibLaTeX's |
||||
|
`\addbibresource`, `\addglobalbib` and `\addsectionbib` commands. |
||||
|
- The table of contents functionality does not depend anymore on the assumption |
||||
|
that `\@writefile{toc}{\contentsline ...}` entries in the `*.aux` file always |
||||
|
occur at the start of some line. |
||||
|
- Completion of `\ref{...}` commands was completely rewritten. It is now able |
||||
|
to handle `\@newlabel{label}{{number}{page}...}` entries in the `*.aux` file |
||||
|
even if `number` or `page` contain arbitrary nested levels of braces. Labels |
||||
|
are additionally held in a cache per `*.aux` file, which is updated only if |
||||
|
the modification time of the file changes. |
||||
|
- The table of contents now opens files different from the one currently being |
||||
|
edited in a new buffer. (I actually think, that this behaviour was |
||||
|
implemented already, but I could not get it working.) To make this work, |
||||
|
LaTeX-Box is not loaded per buffer but globally. |
||||
|
|
||||
|
This plugins aims at being lightweight and simple. For more fully-fledged |
||||
|
plugins, see: |
||||
|
- LaTeX-Suite: vimscript#475 |
||||
|
- AutomaticTexPlugin: vimscript#2945 |
||||
|
|
||||
|
## Installation |
||||
|
### With gmarik vundle |
||||
|
_https://github.com/gmarik/vundle_ |
||||
|
|
||||
|
Add `Plugin 'LaTeX-Box-Team/LaTeX-Box'` to your ~/.vimrc and run |
||||
|
`:PluginInstall` in a vim buffer. Add `!` to the command to update. |
||||
|
|
||||
|
### With pathogen |
||||
|
_https://github.com/tpope/vim-pathogen_ |
||||
|
|
||||
|
Add the LaTeX-Box bundle to your bundle directory, for instance with `git |
||||
|
clone`. This will typically be enough: |
||||
|
|
||||
|
cd ~/.vim/bundle |
||||
|
git clone git://github.com/LaTeX-Box-Team/LaTeX-Box.git |
||||
|
|
||||
|
### Without a plugin manager |
||||
|
|
||||
|
Copy the directories to your `.vim/` folder. |
||||
|
|
||||
|
### Windows users |
||||
|
|
||||
|
Users working with (g)vim on Windows must have a Perl environment installed. |
||||
|
Such an environment can be downloaded at : http://strawberryperl.com/ |
||||
|
|
||||
|
### Installation Notes |
||||
|
|
||||
|
Make sure `filetype plugin on` is set in host `.vimrc`, else LaTeX-Box |
||||
|
will not load. |
||||
|
|
||||
|
Note that there are configurable global variables that can be put in the |
||||
|
`.vimrc`. These are documented, but as an example, one can have the |
||||
|
table of contents open as a horizontal split by utilizing this: |
||||
|
|
||||
|
~/.vimrc |
||||
|
... |
||||
|
if s:extfname ==? "tex" |
||||
|
... |
||||
|
let g:LatexBox_split_type="new" |
||||
|
... |
||||
|
endif |
||||
|
|
||||
|
## Mirror information |
||||
|
|
||||
|
This is mirrored on |
||||
|
|
||||
|
- http://www.vim.org/scripts/script.php?script_id=3109 |
||||
|
- https://launchpad.net/~vim-latex-box |
||||
|
|
||||
|
## Example Table of Contents |
||||
|
|
||||
|
 |
||||
|
|
||||
|
|
||||
@ -0,0 +1,9 @@ |
|||||
|
" adds support for cleverref package |
||||
|
" \Cref, \cref, \cpageref, \labelcref, \labelcpageref |
||||
|
syn region texRefZone matchgroup=texStatement start="\\Cref{" end="}\|%stopzone\>" contains=@texRefGroup |
||||
|
syn region texRefZone matchgroup=texStatement start="\\\(label\|\)c\(page\|\)ref{" end="}\|%stopzone\>" contains=@texRefGroup |
||||
|
|
||||
|
" adds support for listings package |
||||
|
syn region texZone start="\\begin{lstlisting}" end="\\end{lstlisting}\|%stopzone\>" |
||||
|
syn match texInputFile "\\lstinputlisting\s*\(\[.*\]\)\={.\{-}}" contains=texStatement,texInputCurlies,texInputFileOpt |
||||
|
syn match texZone "\\lstinline\s*\(\[.*\]\)\={.\{-}}" |
||||
@ -0,0 +1,833 @@ |
|||||
|
*latex-box.txt* LaTeX Box |
||||
|
*latex-box* |
||||
|
|
||||
|
This plugin consists of a set of tools to help editing LaTeX documents. |
||||
|
|
||||
|
Manifesto: LaTeX Box aims to remain lightweight and stay out of the way. |
||||
|
|
||||
|
This plugin provides: |
||||
|
- Background compilation using latexmk; |
||||
|
- Completion for commands, environments, labels, bibtex entries and inline |
||||
|
maths; |
||||
|
- A simple table of contents; |
||||
|
- Smart indentation (activated with "set smartindent"); |
||||
|
- Highlighting of matching \begin/\end pairs |
||||
|
- Motion between matching \begin/\end pairs with the % key; |
||||
|
- Motion through brackets/braces (with user-defined keys). |
||||
|
- Environment objects (e.g., select environement with "vie" or "vae") |
||||
|
- Inline math objects (e.g., select inline math with "vi$" or "va$") |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
|latex-box-completion| COMPLETION |
||||
|
|latex-box-completion-commands| Commands |
||||
|
|latex-box-completion-environments| Environments |
||||
|
|latex-box-completion-labels| Labels |
||||
|
|latex-box-completion-bibtex| Bibtex |
||||
|
|latex-box-completion-inlineMaths| InlineMaths |
||||
|
|
||||
|
|latex-box-commands| COMMANDS |
||||
|
|latex-box-commands-compilation| Compilation |
||||
|
|latex-box-commands-viewing| Viewing |
||||
|
|latex-box-commands-folding| Folding |
||||
|
|latex-box-commands-motion| Motion |
||||
|
|
||||
|
|latex-box-motion| MOTION |
||||
|
|
||||
|
|latex-box-mappings| MAPPINGS |
||||
|
|latex-box-mappings-compilation| Compilation |
||||
|
|latex-box-mappings-insertion| Insertion |
||||
|
|latex-box-mappings-viewing| Viewing |
||||
|
|latex-box-mappings-folding| Folding |
||||
|
|latex-box-mappings-motion| Motion |
||||
|
|
||||
|
|latex-box-settings| SETTINGS |
||||
|
|latex-box-settings-compilation| Compilation |
||||
|
|latex-box-settings-completion| Completion |
||||
|
|latex-box-settings-windows| Vim Windows |
||||
|
|
||||
|
|latex-box-folding| FOLDING |
||||
|
|
||||
|
|latex-box-indent| INDENTATION |
||||
|
|
||||
|
|latex-box-FAQ| Frequently Asked Questions |
||||
|
|
||||
|
|latex-box-todo| TODO |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
COMPLETION *latex-box-completion* |
||||
|
|
||||
|
Completion is achieved through omni completion |compl-omni|, with default |
||||
|
bindings <CTRL-X><CTRL-O>. There are five types of completion: |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-completion-commands* |
||||
|
Commands ~ |
||||
|
|
||||
|
Command completion is triggered by the '\' character. For example, > |
||||
|
\beg<CTRL-X><CTRL-O> |
||||
|
completes to > |
||||
|
\begin{ |
||||
|
< |
||||
|
|
||||
|
Associated settings: |
||||
|
|g:LatexBox_completion_commands| |
||||
|
|g:LatexBox_completion_close_braces| |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-completion-environments* |
||||
|
Environments ~ |
||||
|
|
||||
|
Environment completion is triggered by '\begin{'. For example, > |
||||
|
\begin{it<CTRL-X><CTRL-O> |
||||
|
completes to > |
||||
|
\begin{itemize} |
||||
|
< |
||||
|
|
||||
|
Completion of '\end{' automatically closes the last open environment. |
||||
|
|
||||
|
Associated settings: |
||||
|
|g:LatexBox_completion_environments| |
||||
|
|g:LatexBox_completion_close_braces| |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-completion-labels* |
||||
|
Labels ~ |
||||
|
|
||||
|
Label completion is triggered by '\ref{' or '\eqref{'. For example, > |
||||
|
\ref{sec:<CTRL-X><CTRL-O> |
||||
|
offers a list of all matching labels, with their associated value and page |
||||
|
number. Labels are read from the aux file, so label completion works only |
||||
|
after compilation. |
||||
|
|
||||
|
It matches: |
||||
|
1. labels: > |
||||
|
\ref{sec:<CTRL-X><CTRL-O> |
||||
|
< 2. numbers: > |
||||
|
\eqref{2<CTRL-X><CTRL-O> |
||||
|
< 3. labels and numbers together (separated by whitespace): > |
||||
|
\eqref{eq 2<CTRL-X><CTRL-O> |
||||
|
< |
||||
|
|
||||
|
Associated settings: |
||||
|
|g:LatexBox_ref_pattern| |
||||
|
|g:LatexBox_completion_close_braces| |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-completion-bibtex* |
||||
|
BibTeX entries ~ |
||||
|
|
||||
|
BibTeX completion is triggered by '\cite{', '\citep{' or '\citet{'. For |
||||
|
example, assume you have in your .bib files an entry looking like: > |
||||
|
|
||||
|
@book { knuth1981, |
||||
|
author = "Donald E. Knuth", |
||||
|
title = "Seminumerical Algorithms", |
||||
|
publisher = "Addison-Wesley", |
||||
|
year = "1981" } |
||||
|
|
||||
|
Then, try: > |
||||
|
|
||||
|
\cite{Knuth 1981<CTRL-X><CTRL-O> |
||||
|
\cite{algo<CTRL-X><CTRL-O> |
||||
|
|
||||
|
You can also use regular expressions (or vim patterns) after '\cite{'. |
||||
|
|
||||
|
Associated settings: |
||||
|
|g:LatexBox_cite_pattern| |
||||
|
|g:LatexBox_bibtex_wild_spaces| |
||||
|
|g:LatexBox_completion_close_braces| |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-completion-inlineMaths* |
||||
|
InlineMaths ~ |
||||
|
|
||||
|
InlineMaths completion is triggered by '$', '\(' or '\[', and can also be |
||||
|
triggered by '$' that locates in math environment '\(...\)', '\[...\]', or |
||||
|
'\begin{eq-env} ... \end{eq-env}'. It suggests the inline maths you write in |
||||
|
'$' pairs and in '\( ... \)' and the corresponding line number. |
||||
|
|
||||
|
Note that an inline math with open and close symbols on different lines will |
||||
|
not be suggested. |
||||
|
|
||||
|
For example, you type two in line maths looking like: > |
||||
|
|
||||
|
$hello$, \(world\) |
||||
|
|
||||
|
And you save them before trying to complete elsewhere: > |
||||
|
|
||||
|
:w |
||||
|
|
||||
|
You type '$', '\(' or '\[', and part of 'hello': > |
||||
|
|
||||
|
$h <CTRL-X><CTRL-O> |
||||
|
\(h <CTRL-X><CTRL-O> |
||||
|
\[h <CTRL-X><CTRL-O> |
||||
|
|
||||
|
They comlete to: > |
||||
|
|
||||
|
$hello$ |
||||
|
\(hello\) |
||||
|
\[hello\] |
||||
|
|
||||
|
You can still add more in line maths in '\(...\)' and '\[...\]': > |
||||
|
|
||||
|
\(hello, $ w <CTRL-X><CTRL-O> \) |
||||
|
\[hello, $ w <CTRL-X><CTRL-O> \] |
||||
|
|
||||
|
The results: > |
||||
|
|
||||
|
\(hello, world\) |
||||
|
\[hello, world\] |
||||
|
|
||||
|
Or cross lines: > |
||||
|
|
||||
|
\( hello, |
||||
|
$ w <CTRL-X><CTRL-O> |
||||
|
|
||||
|
\[ hello, |
||||
|
$ w <CTRL-X><CTRL-O> |
||||
|
|
||||
|
The results: > |
||||
|
|
||||
|
\(hello, |
||||
|
world |
||||
|
|
||||
|
\[hello, |
||||
|
world |
||||
|
|
||||
|
For equation environments, it's always triggered by '$': > |
||||
|
|
||||
|
\begin{eq-env} |
||||
|
$h <CTRL-X><CTRL-O> |
||||
|
$w <CTRL-X><CTRL-O> |
||||
|
\end{eq-env} |
||||
|
|
||||
|
It matches: > |
||||
|
|
||||
|
\begin{eq-env} |
||||
|
hello |
||||
|
world |
||||
|
\end{eq-env} |
||||
|
|
||||
|
|
||||
|
ATTENTION: do not try to complete inline maths when |
||||
|
1. '$' pair is in multi lines: > |
||||
|
|
||||
|
$ |
||||
|
h <CTRL-X><CTRL-O> |
||||
|
|
||||
|
2. '\begin{eq-env}' and '\end{eq-env}' are in single line: > |
||||
|
|
||||
|
\begin{eq-env} $ h <CTRL-X><CTRL-O> \end{eq-env} |
||||
|
|
||||
|
Associated setting: > |
||||
|
g:LatexBox_complete_inlineMath |
||||
|
g:LatexBox_eq_env_patterns |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
COMMANDS *latex-box-commands* |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-commands-compilation* |
||||
|
Compilation ~ |
||||
|
|
||||
|
*:Latexmk* |
||||
|
Compile with latexmk. |
||||
|
See |g:LatexBox_latexmk_async|, |g:LatexBox_latexmk_options|, and |
||||
|
|g:LatexBox_latexmk_preview_continuously|. |
||||
|
*:Latexmk!* |
||||
|
Force compilation with latexmk (runs latexmk with "-g" option). |
||||
|
*:LatexmkClean* |
||||
|
Clean temporary output from LaTeX. |
||||
|
*:LatexmkClean!* |
||||
|
Clean all output from LaTeX. |
||||
|
*:LatexmkStatus* |
||||
|
Show the running status of latexmk for the current buffer. |
||||
|
*:LatexmkStatus!* |
||||
|
Show the running status of latexmk for all buffers with process group |
||||
|
ID's or PID's. |
||||
|
*:LatexmkStop* |
||||
|
Stop latexmk if it is running. |
||||
|
*:LatexErrors* |
||||
|
Load the log file for the current document and jump to the first error. |
||||
|
|
||||
|
Note: The commands |:LatexmkStop| and |:LatexmkStatus| are only relevant when |
||||
|
|g:LatexBox_latexmk_async| or |g:LatexBox_latexmk_preview_continuously| is |
||||
|
set. |
||||
|
|
||||
|
When latexmk terminates, it reports its success or failure (with status |
||||
|
number). To navigate through the errors, you can use the |:cc|, |:cn| and |
||||
|
|:cp| commands, as well as the |:clist| command to list the errors. |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-commands-viewing* |
||||
|
Viewing ~ |
||||
|
|
||||
|
*:LatexView* |
||||
|
Launch viewer on output file. |
||||
|
Takes optional arguments, separated by whitespaces, to be passed to the viewer. |
||||
|
For example, to open the viewer at a specific page and line if SyncTeX is used. |
||||
|
See the FAQ below for an application to SumatraPDF for forward searching. |
||||
|
See |g:LatexBox_output_type| and |g:LatexBox_viewer|. |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-commands-folding* |
||||
|
Folding ~ |
||||
|
|
||||
|
*:LatexFold* |
||||
|
Recalculate the folds in the file. |
||||
|
This is especially useful if you are editing a large file with |
||||
|
automatic folding disabled for performance reasons. |
||||
|
See |g:LatexBox_fold_automatic|. |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-commands-motion* |
||||
|
Motion ~ |
||||
|
|
||||
|
*:LatexTOC* |
||||
|
Open a table of contents. |
||||
|
Use Enter to navigate to selected entry. |
||||
|
See |g:LatexBox_split_type|. |
||||
|
See |g:LatexBox_split_length|. |
||||
|
See |g:LatexBox_split_width|. |
||||
|
See |g:LatexBox_split_side|. |
||||
|
See |g:LatexBox_split_resize|. |
||||
|
*:LatexTOCToggle* |
||||
|
Toggle the display of the table of contents. |
||||
|
*:LatexLabels* |
||||
|
Same as TOC but with regex-selected labels. |
||||
|
|
||||
|
Associated setting: |
||||
|
|g:LatexBox_plaintext_toc| (set this if UTF8 conversion does not work) |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
MOTION *latex-box-motion* |
||||
|
|
||||
|
The function LatexBox_JumpToNextBraces({backward}) allows to jump outside of |
||||
|
the current brace/bracket pair, or inside of the next opening braces/brackets. |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
MAPPINGS *latex-box-mappings* |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-mappings-compilation* |
||||
|
Compilation ~ |
||||
|
|
||||
|
<LocalLeader>ll |:Latexmk| |
||||
|
Compile with latexmk. |
||||
|
<LocalLeader>lL |:Latexmk!| |
||||
|
Force compilation with latexmk. |
||||
|
<LocalLeader>lc |:LatexmkClean| |
||||
|
Clean temporary output from LaTeX. |
||||
|
<LocalLeader>lC |:LatexmkClean!| |
||||
|
Clean all output from LaTeX. |
||||
|
<LocalLeader>lk |:LatexmkStop| |
||||
|
Stop latexmk if it is running. |
||||
|
<LocalLeader>lg |:LatexmkStatus| |
||||
|
Show the running status of latexmk for the current buffer. |
||||
|
<LocalLeader>lG |:LatexmkStatus!| |
||||
|
Show the running status of latexmk for all buffers with process group |
||||
|
ID's. |
||||
|
<LocalLeader>le |:LatexErrors| |
||||
|
Load the log file for the current document and jump to the first error. |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-mappings-viewing* |
||||
|
Viewing ~ |
||||
|
|
||||
|
<LocalLeader>lv |:LatexView| |
||||
|
View output file. |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-mappings-folding* |
||||
|
Folding ~ |
||||
|
|
||||
|
<LocalLeader>lf |:LatexFold| |
||||
|
Recalculate the folds. |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-mappings-insertion* |
||||
|
Insertion ~ |
||||
|
|
||||
|
*<Plug>LatexCloseCurEnv* |
||||
|
Close the last matching open environment. Use with imap, e.g.: > |
||||
|
imap ]] <Plug>LatexCloseCurEnv |
||||
|
< |
||||
|
|
||||
|
*<Plug>LatexChangeEnv* |
||||
|
Change the current environment. Use with nmap, e.g.: > |
||||
|
nmap <F5> <Plug>LatexChangeEnv |
||||
|
< |
||||
|
|
||||
|
*<Plug>LatexToggleStarEnv* |
||||
|
Toggle star environments (add or remove star). Use with nmap, e.g.: > |
||||
|
nmap <F5> <Plug>LatexToggleStarEnv |
||||
|
< |
||||
|
|
||||
|
*<Plug>LatexWrapSelection* |
||||
|
Wrap the current selection in a LaTeX command. Use with vmap, e.g.: > |
||||
|
vmap <F7> <Plug>LatexWrapSelection |
||||
|
< |
||||
|
|
||||
|
*<Plug>LatexEnvWrapSelection* |
||||
|
Wrap the current selection in an environment. Use with vmap, e.g.: > |
||||
|
vmap <S-F7> <Plug>LatexEnvWrapSelection |
||||
|
< |
||||
|
|
||||
|
Suggested mappings to put in ~/.vim/ftplugin/tex.vim: > |
||||
|
imap <buffer> [[ \begin{ |
||||
|
imap <buffer> ]] <Plug>LatexCloseCurEnv |
||||
|
nmap <buffer> <F5> <Plug>LatexChangeEnv |
||||
|
vmap <buffer> <F7> <Plug>LatexWrapSelection |
||||
|
vmap <buffer> <S-F7> <Plug>LatexEnvWrapSelection |
||||
|
imap <buffer> (( \eqref{ |
||||
|
< |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-mappings-motion* |
||||
|
Motion ~ |
||||
|
|
||||
|
<LocalLeader>lt |:LatexTOC| |
||||
|
Open a table of contents. |
||||
|
Use Enter to navigate to selected entry. |
||||
|
|
||||
|
*<Plug>LatexBox_JumpToMatch* |
||||
|
Jump to the matching bracket or \begin/\end pairs. Emulates |%|. |
||||
|
|
||||
|
*<Plug>LatexBox_BackJumpToMatch* |
||||
|
Same as |<Plug>LatexBox_JumpToMatch|, but the initial search is |
||||
|
backward. |
||||
|
|
||||
|
Suggested bindings: > |
||||
|
map <silent> <buffer> ¶ :call LatexBox_JumpToNextBraces(0)<CR> |
||||
|
map <silent> <buffer> § :call LatexBox_JumpToNextBraces(1)<CR> |
||||
|
imap <silent> <buffer> ¶ <C-R>=LatexBox_JumpToNextBraces(0)<CR> |
||||
|
imap <silent> <buffer> § <C-R>=LatexBox_JumpToNextBraces(1)<CR> |
||||
|
< |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
SETTINGS *latex-box-settings* |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Mappings ~ |
||||
|
|
||||
|
*g:LatexBox_no_mappings* |
||||
|
If this variable is defined, the default keyboard mappings will not be |
||||
|
loaded. |
||||
|
|
||||
|
*g:LatexBox_open_pats* |
||||
|
*g:LatexBox_close_pats* |
||||
|
These variables define the patterns that LatexBox use to detect |
||||
|
matching pair of braces, parantheses, environments, and similar. |
||||
|
|
||||
|
Default: > |
||||
|
let g:LatexBox_open_pats = [ |
||||
|
\ '\\{','{','\\(','(','\\\[','\[', |
||||
|
\ '\\begin\s*{.\{-}}', |
||||
|
\ '\\left\s*\%([^\\]\|\\.\|\\\a*\)', |
||||
|
\ ] |
||||
|
let g:LatexBox_close_pats = [ |
||||
|
\ '\\}','}','\\)',')','\\\]','\]', |
||||
|
\ '\\end\s*{.\{-}}', |
||||
|
\ '\\right\s*\%([^\\]\|\\.\|\\\a*\)', |
||||
|
\ ] |
||||
|
< |
||||
|
|
||||
|
*latex-box-settings-completion* |
||||
|
Completion ~ |
||||
|
|
||||
|
*g:LatexBox_completion_close_braces* Default: 1 |
||||
|
If nonzero, omni completion will add closing brackets where relevant. |
||||
|
For example, if nonzero, > |
||||
|
\begin{itemize |
||||
|
< completes to > |
||||
|
\begin{itemize} |
||||
|
|
||||
|
*g:LatexBox_bibtex_wild_spaces* Default: 1 |
||||
|
If nonzero, spaces act as wildcards ('.*') in completion. |
||||
|
|
||||
|
For example, if nonzero, > |
||||
|
\cite{Knuth 1981 |
||||
|
< is equivalent to > |
||||
|
\cite{Knuth.*1981 |
||||
|
|
||||
|
*g:LatexBox_completion_environments* |
||||
|
*g:LatexBox_completion_commands* |
||||
|
Static completion lists for environments |
||||
|
|latex-box-completion-environments| and commands |
||||
|
|latex-box-completion-commands|. |
||||
|
See |complete-items|. |
||||
|
|
||||
|
*g:LatexBox_cite_pattern* |
||||
|
*g:LatexBox_ref_pattern* |
||||
|
Patterns to match \cite and \ref commands for BibTeX and label |
||||
|
completion. They must include the trailing '{'. |
||||
|
|
||||
|
Examples: To match only the 'cite' command (case insensitive), use: > |
||||
|
let LatexBox_cite_pattern = '\c\\cite\*\?\_\s*{' |
||||
|
< To match all commands that end with 'ref' (case insensitive), use: > |
||||
|
let LatexBox_ref_pattern = '\c\\\a*ref\*\?\_\s*{' |
||||
|
< Both of the above examples also match commands with a trailing star. |
||||
|
|
||||
|
Default values: > |
||||
|
let g:LatexBox_cite_pattern |
||||
|
\ = '\m\c\\\a*cite\a*\*\?\(\[[^\]]*\]\)\_\s*{' |
||||
|
let g:LatexBox_ref_pattern |
||||
|
\ = '\m\C\\v\?\(eq\|page\|[cC]\)\?ref\*\?\_\s*{' |
||||
|
< The '\m' flag indicates that these are magic regular expressions. |
||||
|
< The default settings should work for most standard LaTeX packages. |
||||
|
|
||||
|
*g:LatexBox_complete_inlineMath* Default: 0 |
||||
|
Switch for inline math completion. |
||||
|
|
||||
|
*g:LatexBox_eq_env_patterns* |
||||
|
Equation environments besides '$...$', '\(...\)', and '\[...\]' that |
||||
|
support inline math completion. |
||||
|
|
||||
|
Note that 'eq-env-name*' will also be supported if we add |
||||
|
'eq-env-name' in the list. |
||||
|
|
||||
|
Default: > |
||||
|
let g:LatexBox_eq_env_patterns |
||||
|
\ = 'equation\|gather\|multiline\|align' |
||||
|
\ . '\|flalign\|alignat\|eqnarray' |
||||
|
< |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
Templates (DEPRECATED) ~ |
||||
|
|
||||
|
*g:LatexBox_templates* |
||||
|
|
||||
|
Dictionary of environment templates |latex-box-templates|. |
||||
|
|
||||
|
DEPRECATED! |
||||
|
I think it is better to leave this task to plug-ins oriented to do |
||||
|
this well, like snipMate: |
||||
|
http://www.vim.org/scripts/script.php?script_id=2540 |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-settings-compilation* |
||||
|
Compilation ~ |
||||
|
|
||||
|
*g:vim_program* Default: autodetected |
||||
|
Vim program to use on command line for callbacks. If autodetect |
||||
|
fails, defaults to: > |
||||
|
'/Applications/MacVim.app/Contents/MacOS/Vim -g' |
||||
|
< on MacVim, or to |v:progname| on other systems. |
||||
|
|
||||
|
*g:LatexBox_latexmk_async* Default: 0 |
||||
|
Enable asynchronous LaTeX compilation using vimserver. This will |
||||
|
allow latexmk to run in the background and load any compilation |
||||
|
errors in a quickfix window after it finishes running. |
||||
|
|
||||
|
*g:LatexBox_latexmk_preview_continuously* Default: 0 |
||||
|
Run latexmk in continuous mode (i.e. with the "-pvc" option). |
||||
|
Latexmk will track the currently edited file for writes and |
||||
|
recompile automatically when necessary, without hanging VIM. |
||||
|
Setting |g:LatexBox_quickfix|=2 is recommended when this is enabled, |
||||
|
to prevent the quickfix window from stealing the cursor. |
||||
|
|
||||
|
*g:LatexBox_latexmk_env* Default: "" |
||||
|
Additional environment options to place in front of the latexmk |
||||
|
command, e.g. > |
||||
|
let g:LatexBox_latexmk_env = "TEXINPUTS=~/mytex:" |
||||
|
|
||||
|
*g:LatexBox_latexmk_options* Default: "" |
||||
|
Additional options to pass to latexmk during compilation, e.g, "-d". |
||||
|
|
||||
|
*g:LatexBox_output_type* Default: "pdf" |
||||
|
Extension of the output file. One of "pdf", "dvi" or "ps". |
||||
|
|
||||
|
*g:LatexBox_viewer* Default: "xdg-open" |
||||
|
Viewer application for the output file, e.g., "xpdf". |
||||
|
|
||||
|
*g:LatexBox_quickfix* Default: 1 |
||||
|
Adjust the behavior of the quickfix window when there are compilation |
||||
|
errors or warnings. See also |g:LatexBox_show_warnings|. Recognized |
||||
|
options are: |
||||
|
|
||||
|
Value Effect ~ |
||||
|
0 The quickfix is not opened automatically. |
||||
|
1 The quickfix window is opened automatically if not |
||||
|
empty and becomes the active window. |
||||
|
2 The quickfix window is opened automatically if not |
||||
|
empty but the cursor stays in the current window. |
||||
|
3 The quickfix window is opened automatically if not |
||||
|
empty and becomes the active window. Quickfix window is not |
||||
|
opened on warnings, only on errors. |
||||
|
4 The quickfix window is opened automatically if not |
||||
|
empty but the cursor stays in the current window. Quickfix |
||||
|
window is not opened on warnings, only on errors. |
||||
|
|
||||
|
*g:LatexBox_autojump* Default: 0 |
||||
|
Automatically jump to first error after calling latexmk. |
||||
|
|
||||
|
*b:main_tex_file* Default: "" |
||||
|
Path to the main LaTeX file associated to the current buffer. |
||||
|
When editing a LaTeX document consisting of multiple source files, set |
||||
|
this variable to the path of the main source file on which LaTeX must |
||||
|
be called. |
||||
|
|
||||
|
*g:LatexBox_show_warnings* Default: 1 |
||||
|
If set to 1, warnings in compilation will be listed as errors. |
||||
|
|
||||
|
*g:LatexBox_ignore_warnings* |
||||
|
A list of warnings to be ignored. |
||||
|
|
||||
|
Default: > |
||||
|
let g:LatexBox_ignore_warnings |
||||
|
\ = ['Underfull', 'Overfull', 'specifier changed to'] |
||||
|
< |
||||
|
|
||||
|
*g:LatexBox_build_dir* Default: "" |
||||
|
Set output directory for build files. |
||||
|
|
||||
|
*b:build_dir* Default: "" |
||||
|
Set output directory for build files. This overrides the global |
||||
|
setting. |
||||
|
|
||||
|
*g:LatexBox_jobname* Default: "" |
||||
|
Sets the name of the output build files. |
||||
|
|
||||
|
------------------------------------------------------------------------------ |
||||
|
|
||||
|
*latex-box-settings-windows* |
||||
|
Vim Windows ~ |
||||
|
|
||||
|
For different settings, change the .vimrc so that a more comfortable |
||||
|
global variable is used. For example, if one prefers horizontal splits |
||||
|
(non-default, featured in screenshot), consider the following lines in |
||||
|
the .vimrc: |
||||
|
|
||||
|
> |
||||
|
if s:extfname ==? "tex" |
||||
|
... |
||||
|
let |g:LatexBox_split_type| = "new" |
||||
|
... |
||||
|
end if |
||||
|
< |
||||
|
|
||||
|
*g:LatexBox_split_type* Default: "vnew" |
||||
|
The type of split for the Table of Contents. Use "new" for horizontal, |
||||
|
"vnew" for vertical. Note that these are the general commands for |
||||
|
splitting--more info can be found via :help new. |
||||
|
|
||||
|
*g:LatexBox_split_length* Default: 15 |
||||
|
Length of horizontally split vim windows. Used for the table of contents. |
||||
|
|
||||
|
*g:LatexBox_split_width* Default: 30 |
||||
|
Width of vertically split vim windows. Used for the table of contents. |
||||
|
|
||||
|
*g:LatexBox_split_side* Default: "aboveleft" |
||||
|
On which side the split windows appear. Above for horizontal splits |
||||
|
and left for vertical splits. Used for the table of contents. |
||||
|
Set to "belowright" to have it on the below/right side. |
||||
|
|
||||
|
*g:LatexBox_split_resize* Default: 0 |
||||
|
Resize vim/gvim when opening new windows. Used for the table of |
||||
|
contents. If set to 1, it will add/remove |g:LatexBox_split_width| or |
||||
|
|g:LatexBox_split_length| to the number of columns dynamically, |
||||
|
in order to keep the latex file open with the desired dimension. |
||||
|
|
||||
|
*g:LatexBox_toc_hidehelp* Default: 0 |
||||
|
If enabled, the help info at the bottom of the TOC window will be |
||||
|
hidden. |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
FOLDING *latex-box-folding* |
||||
|
|
||||
|
LatexBox can fold texts according to LaTeX structure (part, chapter, section |
||||
|
and subsection). Folding is off by default, and can be turned on by defining |
||||
|
the |g:LatexBox_Folding| variable. |
||||
|
|
||||
|
The standard fold settings should suffice for most people. When folding is |
||||
|
turned on and a latex document is opened, the document is parsed once in order |
||||
|
to define the highest fold level based on which parts and sections should be |
||||
|
folded. |
||||
|
|
||||
|
*g:LatexBox_Folding* Default: 0 |
||||
|
Set to 1 to activate LaTeX structure folding. Please note that any |
||||
|
modeline that would set |foldmethod| to something else than |
||||
|
'fold-expr' will disable the function. The same goes for |foldexpr|. |
||||
|
Set this variable in your .vimrc |
||||
|
|
||||
|
*g:LatexBox_fold_text* Default: 1 |
||||
|
Turn on/off LaTeX enhenced foldtext() function. Turn on this option |
||||
|
makes LaTeX-Box override the |foldtext| option. Turn off if you want |
||||
|
to set your own |foldtext|. |
||||
|
|
||||
|
*g:LatexBox_fold_preamble* Default: 1 |
||||
|
Turn on/off folding of preamble |
||||
|
|
||||
|
*g:LatexBox_fold_envs* Default: 1 |
||||
|
Turn on/off folding of environments |
||||
|
|
||||
|
*g:LatexBox_fold_parts* |
||||
|
Define parts that should be folded. These are intended as top level |
||||
|
parts such as \frontmatter and \appendix, and if they are present in |
||||
|
a latex document they will get fold level 1. |
||||
|
|
||||
|
Default: > |
||||
|
let g:LatexBox_fold_parts = [ |
||||
|
\ "appendix", |
||||
|
\ "frontmatter", |
||||
|
\ "mainmatter", |
||||
|
\ "backmatter" |
||||
|
\ ] |
||||
|
< |
||||
|
|
||||
|
*g:LatexBox_fold_sections* |
||||
|
Define which section levels should be folded. The order of the |
||||
|
elements defines the order in which they are folded. |
||||
|
|
||||
|
Default: > |
||||
|
let g:LatexBox_fold_sections = [ |
||||
|
\ "part", |
||||
|
\ "chapter", |
||||
|
\ "section", |
||||
|
\ "subsection", |
||||
|
\ "subsubsection" |
||||
|
\ ] |
||||
|
< |
||||
|
|
||||
|
*g:LatexBox_fold_toc* Default: 0 |
||||
|
Turn on/off folding of TOC (|latex-box-commands-motion|). |
||||
|
|
||||
|
*g:LatexBox_fold_toc_levels* Default: 1 |
||||
|
Set number of section levels to fold in TOC. |
||||
|
|
||||
|
*g:LatexBox_fold_automatic* Default: 1 |
||||
|
Turn on/off automatic calculation of folds. |
||||
|
By default LaTeX-Box recalculates the folds every time you exit insert |
||||
|
mode. However for large files this can be a rather slow process: a |
||||
|
couple of seconds to 10s of seconds. |
||||
|
If this option is set to 0 the folding code is still enabled but isn't |
||||
|
activated by default. Hence you need to manually tell vim to |
||||
|
recalculate folds every time you find it apropriate. |
||||
|
You can recalculate the folds using <LocalLeader>lf or |:LatexFold| |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
INDENTATION *latex-box-indent* |
||||
|
|
||||
|
*g:LatexBox_custom_indent* Default: Not defined |
||||
|
The custom indent file of LaTeX-Box is ignored if this variable is |
||||
|
defined and set to 0. This will revert to the default indentation |
||||
|
file from vim. |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
FREQUENTLY ASKED QUESTIONS *latex-box-FAQ* |
||||
|
|
||||
|
Q: How can I use SyncTeX with the Skim viewer? |
||||
|
|
||||
|
A: Add the following line in your ~/.latexmkrc file: > |
||||
|
|
||||
|
$pdflatex = 'pdflatex -synctex=1 %O %S' |
||||
|
|
||||
|
< and create a "latex-search" mapping (<Leader>ls) in your ~/.vimrc: > |
||||
|
|
||||
|
map <silent> <Leader>ls :silent |
||||
|
\ !/Applications/Skim.app/Contents/SharedSupport/displayline |
||||
|
\ <C-R>=line('.')<CR> "<C-R>=LatexBox_GetOutputFile()<CR>" |
||||
|
\ "%:p" <CR> |
||||
|
|
||||
|
< (inspired from vim-latex). |
||||
|
|
||||
|
Alternatively, the option for latexmk may be given through the variable |
||||
|
|g:LatexBox_latexmk_options|, for instance as: > |
||||
|
|
||||
|
let g:LatexBox_latexmk_options |
||||
|
\ = "-pdflatex='pdflatex -synctex=1 \%O \%S'" |
||||
|
|
||||
|
< which can be added to your .vimrc file as desired. |
||||
|
|
||||
|
Q: How can I use SyncTeX with the SumatraPDF viewer? |
||||
|
|
||||
|
A: To enable SyncTeX add the following LatexBox settings to your ~/.vimrc file: > |
||||
|
|
||||
|
let g:LatexBox_latexmk_options = |
||||
|
\ '-pdflatex="pdflatex -synctex=1 %O %S"' |
||||
|
|
||||
|
To enable Inverse Search, that is, jumping from a position in the PDF |
||||
|
document to the TeX file, add the following LatexBox settings to your |
||||
|
~/.vimrc file: > |
||||
|
|
||||
|
let g:LatexBox_latexmk_options = |
||||
|
\ '-pdflatex="pdflatex -synctex=1 %O %S"' |
||||
|
|
||||
|
let g:LatexBox_viewer = 'SumatraPDF -reuse-instance -inverse-search ' |
||||
|
\ . '"gvim --servername ' . v:servername |
||||
|
\ . ' --remote-send \"^<C-\^>^<C-n^>' |
||||
|
\ . ':drop \%f^<CR^>:\%l^<CR^>:normal\! zzzv^<CR^>' |
||||
|
\ . ':call remote_foreground('''.v:servername.''')^<CR^>\""' |
||||
|
|
||||
|
< The above approach inspired by remoteOpen.vim from LaTeX-suite. The naive |
||||
|
try, > |
||||
|
|
||||
|
..\ "gvim +\%l \%f" |
||||
|
|
||||
|
< changes the current work dir to the dir of the viewer (see |
||||
|
http://vim.1045645.n5.nabble.com/autochdir-td1140014.html) and produces |
||||
|
a lot of error messages. |
||||
|
|
||||
|
To enable Forward Search, that is, jumping from a position in the TeX file |
||||
|
to the PDF document, add the following mapping to your |
||||
|
~/.vim/ftplugin/tex.vim file: > |
||||
|
|
||||
|
nnoremap <expr><buffer> <C-F11> ':LatexView ' . '-forward-search ' |
||||
|
\ . shellescape(expand('%:p')) . ' ' . line(".") . '\<CR>' |
||||
|
|
||||
|
< When hitting <C-F11>, the viewer (SumatraPDF) will open the PDF document |
||||
|
at the page corresponding to the current cursor position in the TeX |
||||
|
document. |
||||
|
|
||||
|
Q: How can I use xelatex instead of pdflatex for some documents only? |
||||
|
|
||||
|
A: Instead of putting the settings in your ~/.latexmkrc file, put them in your |
||||
|
document's working directory, in a file named latexmkrc or .latexmkrc: > |
||||
|
$pdflatex = 'xelatex %O %S' |
||||
|
|
||||
|
Q: How can I specify the main TeX file for a multi-file document |
||||
|
|
||||
|
A: There are several ways to do this: |
||||
|
|
||||
|
1. Add a comment to the first few lines of your file to specify this: > |
||||
|
%! TEX root = main.tex |
||||
|
< 2. Create an empty file called 'main.tex.latexmain' in the same directory. |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
TODO *latex-box-todo* |
||||
|
|
||||
|
- Improve TOC jumping and filter out weird characters. Deal with multiple |
||||
|
sections with the same name. |
||||
|
- Fix bugs? |
||||
|
|
||||
|
============================================================================== |
||||
|
|
||||
|
vim:tw=78:ts=8:ft=help:norl: |
||||
@ -0,0 +1,413 @@ |
|||||
|
" LaTeX Box common functions |
||||
|
|
||||
|
" Error Format {{{ |
||||
|
" Note: The error formats assume we're using the -file-line-error with |
||||
|
" [pdf]latex. |
||||
|
" Note: See |errorformat-LaTeX| for more info. |
||||
|
|
||||
|
" Check for options |
||||
|
if !exists("g:LatexBox_show_warnings") |
||||
|
let g:LatexBox_show_warnings=1 |
||||
|
endif |
||||
|
if !exists("g:LatexBox_ignore_warnings") |
||||
|
let g:LatexBox_ignore_warnings = |
||||
|
\['Underfull', |
||||
|
\ 'Overfull', |
||||
|
\ 'specifier changed to'] |
||||
|
endif |
||||
|
|
||||
|
" Standard error message formats |
||||
|
" Note: We consider statements that starts with "!" as errors |
||||
|
setlocal efm=%E!\ LaTeX\ %trror:\ %m |
||||
|
setlocal efm+=%E%f:%l:\ %m |
||||
|
setlocal efm+=%E!\ %m |
||||
|
|
||||
|
" More info for undefined control sequences |
||||
|
setlocal efm+=%Z<argument>\ %m |
||||
|
|
||||
|
" More info for some errors |
||||
|
setlocal efm+=%Cl.%l\ %m |
||||
|
|
||||
|
" Show or ignore warnings |
||||
|
if g:LatexBox_show_warnings |
||||
|
" Parse biblatex warnings |
||||
|
setlocal efm+=%-C(biblatex)%.%#in\ t%.%# |
||||
|
setlocal efm+=%-C(biblatex)%.%#Please\ v%.%# |
||||
|
setlocal efm+=%-C(biblatex)%.%#LaTeX\ a%.%# |
||||
|
setlocal efm+=%-Z(biblatex)%m |
||||
|
|
||||
|
" Parse hyperref warnings |
||||
|
setlocal efm+=%-C(hyperref)%.%#on\ input\ line\ %l. |
||||
|
|
||||
|
for w in g:LatexBox_ignore_warnings |
||||
|
let warning = escape(substitute(w, '[\,]', '%\\\\&', 'g'), ' ') |
||||
|
exe 'setlocal efm+=%-G%.%#'. warning .'%.%#' |
||||
|
endfor |
||||
|
setlocal efm+=%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%# |
||||
|
setlocal efm+=%+W%.%#\ at\ lines\ %l--%*\\d |
||||
|
setlocal efm+=%+WLaTeX\ %.%#Warning:\ %m |
||||
|
setlocal efm+=%+W%.%#Warning:\ %m |
||||
|
else |
||||
|
setlocal efm+=%-WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%# |
||||
|
setlocal efm+=%-W%.%#\ at\ lines\ %l--%*\\d |
||||
|
setlocal efm+=%-WLaTeX\ %.%#Warning:\ %m |
||||
|
setlocal efm+=%-W%.%#Warning:\ %m |
||||
|
endif |
||||
|
|
||||
|
" Push file to file stack |
||||
|
setlocal efm+=%+P**%f |
||||
|
setlocal efm+=%+P**\"%f\" |
||||
|
|
||||
|
" Ignore unmatched lines |
||||
|
setlocal efm+=%-G%.%# |
||||
|
" }}} |
||||
|
|
||||
|
" Vim Windows {{{ |
||||
|
|
||||
|
" Type of split, "new" for horiz. "vnew" for vert. |
||||
|
if !exists('g:LatexBox_split_type') |
||||
|
let g:LatexBox_split_type = "vnew" |
||||
|
endif |
||||
|
|
||||
|
" Length of vertical splits |
||||
|
if !exists('g:LatexBox_split_length') |
||||
|
let g:LatexBox_split_length = 15 |
||||
|
endif |
||||
|
|
||||
|
" Width of horizontal splits |
||||
|
if !exists('g:LatexBox_split_width') |
||||
|
let g:LatexBox_split_width = 30 |
||||
|
endif |
||||
|
|
||||
|
" Where splits appear |
||||
|
if !exists('g:LatexBox_split_side') |
||||
|
let g:LatexBox_split_side = "aboveleft" |
||||
|
endif |
||||
|
|
||||
|
" Resize when split? |
||||
|
if !exists('g:LatexBox_split_resize') |
||||
|
let g:LatexBox_split_resize = 0 |
||||
|
endif |
||||
|
|
||||
|
" Toggle help info |
||||
|
if !exists('g:LatexBox_toc_hidehelp') |
||||
|
let g:LatexBox_toc_hidehelp = 0 |
||||
|
endif |
||||
|
" }}} |
||||
|
|
||||
|
" Filename utilities {{{ |
||||
|
function! LatexBox_GetMainTexFile() |
||||
|
|
||||
|
" 1. check for the b:main_tex_file variable |
||||
|
if exists('b:main_tex_file') && filereadable(b:main_tex_file) |
||||
|
return b:main_tex_file |
||||
|
endif |
||||
|
|
||||
|
|
||||
|
" 2. scan the first few lines of the file for root = filename |
||||
|
for linenum in range(1,5) |
||||
|
let linecontents = getline(linenum) |
||||
|
if linecontents =~ 'root\s*=' |
||||
|
" Remove everything but the filename |
||||
|
let b:main_tex_file = substitute(linecontents, |
||||
|
\ '.*root\s*=\s*', "", "") |
||||
|
let b:main_tex_file = substitute(b:main_tex_file, '\s*$', "", "") |
||||
|
" Prepend current directory if this isn't an absolute path |
||||
|
if b:main_tex_file !~ '^/' |
||||
|
let b:main_tex_file = expand('%:p:h') . '/' . b:main_tex_file |
||||
|
endif |
||||
|
let b:main_tex_file = fnamemodify(b:main_tex_file, ":p") |
||||
|
if b:main_tex_file !~ '\.tex$' |
||||
|
let b:main_tex_file .= '.tex' |
||||
|
endif |
||||
|
return b:main_tex_file |
||||
|
endif |
||||
|
endfor |
||||
|
|
||||
|
" 3. scan current file for "\begin{document}" |
||||
|
if &filetype == 'tex' && search('\m\C\\begin\_\s*{document}', 'nw') != 0 |
||||
|
return expand('%:p') |
||||
|
endif |
||||
|
|
||||
|
" 4. use 'main.tex' if it exists in the same directory (and is readable) |
||||
|
let s:main_dot_tex_file=expand('%:p:h') . '/main.tex' |
||||
|
if filereadable(s:main_dot_tex_file) |
||||
|
let b:main_tex_file=s:main_dot_tex_file |
||||
|
return b:main_tex_file |
||||
|
endif |
||||
|
|
||||
|
" 5. borrow the Vim-Latex-Suite method of finding it |
||||
|
if LatexBox_GetMainFileName() != expand('%:p') |
||||
|
let b:main_tex_file = LatexBox_GetMainFileName() |
||||
|
return b:main_tex_file |
||||
|
endif |
||||
|
|
||||
|
" 6. prompt for file with completion |
||||
|
let b:main_tex_file = s:PromptForMainFile() |
||||
|
return b:main_tex_file |
||||
|
endfunction |
||||
|
|
||||
|
function! s:PromptForMainFile() |
||||
|
let saved_dir = getcwd() |
||||
|
execute 'cd ' . fnameescape(expand('%:p:h')) |
||||
|
|
||||
|
" Prompt for file |
||||
|
let l:file = '' |
||||
|
while !filereadable(l:file) |
||||
|
let l:file = input('main LaTeX file: ', '', 'file') |
||||
|
if l:file !~ '\.tex$' |
||||
|
let l:file .= '.tex' |
||||
|
endif |
||||
|
endwhile |
||||
|
let l:file = fnamemodify(l:file, ':p') |
||||
|
|
||||
|
" Make persistent |
||||
|
let l:persistent = '' |
||||
|
while l:persistent !~ '\v^(y|n)' |
||||
|
let l:persistent = input('make choice persistent? (y, n) ') |
||||
|
if l:persistent == 'y' |
||||
|
call writefile([], l:file . '.latexmain') |
||||
|
endif |
||||
|
endwhile |
||||
|
|
||||
|
execute 'cd ' . fnameescape(saved_dir) |
||||
|
return l:file |
||||
|
endfunction |
||||
|
|
||||
|
" Return the directory of the main tex file |
||||
|
function! LatexBox_GetTexRoot() |
||||
|
return fnamemodify(LatexBox_GetMainTexFile(), ':h') |
||||
|
endfunction |
||||
|
|
||||
|
function! LatexBox_GetBuildBasename(with_dir) |
||||
|
" 1. Check for g:LatexBox_jobname |
||||
|
if exists('g:LatexBox_jobname') |
||||
|
return g:LatexBox_jobname |
||||
|
endif |
||||
|
|
||||
|
" 2. Get the basename from the main tex file |
||||
|
if a:with_dir |
||||
|
return fnamemodify(LatexBox_GetMainTexFile(), ':r') |
||||
|
else |
||||
|
return fnamemodify(LatexBox_GetMainTexFile(), ':t:r') |
||||
|
endif |
||||
|
endfunction |
||||
|
|
||||
|
function! LatexBox_GetAuxFile() |
||||
|
" 1. check for b:build_dir variable |
||||
|
if exists('b:build_dir') && isdirectory(b:build_dir) |
||||
|
return b:build_dir . '/' . LatexBox_GetBuildBasename(0) . '.aux' |
||||
|
endif |
||||
|
|
||||
|
" 2. check for g:LatexBox_build_dir variable |
||||
|
if exists('g:LatexBox_build_dir') && isdirectory(g:LatexBox_build_dir) |
||||
|
return g:LatexBox_build_dir . '/' . LatexBox_GetBuildBasename(0) . '.aux' |
||||
|
endif |
||||
|
|
||||
|
" 3. use the base name of main tex file |
||||
|
return LatexBox_GetBuildBasename(1) . '.aux' |
||||
|
endfunction |
||||
|
|
||||
|
function! LatexBox_GetLogFile() |
||||
|
" 1. check for b:build_dir variable |
||||
|
if exists('b:build_dir') && isdirectory(b:build_dir) |
||||
|
return b:build_dir . '/' . LatexBox_GetBuildBasename(0) . '.log' |
||||
|
endif |
||||
|
|
||||
|
" 2. check for g:LatexBox_build_dir variable |
||||
|
if exists('g:LatexBox_build_dir') && isdirectory(g:LatexBox_build_dir) |
||||
|
return g:LatexBox_build_dir . '/' . LatexBox_GetBuildBasename(0) . '.log' |
||||
|
endif |
||||
|
|
||||
|
" 3. use the base name of main tex file |
||||
|
return LatexBox_GetBuildBasename(1) . '.log' |
||||
|
endfunction |
||||
|
|
||||
|
function! LatexBox_GetOutputFile() |
||||
|
" 1. check for b:build_dir variable |
||||
|
if exists('b:build_dir') && isdirectory(b:build_dir) |
||||
|
return b:build_dir . '/' . LatexBox_GetBuildBasename(0) |
||||
|
\ . '.' . g:LatexBox_output_type |
||||
|
endif |
||||
|
|
||||
|
" 2. check for g:LatexBox_build_dir variable |
||||
|
if exists('g:LatexBox_build_dir') && isdirectory(g:LatexBox_build_dir) |
||||
|
return g:LatexBox_build_dir . '/' . LatexBox_GetBuildBasename(0) |
||||
|
\ . '.' . g:LatexBox_output_type |
||||
|
endif |
||||
|
|
||||
|
" 3. use the base name of main tex file |
||||
|
return LatexBox_GetBuildBasename(1) . '.' . g:LatexBox_output_type |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" View Output {{{ |
||||
|
|
||||
|
" Default pdf viewer |
||||
|
if !exists('g:LatexBox_viewer') |
||||
|
" On windows, 'running' a file will open it with the default program |
||||
|
let s:viewer = '' |
||||
|
if has('unix') |
||||
|
" echo -n necessary as uname -s will append \n otherwise |
||||
|
let s:uname = system('echo -n $(uname -s)') |
||||
|
if s:uname == "Darwin" |
||||
|
let s:viewer = 'open' |
||||
|
else |
||||
|
let s:viewer = 'xdg-open' |
||||
|
endif |
||||
|
endif |
||||
|
let g:LatexBox_viewer = s:viewer |
||||
|
endif |
||||
|
|
||||
|
function! LatexBox_View(...) |
||||
|
let lvargs = join(a:000, ' ') |
||||
|
let outfile = LatexBox_GetOutputFile() |
||||
|
if !filereadable(outfile) |
||||
|
echomsg fnamemodify(outfile, ':.') . ' is not readable' |
||||
|
return |
||||
|
endif |
||||
|
let cmd = g:LatexBox_viewer . ' ' . lvargs . ' ' . shellescape(outfile) |
||||
|
if has('win32') |
||||
|
let cmd = '!start /b ' . cmd . ' >nul' |
||||
|
else |
||||
|
let cmd = '!' . cmd . ' ' |
||||
|
if fnamemodify(&shell, ':t') ==# 'fish' |
||||
|
let cmd .= ' >/dev/null ^/dev/null &' |
||||
|
else |
||||
|
let cmd .= ' &>/dev/null &' |
||||
|
endif |
||||
|
endif |
||||
|
silent execute cmd |
||||
|
if !has("gui_running") |
||||
|
redraw! |
||||
|
endif |
||||
|
endfunction |
||||
|
|
||||
|
command! -nargs=* LatexView call LatexBox_View('<args>') |
||||
|
" }}} |
||||
|
|
||||
|
" In Comment {{{ |
||||
|
|
||||
|
" LatexBox_InComment([line], [col]) |
||||
|
" return true if inside comment |
||||
|
function! LatexBox_InComment(...) |
||||
|
let line = a:0 >= 1 ? a:1 : line('.') |
||||
|
let col = a:0 >= 2 ? a:2 : col('.') |
||||
|
return synIDattr(synID(line, col, 0), "name") =~# '^texComment' |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Get Current Environment {{{ |
||||
|
|
||||
|
" LatexBox_GetCurrentEnvironment([with_pos]) |
||||
|
" Returns: |
||||
|
" - environment |
||||
|
" if with_pos is not given |
||||
|
" - [envirnoment, lnum_begin, cnum_begin, lnum_end, cnum_end] |
||||
|
" if with_pos is nonzero |
||||
|
function! LatexBox_GetCurrentEnvironment(...) |
||||
|
if a:0 > 0 |
||||
|
let with_pos = a:1 |
||||
|
else |
||||
|
let with_pos = 0 |
||||
|
endif |
||||
|
|
||||
|
let begin_pat = '\C\\begin\_\s*{[^}]*}\|\\\@<!\\\[\|\\\@<!\\(' |
||||
|
let end_pat = '\C\\end\_\s*{[^}]*}\|\\\@<!\\\]\|\\\@<!\\)' |
||||
|
let saved_pos = getpos('.') |
||||
|
|
||||
|
" move to the left until on a backslash |
||||
|
let [bufnum, lnum, cnum, off] = getpos('.') |
||||
|
let line = getline(lnum) |
||||
|
while cnum > 1 && line[cnum - 1] != '\' |
||||
|
let cnum -= 1 |
||||
|
endwhile |
||||
|
call cursor(lnum, cnum) |
||||
|
|
||||
|
" match begin/end pairs but skip comments |
||||
|
let flags = 'bnW' |
||||
|
if strpart(getline('.'), col('.') - 1) =~ '^\%(' . begin_pat . '\)' |
||||
|
let flags .= 'c' |
||||
|
endif |
||||
|
let [lnum1, cnum1] = searchpairpos(begin_pat, '', end_pat, flags, |
||||
|
\ 'LatexBox_InComment()') |
||||
|
|
||||
|
let env = '' |
||||
|
|
||||
|
if lnum1 |
||||
|
let line = strpart(getline(lnum1), cnum1 - 1) |
||||
|
|
||||
|
if empty(env) |
||||
|
let env = matchstr(line, '^\C\\begin\_\s*{\zs[^}]*\ze}') |
||||
|
endif |
||||
|
if empty(env) |
||||
|
let env = matchstr(line, '^\\\[') |
||||
|
endif |
||||
|
if empty(env) |
||||
|
let env = matchstr(line, '^\\(') |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
if with_pos == 1 |
||||
|
let flags = 'nW' |
||||
|
if !(lnum1 == lnum && cnum1 == cnum) |
||||
|
let flags .= 'c' |
||||
|
endif |
||||
|
|
||||
|
let [lnum2, cnum2] = searchpairpos(begin_pat, '', end_pat, flags, |
||||
|
\ 'LatexBox_InComment()') |
||||
|
|
||||
|
call setpos('.', saved_pos) |
||||
|
return [env, lnum1, cnum1, lnum2, cnum2] |
||||
|
else |
||||
|
call setpos('.', saved_pos) |
||||
|
return env |
||||
|
endif |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Tex To Tree {{{ |
||||
|
" stores nested braces in a tree structure |
||||
|
function! LatexBox_TexToTree(str) |
||||
|
let tree = [] |
||||
|
let i1 = 0 |
||||
|
let i2 = -1 |
||||
|
let depth = 0 |
||||
|
while i2 < len(a:str) |
||||
|
let i2 = match(a:str, '[{}]', i2 + 1) |
||||
|
if i2 < 0 |
||||
|
let i2 = len(a:str) |
||||
|
endif |
||||
|
if i2 >= len(a:str) || a:str[i2] == '{' |
||||
|
if depth == 0 |
||||
|
let item = substitute(strpart(a:str, i1, i2 - i1), |
||||
|
\ '^\s*\|\s*$', '', 'g') |
||||
|
if !empty(item) |
||||
|
call add(tree, item) |
||||
|
endif |
||||
|
let i1 = i2 + 1 |
||||
|
endif |
||||
|
let depth += 1 |
||||
|
else |
||||
|
let depth -= 1 |
||||
|
if depth == 0 |
||||
|
call add(tree, LatexBox_TexToTree(strpart(a:str, i1, i2 - i1))) |
||||
|
let i1 = i2 + 1 |
||||
|
endif |
||||
|
endif |
||||
|
endwhile |
||||
|
return tree |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Tree To Tex {{{ |
||||
|
function! LatexBox_TreeToTex(tree) |
||||
|
if type(a:tree) == type('') |
||||
|
return a:tree |
||||
|
else |
||||
|
return '{' . join(map(a:tree, 'LatexBox_TreeToTex(v:val)'), '') . '}' |
||||
|
endif |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" vim:fdm=marker:ff=unix:noet:ts=4:sw=4 |
||||
@ -0,0 +1,932 @@ |
|||||
|
" LaTeX Box completion |
||||
|
|
||||
|
setlocal omnifunc=LatexBox_Complete |
||||
|
|
||||
|
" <SID> Wrap {{{ |
||||
|
function! s:GetSID() |
||||
|
return matchstr(expand('<sfile>'), '\zs<SNR>\d\+_\ze.*$') |
||||
|
endfunction |
||||
|
let s:SID = s:GetSID() |
||||
|
function! s:SIDWrap(func) |
||||
|
return s:SID . a:func |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Completion {{{ |
||||
|
if !exists('g:LatexBox_completion_close_braces') |
||||
|
let g:LatexBox_completion_close_braces = 1 |
||||
|
endif |
||||
|
if !exists('g:LatexBox_bibtex_wild_spaces') |
||||
|
let g:LatexBox_bibtex_wild_spaces = 1 |
||||
|
endif |
||||
|
|
||||
|
if !exists('g:LatexBox_cite_pattern') |
||||
|
let g:LatexBox_cite_pattern = '\C\\\a*cite\a*\*\?\(\[[^\]]*\]\)*\_\s*{' |
||||
|
endif |
||||
|
if !exists('g:LatexBox_ref_pattern') |
||||
|
let g:LatexBox_ref_pattern = '\C\\v\?\(eq\|page\|[cC]\|labelc\|name\|auto\)\?ref\*\?\_\s*{' |
||||
|
endif |
||||
|
|
||||
|
if !exists('g:LatexBox_completion_environments') |
||||
|
let g:LatexBox_completion_environments = [ |
||||
|
\ {'word': 'itemize', 'menu': 'bullet list' }, |
||||
|
\ {'word': 'enumerate', 'menu': 'numbered list' }, |
||||
|
\ {'word': 'description', 'menu': 'description' }, |
||||
|
\ {'word': 'center', 'menu': 'centered text' }, |
||||
|
\ {'word': 'figure', 'menu': 'floating figure' }, |
||||
|
\ {'word': 'table', 'menu': 'floating table' }, |
||||
|
\ {'word': 'equation', 'menu': 'equation (numbered)' }, |
||||
|
\ {'word': 'align', 'menu': 'aligned equations (numbered)' }, |
||||
|
\ {'word': 'align*', 'menu': 'aligned equations' }, |
||||
|
\ {'word': 'document' }, |
||||
|
\ {'word': 'abstract' }, |
||||
|
\ ] |
||||
|
endif |
||||
|
|
||||
|
if !exists('g:LatexBox_completion_commands') |
||||
|
let g:LatexBox_completion_commands = [ |
||||
|
\ {'word': '\begin{' }, |
||||
|
\ {'word': '\end{' }, |
||||
|
\ {'word': '\item' }, |
||||
|
\ {'word': '\label{' }, |
||||
|
\ {'word': '\ref{' }, |
||||
|
\ {'word': '\eqref{eq:' }, |
||||
|
\ {'word': '\cite{' }, |
||||
|
\ {'word': '\chapter{' }, |
||||
|
\ {'word': '\section{' }, |
||||
|
\ {'word': '\subsection{' }, |
||||
|
\ {'word': '\subsubsection{' }, |
||||
|
\ {'word': '\paragraph{' }, |
||||
|
\ {'word': '\nonumber' }, |
||||
|
\ {'word': '\bibliography' }, |
||||
|
\ {'word': '\bibliographystyle' }, |
||||
|
\ ] |
||||
|
endif |
||||
|
|
||||
|
if !exists('g:LatexBox_complete_inlineMath') |
||||
|
let g:LatexBox_complete_inlineMath = 0 |
||||
|
endif |
||||
|
|
||||
|
if !exists('g:LatexBox_eq_env_patterns') |
||||
|
let g:LatexBox_eq_env_patterns = 'equation\|gather\|multiline\|align\|flalign\|alignat\|eqnarray' |
||||
|
endif |
||||
|
|
||||
|
" }}} |
||||
|
|
||||
|
"LatexBox_kpsewhich {{{ |
||||
|
function! LatexBox_kpsewhich(file) |
||||
|
let old_dir = getcwd() |
||||
|
execute 'lcd ' . fnameescape(LatexBox_GetTexRoot()) |
||||
|
let out = system('kpsewhich "' . a:file . '"') |
||||
|
|
||||
|
" If kpsewhich has found something, it returns a non-empty string with a |
||||
|
" newline at the end; otherwise the string is empty |
||||
|
if len(out) |
||||
|
" Remove the trailing newline |
||||
|
let out = fnamemodify(out[:-2], ':p') |
||||
|
endif |
||||
|
|
||||
|
execute 'lcd ' . fnameescape(old_dir) |
||||
|
|
||||
|
return out |
||||
|
endfunction |
||||
|
"}}} |
||||
|
|
||||
|
" Omni Completion {{{ |
||||
|
|
||||
|
let s:completion_type = '' |
||||
|
|
||||
|
function! LatexBox_Complete(findstart, base) |
||||
|
if a:findstart |
||||
|
" return the starting position of the word |
||||
|
let line = getline('.') |
||||
|
let pos = col('.') - 1 |
||||
|
while pos > 0 && line[pos - 1] !~ '\\\|{' |
||||
|
let pos -= 1 |
||||
|
endwhile |
||||
|
|
||||
|
let line_start = line[:pos-1] |
||||
|
if line_start =~ '\m\C\\begin\_\s*{$' |
||||
|
let s:completion_type = 'begin' |
||||
|
elseif line_start =~ '\m\C\\end\_\s*{$' |
||||
|
let s:completion_type = 'end' |
||||
|
elseif line_start =~ '\m' . g:LatexBox_ref_pattern . '$' |
||||
|
let s:completion_type = 'ref' |
||||
|
elseif line_start =~ '\m' . g:LatexBox_cite_pattern . '$' |
||||
|
let s:completion_type = 'bib' |
||||
|
" check for multiple citations |
||||
|
let pos = col('.') - 1 |
||||
|
while pos > 0 && line[pos - 1] !~ '{\|,' |
||||
|
let pos -= 1 |
||||
|
endwhile |
||||
|
elseif s:LatexBox_complete_inlineMath_or_not() |
||||
|
let s:completion_type = 'inlineMath' |
||||
|
let pos = s:eq_pos |
||||
|
else |
||||
|
let s:completion_type = 'command' |
||||
|
if line[pos - 1] == '\' |
||||
|
let pos -= 1 |
||||
|
endif |
||||
|
endif |
||||
|
return pos |
||||
|
else |
||||
|
" return suggestions in an array |
||||
|
let suggestions = [] |
||||
|
|
||||
|
if s:completion_type == 'begin' |
||||
|
" suggest known environments |
||||
|
for entry in g:LatexBox_completion_environments |
||||
|
if entry.word =~ '^' . escape(a:base, '\') |
||||
|
if g:LatexBox_completion_close_braces && !s:NextCharsMatch('^}') |
||||
|
" add trailing '}' |
||||
|
let entry = copy(entry) |
||||
|
let entry.abbr = entry.word |
||||
|
let entry.word = entry.word . '}' |
||||
|
endif |
||||
|
call add(suggestions, entry) |
||||
|
endif |
||||
|
endfor |
||||
|
elseif s:completion_type == 'end' |
||||
|
" suggest known environments |
||||
|
let env = LatexBox_GetCurrentEnvironment() |
||||
|
if env != '' |
||||
|
if g:LatexBox_completion_close_braces && !s:NextCharsMatch('^\s*[,}]') |
||||
|
call add(suggestions, {'word': env . '}', 'abbr': env}) |
||||
|
else |
||||
|
call add(suggestions, env) |
||||
|
endif |
||||
|
endif |
||||
|
elseif s:completion_type == 'command' |
||||
|
" suggest known commands |
||||
|
for entry in g:LatexBox_completion_commands |
||||
|
if entry.word =~ '^' . escape(a:base, '\') |
||||
|
" do not display trailing '{' |
||||
|
if entry.word =~ '{' |
||||
|
let entry.abbr = entry.word[0:-2] |
||||
|
endif |
||||
|
call add(suggestions, entry) |
||||
|
endif |
||||
|
endfor |
||||
|
elseif s:completion_type == 'ref' |
||||
|
let suggestions = s:CompleteLabels(a:base) |
||||
|
elseif s:completion_type == 'bib' |
||||
|
" suggest BibTeX entries |
||||
|
let suggestions = LatexBox_BibComplete(a:base) |
||||
|
elseif s:completion_type == 'inlineMath' |
||||
|
let suggestions = s:LatexBox_inlineMath_completion(a:base) |
||||
|
endif |
||||
|
if !has('gui_running') |
||||
|
redraw! |
||||
|
endif |
||||
|
return suggestions |
||||
|
endif |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" BibTeX search {{{ |
||||
|
|
||||
|
" find the \bibliography{...} commands |
||||
|
" the optional argument is the file name to be searched |
||||
|
|
||||
|
function! s:FindBibData(...) |
||||
|
if a:0 == 0 |
||||
|
let file = LatexBox_GetMainTexFile() |
||||
|
else |
||||
|
let file = a:1 |
||||
|
endif |
||||
|
|
||||
|
if !filereadable(file) |
||||
|
return [] |
||||
|
endif |
||||
|
let lines = readfile(file) |
||||
|
let bibdata_list = [] |
||||
|
|
||||
|
" |
||||
|
" Search for added bibliographies |
||||
|
" |
||||
|
let bibliography_cmds = [ |
||||
|
\ '\\bibliography', |
||||
|
\ '\\addbibresource', |
||||
|
\ '\\addglobalbib', |
||||
|
\ '\\addsectionbib', |
||||
|
\ ] |
||||
|
for cmd in bibliography_cmds |
||||
|
let filtered = filter(copy(lines), |
||||
|
\ 'v:val =~ ''\C' . cmd . '\s*{[^}]\+}''') |
||||
|
let files = map(filtered, |
||||
|
\ 'matchstr(v:val, ''\C' . cmd . '\s*{\zs[^}]\+\ze}'')') |
||||
|
for file in files |
||||
|
let bibdata_list += map(split(file, ','), |
||||
|
\ 'fnamemodify(v:val, '':r'')') |
||||
|
endfor |
||||
|
endfor |
||||
|
|
||||
|
" |
||||
|
" Also search included files |
||||
|
" |
||||
|
for input in filter(lines, |
||||
|
\ 'v:val =~ ''\C\\\%(input\|include\)\s*{[^}]\+}''') |
||||
|
let bibdata_list += s:FindBibData(LatexBox_kpsewhich( |
||||
|
\ matchstr(input, |
||||
|
\ '\C\\\%(input\|include\)\s*{\zs[^}]\+\ze}'))) |
||||
|
endfor |
||||
|
|
||||
|
return bibdata_list |
||||
|
endfunction |
||||
|
|
||||
|
let s:bstfile = expand('<sfile>:p:h') . '/vimcomplete' |
||||
|
|
||||
|
function! LatexBox_BibSearch(regexp) |
||||
|
let res = [] |
||||
|
|
||||
|
" Find data from bib files |
||||
|
let bibdata = join(s:FindBibData(), ',') |
||||
|
if bibdata != '' |
||||
|
|
||||
|
" write temporary aux file |
||||
|
let tmpbase = LatexBox_GetTexRoot() . '/_LatexBox_BibComplete' |
||||
|
let auxfile = tmpbase . '.aux' |
||||
|
let bblfile = tmpbase . '.bbl' |
||||
|
let blgfile = tmpbase . '.blg' |
||||
|
|
||||
|
call writefile(['\citation{*}', '\bibstyle{' . s:bstfile . '}', |
||||
|
\ '\bibdata{' . bibdata . '}'], auxfile) |
||||
|
|
||||
|
if has('win32') |
||||
|
let l:old_shellslash = &l:shellslash |
||||
|
setlocal noshellslash |
||||
|
call system('cd ' . shellescape(LatexBox_GetTexRoot()) . |
||||
|
\ ' & bibtex -terse ' |
||||
|
\ . fnamemodify(auxfile, ':t') . ' >nul') |
||||
|
let &l:shellslash = l:old_shellslash |
||||
|
else |
||||
|
call system('cd ' . shellescape(LatexBox_GetTexRoot()) . |
||||
|
\ ' ; bibtex -terse ' |
||||
|
\ . fnamemodify(auxfile, ':t') . ' >/dev/null') |
||||
|
endif |
||||
|
|
||||
|
let lines = split(substitute(join(readfile(bblfile), "\n"), |
||||
|
\ '\n\n\@!\(\s\=\)\s*\|{\|}', '\1', 'g'), "\n") |
||||
|
|
||||
|
for line in filter(lines, 'v:val =~ a:regexp') |
||||
|
let matches = matchlist(line, |
||||
|
\ '^\(.*\)||\(.*\)||\(.*\)||\(.*\)||\(.*\)') |
||||
|
if !empty(matches) && !empty(matches[1]) |
||||
|
let s:type_length = max([s:type_length, |
||||
|
\ len(matches[2]) + 3]) |
||||
|
call add(res, { |
||||
|
\ 'key': matches[1], |
||||
|
\ 'type': matches[2], |
||||
|
\ 'author': matches[3], |
||||
|
\ 'year': matches[4], |
||||
|
\ 'title': matches[5], |
||||
|
\ }) |
||||
|
endif |
||||
|
endfor |
||||
|
|
||||
|
call delete(auxfile) |
||||
|
call delete(bblfile) |
||||
|
call delete(blgfile) |
||||
|
endif |
||||
|
|
||||
|
" Find data from 'thebibliography' environments |
||||
|
let lines = readfile(LatexBox_GetMainTexFile()) |
||||
|
if match(lines, '\C\\begin{thebibliography}') >= 0 |
||||
|
for line in filter(filter(lines, 'v:val =~ ''\C\\bibitem'''), |
||||
|
\ 'v:val =~ a:regexp') |
||||
|
let match = matchlist(line, '\\bibitem{\([^}]*\)')[1] |
||||
|
call add(res, { |
||||
|
\ 'key': match, |
||||
|
\ 'type': '', |
||||
|
\ 'author': '', |
||||
|
\ 'year': '', |
||||
|
\ 'title': match, |
||||
|
\ }) |
||||
|
endfor |
||||
|
endif |
||||
|
|
||||
|
return res |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" BibTeX completion {{{ |
||||
|
let s:type_length=0 |
||||
|
function! LatexBox_BibComplete(regexp) |
||||
|
|
||||
|
" treat spaces as '.*' if needed |
||||
|
if g:LatexBox_bibtex_wild_spaces |
||||
|
"let regexp = substitute(a:regexp, '\s\+', '.*', 'g') |
||||
|
let regexp = '.*' . substitute(a:regexp, '\s\+', '\\\&.*', 'g') |
||||
|
else |
||||
|
let regexp = a:regexp |
||||
|
endif |
||||
|
|
||||
|
let res = [] |
||||
|
let s:type_length = 4 |
||||
|
for m in LatexBox_BibSearch(regexp) |
||||
|
let type = m['type'] == '' ? '[-]' : '[' . m['type'] . '] ' |
||||
|
let type = printf('%-' . s:type_length . 's', type) |
||||
|
let auth = m['author'] == '' ? '' : m['author'][:20] . ' ' |
||||
|
let auth = substitute(auth, '\~', ' ', 'g') |
||||
|
let auth = substitute(auth, ',.*\ze', ' et al. ', '') |
||||
|
let year = m['year'] == '' ? '' : '(' . m['year'] . ')' |
||||
|
let w = { 'word': m['key'], |
||||
|
\ 'abbr': type . auth . year, |
||||
|
\ 'menu': m['title'] } |
||||
|
|
||||
|
" close braces if needed |
||||
|
if g:LatexBox_completion_close_braces && !s:NextCharsMatch('^\s*[,}]') |
||||
|
let w.word = w.word . '}' |
||||
|
endif |
||||
|
|
||||
|
call add(res, w) |
||||
|
endfor |
||||
|
return res |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" ExtractLabels {{{ |
||||
|
" Generate list of \newlabel commands in current buffer. |
||||
|
" |
||||
|
" Searches the current buffer for commands of the form |
||||
|
" \newlabel{name}{{number}{page}.* |
||||
|
" and returns list of [ name, number, page ] tuples. |
||||
|
function! s:ExtractLabels() |
||||
|
call cursor(1,1) |
||||
|
|
||||
|
let matches = [] |
||||
|
let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) |
||||
|
|
||||
|
while [lblline, lblbegin] != [0,0] |
||||
|
let [nln, nameend] = searchpairpos( '{', '', '}', 'W' ) |
||||
|
if nln != lblline |
||||
|
let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) |
||||
|
continue |
||||
|
endif |
||||
|
let curname = strpart( getline( lblline ), lblbegin, nameend - lblbegin - 1 ) |
||||
|
|
||||
|
" Ignore cref entries (because they are duplicates) |
||||
|
if curname =~# "@cref$" |
||||
|
let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) |
||||
|
continue |
||||
|
endif |
||||
|
|
||||
|
if 0 == search( '\m{\w*{', 'ce', lblline ) |
||||
|
let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) |
||||
|
continue |
||||
|
endif |
||||
|
|
||||
|
let numberbegin = getpos('.')[2] |
||||
|
let [nln, numberend] = searchpairpos( '{', '', '}', 'W' ) |
||||
|
if nln != lblline |
||||
|
let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) |
||||
|
continue |
||||
|
endif |
||||
|
let curnumber = strpart( getline( lblline ), numberbegin, numberend - numberbegin - 1 ) |
||||
|
|
||||
|
if 0 == search( '\m\w*{', 'ce', lblline ) |
||||
|
let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) |
||||
|
continue |
||||
|
endif |
||||
|
|
||||
|
let pagebegin = getpos('.')[2] |
||||
|
let [nln, pageend] = searchpairpos( '{', '', '}', 'W' ) |
||||
|
if nln != lblline |
||||
|
let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) |
||||
|
continue |
||||
|
endif |
||||
|
let curpage = strpart( getline( lblline ), pagebegin, pageend - pagebegin - 1 ) |
||||
|
|
||||
|
let matches += [ [ curname, curnumber, curpage ] ] |
||||
|
|
||||
|
let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) |
||||
|
endwhile |
||||
|
|
||||
|
return matches |
||||
|
endfunction |
||||
|
"}}} |
||||
|
|
||||
|
" ExtractInputs {{{ |
||||
|
" Generate list of \@input commands in current buffer. |
||||
|
" |
||||
|
" Searches the current buffer for \@input{file} entries and |
||||
|
" returns list of all files. |
||||
|
function! s:ExtractInputs() |
||||
|
call cursor(1,1) |
||||
|
|
||||
|
let matches = [] |
||||
|
let [inline, inbegin] = searchpos( '\\@input{', 'ecW' ) |
||||
|
|
||||
|
while [inline, inbegin] != [0,0] |
||||
|
let [nln, inend] = searchpairpos( '{', '', '}', 'W' ) |
||||
|
if nln != inline |
||||
|
let [inline, inbegin] = searchpos( '\\@input{', 'ecW' ) |
||||
|
continue |
||||
|
endif |
||||
|
let matches += [ LatexBox_kpsewhich(strpart( getline( inline ), inbegin, inend - inbegin - 1 )) ] |
||||
|
|
||||
|
let [inline, inbegin] = searchpos( '\\@input{', 'ecW' ) |
||||
|
endwhile |
||||
|
|
||||
|
" Remove empty strings for nonexistant .aux files |
||||
|
return filter(matches, 'v:val != ""') |
||||
|
endfunction |
||||
|
"}}} |
||||
|
|
||||
|
" LabelCache {{{ |
||||
|
" Cache of all labels. |
||||
|
" |
||||
|
" LabelCache is a dictionary mapping filenames to tuples |
||||
|
" [ time, labels, inputs ] |
||||
|
" where |
||||
|
" * time is modification time of the cache entry |
||||
|
" * labels is a list like returned by ExtractLabels |
||||
|
" * inputs is a list like returned by ExtractInputs |
||||
|
let s:LabelCache = {} |
||||
|
"}}} |
||||
|
|
||||
|
" GetLabelCache {{{ |
||||
|
" Extract labels from LabelCache and update it. |
||||
|
" |
||||
|
" Compares modification time of each entry in the label |
||||
|
" cache and updates it, if necessary. During traversal of |
||||
|
" the LabelCache, all current labels are collected and |
||||
|
" returned. |
||||
|
function! s:GetLabelCache(file) |
||||
|
if !filereadable(a:file) |
||||
|
return [] |
||||
|
endif |
||||
|
|
||||
|
if !has_key(s:LabelCache , a:file) || s:LabelCache[a:file][0] != getftime(a:file) |
||||
|
" Open file in temporary split window for label extraction. |
||||
|
let main_tex_file = LatexBox_GetMainTexFile() |
||||
|
silent execute '1sp +let\ b:main_tex_file=main_tex_file|let\ labels=s:ExtractLabels()|let\ inputs=s:ExtractInputs()|quit! ' . fnameescape(a:file) |
||||
|
let s:LabelCache[a:file] = [ getftime(a:file), labels, inputs ] |
||||
|
endif |
||||
|
|
||||
|
" We need to create a copy of s:LabelCache[fid][1], otherwise all inputs' |
||||
|
" labels would be added to the current file's label cache upon each |
||||
|
" completion call, leading to duplicates/triplicates/etc. and decreased |
||||
|
" performance. |
||||
|
" Also, because we don't anything with the list besides matching copies, |
||||
|
" we can get away with a shallow copy for now. |
||||
|
let labels = copy(s:LabelCache[a:file][1]) |
||||
|
|
||||
|
for input in s:LabelCache[a:file][2] |
||||
|
let labels += s:GetLabelCache(input) |
||||
|
endfor |
||||
|
|
||||
|
return labels |
||||
|
endfunction |
||||
|
"}}} |
||||
|
|
||||
|
" Complete Labels {{{ |
||||
|
function! s:CompleteLabels(regex) |
||||
|
let labels = s:GetLabelCache(LatexBox_GetAuxFile()) |
||||
|
|
||||
|
let matches = filter( copy(labels), 'match(v:val[0], "' . a:regex . '") != -1' ) |
||||
|
if empty(matches) |
||||
|
" also try to match label and number |
||||
|
let regex_split = split(a:regex) |
||||
|
if len(regex_split) > 1 |
||||
|
let base = regex_split[0] |
||||
|
let number = escape(join(regex_split[1:], ' '), '.') |
||||
|
let matches = filter( copy(labels), 'match(v:val[0], "' . base . '") != -1 && match(v:val[1], "' . number . '") != -1' ) |
||||
|
endif |
||||
|
endif |
||||
|
if empty(matches) |
||||
|
" also try to match number |
||||
|
let matches = filter( copy(labels), 'match(v:val[1], "' . a:regex . '") != -1' ) |
||||
|
endif |
||||
|
|
||||
|
let suggestions = [] |
||||
|
for m in matches |
||||
|
let entry = {'word': m[0], 'menu': printf("%7s [p. %s]", '('.m[1].')', m[2])} |
||||
|
if g:LatexBox_completion_close_braces && !s:NextCharsMatch('^\s*[,}]') |
||||
|
" add trailing '}' |
||||
|
let entry = copy(entry) |
||||
|
let entry.abbr = entry.word |
||||
|
let entry.word = entry.word . '}' |
||||
|
endif |
||||
|
call add(suggestions, entry) |
||||
|
endfor |
||||
|
|
||||
|
return suggestions |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Complete Inline Math Or Not {{{ |
||||
|
" Return 1, when cursor is in a math env: |
||||
|
" 1, there is a single $ in the current line on the left of cursor |
||||
|
" 2, there is an open-eq-env on/above the current line |
||||
|
" (open-eq-env : \(, \[, and \begin{eq-env} ) |
||||
|
" Return 0, when cursor is not in a math env |
||||
|
function! s:LatexBox_complete_inlineMath_or_not() |
||||
|
|
||||
|
" switch of inline math completion feature |
||||
|
if g:LatexBox_complete_inlineMath == 0 |
||||
|
return 0 |
||||
|
endif |
||||
|
|
||||
|
" env names that can't appear in an eq env |
||||
|
if !exists('s:LatexBox_doc_structure_patterns') |
||||
|
let s:LatexBox_doc_structure_patterns = '\%(' . '\\begin\s*{document}\|' . |
||||
|
\ '\\\%(chapter\|section\|subsection\|subsubsection\)\*\?\s*{' . '\)' |
||||
|
endif |
||||
|
|
||||
|
if !exists('s:LatexBox_eq_env_open_patterns') |
||||
|
let s:LatexBox_eq_env_open_patterns = ['\\(','\\\['] |
||||
|
endif |
||||
|
if !exists('s:LatexBox_eq_env_close_patterns') |
||||
|
let s:LatexBox_eq_env_close_patterns = ['\\)','\\\]'] |
||||
|
endif |
||||
|
|
||||
|
let notcomment = '\%(\%(\\\@<!\%(\\\\\)*\)\@<=%.*\)\@<!' |
||||
|
|
||||
|
let lnum_saved = line('.') |
||||
|
let cnum_saved = col('.') -1 |
||||
|
|
||||
|
let line = getline('.') |
||||
|
let line_start_2_cnum_saved = line[:cnum_saved] |
||||
|
|
||||
|
" determine whether there is a single $ before cursor |
||||
|
let cursor_dollar_pair = 0 |
||||
|
while matchend(line_start_2_cnum_saved, '\$[^$]\+\$', cursor_dollar_pair) >= 0 |
||||
|
" find the end of dollar pair |
||||
|
let cursor_dollar_pair = matchend(line_start_2_cnum_saved, '\$[^$]\+\$', cursor_dollar_pair) |
||||
|
endwhile |
||||
|
" find single $ after cursor_dollar_pair |
||||
|
let cursor_single_dollar = matchend(line_start_2_cnum_saved, '\$', cursor_dollar_pair) |
||||
|
|
||||
|
" if single $ is found |
||||
|
if cursor_single_dollar >= 0 |
||||
|
" check whether $ is in \(...\), \[...\], or \begin{eq}...\end{eq} |
||||
|
|
||||
|
" check current line, |
||||
|
" search for LatexBox_eq_env_close_patterns: \[ and \( |
||||
|
let lnum = line('.') |
||||
|
for i in range(0, (len(s:LatexBox_eq_env_open_patterns)-1)) |
||||
|
call cursor(lnum_saved, cnum_saved) |
||||
|
let cnum_close = searchpos(''. s:LatexBox_eq_env_close_patterns[i].'', 'cbW', lnum_saved)[1] |
||||
|
let cnum_open = matchend(line_start_2_cnum_saved, s:LatexBox_eq_env_open_patterns[i], cnum_close) |
||||
|
if cnum_open >= 0 |
||||
|
let s:eq_dollar_parenthesis_bracket_empty = '' |
||||
|
let s:eq_pos = cursor_single_dollar - 1 |
||||
|
return 1 |
||||
|
end |
||||
|
endfor |
||||
|
|
||||
|
" check the lines above |
||||
|
" search for s:LatexBox_doc_structure_patterns, and end-of-math-env |
||||
|
let lnum -= 1 |
||||
|
while lnum > 0 |
||||
|
let line = getline(lnum) |
||||
|
if line =~ notcomment . '\(' . s:LatexBox_doc_structure_patterns . |
||||
|
\ '\|' . '\\end\s*{\(' . g:LatexBox_eq_env_patterns . '\)\*\?}\)' |
||||
|
" when s:LatexBox_doc_structure_patterns or g:LatexBox_eq_env_patterns |
||||
|
" are found first, complete math, leave with $ at both sides |
||||
|
let s:eq_dollar_parenthesis_bracket_empty = '$' |
||||
|
let s:eq_pos = cursor_single_dollar |
||||
|
break |
||||
|
elseif line =~ notcomment . '\\begin\s*{\(' . g:LatexBox_eq_env_patterns . '\)\*\?}' |
||||
|
" g:LatexBox_eq_env_patterns is found, complete math, remove $ |
||||
|
let s:eq_dollar_parenthesis_bracket_empty = '' |
||||
|
let s:eq_pos = cursor_single_dollar - 1 |
||||
|
break |
||||
|
endif |
||||
|
let lnum -= 1 |
||||
|
endwhile |
||||
|
|
||||
|
return 1 |
||||
|
else |
||||
|
" no $ is found, then search for \( or \[ in current line |
||||
|
" 1, whether there is \( |
||||
|
call cursor(lnum_saved, cnum_saved) |
||||
|
let cnum_parenthesis_close = searchpos('\\)', 'cbW', lnum_saved)[1] |
||||
|
let cnum_parenthesis_open = matchend(line_start_2_cnum_saved, '\\(', cnum_parenthesis_close) |
||||
|
if cnum_parenthesis_open >= 0 |
||||
|
let s:eq_dollar_parenthesis_bracket_empty = '\)' |
||||
|
let s:eq_pos = cnum_parenthesis_open |
||||
|
return 1 |
||||
|
end |
||||
|
|
||||
|
" 2, whether there is \[ |
||||
|
call cursor(lnum_saved, cnum_saved) |
||||
|
let cnum_bracket_close = searchpos('\\\]', 'cbW', lnum_saved)[1] |
||||
|
let cnum_bracket_open = matchend(line_start_2_cnum_saved, '\\\[', cnum_bracket_close) |
||||
|
if cnum_bracket_open >= 0 |
||||
|
let s:eq_dollar_parenthesis_bracket_empty = '\]' |
||||
|
let s:eq_pos = cnum_bracket_open |
||||
|
return 1 |
||||
|
end |
||||
|
|
||||
|
" not inline math completion |
||||
|
return 0 |
||||
|
endif |
||||
|
|
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Complete inline euqation{{{ |
||||
|
function! s:LatexBox_inlineMath_completion(regex, ...) |
||||
|
|
||||
|
if a:0 == 0 |
||||
|
let file = LatexBox_GetMainTexFile() |
||||
|
else |
||||
|
let file = a:1 |
||||
|
endif |
||||
|
|
||||
|
if empty(glob(file, 1)) |
||||
|
return '' |
||||
|
endif |
||||
|
|
||||
|
if empty(s:eq_dollar_parenthesis_bracket_empty) |
||||
|
let inline_pattern1 = '\$\s*\(' . escape(substitute(a:regex[1:], '^\s\+', '', ""), '\.*^') . '[^$]*\)\s*\$' |
||||
|
let inline_pattern2 = '\\(\s*\(' . escape(substitute(a:regex[1:], '^\s\+', '', ""), '\.*^') . '.*\)\s*\\)' |
||||
|
else |
||||
|
let inline_pattern1 = '\$\s*\(' . escape(substitute(a:regex, '^\s\+', '', ""), '\.*^') . '[^$]*\)\s*\$' |
||||
|
let inline_pattern2 = '\\(\s*\(' . escape(substitute(a:regex, '^\s\+', '', ""), '\.*^') . '.*\)\s*\\)' |
||||
|
endif |
||||
|
|
||||
|
|
||||
|
let suggestions = [] |
||||
|
let line_num = 0 |
||||
|
for line in readfile(file) |
||||
|
let line_num = line_num + 1 |
||||
|
|
||||
|
let suggestions += s:LatexBox_inlineMath_mathlist(line,inline_pattern1 , line_num) + s:LatexBox_inlineMath_mathlist( line,inline_pattern2, line_num) |
||||
|
|
||||
|
" search for included files |
||||
|
let included_file = matchstr(line, '^\\@input{\zs[^}]*\ze}') |
||||
|
if included_file != '' |
||||
|
let included_file = LatexBox_kpsewhich(included_file) |
||||
|
call extend(suggestions, s:LatexBox_inlineMath_completion(a:regex, included_file)) |
||||
|
endif |
||||
|
endfor |
||||
|
|
||||
|
return suggestions |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Search for inline maths {{{ |
||||
|
" search for $ ... $ and \( ... \) in each line |
||||
|
function! s:LatexBox_inlineMath_mathlist(line,inline_pattern, line_num) |
||||
|
let col_start = 0 |
||||
|
let suggestions = [] |
||||
|
while 1 |
||||
|
let matches = matchlist(a:line, a:inline_pattern, col_start) |
||||
|
if !empty(matches) |
||||
|
|
||||
|
" show line number of inline math |
||||
|
let entry = {'word': matches[1], 'menu': '[' . a:line_num . ']'} |
||||
|
|
||||
|
if s:eq_dollar_parenthesis_bracket_empty != '' |
||||
|
let entry = copy(entry) |
||||
|
let entry.abbr = entry.word |
||||
|
let entry.word = entry.word . s:eq_dollar_parenthesis_bracket_empty |
||||
|
endif |
||||
|
call add(suggestions, entry) |
||||
|
|
||||
|
" update col_start |
||||
|
let col_start = matchend(a:line, a:inline_pattern, col_start) |
||||
|
else |
||||
|
break |
||||
|
endif |
||||
|
endwhile |
||||
|
|
||||
|
return suggestions |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Close Current Environment {{{ |
||||
|
function! s:CloseCurEnv() |
||||
|
" first, try with \left/\right pairs |
||||
|
let [lnum, cnum] = searchpairpos('\C\\left\>', '', '\C\\right\>', 'bnW', 'LatexBox_InComment()') |
||||
|
if lnum |
||||
|
let line = strpart(getline(lnum), cnum - 1) |
||||
|
let bracket = matchstr(line, '^\\left\zs\((\|\[\|\\{\||\|\.\)\ze') |
||||
|
for [open, close] in [['(', ')'], ['\[', '\]'], ['\\{', '\\}'], ['|', '|'], ['\.', '|']] |
||||
|
let bracket = substitute(bracket, open, close, 'g') |
||||
|
endfor |
||||
|
return '\right' . bracket |
||||
|
endif |
||||
|
|
||||
|
" second, try with environments |
||||
|
let env = LatexBox_GetCurrentEnvironment() |
||||
|
if env == '\[' |
||||
|
return '\]' |
||||
|
elseif env == '\(' |
||||
|
return '\)' |
||||
|
elseif env != '' |
||||
|
return '\end{' . env . '}' |
||||
|
endif |
||||
|
return '' |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Wrap Selection {{{ |
||||
|
function! s:WrapSelection(wrapper) |
||||
|
keepjumps normal! `>a} |
||||
|
execute 'keepjumps normal! `<i\' . a:wrapper . '{' |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Wrap Selection in Environment with Prompt {{{ |
||||
|
function! s:PromptEnvWrapSelection(...) |
||||
|
let env = input('environment: ', '', 'customlist,' . s:SIDWrap('GetEnvironmentList')) |
||||
|
if empty(env) |
||||
|
return |
||||
|
endif |
||||
|
" LaTeXBox's custom indentation can interfere with environment |
||||
|
" insertion when environments are indented (common for nested |
||||
|
" environments). Temporarily disable it for this operation: |
||||
|
let ieOld = &indentexpr |
||||
|
setlocal indentexpr="" |
||||
|
if visualmode() ==# 'V' |
||||
|
execute 'keepjumps normal! `>o\end{' . env . '}' |
||||
|
execute 'keepjumps normal! `<O\begin{' . env . '}' |
||||
|
" indent and format, if requested. |
||||
|
if a:0 && a:1 |
||||
|
normal! gv> |
||||
|
normal! gvgq |
||||
|
endif |
||||
|
else |
||||
|
execute 'keepjumps normal! `>a\end{' . env . '}' |
||||
|
execute 'keepjumps normal! `<i\begin{' . env . '}' |
||||
|
endif |
||||
|
exe "setlocal indentexpr=" . ieOld |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" List Labels with Prompt {{{ |
||||
|
function! s:PromptLabelList(...) |
||||
|
" Check if window already exists |
||||
|
let winnr = bufwinnr(bufnr('LaTeX Labels')) |
||||
|
if winnr >= 0 |
||||
|
if a:0 == 0 |
||||
|
silent execute winnr . 'wincmd w' |
||||
|
else |
||||
|
" Supplying an argument to this function causes toggling instead |
||||
|
" of jumping to the labels window |
||||
|
if g:LatexBox_split_resize |
||||
|
silent exe "set columns-=" . g:LatexBox_split_width |
||||
|
endif |
||||
|
silent execute 'bwipeout' . bufnr('LaTeX Labels') |
||||
|
endif |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
" Get label suggestions |
||||
|
let regexp = input('filter labels with regexp: ', '') |
||||
|
let labels = s:CompleteLabels(regexp) |
||||
|
|
||||
|
let calling_buf = bufnr('%') |
||||
|
|
||||
|
" Create labels window and set local settings |
||||
|
if g:LatexBox_split_resize |
||||
|
silent exe "set columns+=" . g:LatexBox_split_width |
||||
|
endif |
||||
|
silent exe g:LatexBox_split_side g:LatexBox_split_width . 'vnew LaTeX\ Labels' |
||||
|
let b:toc = [] |
||||
|
let b:toc_numbers = 1 |
||||
|
let b:calling_win = bufwinnr(calling_buf) |
||||
|
setlocal filetype=latextoc |
||||
|
|
||||
|
" Add label entries and jump to the closest section |
||||
|
for entry in labels |
||||
|
let number = matchstr(entry['menu'], '^\s*(\zs[^)]\+\ze)') |
||||
|
let page = matchstr(entry['menu'], '^[^)]*)\s*\[\zs[^]]\+\ze\]') |
||||
|
let e = {'file': bufname(calling_buf), |
||||
|
\ 'level': 'label', |
||||
|
\ 'number': number, |
||||
|
\ 'text': entry['abbr'], |
||||
|
\ 'page': page} |
||||
|
call add(b:toc, e) |
||||
|
if b:toc_numbers |
||||
|
call append('$', e['number'] . "\t" . e['text']) |
||||
|
else |
||||
|
call append('$', e['text']) |
||||
|
endif |
||||
|
endfor |
||||
|
if !g:LatexBox_toc_hidehelp |
||||
|
call append('$', "") |
||||
|
call append('$', "<Esc>/q: close") |
||||
|
call append('$', "<Space>: jump") |
||||
|
call append('$', "<Enter>: jump and close") |
||||
|
call append('$', "s: hide numbering") |
||||
|
endif |
||||
|
0delete _ |
||||
|
|
||||
|
" Lock buffer |
||||
|
setlocal nomodifiable |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Change Environment {{{ |
||||
|
function! s:ChangeEnvPrompt() |
||||
|
|
||||
|
let [env, lnum, cnum, lnum2, cnum2] = LatexBox_GetCurrentEnvironment(1) |
||||
|
|
||||
|
let new_env = input('change ' . env . ' for: ', '', 'customlist,' . s:SIDWrap('GetEnvironmentList')) |
||||
|
if empty(new_env) |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
if new_env == '\[' || new_env == '[' |
||||
|
let begin = '\[' |
||||
|
let end = '\]' |
||||
|
elseif new_env == '\(' || new_env == '(' |
||||
|
let begin = '\(' |
||||
|
let end = '\)' |
||||
|
else |
||||
|
let l:begin = '\begin{' . new_env . '}' |
||||
|
let l:end = '\end{' . new_env . '}' |
||||
|
endif |
||||
|
|
||||
|
if env == '\[' || env == '\(' |
||||
|
let line = getline(lnum2) |
||||
|
let line = strpart(line, 0, cnum2 - 1) . l:end . strpart(line, cnum2 + 1) |
||||
|
call setline(lnum2, line) |
||||
|
|
||||
|
let line = getline(lnum) |
||||
|
let line = strpart(line, 0, cnum - 1) . l:begin . strpart(line, cnum + 1) |
||||
|
call setline(lnum, line) |
||||
|
else |
||||
|
let line = getline(lnum2) |
||||
|
let line = strpart(line, 0, cnum2 - 1) . l:end . strpart(line, cnum2 + len(env) + 5) |
||||
|
call setline(lnum2, line) |
||||
|
|
||||
|
let line = getline(lnum) |
||||
|
let line = strpart(line, 0, cnum - 1) . l:begin . strpart(line, cnum + len(env) + 7) |
||||
|
call setline(lnum, line) |
||||
|
endif |
||||
|
endfunction |
||||
|
|
||||
|
function! s:GetEnvironmentList(lead, cmdline, pos) |
||||
|
let suggestions = [] |
||||
|
for entry in g:LatexBox_completion_environments |
||||
|
let env = entry.word |
||||
|
if env =~ '^' . a:lead |
||||
|
call add(suggestions, env) |
||||
|
endif |
||||
|
endfor |
||||
|
return suggestions |
||||
|
endfunction |
||||
|
|
||||
|
function! s:LatexToggleStarEnv() |
||||
|
let [env, lnum, cnum, lnum2, cnum2] = LatexBox_GetCurrentEnvironment(1) |
||||
|
|
||||
|
if env == '\(' |
||||
|
return |
||||
|
elseif env == '\[' |
||||
|
let begin = '\begin{equation}' |
||||
|
let end = '\end{equation}' |
||||
|
elseif env[-1:] == '*' |
||||
|
let begin = '\begin{' . env[:-2] . '}' |
||||
|
let end = '\end{' . env[:-2] . '}' |
||||
|
else |
||||
|
let begin = '\begin{' . env . '*}' |
||||
|
let end = '\end{' . env . '*}' |
||||
|
endif |
||||
|
|
||||
|
if env == '\[' |
||||
|
let line = getline(lnum2) |
||||
|
let line = strpart(line, 0, cnum2 - 1) . l:end . strpart(line, cnum2 + 1) |
||||
|
call setline(lnum2, line) |
||||
|
|
||||
|
let line = getline(lnum) |
||||
|
let line = strpart(line, 0, cnum - 1) . l:begin . strpart(line, cnum + 1) |
||||
|
call setline(lnum, line) |
||||
|
else |
||||
|
let line = getline(lnum2) |
||||
|
let line = strpart(line, 0, cnum2 - 1) . l:end . strpart(line, cnum2 + len(env) + 5) |
||||
|
call setline(lnum2, line) |
||||
|
|
||||
|
let line = getline(lnum) |
||||
|
let line = strpart(line, 0, cnum - 1) . l:begin . strpart(line, cnum + len(env) + 7) |
||||
|
call setline(lnum, line) |
||||
|
endif |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Next Charaters Match {{{ |
||||
|
function! s:NextCharsMatch(regex) |
||||
|
let rest_of_line = strpart(getline('.'), col('.') - 1) |
||||
|
return rest_of_line =~ a:regex |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Mappings {{{ |
||||
|
inoremap <silent> <Plug>LatexCloseCurEnv <C-R>=<SID>CloseCurEnv()<CR> |
||||
|
vnoremap <silent> <Plug>LatexWrapSelection :<c-u>call <SID>WrapSelection('')<CR>i |
||||
|
vnoremap <silent> <Plug>LatexEnvWrapSelection :<c-u>call <SID>PromptEnvWrapSelection()<CR> |
||||
|
vnoremap <silent> <Plug>LatexEnvWrapFmtSelection :<c-u>call <SID>PromptEnvWrapSelection(1)<CR> |
||||
|
nnoremap <silent> <Plug>LatexChangeEnv :call <SID>ChangeEnvPrompt()<CR> |
||||
|
nnoremap <silent> <Plug>LatexToggleStarEnv :call <SID>LatexToggleStarEnv()<CR> |
||||
|
" }}} |
||||
|
|
||||
|
" Commands {{{ |
||||
|
command! LatexLabels call <SID>PromptLabelList() |
||||
|
" }}} |
||||
|
|
||||
|
" vim:fdm=marker:ff=unix:noet:ts=4:sw=4 |
||||
@ -0,0 +1,62 @@ |
|||||
|
" LatexBox_GetMainFileName: gets the name of the main file being compiled. {{{ |
||||
|
" Description: returns the full path name of the main file. |
||||
|
" This function checks for the existence of a .latexmain file |
||||
|
" which might point to the location of a "main" latex file. |
||||
|
" If .latexmain exists, then return the full path name of the |
||||
|
" file being pointed to by it. |
||||
|
" |
||||
|
" Otherwise, return the full path name of the current buffer. |
||||
|
" |
||||
|
" You can supply an optional "modifier" argument to the |
||||
|
" function, which will optionally modify the file name before |
||||
|
" returning. |
||||
|
" NOTE: From version 1.6 onwards, this function always trims |
||||
|
" away the .latexmain part of the file name before applying the |
||||
|
" modifier argument. |
||||
|
" NOTE: This function is copied from the Latex-Suite project! |
||||
|
function! LatexBox_GetMainFileName(...) |
||||
|
if a:0 > 0 |
||||
|
let modifier = a:1 |
||||
|
else |
||||
|
let modifier = ':p' |
||||
|
endif |
||||
|
|
||||
|
let s:origdir = fnameescape(getcwd()) |
||||
|
|
||||
|
let dirmodifier = '%:p:h' |
||||
|
let dirLast = fnameescape(expand(dirmodifier)) |
||||
|
exe 'cd '.dirLast |
||||
|
|
||||
|
" move up the directory tree until we find a .latexmain file. |
||||
|
" TODO: Should we be doing this recursion by default, or should there be a |
||||
|
" setting? |
||||
|
while glob('*.latexmain',1) == '' |
||||
|
let dirmodifier = dirmodifier.':h' |
||||
|
let dirNew = fnameescape(expand(dirmodifier)) |
||||
|
" break from the loop if we cannot go up any further. |
||||
|
if dirNew == dirLast |
||||
|
break |
||||
|
endif |
||||
|
let dirLast = dirNew |
||||
|
exe 'cd '.dirLast |
||||
|
endwhile |
||||
|
|
||||
|
let lheadfile = glob('*.latexmain',1) |
||||
|
if lheadfile != '' |
||||
|
" Remove the trailing .latexmain part of the filename... We never want |
||||
|
" that. |
||||
|
let lheadfile = fnamemodify(substitute(lheadfile, '\.latexmain$', '', ''), modifier) |
||||
|
else |
||||
|
" If we cannot find any main file, just modify the filename of the |
||||
|
" current buffer. |
||||
|
let lheadfile = expand('%'.modifier) |
||||
|
endif |
||||
|
|
||||
|
exe 'cd '.s:origdir |
||||
|
|
||||
|
" NOTE: The caller of this function needs to escape the file name with |
||||
|
" fnameescape() . The reason its not done here is that escaping is not |
||||
|
" safe if this file is to be used as part of an external command on |
||||
|
" certain platforms. |
||||
|
return lheadfile |
||||
|
endfunction |
||||
@ -0,0 +1,378 @@ |
|||||
|
" Folding support for LaTeX |
||||
|
|
||||
|
" |
||||
|
" Options |
||||
|
" g:LatexBox_Folding - Turn on/off folding |
||||
|
" g:LatexBox_fold_text - Turn on/off LatexBox fold text function |
||||
|
" g:LatexBox_fold_preamble - Turn on/off folding of preamble |
||||
|
" g:LatexBox_fold_parts - Define parts (eq. appendix, frontmatter) to fold |
||||
|
" g:LatexBox_fold_sections - Define section levels to fold |
||||
|
" g:LatexBox_fold_envs - Turn on/off folding of environments |
||||
|
" g:LatexBox_fold_toc - Turn on/off folding of TOC |
||||
|
" g:LatexBox_fold_toc_levels - Set max TOC fold level |
||||
|
" |
||||
|
" {{{1 Initialize options to default values. |
||||
|
if !exists('g:LatexBox_Folding') |
||||
|
let g:LatexBox_Folding=0 |
||||
|
endif |
||||
|
if !exists('g:LatexBox_fold_text') |
||||
|
let g:LatexBox_fold_text=1 |
||||
|
endif |
||||
|
if !exists('g:LatexBox_fold_preamble') |
||||
|
let g:LatexBox_fold_preamble=1 |
||||
|
endif |
||||
|
if !exists('g:LatexBox_fold_envs') |
||||
|
let g:LatexBox_fold_envs=1 |
||||
|
endif |
||||
|
if !exists('g:LatexBox_fold_envs_force') |
||||
|
let g:LatexBox_fold_envs_force = [] |
||||
|
endif |
||||
|
if !exists('g:LatexBox_fold_parts') |
||||
|
let g:LatexBox_fold_parts=[ |
||||
|
\ "appendix", |
||||
|
\ "frontmatter", |
||||
|
\ "mainmatter", |
||||
|
\ "backmatter" |
||||
|
\ ] |
||||
|
endif |
||||
|
if !exists('g:LatexBox_fold_sections') |
||||
|
let g:LatexBox_fold_sections=[ |
||||
|
\ "part", |
||||
|
\ "chapter", |
||||
|
\ "section", |
||||
|
\ "subsection", |
||||
|
\ "subsubsection" |
||||
|
\ ] |
||||
|
endif |
||||
|
if !exists('g:LatexBox_fold_toc') |
||||
|
let g:LatexBox_fold_toc=0 |
||||
|
endif |
||||
|
if !exists('g:LatexBox_fold_toc_levels') |
||||
|
let g:LatexBox_fold_toc_levels=1 |
||||
|
endif |
||||
|
if !exists('g:LatexBox_fold_automatic') |
||||
|
let g:LatexBox_fold_automatic=1 |
||||
|
endif |
||||
|
" }}}1 |
||||
|
|
||||
|
if g:LatexBox_Folding == 0 |
||||
|
finish |
||||
|
endif |
||||
|
|
||||
|
" {{{1 Set folding options for vim |
||||
|
setl foldexpr=LatexBox_FoldLevel(v:lnum) |
||||
|
if g:LatexBox_fold_text == 1 |
||||
|
setl foldtext=LatexBox_FoldText() |
||||
|
endif |
||||
|
if g:LatexBox_fold_automatic == 1 |
||||
|
setl foldmethod=expr |
||||
|
|
||||
|
" |
||||
|
" The foldexpr function returns "=" for most lines, which means it can become |
||||
|
" slow for large files. The following is a hack that is based on this reply to |
||||
|
" a discussion on the Vim Developer list: |
||||
|
" http://permalink.gmane.org/gmane.editors.vim.devel/14100 |
||||
|
" |
||||
|
augroup FastFold |
||||
|
autocmd! |
||||
|
autocmd InsertEnter *.tex if !&diff | setlocal foldmethod=manual | endif |
||||
|
autocmd InsertLeave *.tex if !&diff | setlocal foldmethod=expr | endif |
||||
|
augroup end |
||||
|
else |
||||
|
setl foldmethod=manual |
||||
|
endif |
||||
|
|
||||
|
function! LatexBox_FoldOnDemand() |
||||
|
setl foldmethod=expr |
||||
|
normal! zx |
||||
|
setl foldmethod=manual |
||||
|
endfunction |
||||
|
|
||||
|
command! LatexFold call LatexBox_FoldOnDemand() |
||||
|
|
||||
|
" {{{1 LatexBox_FoldLevel help functions |
||||
|
|
||||
|
" This function parses the tex file to find the sections that are to be folded |
||||
|
" and their levels, and then predefines the patterns for optimized folding. |
||||
|
function! s:FoldSectionLevels() |
||||
|
" Initialize |
||||
|
let level = 1 |
||||
|
let foldsections = [] |
||||
|
|
||||
|
" If we use two or more of the *matter commands, we need one more foldlevel |
||||
|
let nparts = 0 |
||||
|
for part in g:LatexBox_fold_parts |
||||
|
let i = 1 |
||||
|
while i < line("$") |
||||
|
if getline(i) =~ '^\s*\\' . part . '\>' |
||||
|
let nparts += 1 |
||||
|
break |
||||
|
endif |
||||
|
let i += 1 |
||||
|
endwhile |
||||
|
if nparts > 1 |
||||
|
let level = 2 |
||||
|
break |
||||
|
endif |
||||
|
endfor |
||||
|
|
||||
|
" Combine sections and levels, but ignore unused section commands: If we |
||||
|
" don't use the part command, then chapter should have the highest |
||||
|
" level. If we don't use the chapter command, then section should be the |
||||
|
" highest level. And so on. |
||||
|
let ignore = 1 |
||||
|
for part in g:LatexBox_fold_sections |
||||
|
" For each part, check if it is used in the file. We start adding the |
||||
|
" part patterns to the fold sections array whenever we find one. |
||||
|
let partpattern = '^\s*\(\\\|% Fake\)' . part . '\>' |
||||
|
if ignore |
||||
|
let i = 1 |
||||
|
while i < line("$") |
||||
|
if getline(i) =~# partpattern |
||||
|
call insert(foldsections, [partpattern, level]) |
||||
|
let level += 1 |
||||
|
let ignore = 0 |
||||
|
break |
||||
|
endif |
||||
|
let i += 1 |
||||
|
endwhile |
||||
|
else |
||||
|
call insert(foldsections, [partpattern, level]) |
||||
|
let level += 1 |
||||
|
endif |
||||
|
endfor |
||||
|
|
||||
|
return foldsections |
||||
|
endfunction |
||||
|
|
||||
|
" {{{1 LatexBox_FoldLevel |
||||
|
|
||||
|
" Parse file to dynamically set the sectioning fold levels |
||||
|
let b:LatexBox_FoldSections = s:FoldSectionLevels() |
||||
|
|
||||
|
" Optimize by predefine common patterns |
||||
|
let s:notbslash = '\%(\\\@<!\%(\\\\\)*\)\@<=' |
||||
|
let s:notcomment = '\%(\%(\\\@<!\%(\\\\\)*\)\@<=%.*\)\@<!' |
||||
|
let s:envbeginpattern = s:notcomment . s:notbslash . '\\begin\s*{.\{-}}' |
||||
|
let s:envendpattern = s:notcomment . s:notbslash . '\\end\s*{.\{-}}' |
||||
|
let s:foldparts = '^\s*\\\%(' . join(g:LatexBox_fold_parts, '\|') . '\)' |
||||
|
let s:folded = '\(% Fake\|\\\(document\|begin\|end\|paragraph\|' |
||||
|
\ . 'front\|main\|back\|app\|sub\|section\|chapter\|part\)\)' |
||||
|
|
||||
|
function! LatexBox_FoldLevel(lnum) |
||||
|
" Check for normal lines first (optimization) |
||||
|
let line = getline(a:lnum) |
||||
|
if line !~ s:folded |
||||
|
return "=" |
||||
|
endif |
||||
|
|
||||
|
" Fold preamble |
||||
|
if g:LatexBox_fold_preamble == 1 |
||||
|
if line =~# s:notcomment . s:notbslash . '\s*\\documentclass' |
||||
|
return ">1" |
||||
|
elseif line =~# s:notcomment . s:notbslash . '\s*\\begin\s*{\s*document\s*}' |
||||
|
return "0" |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
" Fold parts (\frontmatter, \mainmatter, \backmatter, and \appendix) |
||||
|
if line =~# s:foldparts |
||||
|
return ">1" |
||||
|
endif |
||||
|
|
||||
|
" Fold chapters and sections |
||||
|
for [part, level] in b:LatexBox_FoldSections |
||||
|
if line =~# part |
||||
|
return ">" . level |
||||
|
endif |
||||
|
endfor |
||||
|
|
||||
|
" Never fold \end{document} |
||||
|
if line =~# '^\s*\\end{document}' |
||||
|
return 0 |
||||
|
endif |
||||
|
|
||||
|
" Fold environments |
||||
|
if line =~# s:envbeginpattern && line =~# s:envendpattern |
||||
|
" If the begin and end pattern are on the same line , do not fold |
||||
|
return "=" |
||||
|
else |
||||
|
if line =~# s:envbeginpattern |
||||
|
if g:LatexBox_fold_envs == 1 |
||||
|
return "a1" |
||||
|
else |
||||
|
let env = matchstr(line,'\\begin\*\?{\zs\w*\*\?\ze}') |
||||
|
if index(g:LatexBox_fold_envs_force, env) >= 0 |
||||
|
return "a1" |
||||
|
else |
||||
|
return "=" |
||||
|
endif |
||||
|
endif |
||||
|
elseif line =~# s:envendpattern |
||||
|
if g:LatexBox_fold_envs == 1 |
||||
|
return "s1" |
||||
|
else |
||||
|
let env = matchstr(line,'\\end\*\?{\zs\w*\*\?\ze}') |
||||
|
if index(g:LatexBox_fold_envs_force, env) >= 0 |
||||
|
return "s1" |
||||
|
else |
||||
|
return "=" |
||||
|
endif |
||||
|
endif |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
" Return foldlevel of previous line |
||||
|
return "=" |
||||
|
endfunction |
||||
|
|
||||
|
" {{{1 LatexBox_FoldText help functions |
||||
|
function! s:LabelEnv() |
||||
|
let i = v:foldend |
||||
|
while i >= v:foldstart |
||||
|
if getline(i) =~ '^\s*\\label' |
||||
|
return matchstr(getline(i), '^\s*\\label{\zs.*\ze}') |
||||
|
end |
||||
|
let i -= 1 |
||||
|
endwhile |
||||
|
return "" |
||||
|
endfunction |
||||
|
|
||||
|
function! s:CaptionEnv() |
||||
|
let i = v:foldend |
||||
|
while i >= v:foldstart |
||||
|
if getline(i) =~ '^\s*\\caption' |
||||
|
return matchstr(getline(i), '^\s*\\caption\(\[.*\]\)\?{\zs.\+') |
||||
|
end |
||||
|
let i -= 1 |
||||
|
endwhile |
||||
|
return "" |
||||
|
endfunction |
||||
|
|
||||
|
function! s:CaptionTable() |
||||
|
let i = v:foldstart |
||||
|
while i <= v:foldend |
||||
|
if getline(i) =~ '^\s*\\caption' |
||||
|
return matchstr(getline(i), '^\s*\\caption\(\[.*\]\)\?{\zs.\+') |
||||
|
end |
||||
|
let i += 1 |
||||
|
endwhile |
||||
|
return "" |
||||
|
endfunction |
||||
|
|
||||
|
function! s:CaptionFrame(line) |
||||
|
" Test simple variants first |
||||
|
let caption1 = matchstr(a:line,'\\begin\*\?{.*}{\zs.\+\ze}') |
||||
|
let caption2 = matchstr(a:line,'\\begin\*\?{.*}{\zs.\+') |
||||
|
|
||||
|
if len(caption1) > 0 |
||||
|
return caption1 |
||||
|
elseif len(caption2) > 0 |
||||
|
return caption2 |
||||
|
else |
||||
|
let i = v:foldstart |
||||
|
while i <= v:foldend |
||||
|
if getline(i) =~ '^\s*\\frametitle' |
||||
|
return matchstr(getline(i), |
||||
|
\ '^\s*\\frametitle\(\[.*\]\)\?{\zs.\+') |
||||
|
end |
||||
|
let i += 1 |
||||
|
endwhile |
||||
|
|
||||
|
return "" |
||||
|
endif |
||||
|
endfunction |
||||
|
|
||||
|
function! LatexBox_FoldText_title() |
||||
|
let line = getline(v:foldstart) |
||||
|
let title = 'Not defined' |
||||
|
|
||||
|
" Preamble |
||||
|
if line =~ '\s*\\documentclass' |
||||
|
return "Preamble" |
||||
|
endif |
||||
|
|
||||
|
" Parts, sections and fakesections |
||||
|
let sections = '\(\(sub\)*\(section\|paragraph\)\|part\|chapter\)' |
||||
|
let secpat1 = '^\s*\\' . sections . '\*\?\s*{' |
||||
|
let secpat2 = '^\s*\\' . sections . '\*\?\s*\[' |
||||
|
if line =~ '\\frontmatter' |
||||
|
let title = "Frontmatter" |
||||
|
elseif line =~ '\\mainmatter' |
||||
|
let title = "Mainmatter" |
||||
|
elseif line =~ '\\backmatter' |
||||
|
let title = "Backmatter" |
||||
|
elseif line =~ '\\appendix' |
||||
|
let title = "Appendix" |
||||
|
elseif line =~ secpat1 . '.*}' |
||||
|
let title = matchstr(line, secpat1 . '\zs.\{-}\ze}') |
||||
|
elseif line =~ secpat1 |
||||
|
let title = matchstr(line, secpat1 . '\zs.*') |
||||
|
elseif line =~ secpat2 . '.*\]' |
||||
|
let title = matchstr(line, secpat2 . '\zs.\{-}\ze\]') |
||||
|
elseif line =~ secpat2 |
||||
|
let title = matchstr(line, secpat2 . '\zs.*') |
||||
|
elseif line =~ 'Fake' . sections . ':' |
||||
|
let title = matchstr(line,'Fake' . sections . ':\s*\zs.*') |
||||
|
elseif line =~ 'Fake' . sections |
||||
|
let title = matchstr(line, 'Fake' . sections) |
||||
|
endif |
||||
|
|
||||
|
" Environments |
||||
|
if line =~ '\\begin' |
||||
|
" Capture environment name |
||||
|
let env = matchstr(line,'\\begin\*\?{\zs\w*\*\?\ze}') |
||||
|
|
||||
|
" Set caption based on type of environment |
||||
|
if env == 'frame' |
||||
|
let label = '' |
||||
|
let caption = s:CaptionFrame(line) |
||||
|
elseif env == 'table' |
||||
|
let label = s:LabelEnv() |
||||
|
let caption = s:CaptionTable() |
||||
|
else |
||||
|
let label = s:LabelEnv() |
||||
|
let caption = s:CaptionEnv() |
||||
|
endif |
||||
|
|
||||
|
" If no caption found, check for a caption comment |
||||
|
if caption == '' |
||||
|
let caption = matchstr(line,'\\begin\*\?{.*}\s*%\s*\zs.*') |
||||
|
endif |
||||
|
|
||||
|
" Create title based on caption and label |
||||
|
if caption . label == '' |
||||
|
let title = env |
||||
|
elseif label == '' |
||||
|
let title = printf('%-12s%s', env . ':', |
||||
|
\ substitute(caption, '}\s*$', '','')) |
||||
|
elseif caption == '' |
||||
|
let title = printf('%-12s%56s', env, '(' . label . ')') |
||||
|
else |
||||
|
let title = printf('%-12s%-30s %21s', env . ':', |
||||
|
\ strpart(substitute(caption, '}\s*$', '',''),0,34), |
||||
|
\ '(' . label . ')') |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
return title |
||||
|
endfunction |
||||
|
|
||||
|
" {{{1 LatexBox_FoldText |
||||
|
function! LatexBox_FoldText() |
||||
|
let nlines = v:foldend - v:foldstart + 1 |
||||
|
let title = strpart(LatexBox_FoldText_title(), 0, 68) |
||||
|
let level = '' |
||||
|
|
||||
|
" Fold level |
||||
|
let level = strpart(repeat('-', v:foldlevel-1) . '*',0,3) |
||||
|
if v:foldlevel > 3 |
||||
|
let level = strpart(level, 1) . v:foldlevel |
||||
|
endif |
||||
|
let level = printf('%-3s', level) |
||||
|
|
||||
|
return printf('%-3s %-68s #%5d', level, title, nlines) |
||||
|
endfunction |
||||
|
|
||||
|
" {{{1 Footer |
||||
|
" vim:fdm=marker:ff=unix:ts=4:sw=4 |
||||
@ -0,0 +1,554 @@ |
|||||
|
" LaTeX Box latexmk functions |
||||
|
|
||||
|
" Options and variables {{{ |
||||
|
|
||||
|
if !exists('g:LatexBox_latexmk_options') |
||||
|
let g:LatexBox_latexmk_options = '' |
||||
|
endif |
||||
|
if !exists('g:LatexBox_latexmk_env') |
||||
|
let g:LatexBox_latexmk_env = '' |
||||
|
endif |
||||
|
if !exists('g:LatexBox_latexmk_async') |
||||
|
let g:LatexBox_latexmk_async = 0 |
||||
|
endif |
||||
|
if !exists('g:LatexBox_latexmk_preview_continuously') |
||||
|
let g:LatexBox_latexmk_preview_continuously = 0 |
||||
|
endif |
||||
|
if !exists('g:LatexBox_output_type') |
||||
|
let g:LatexBox_output_type = 'pdf' |
||||
|
endif |
||||
|
if !exists('g:LatexBox_autojump') |
||||
|
let g:LatexBox_autojump = 0 |
||||
|
endif |
||||
|
if ! exists('g:LatexBox_quickfix') |
||||
|
let g:LatexBox_quickfix = 1 |
||||
|
endif |
||||
|
if ! exists('g:LatexBox_personal_latexmkrc') |
||||
|
let g:LatexBox_personal_latexmkrc = 0 |
||||
|
endif |
||||
|
|
||||
|
" }}} |
||||
|
|
||||
|
" Process ID management (used for asynchronous and continuous mode) {{{ |
||||
|
|
||||
|
" A dictionary of latexmk PID's (basename: pid) |
||||
|
if !exists('g:latexmk_running_pids') |
||||
|
let g:latexmk_running_pids = {} |
||||
|
endif |
||||
|
|
||||
|
" Set PID {{{ |
||||
|
function! s:LatexmkSetPID(basename, pid) |
||||
|
let g:latexmk_running_pids[a:basename] = a:pid |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" kill_latexmk_process {{{ |
||||
|
function! s:kill_latexmk_process(pid) |
||||
|
if has('win32') |
||||
|
silent execute '!taskkill /PID ' . a:pid . ' /T /F' |
||||
|
else |
||||
|
if g:LatexBox_latexmk_async |
||||
|
" vim-server mode |
||||
|
let pids = [] |
||||
|
let tmpfile = tempname() |
||||
|
silent execute '!ps x -o pgid,pid > ' . tmpfile |
||||
|
for line in readfile(tmpfile) |
||||
|
let new_pid = matchstr(line, '^\s*' . a:pid . '\s\+\zs\d\+\ze') |
||||
|
if !empty(new_pid) |
||||
|
call add(pids, new_pid) |
||||
|
endif |
||||
|
endfor |
||||
|
call delete(tmpfile) |
||||
|
if !empty(pids) |
||||
|
silent execute '!kill ' . join(pids) |
||||
|
endif |
||||
|
else |
||||
|
" single background process |
||||
|
silent execute '!kill ' . a:pid |
||||
|
endif |
||||
|
endif |
||||
|
if !has('gui_running') |
||||
|
redraw! |
||||
|
endif |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" kill_all_latexmk_processes {{{ |
||||
|
function! s:kill_all_latexmk_processes() |
||||
|
for pid in values(g:latexmk_running_pids) |
||||
|
call s:kill_latexmk_process(pid) |
||||
|
endfor |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" }}} |
||||
|
|
||||
|
" Setup for vim-server {{{ |
||||
|
function! s:SIDWrap(func) |
||||
|
if !exists('s:SID') |
||||
|
let s:SID = matchstr(expand('<sfile>'), '\zs<SNR>\d\+_\ze.*$') |
||||
|
endif |
||||
|
return s:SID . a:func |
||||
|
endfunction |
||||
|
|
||||
|
function! s:LatexmkCallback(basename, status) |
||||
|
" Only remove the pid if not in continuous mode |
||||
|
if !g:LatexBox_latexmk_preview_continuously |
||||
|
call remove(g:latexmk_running_pids, a:basename) |
||||
|
endif |
||||
|
call LatexBox_LatexErrors(a:status, a:basename) |
||||
|
endfunction |
||||
|
|
||||
|
function! s:setup_vim_server() |
||||
|
if !exists('g:vim_program') |
||||
|
|
||||
|
" attempt autodetection of vim executable |
||||
|
let g:vim_program = '' |
||||
|
if has('win32') |
||||
|
" Just drop through to the default for windows |
||||
|
else |
||||
|
if match(&shell, '\(bash\|zsh\)$') >= 0 |
||||
|
let ppid = '$PPID' |
||||
|
else |
||||
|
let ppid = '$$' |
||||
|
endif |
||||
|
|
||||
|
let tmpfile = tempname() |
||||
|
silent execute '!ps -o command= -p ' . ppid . ' > ' . tmpfile |
||||
|
for line in readfile(tmpfile) |
||||
|
let line = matchstr(line, '^\S\+\>') |
||||
|
if !empty(line) && executable(line) |
||||
|
let g:vim_program = line . ' -g' |
||||
|
break |
||||
|
endif |
||||
|
endfor |
||||
|
call delete(tmpfile) |
||||
|
endif |
||||
|
|
||||
|
if empty(g:vim_program) |
||||
|
if has('gui_macvim') |
||||
|
let g:vim_program |
||||
|
\ = '/Applications/MacVim.app/Contents/MacOS/Vim -g' |
||||
|
else |
||||
|
let g:vim_program = v:progname |
||||
|
endif |
||||
|
endif |
||||
|
endif |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Latexmk {{{ |
||||
|
|
||||
|
function! LatexBox_Latexmk(force) |
||||
|
" Define often used names |
||||
|
let basepath = LatexBox_GetBuildBasename(1) |
||||
|
let basename = fnamemodify(basepath, ':t') |
||||
|
let texroot = shellescape(LatexBox_GetTexRoot()) |
||||
|
let mainfile = fnameescape(fnamemodify(LatexBox_GetMainTexFile(), ':t')) |
||||
|
|
||||
|
" Check if latexmk is installed |
||||
|
if !executable('latexmk') |
||||
|
echomsg "Error: LaTeX-Box relies on latexmk for compilation, but it" . |
||||
|
\ " is not installed!" |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
" Check if already running |
||||
|
if has_key(g:latexmk_running_pids, basepath) |
||||
|
echomsg "latexmk is already running for `" . basename . "'" |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
" Set wrap width in log file |
||||
|
let max_print_line = 2000 |
||||
|
if has('win32') |
||||
|
let env = 'set max_print_line=' . max_print_line . ' & ' |
||||
|
elseif match(&shell, '/tcsh$') >= 0 |
||||
|
let env = 'setenv max_print_line ' . max_print_line . '; ' |
||||
|
else |
||||
|
if fnamemodify(&shell, ':t') ==# 'fish' |
||||
|
let env = 'set max_print_line ' . max_print_line . '; and ' |
||||
|
else |
||||
|
let env = 'max_print_line=' . max_print_line |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
" Set environment options |
||||
|
let env .= ' ' . g:LatexBox_latexmk_env . ' ' |
||||
|
|
||||
|
" Set latexmk command with options |
||||
|
if has('win32') |
||||
|
" Make sure to switch drive as well as directory |
||||
|
let cmd = 'cd /D ' . texroot . ' && ' |
||||
|
else |
||||
|
if fnamemodify(&shell, ':t') ==# 'fish' |
||||
|
let cmd = 'cd ' . texroot . '; and ' |
||||
|
else |
||||
|
let cmd = 'cd ' . texroot . ' && ' |
||||
|
endif |
||||
|
endif |
||||
|
let cmd .= env . ' latexmk' |
||||
|
if ! g:LatexBox_personal_latexmkrc |
||||
|
let cmd .= ' -' . g:LatexBox_output_type |
||||
|
endif |
||||
|
let cmd .= ' -quiet ' |
||||
|
let cmd .= g:LatexBox_latexmk_options |
||||
|
if a:force |
||||
|
let cmd .= ' -g' |
||||
|
endif |
||||
|
if g:LatexBox_latexmk_preview_continuously |
||||
|
let cmd .= ' -pvc' |
||||
|
endif |
||||
|
let cmd .= ' -e ' . shellescape('$pdflatex =~ s/ / -file-line-error /') |
||||
|
let cmd .= ' -e ' . shellescape('$latex =~ s/ / -file-line-error /') |
||||
|
if g:LatexBox_latexmk_preview_continuously |
||||
|
let cmd .= ' -e ' . shellescape('$success_cmd = $ENV{SUCCESSCMD}') |
||||
|
let cmd .= ' -e ' . shellescape('$failure_cmd = $ENV{FAILURECMD}') |
||||
|
endif |
||||
|
let cmd .= ' ' . mainfile |
||||
|
|
||||
|
" Redirect output to null |
||||
|
if has('win32') |
||||
|
let cmd .= ' >nul' |
||||
|
else |
||||
|
if fnamemodify(&shell, ':t') ==# 'fish' |
||||
|
let cmd .= ' >/dev/null ^/dev/null' |
||||
|
else |
||||
|
let cmd .= ' &>/dev/null' |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
if g:LatexBox_latexmk_async |
||||
|
" Check if VIM server exists |
||||
|
if empty(v:servername) |
||||
|
echoerr "cannot run latexmk in background without a VIM server" |
||||
|
echoerr "set g:LatexBox_latexmk_async to 0 to change compiling mode" |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
" Start vim server if necessary |
||||
|
call s:setup_vim_server() |
||||
|
|
||||
|
let setpidfunc = s:SIDWrap('LatexmkSetPID') |
||||
|
let callbackfunc = s:SIDWrap('LatexmkCallback') |
||||
|
if has('win32') |
||||
|
let vim_program = substitute(g:vim_program, |
||||
|
\ 'gvim\.exe$', 'vim.exe', '') |
||||
|
|
||||
|
" Define callback to set the pid |
||||
|
let callsetpid = setpidfunc . '(''' . basepath . ''', %CMDPID%)' |
||||
|
let vimsetpid = vim_program . ' --servername ' . v:servername |
||||
|
\ . ' --remote-expr ' . shellescape(callsetpid) |
||||
|
|
||||
|
" Define callback after latexmk is finished |
||||
|
let callback = callbackfunc . '(''' . basepath . ''', %LATEXERR%)' |
||||
|
let vimcmd = vim_program . ' --servername ' . v:servername |
||||
|
\ . ' --remote-expr ' . shellescape(callback) |
||||
|
let scallback = callbackfunc . '(''' . basepath . ''', 0)' |
||||
|
let svimcmd = vim_program . ' --servername ' . v:servername |
||||
|
\ . ' --remote-expr ' . shellescape(scallback) |
||||
|
let fcallback = callbackfunc . '(''' . basepath . ''', 1)' |
||||
|
let fvimcmd = vim_program . ' --servername ' . v:servername |
||||
|
\ . ' --remote-expr ' . shellescape(fcallback) |
||||
|
|
||||
|
let asyncbat = tempname() . '.bat' |
||||
|
if g:LatexBox_latexmk_preview_continuously |
||||
|
call writefile(['setlocal', |
||||
|
\ 'set T=%TEMP%\sthUnique.tmp', |
||||
|
\ 'wmic process where (Name="WMIC.exe" AND CommandLine LIKE "%%%TIME%%%") ' |
||||
|
\ . 'get ParentProcessId /value | find "ParentProcessId" >%T%', |
||||
|
\ 'set /P A=<%T%', |
||||
|
\ 'set CMDPID=%A:~16% & del %T%', |
||||
|
\ vimsetpid, |
||||
|
\ 'set SUCCESSCMD='.svimcmd, |
||||
|
\ 'set FAILURECMD='.fvimcmd, |
||||
|
\ cmd, |
||||
|
\ 'endlocal'], asyncbat) |
||||
|
else |
||||
|
call writefile(['setlocal', |
||||
|
\ 'set T=%TEMP%\sthUnique.tmp', |
||||
|
\ 'wmic process where (Name="WMIC.exe" AND CommandLine LIKE "%%%TIME%%%") ' |
||||
|
\ . 'get ParentProcessId /value | find "ParentProcessId" >%T%', |
||||
|
\ 'set /P A=<%T%', |
||||
|
\ 'set CMDPID=%A:~16% & del %T%', |
||||
|
\ vimsetpid, |
||||
|
\ cmd, |
||||
|
\ 'set LATEXERR=%ERRORLEVEL%', |
||||
|
\ vimcmd, |
||||
|
\ 'endlocal'], asyncbat) |
||||
|
endif |
||||
|
|
||||
|
" Define command |
||||
|
let cmd = '!start /b ' . asyncbat . ' & del ' . asyncbat |
||||
|
else |
||||
|
" Define callback to set the pid |
||||
|
let callsetpid = shellescape(setpidfunc).'"(\"'.basepath.'\",$$)"' |
||||
|
let vimsetpid = g:vim_program . ' --servername ' . v:servername |
||||
|
\ . ' --remote-expr ' . callsetpid |
||||
|
|
||||
|
" Define callback after latexmk is finished |
||||
|
let callback = shellescape(callbackfunc).'"(\"'.basepath.'\",$?)"' |
||||
|
let vimcmd = g:vim_program . ' --servername ' . v:servername |
||||
|
\ . ' --remote-expr ' . callback |
||||
|
let scallback = shellescape(callbackfunc).'"(\"'.basepath.'\",0)"' |
||||
|
let svimcmd = g:vim_program . ' --servername ' . v:servername |
||||
|
\ . ' --remote-expr ' . scallback |
||||
|
let fcallback = shellescape(callbackfunc).'"(\"'.basepath.'\",1)"' |
||||
|
let fvimcmd = g:vim_program . ' --servername ' . v:servername |
||||
|
\ . ' --remote-expr ' . fcallback |
||||
|
|
||||
|
" Define command |
||||
|
" Note: Here we escape '%' because it may be given as a user option |
||||
|
" through g:LatexBox_latexmk_options, for instance with |
||||
|
" g:Latex..._options = "-pdflatex='pdflatex -synctex=1 \%O \%S'" |
||||
|
if g:LatexBox_latexmk_preview_continuously |
||||
|
let cmd = vimsetpid . ' ; ' |
||||
|
\ . 'export SUCCESSCMD=' . shellescape(svimcmd) . ' ' |
||||
|
\ . ' FAILURECMD=' . shellescape(fvimcmd) . ' ; ' |
||||
|
\ . escape(cmd, '%') |
||||
|
else |
||||
|
let cmd = vimsetpid . ' ; ' . escape(cmd, '%') . ' ; ' . vimcmd |
||||
|
endif |
||||
|
let cmd = '! (' . cmd . ') >/dev/null &' |
||||
|
endif |
||||
|
|
||||
|
if g:LatexBox_latexmk_preview_continuously |
||||
|
echo 'Compiling to ' . g:LatexBox_output_type |
||||
|
\ . ' with continuous preview.' |
||||
|
else |
||||
|
echo 'Compiling to ' . g:LatexBox_output_type . ' ...' |
||||
|
endif |
||||
|
silent execute cmd |
||||
|
else |
||||
|
if g:LatexBox_latexmk_preview_continuously |
||||
|
if has('win32') |
||||
|
let cmd = '!start /b cmd /s /c "' . cmd . '"' |
||||
|
else |
||||
|
let cmd = '!' . cmd . ' &' |
||||
|
endif |
||||
|
echo 'Compiling to ' . g:LatexBox_output_type . ' ...' |
||||
|
silent execute cmd |
||||
|
|
||||
|
" Save PID in order to be able to kill the process when wanted. |
||||
|
if has('win32') |
||||
|
let tmpfile = tempname() |
||||
|
let pidcmd = 'cmd /c "wmic process where ' |
||||
|
\ . '(CommandLine LIKE "latexmk\%'.mainfile.'\%") ' |
||||
|
\ . 'get ProcessId /value | find "ProcessId" ' |
||||
|
\ . '>'.tmpfile.' "' |
||||
|
silent execute '! ' . pidcmd |
||||
|
let pids = readfile(tmpfile) |
||||
|
let pid = strpart(pids[0], 10) |
||||
|
let g:latexmk_running_pids[basepath] = pid |
||||
|
else |
||||
|
let pid = substitute(system('pgrep -f "perl.*' |
||||
|
\ . mainfile . '" | head -n 1'),'\D','','') |
||||
|
let g:latexmk_running_pids[basepath] = pid |
||||
|
endif |
||||
|
else |
||||
|
" Execute command and check for errors |
||||
|
echo 'Compiling to ' . g:LatexBox_output_type . ' ... (async off!)' |
||||
|
call system(cmd) |
||||
|
call LatexBox_LatexErrors(v:shell_error) |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
" Redraw screen if necessary |
||||
|
if !has("gui_running") |
||||
|
redraw! |
||||
|
endif |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" LatexmkClean {{{ |
||||
|
function! LatexBox_LatexmkClean(cleanall) |
||||
|
" Check if latexmk is installed |
||||
|
if !executable('latexmk') |
||||
|
echomsg "Error: LaTeX-Box relies on latexmk for compilation, but it" . |
||||
|
\ " is not installed!" |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
let basename = LatexBox_GetBuildBasename(1) |
||||
|
|
||||
|
if has_key(g:latexmk_running_pids, basename) |
||||
|
echomsg "don't clean when latexmk is running" |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
if has('win32') |
||||
|
let cmd = 'cd /D ' . shellescape(LatexBox_GetTexRoot()) . ' & ' |
||||
|
else |
||||
|
let cmd = 'cd ' . shellescape(LatexBox_GetTexRoot()) . ';' |
||||
|
endif |
||||
|
if a:cleanall |
||||
|
let cmd .= 'latexmk -C ' |
||||
|
else |
||||
|
let cmd .= 'latexmk -c ' |
||||
|
endif |
||||
|
let cmd .= shellescape(LatexBox_GetMainTexFile()) |
||||
|
if has('win32') |
||||
|
let cmd .= ' >nul' |
||||
|
else |
||||
|
let cmd .= ' >&/dev/null' |
||||
|
endif |
||||
|
|
||||
|
call system(cmd) |
||||
|
if !has('gui_running') |
||||
|
redraw! |
||||
|
endif |
||||
|
|
||||
|
echomsg "latexmk clean finished" |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" LatexErrors {{{ |
||||
|
function! LatexBox_LatexErrors(status, ...) |
||||
|
if a:0 >= 1 |
||||
|
let log = a:1 . '.log' |
||||
|
else |
||||
|
let log = LatexBox_GetLogFile() |
||||
|
endif |
||||
|
|
||||
|
cclose |
||||
|
|
||||
|
" set cwd to expand error file correctly |
||||
|
let l:cwd = fnamemodify(getcwd(), ':p') |
||||
|
execute 'lcd ' . fnameescape(LatexBox_GetTexRoot()) |
||||
|
try |
||||
|
if g:LatexBox_autojump |
||||
|
execute 'cfile ' . fnameescape(log) |
||||
|
else |
||||
|
execute 'cgetfile ' . fnameescape(log) |
||||
|
endif |
||||
|
finally |
||||
|
" restore cwd |
||||
|
execute 'lcd ' . fnameescape(l:cwd) |
||||
|
endtry |
||||
|
|
||||
|
" Always open window if started by LatexErrors command |
||||
|
if a:status < 0 |
||||
|
botright copen |
||||
|
else |
||||
|
" Only open window when an error/warning is detected |
||||
|
if g:LatexBox_quickfix >= 3 |
||||
|
\ ? s:log_contains_error(log) |
||||
|
\ : g:LatexBox_quickfix > 0 |
||||
|
belowright cw |
||||
|
if g:LatexBox_quickfix == 2 || g:LatexBox_quickfix == 4 |
||||
|
wincmd p |
||||
|
endif |
||||
|
endif |
||||
|
redraw |
||||
|
|
||||
|
" Write status message to screen |
||||
|
if a:status > 0 || len(getqflist())>1 |
||||
|
if s:log_contains_error(log) |
||||
|
let l:status_msg = ' ... failed!' |
||||
|
else |
||||
|
let l:status_msg = ' ... there were warnings!' |
||||
|
endif |
||||
|
else |
||||
|
let l:status_msg = ' ... success!' |
||||
|
endif |
||||
|
echomsg 'Compiling to ' . g:LatexBox_output_type . l:status_msg |
||||
|
endif |
||||
|
endfunction |
||||
|
|
||||
|
" Redefine uniq() for compatibility with older Vim versions (< 7.4.218) |
||||
|
function! s:uniq(list) |
||||
|
if exists('*uniq') |
||||
|
return uniq(a:list) |
||||
|
elseif len(a:list) <= 1 |
||||
|
return a:list |
||||
|
endif |
||||
|
|
||||
|
let last_element = get(a:list,0) |
||||
|
let uniq_list = [last_element] |
||||
|
|
||||
|
for i in range(1, len(a:list)-1) |
||||
|
let next_element = get(a:list, i) |
||||
|
if last_element == next_element |
||||
|
continue |
||||
|
endif |
||||
|
let last_element = next_element |
||||
|
call add(uniq_list, next_element) |
||||
|
endfor |
||||
|
return uniq_list |
||||
|
endfunction |
||||
|
|
||||
|
function! s:log_contains_error(file) |
||||
|
let lines = readfile(a:file) |
||||
|
let lines = filter(lines, 'v:val =~ ''^.*:\d\+: ''') |
||||
|
let lines = s:uniq(map(lines, 'matchstr(v:val, ''^.*\ze:\d\+:'')')) |
||||
|
let lines = filter(lines, 'filereadable(fnameescape(v:val))') |
||||
|
return len(lines) > 0 |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" LatexmkStatus {{{ |
||||
|
function! LatexBox_LatexmkStatus(detailed) |
||||
|
if a:detailed |
||||
|
if empty(g:latexmk_running_pids) |
||||
|
echo "latexmk is not running" |
||||
|
else |
||||
|
let plist = "" |
||||
|
for [basename, pid] in items(g:latexmk_running_pids) |
||||
|
if !empty(plist) |
||||
|
let plist .= '; ' |
||||
|
endif |
||||
|
let plist .= fnamemodify(basename, ':t') . ':' . pid |
||||
|
endfor |
||||
|
echo "latexmk is running (" . plist . ")" |
||||
|
endif |
||||
|
else |
||||
|
let basename = LatexBox_GetBuildBasename(1) |
||||
|
if has_key(g:latexmk_running_pids, basename) |
||||
|
echo "latexmk is running" |
||||
|
else |
||||
|
echo "latexmk is not running" |
||||
|
endif |
||||
|
endif |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" LatexmkStop {{{ |
||||
|
function! LatexBox_LatexmkStop(silent) |
||||
|
if empty(g:latexmk_running_pids) |
||||
|
if !a:silent |
||||
|
let basepath = LatexBox_GetBuildBasename(1) |
||||
|
let basename = fnamemodify(basepath, ':t') |
||||
|
echoerr "latexmk is not running for `" . basename . "'" |
||||
|
endif |
||||
|
else |
||||
|
let basepath = LatexBox_GetBuildBasename(1) |
||||
|
let basename = fnamemodify(basepath, ':t') |
||||
|
if has_key(g:latexmk_running_pids, basepath) |
||||
|
call s:kill_latexmk_process(g:latexmk_running_pids[basepath]) |
||||
|
call remove(g:latexmk_running_pids, basepath) |
||||
|
if !a:silent |
||||
|
echomsg "latexmk stopped for `" . basename . "'" |
||||
|
endif |
||||
|
elseif !a:silent |
||||
|
echoerr "latexmk is not running for `" . basename . "'" |
||||
|
endif |
||||
|
endif |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Commands {{{ |
||||
|
|
||||
|
command! -bang Latexmk call LatexBox_Latexmk(<q-bang> == "!") |
||||
|
command! -bang LatexmkClean call LatexBox_LatexmkClean(<q-bang> == "!") |
||||
|
command! -bang LatexmkStatus call LatexBox_LatexmkStatus(<q-bang> == "!") |
||||
|
command! LatexmkStop call LatexBox_LatexmkStop(0) |
||||
|
command! LatexErrors call LatexBox_LatexErrors(-1) |
||||
|
|
||||
|
if g:LatexBox_latexmk_async || g:LatexBox_latexmk_preview_continuously |
||||
|
autocmd BufUnload <buffer> call LatexBox_LatexmkStop(1) |
||||
|
autocmd VimLeave * call <SID>kill_all_latexmk_processes() |
||||
|
endif |
||||
|
|
||||
|
" }}} |
||||
|
|
||||
|
" vim:fdm=marker:ff=unix:noet:ts=4:sw=4 |
||||
@ -0,0 +1,106 @@ |
|||||
|
" LaTeX Box mappings |
||||
|
|
||||
|
if exists("g:LatexBox_no_mappings") |
||||
|
finish |
||||
|
endif |
||||
|
|
||||
|
" latexmk {{{ |
||||
|
noremap <buffer> <LocalLeader>ll :Latexmk<CR> |
||||
|
noremap <buffer> <LocalLeader>lL :Latexmk!<CR> |
||||
|
noremap <buffer> <LocalLeader>lc :LatexmkClean<CR> |
||||
|
noremap <buffer> <LocalLeader>lC :LatexmkClean!<CR> |
||||
|
noremap <buffer> <LocalLeader>lg :LatexmkStatus<CR> |
||||
|
noremap <buffer> <LocalLeader>lG :LatexmkStatus!<CR> |
||||
|
noremap <buffer> <LocalLeader>lk :LatexmkStop<CR> |
||||
|
noremap <buffer> <LocalLeader>le :LatexErrors<CR> |
||||
|
" }}} |
||||
|
|
||||
|
" View {{{ |
||||
|
noremap <buffer> <LocalLeader>lv :LatexView<CR> |
||||
|
" }}} |
||||
|
|
||||
|
" TOC {{{ |
||||
|
noremap <silent> <buffer> <LocalLeader>lt :LatexTOC<CR> |
||||
|
" }}} |
||||
|
|
||||
|
" List of labels {{{ |
||||
|
noremap <silent> <buffer> <LocalLeader>lj :LatexLabels<CR> |
||||
|
" }}} |
||||
|
|
||||
|
" Folding {{{ |
||||
|
if g:LatexBox_Folding == 1 |
||||
|
noremap <buffer> <LocalLeader>lf :LatexFold<CR> |
||||
|
endif |
||||
|
" }}} |
||||
|
|
||||
|
" Jump to match {{{ |
||||
|
if !exists('g:LatexBox_loaded_matchparen') |
||||
|
nmap <buffer> % <Plug>LatexBox_JumpToMatch |
||||
|
vmap <buffer> % <Plug>LatexBox_JumpToMatch |
||||
|
omap <buffer> % <Plug>LatexBox_JumpToMatch |
||||
|
endif |
||||
|
" }}} |
||||
|
|
||||
|
" Define text objects {{{ |
||||
|
vmap <buffer> ie <Plug>LatexBox_SelectCurrentEnvInner |
||||
|
vmap <buffer> ae <Plug>LatexBox_SelectCurrentEnvOuter |
||||
|
onoremap <buffer> ie :normal vie<CR> |
||||
|
onoremap <buffer> ae :normal vae<CR> |
||||
|
vmap <buffer> i$ <Plug>LatexBox_SelectInlineMathInner |
||||
|
vmap <buffer> a$ <Plug>LatexBox_SelectInlineMathOuter |
||||
|
onoremap <buffer> i$ :normal vi$<CR> |
||||
|
onoremap <buffer> a$ :normal va$<CR> |
||||
|
" }}} |
||||
|
|
||||
|
" Jump between sections {{{ |
||||
|
function! s:LatexBoxNextSection(type, backwards, visual) |
||||
|
" Restore visual mode if desired |
||||
|
if a:visual |
||||
|
normal! gv |
||||
|
endif |
||||
|
|
||||
|
" For the [] and ][ commands we move up or down before the search |
||||
|
if a:type == 1 |
||||
|
if a:backwards |
||||
|
normal! k |
||||
|
else |
||||
|
normal! j |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
" Define search pattern and do the search while preserving "/ |
||||
|
let save_search = @/ |
||||
|
let flags = 'W' |
||||
|
if a:backwards |
||||
|
let flags = 'b' . flags |
||||
|
endif |
||||
|
let notcomment = '\%(\%(\\\@<!\%(\\\\\)*\)\@<=%.*\)\@<!' |
||||
|
let pattern = notcomment . '\v\s*\\(' . join([ |
||||
|
\ '(sub)*section', |
||||
|
\ 'chapter', |
||||
|
\ 'part', |
||||
|
\ 'appendix', |
||||
|
\ '(front|back|main)matter'], '|') . ')>' |
||||
|
call search(pattern, flags) |
||||
|
let @/ = save_search |
||||
|
|
||||
|
" For the [] and ][ commands we move down or up after the search |
||||
|
if a:type == 1 |
||||
|
if a:backwards |
||||
|
normal! j |
||||
|
else |
||||
|
normal! k |
||||
|
endif |
||||
|
endif |
||||
|
endfunction |
||||
|
noremap <buffer> <silent> ]] :call <SID>LatexBoxNextSection(0,0,0)<CR> |
||||
|
noremap <buffer> <silent> ][ :call <SID>LatexBoxNextSection(1,0,0)<CR> |
||||
|
noremap <buffer> <silent> [] :call <SID>LatexBoxNextSection(1,1,0)<CR> |
||||
|
noremap <buffer> <silent> [[ :call <SID>LatexBoxNextSection(0,1,0)<CR> |
||||
|
vnoremap <buffer> <silent> ]] :<c-u>call <SID>LatexBoxNextSection(0,0,1)<CR> |
||||
|
vnoremap <buffer> <silent> ][ :<c-u>call <SID>LatexBoxNextSection(1,0,1)<CR> |
||||
|
vnoremap <buffer> <silent> [] :<c-u>call <SID>LatexBoxNextSection(1,1,1)<CR> |
||||
|
vnoremap <buffer> <silent> [[ :<c-u>call <SID>LatexBoxNextSection(0,1,1)<CR> |
||||
|
" }}} |
||||
|
|
||||
|
" vim:fdm=marker:ff=unix:noet:ts=4:sw=4 |
||||
@ -0,0 +1,544 @@ |
|||||
|
" LaTeX Box motion functions |
||||
|
|
||||
|
" Motion options {{{ |
||||
|
" Opening and closing patterns |
||||
|
if !exists('g:LatexBox_open_pats') |
||||
|
let g:LatexBox_open_pats = [ '\\{','{','\\(','(','\\\[','\[', |
||||
|
\ '\\begin\s*{.\{-}}', '\\left\s*\%([^\\]\|\\.\|\\\a*\)'] |
||||
|
let g:LatexBox_close_pats = [ '\\}','}','\\)',')','\\\]','\]', |
||||
|
\ '\\end\s*{.\{-}}', '\\right\s*\%([^\\]\|\\.\|\\\a*\)'] |
||||
|
endif |
||||
|
" }}} |
||||
|
|
||||
|
" HasSyntax {{{ |
||||
|
" s:HasSyntax(syntaxName, [line], [col]) |
||||
|
function! s:HasSyntax(syntaxName, ...) |
||||
|
let line = a:0 >= 1 ? a:1 : line('.') |
||||
|
let col = a:0 >= 2 ? a:2 : col('.') |
||||
|
return index(map(synstack(line, col), |
||||
|
\ 'synIDattr(v:val, "name") == "' . a:syntaxName . '"'), |
||||
|
\ 1) >= 0 |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Search and Skip Comments {{{ |
||||
|
" s:SearchAndSkipComments(pattern, [flags], [stopline]) |
||||
|
function! s:SearchAndSkipComments(pat, ...) |
||||
|
let flags = a:0 >= 1 ? a:1 : '' |
||||
|
let stopline = a:0 >= 2 ? a:2 : 0 |
||||
|
let saved_pos = getpos('.') |
||||
|
|
||||
|
" search once |
||||
|
let ret = search(a:pat, flags, stopline) |
||||
|
|
||||
|
if ret |
||||
|
" do not match at current position if inside comment |
||||
|
let flags = substitute(flags, 'c', '', 'g') |
||||
|
|
||||
|
" keep searching while in comment |
||||
|
while LatexBox_InComment() |
||||
|
let ret = search(a:pat, flags, stopline) |
||||
|
if !ret |
||||
|
break |
||||
|
endif |
||||
|
endwhile |
||||
|
endif |
||||
|
|
||||
|
if !ret |
||||
|
" if no match found, restore position |
||||
|
call setpos('.', saved_pos) |
||||
|
endif |
||||
|
|
||||
|
return ret |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Finding Matching Pair {{{ |
||||
|
function! s:FindMatchingPair(mode) |
||||
|
|
||||
|
if a:mode =~ 'h\|i' |
||||
|
2match none |
||||
|
elseif a:mode == 'v' |
||||
|
normal! gv |
||||
|
endif |
||||
|
|
||||
|
if LatexBox_InComment() | return | endif |
||||
|
|
||||
|
" open/close pairs (dollars signs are treated apart) |
||||
|
let dollar_pat = '\$' |
||||
|
let notbslash = '\%(\\\@<!\%(\\\\\)*\)\@<=' |
||||
|
let notcomment = '\%(\%(\\\@<!\%(\\\\\)*\)\@<=%.*\)\@<!' |
||||
|
let anymatch = '\(' |
||||
|
\ . join(g:LatexBox_open_pats + g:LatexBox_close_pats, '\|') |
||||
|
\ . '\|' . dollar_pat . '\)' |
||||
|
|
||||
|
let lnum = line('.') |
||||
|
let cnum = searchpos('\A', 'cbnW', lnum)[1] |
||||
|
" if the previous char is a backslash |
||||
|
if strpart(getline(lnum), cnum-2, 1) == '\' |
||||
|
let cnum = cnum-1 |
||||
|
endif |
||||
|
let delim = matchstr(getline(lnum), '\C^'. anymatch , cnum - 1) |
||||
|
|
||||
|
if empty(delim) || strlen(delim)+cnum-1< col('.') |
||||
|
if a:mode =~ 'n\|v\|o' |
||||
|
" if not found, search forward |
||||
|
let cnum = match(getline(lnum), '\C'. anymatch , col('.') - 1) + 1 |
||||
|
if cnum == 0 | return | endif |
||||
|
call cursor(lnum, cnum) |
||||
|
let delim = matchstr(getline(lnum), '\C^'. anymatch , cnum - 1) |
||||
|
elseif a:mode =~ 'i' |
||||
|
" if not found, move one char bacward and search |
||||
|
let cnum = searchpos('\A', 'bnW', lnum)[1] |
||||
|
" if the previous char is a backslash |
||||
|
if strpart(getline(lnum), cnum-2, 1) == '\' |
||||
|
let cnum = cnum-1 |
||||
|
endif |
||||
|
let delim = matchstr(getline(lnum), '\C^'. anymatch , cnum - 1) |
||||
|
if empty(delim) || strlen(delim)+cnum< col('.') | return | endif |
||||
|
elseif a:mode =~ 'h' |
||||
|
return |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
if delim =~ '^\$' |
||||
|
|
||||
|
" match $-pairs |
||||
|
" check if next character is in inline math |
||||
|
let [lnum0, cnum0] = searchpos('.', 'nW') |
||||
|
if lnum0 && s:HasSyntax('texMathZoneX', lnum0, cnum0) |
||||
|
let [lnum2, cnum2] = searchpos(notcomment . notbslash. dollar_pat, 'nW', line('w$')*(a:mode =~ 'h\|i') , 200) |
||||
|
else |
||||
|
let [lnum2, cnum2] = searchpos('\%(\%'. lnum . 'l\%' . cnum . 'c\)\@!'. notcomment . notbslash . dollar_pat, 'bnW', line('w0')*(a:mode =~ 'h\|i') , 200) |
||||
|
endif |
||||
|
|
||||
|
if a:mode =~ 'h\|i' |
||||
|
execute '2match MatchParen /\%(\%' . lnum . 'l\%' . cnum . 'c\$' . '\|\%' . lnum2 . 'l\%' . cnum2 . 'c\$\)/' |
||||
|
elseif a:mode =~ 'n\|v\|o' |
||||
|
call cursor(lnum2,cnum2) |
||||
|
endif |
||||
|
|
||||
|
else |
||||
|
" match other pairs |
||||
|
for i in range(len(g:LatexBox_open_pats)) |
||||
|
let open_pat = notbslash . g:LatexBox_open_pats[i] |
||||
|
let close_pat = notbslash . g:LatexBox_close_pats[i] |
||||
|
|
||||
|
if delim =~# '^' . open_pat |
||||
|
" if on opening pattern, search for closing pattern |
||||
|
let [lnum2, cnum2] = searchpairpos('\C' . open_pat, '', '\C' |
||||
|
\ . close_pat, 'nW', 'LatexBox_InComment()', |
||||
|
\ line('w$')*(a:mode =~ 'h\|i') , 200) |
||||
|
if a:mode =~ 'h\|i' |
||||
|
execute '2match MatchParen /\%(\%' . lnum . 'l\%' . cnum |
||||
|
\ . 'c' . g:LatexBox_open_pats[i] . '\|\%' |
||||
|
\ . lnum2 . 'l\%' . cnum2 . 'c' |
||||
|
\ . g:LatexBox_close_pats[i] . '\)/' |
||||
|
elseif a:mode =~ 'n\|v\|o' |
||||
|
call cursor(lnum2,cnum2) |
||||
|
if strlen(close_pat)>1 && a:mode =~ 'o' |
||||
|
call cursor(lnum2, matchend(getline('.'), '\C' |
||||
|
\ . close_pat, col('.')-1)) |
||||
|
endif |
||||
|
endif |
||||
|
break |
||||
|
elseif delim =~# '^' . close_pat |
||||
|
" if on closing pattern, search for opening pattern |
||||
|
let [lnum2, cnum2] = searchpairpos('\C' . open_pat, '', |
||||
|
\ '\C\%(\%'. lnum . 'l\%' . cnum . 'c\)\@!' |
||||
|
\ . close_pat, 'bnW', 'LatexBox_InComment()', |
||||
|
\ line('w0')*(a:mode =~ 'h\|i') , 200) |
||||
|
if a:mode =~ 'h\|i' |
||||
|
execute '2match MatchParen /\%(\%' . lnum2 . 'l\%' . cnum2 |
||||
|
\ . 'c' . g:LatexBox_open_pats[i] . '\|\%' |
||||
|
\ . lnum . 'l\%' . cnum . 'c' |
||||
|
\ . g:LatexBox_close_pats[i] . '\)/' |
||||
|
elseif a:mode =~ 'n\|v\|o' |
||||
|
call cursor(lnum2,cnum2) |
||||
|
endif |
||||
|
break |
||||
|
endif |
||||
|
endfor |
||||
|
|
||||
|
endif |
||||
|
endfunction |
||||
|
|
||||
|
" Allow to disable functionality if desired |
||||
|
if !exists('g:LatexBox_loaded_matchparen') |
||||
|
" Disable matchparen autocommands |
||||
|
augroup LatexBox_HighlightPairs |
||||
|
autocmd BufEnter * if !exists("g:loaded_matchparen") || !g:loaded_matchparen | runtime plugin/matchparen.vim | endif |
||||
|
autocmd BufEnter *.tex 3match none | unlet! g:loaded_matchparen | au! matchparen |
||||
|
autocmd! CursorMoved *.tex call s:FindMatchingPair('h') |
||||
|
autocmd! CursorMovedI *.tex call s:FindMatchingPair('i') |
||||
|
augroup END |
||||
|
endif |
||||
|
|
||||
|
" Use LatexBox'es FindMatchingPair as '%' (enable jump between e.g. $'s) |
||||
|
nnoremap <silent> <Plug>LatexBox_JumpToMatch :call <SID>FindMatchingPair('n')<CR> |
||||
|
vnoremap <silent> <Plug>LatexBox_JumpToMatch :call <SID>FindMatchingPair('v')<CR> |
||||
|
onoremap <silent> <Plug>LatexBox_JumpToMatch v:call <SID>FindMatchingPair('o')<CR> |
||||
|
|
||||
|
" }}} |
||||
|
|
||||
|
" select inline math {{{ |
||||
|
" s:SelectInlineMath(seltype) |
||||
|
" where seltype is either 'inner' or 'outer' |
||||
|
function! s:SelectInlineMath(seltype) |
||||
|
|
||||
|
let dollar_pat = '\\\@<!\$' |
||||
|
|
||||
|
if s:HasSyntax('texMathZoneX') |
||||
|
call s:SearchAndSkipComments(dollar_pat, 'cbW') |
||||
|
elseif getline('.')[col('.') - 1] == '$' |
||||
|
call s:SearchAndSkipComments(dollar_pat, 'bW') |
||||
|
else |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
if a:seltype == 'inner' |
||||
|
normal! l |
||||
|
endif |
||||
|
|
||||
|
if visualmode() ==# 'V' |
||||
|
normal! V |
||||
|
else |
||||
|
normal! v |
||||
|
endif |
||||
|
|
||||
|
call s:SearchAndSkipComments(dollar_pat, 'W') |
||||
|
|
||||
|
if a:seltype == 'inner' |
||||
|
normal! h |
||||
|
endif |
||||
|
endfunction |
||||
|
|
||||
|
vnoremap <silent> <Plug>LatexBox_SelectInlineMathInner |
||||
|
\ :<C-U>call <SID>SelectInlineMath('inner')<CR> |
||||
|
vnoremap <silent> <Plug>LatexBox_SelectInlineMathOuter |
||||
|
\ :<C-U>call <SID>SelectInlineMath('outer')<CR> |
||||
|
" }}} |
||||
|
|
||||
|
" select current environment {{{ |
||||
|
function! s:SelectCurrentEnv(seltype) |
||||
|
let [env, lnum, cnum, lnum2, cnum2] = LatexBox_GetCurrentEnvironment(1) |
||||
|
call cursor(lnum, cnum) |
||||
|
if a:seltype == 'inner' |
||||
|
if env =~ '^\' |
||||
|
call search('\\.\_\s*\S', 'eW') |
||||
|
else |
||||
|
call search('}\(\_\s*\[\_[^]]*\]\)\?\_\s*\S', 'eW') |
||||
|
endif |
||||
|
endif |
||||
|
if visualmode() ==# 'V' |
||||
|
normal! V |
||||
|
else |
||||
|
normal! v |
||||
|
endif |
||||
|
call cursor(lnum2, cnum2) |
||||
|
if a:seltype == 'inner' |
||||
|
call search('\S\_\s*', 'bW') |
||||
|
else |
||||
|
if env =~ '^\' |
||||
|
normal! l |
||||
|
else |
||||
|
call search('}', 'eW') |
||||
|
endif |
||||
|
endif |
||||
|
endfunction |
||||
|
vnoremap <silent> <Plug>LatexBox_SelectCurrentEnvInner :<C-U>call <SID>SelectCurrentEnv('inner')<CR> |
||||
|
vnoremap <silent> <Plug>LatexBox_SelectCurrentEnvOuter :<C-U>call <SID>SelectCurrentEnv('outer')<CR> |
||||
|
" }}} |
||||
|
|
||||
|
" Jump to the next braces {{{ |
||||
|
" |
||||
|
function! LatexBox_JumpToNextBraces(backward) |
||||
|
let flags = '' |
||||
|
if a:backward |
||||
|
normal h |
||||
|
let flags .= 'b' |
||||
|
else |
||||
|
let flags .= 'c' |
||||
|
endif |
||||
|
if search('[][}{]', flags) > 0 |
||||
|
normal l |
||||
|
endif |
||||
|
let prev = strpart(getline('.'), col('.') - 2, 1) |
||||
|
let next = strpart(getline('.'), col('.') - 1, 1) |
||||
|
if next =~ '[]}]' && prev !~ '[][{}]' |
||||
|
return "\<Right>" |
||||
|
else |
||||
|
return '' |
||||
|
endif |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Table of Contents {{{ |
||||
|
|
||||
|
" Special UTF-8 conversion |
||||
|
function! s:ConvertBack(line) |
||||
|
let line = a:line |
||||
|
if exists('g:LatexBox_plaintext_toc') |
||||
|
" |
||||
|
" Substitute stuff like '\IeC{\"u}' to plain 'u' |
||||
|
" |
||||
|
let line = substitute(line, '\\IeC\s*{\\.\(.\)}', '\1', 'g') |
||||
|
else |
||||
|
" |
||||
|
" Substitute stuff like '\IeC{\"u}' to corresponding unicode symbols |
||||
|
" |
||||
|
for [pat, symbol] in s:ConvBackPats |
||||
|
let line = substitute(line, pat, symbol, 'g') |
||||
|
endfor |
||||
|
endif |
||||
|
return line |
||||
|
endfunction |
||||
|
|
||||
|
function! s:ReadTOC(auxfile, texfile, ...) |
||||
|
let texfile = a:texfile |
||||
|
let prefix = fnamemodify(a:auxfile, ':p:h') |
||||
|
|
||||
|
if a:0 != 2 |
||||
|
let toc = [] |
||||
|
let fileindices = { texfile : [] } |
||||
|
else |
||||
|
let toc = a:1 |
||||
|
let fileindices = a:2 |
||||
|
let fileindices[ texfile ] = [] |
||||
|
endif |
||||
|
|
||||
|
for line in readfile(a:auxfile) |
||||
|
let included = matchstr(line, '^\\@input{\zs[^}]*\ze}') |
||||
|
if included != '' |
||||
|
" append the input TOX to `toc` and `fileindices` |
||||
|
let newaux = prefix . '/' . included |
||||
|
let newtex = fnamemodify(newaux, ':r') . '.tex' |
||||
|
call s:ReadTOC(newaux, newtex, toc, fileindices) |
||||
|
continue |
||||
|
endif |
||||
|
|
||||
|
" Parse statements like: |
||||
|
" \@writefile{toc}{\contentsline {section}{\numberline {secnum}Section Title}{pagenumber}} |
||||
|
" \@writefile{toc}{\contentsline {section}{\tocsection {}{1}{Section Title}}{pagenumber}} |
||||
|
" \@writefile{toc}{\contentsline {section}{\numberline {secnum}Section Title}{pagenumber}{otherstuff}} |
||||
|
|
||||
|
let line = matchstr(line, |
||||
|
\ '\\@writefile{toc}{\\contentsline\s*\zs.*\ze}\s*$') |
||||
|
if empty(line) |
||||
|
continue |
||||
|
endif |
||||
|
|
||||
|
let tree = LatexBox_TexToTree(s:ConvertBack(line)) |
||||
|
|
||||
|
if len(tree) < 3 |
||||
|
" unknown entry type: just skip it |
||||
|
continue |
||||
|
endif |
||||
|
|
||||
|
" parse level |
||||
|
let level = tree[0][0] |
||||
|
" parse page |
||||
|
if !empty(tree[2]) |
||||
|
let page = tree[2][0] |
||||
|
else |
||||
|
let page = '' |
||||
|
endif |
||||
|
" parse section number |
||||
|
let secnum = '' |
||||
|
let tree = tree[1] |
||||
|
if len(tree) > 3 && empty(tree[1]) |
||||
|
call remove(tree, 1) |
||||
|
endif |
||||
|
if len(tree) > 1 && type(tree[0]) == type("") && tree[0] =~ '^\\\(\(chapter\)\?numberline\|tocsection\)' |
||||
|
let secnum = LatexBox_TreeToTex(tree[1]) |
||||
|
let secnum = substitute(secnum, '\\\S\+\s', '', 'g') |
||||
|
let secnum = substitute(secnum, '\\\S\+{\(.\{-}\)}', '\1', 'g') |
||||
|
let secnum = substitute(secnum, '^{\+\|}\+$', '', 'g') |
||||
|
call remove(tree, 1) |
||||
|
endif |
||||
|
" parse section title |
||||
|
let text = LatexBox_TreeToTex(tree) |
||||
|
let text = substitute(text, '^{\+\|}\+$', '', 'g') |
||||
|
let text = substitute(text, '\m^\\\(no\)\?\(chapter\)\?numberline\s*', '', '') |
||||
|
let text = substitute(text, '\*', '', 'g') |
||||
|
|
||||
|
" add TOC entry |
||||
|
call add(fileindices[texfile], len(toc)) |
||||
|
call add(toc, {'file': texfile, |
||||
|
\ 'level': level, |
||||
|
\ 'number': secnum, |
||||
|
\ 'text': text, |
||||
|
\ 'page': page}) |
||||
|
endfor |
||||
|
|
||||
|
return [toc, fileindices] |
||||
|
|
||||
|
endfunction |
||||
|
|
||||
|
function! LatexBox_TOC(...) |
||||
|
|
||||
|
" Check if window already exists |
||||
|
let winnr = bufwinnr(bufnr('LaTeX TOC')) |
||||
|
" Two types of splits, horizontal and vertical |
||||
|
let l:hori = "new" |
||||
|
let l:vert = "vnew" |
||||
|
|
||||
|
" Set General Vars and initialize size |
||||
|
let l:type = g:LatexBox_split_type |
||||
|
let l:size = 10 |
||||
|
|
||||
|
" Size detection |
||||
|
if l:type == l:hori |
||||
|
let l:size = g:LatexBox_split_length |
||||
|
elseif l:type == l:vert |
||||
|
let l:size = g:LatexBox_split_width |
||||
|
endif |
||||
|
|
||||
|
if winnr >= 0 |
||||
|
if a:0 == 0 |
||||
|
silent execute winnr . 'wincmd w' |
||||
|
else |
||||
|
" Supplying an argument to this function causes toggling instead |
||||
|
" of jumping to the TOC window |
||||
|
if g:LatexBox_split_resize |
||||
|
silent exe "set columns-=" . l:size |
||||
|
endif |
||||
|
silent execute 'bwipeout' . bufnr('LaTeX TOC') |
||||
|
endif |
||||
|
return |
||||
|
endif |
||||
|
" Read TOC |
||||
|
let [toc, fileindices] = s:ReadTOC(LatexBox_GetAuxFile(), |
||||
|
\ LatexBox_GetMainTexFile()) |
||||
|
let calling_buf = bufnr('%') |
||||
|
|
||||
|
" Find closest section in current buffer |
||||
|
let closest_index = s:FindClosestSection(toc,fileindices) |
||||
|
|
||||
|
" Create TOC window and set local settings |
||||
|
if g:LatexBox_split_resize |
||||
|
silent exe "set columns+=" . l:size |
||||
|
endif |
||||
|
silent exe g:LatexBox_split_side l:size . l:type . ' LaTeX\ TOC' |
||||
|
|
||||
|
let b:toc = toc |
||||
|
let b:toc_numbers = 1 |
||||
|
let b:calling_win = bufwinnr(calling_buf) |
||||
|
setlocal filetype=latextoc |
||||
|
|
||||
|
" Add TOC entries and jump to the closest section |
||||
|
for entry in toc |
||||
|
call append('$', entry['number'] . "\t" . entry['text']) |
||||
|
endfor |
||||
|
if !g:LatexBox_toc_hidehelp |
||||
|
call append('$', "") |
||||
|
call append('$', "<Esc>/q: close") |
||||
|
call append('$', "<Space>: jump") |
||||
|
call append('$', "<Enter>: jump and close") |
||||
|
call append('$', "s: hide numbering") |
||||
|
endif |
||||
|
0delete _ |
||||
|
|
||||
|
execute 'normal! ' . (closest_index + 1) . 'G' |
||||
|
|
||||
|
" Lock buffer |
||||
|
setlocal nomodifiable |
||||
|
endfunction |
||||
|
|
||||
|
" Binary search for the closest section |
||||
|
" return the index of the TOC entry |
||||
|
function! s:FindClosestSection(toc, fileindices) |
||||
|
let file = expand('%:p') |
||||
|
if !has_key(a:fileindices, file) |
||||
|
return 0 |
||||
|
endif |
||||
|
|
||||
|
let imax = len(a:fileindices[file]) |
||||
|
if imax > 0 |
||||
|
let imin = 0 |
||||
|
while imin < imax - 1 |
||||
|
let i = (imax + imin) / 2 |
||||
|
let tocindex = a:fileindices[file][i] |
||||
|
let entry = a:toc[tocindex] |
||||
|
let titlestr = entry['text'] |
||||
|
let titlestr = escape(titlestr, '\') |
||||
|
let titlestr = substitute(titlestr, ' ', '\\_\\s\\+', 'g') |
||||
|
let [lnum, cnum] = searchpos('\\' . entry['level'] . '\_\s*{' . titlestr . '}', 'nW') |
||||
|
if lnum |
||||
|
let imax = i |
||||
|
else |
||||
|
let imin = i |
||||
|
endif |
||||
|
endwhile |
||||
|
return a:fileindices[file][imin] |
||||
|
else |
||||
|
return 0 |
||||
|
endif |
||||
|
endfunction |
||||
|
|
||||
|
let s:ConvBackPats = map([ |
||||
|
\ ['\\''A}' , 'Á'], |
||||
|
\ ['\\`A}' , 'À'], |
||||
|
\ ['\\^A}' , 'À'], |
||||
|
\ ['\\¨A}' , 'Ä'], |
||||
|
\ ['\\"A}' , 'Ä'], |
||||
|
\ ['\\''a}' , 'á'], |
||||
|
\ ['\\`a}' , 'à'], |
||||
|
\ ['\\^a}' , 'à'], |
||||
|
\ ['\\¨a}' , 'ä'], |
||||
|
\ ['\\"a}' , 'ä'], |
||||
|
\ ['\\''E}' , 'É'], |
||||
|
\ ['\\`E}' , 'È'], |
||||
|
\ ['\\^E}' , 'Ê'], |
||||
|
\ ['\\¨E}' , 'Ë'], |
||||
|
\ ['\\"E}' , 'Ë'], |
||||
|
\ ['\\''e}' , 'é'], |
||||
|
\ ['\\`e}' , 'è'], |
||||
|
\ ['\\^e}' , 'ê'], |
||||
|
\ ['\\¨e}' , 'ë'], |
||||
|
\ ['\\"e}' , 'ë'], |
||||
|
\ ['\\''I}' , 'Í'], |
||||
|
\ ['\\`I}' , 'Î'], |
||||
|
\ ['\\^I}' , 'Ì'], |
||||
|
\ ['\\¨I}' , 'Ï'], |
||||
|
\ ['\\"I}' , 'Ï'], |
||||
|
\ ['\\''i}' , 'í'], |
||||
|
\ ['\\`i}' , 'î'], |
||||
|
\ ['\\^i}' , 'ì'], |
||||
|
\ ['\\¨i}' , 'ï'], |
||||
|
\ ['\\"i}' , 'ï'], |
||||
|
\ ['\\''{\?\\i }' , 'í'], |
||||
|
\ ['\\''O}' , 'Ó'], |
||||
|
\ ['\\`O}' , 'Ò'], |
||||
|
\ ['\\^O}' , 'Ô'], |
||||
|
\ ['\\¨O}' , 'Ö'], |
||||
|
\ ['\\"O}' , 'Ö'], |
||||
|
\ ['\\''o}' , 'ó'], |
||||
|
\ ['\\`o}' , 'ò'], |
||||
|
\ ['\\^o}' , 'ô'], |
||||
|
\ ['\\¨o}' , 'ö'], |
||||
|
\ ['\\"o}' , 'ö'], |
||||
|
\ ['\\''U}' , 'Ú'], |
||||
|
\ ['\\`U}' , 'Ù'], |
||||
|
\ ['\\^U}' , 'Û'], |
||||
|
\ ['\\¨U}' , 'Ü'], |
||||
|
\ ['\\"U}' , 'Ü'], |
||||
|
\ ['\\''u}' , 'ú'], |
||||
|
\ ['\\`u}' , 'ù'], |
||||
|
\ ['\\^u}' , 'û'], |
||||
|
\ ['\\¨u}' , 'ü'], |
||||
|
\ ['\\"u}' , 'ü'], |
||||
|
\ ['\\`N}' , 'Ǹ'], |
||||
|
\ ['\\\~N}' , 'Ñ'], |
||||
|
\ ['\\''n}' , 'ń'], |
||||
|
\ ['\\`n}' , 'ǹ'], |
||||
|
\ ['\\\~n}' , 'ñ'], |
||||
|
\], '[''\C\(\\IeC\s*{\)\?'' . v:val[0], v:val[1]]') |
||||
|
" }}} |
||||
|
|
||||
|
" TOC Command {{{ |
||||
|
command! LatexTOC call LatexBox_TOC() |
||||
|
command! LatexTOCToggle call LatexBox_TOC(1) |
||||
|
" }}} |
||||
|
|
||||
|
" vim:fdm=marker:ff=unix:noet:ts=4:sw=4 |
||||
@ -0,0 +1,306 @@ |
|||||
|
ENTRY |
||||
|
{ address author booktitle chapter doi edition editor eid howpublished institution isbn issn journal key month note number organization pages publisher school series title type volume year } |
||||
|
{} |
||||
|
{ label } |
||||
|
STRINGS { s t} |
||||
|
|
||||
|
FUNCTION {output} |
||||
|
{ 's := |
||||
|
%purify$ |
||||
|
%"}{" * write$ |
||||
|
"||" * write$ |
||||
|
s |
||||
|
} |
||||
|
FUNCTION {fin.entry} |
||||
|
%{ "}" * write$ |
||||
|
{ write$ |
||||
|
newline$ |
||||
|
} |
||||
|
|
||||
|
FUNCTION {not} |
||||
|
{ { #0 } |
||||
|
{ #1 } |
||||
|
if$ |
||||
|
} |
||||
|
FUNCTION {and} |
||||
|
{ 'skip$ |
||||
|
{ pop$ #0 } |
||||
|
if$ |
||||
|
} |
||||
|
FUNCTION {or} |
||||
|
{ { pop$ #1 } |
||||
|
'skip$ |
||||
|
if$ |
||||
|
} |
||||
|
FUNCTION {field.or.null} |
||||
|
{ duplicate$ empty$ |
||||
|
{ pop$ "" } |
||||
|
'skip$ |
||||
|
if$ |
||||
|
} |
||||
|
|
||||
|
FUNCTION {capitalize} |
||||
|
{ "u" change.case$ "t" change.case$ } |
||||
|
|
||||
|
FUNCTION {space.word} |
||||
|
{ " " swap$ * " " * } |
||||
|
|
||||
|
FUNCTION {bbl.and} { "&"} |
||||
|
FUNCTION {bbl.etal} { "et al." } |
||||
|
|
||||
|
INTEGERS { nameptr namesleft numnames } |
||||
|
|
||||
|
STRINGS { bibinfo} |
||||
|
|
||||
|
FUNCTION {format.names} |
||||
|
{ duplicate$ empty$ 'skip$ { |
||||
|
's := |
||||
|
"" 't := |
||||
|
#1 'nameptr := |
||||
|
s num.names$ 'numnames := |
||||
|
numnames 'namesleft := |
||||
|
{ namesleft #0 > } |
||||
|
{ s nameptr |
||||
|
%"{vv~}{ll}{, f.}{, jj}" |
||||
|
"{vv }{ll}{}{}" |
||||
|
format.name$ |
||||
|
't := |
||||
|
nameptr #1 > |
||||
|
{ |
||||
|
namesleft #1 > |
||||
|
{ ", " * t * } |
||||
|
{ |
||||
|
s nameptr "{ll}" format.name$ duplicate$ "others" = |
||||
|
{ 't := } |
||||
|
{ pop$ } |
||||
|
if$ |
||||
|
t "others" = |
||||
|
{ |
||||
|
" " * bbl.etal * |
||||
|
} |
||||
|
{ |
||||
|
bbl.and |
||||
|
space.word * t * |
||||
|
} |
||||
|
if$ |
||||
|
} |
||||
|
if$ |
||||
|
} |
||||
|
't |
||||
|
if$ |
||||
|
nameptr #1 + 'nameptr := |
||||
|
namesleft #1 - 'namesleft := |
||||
|
} |
||||
|
while$ |
||||
|
} if$ |
||||
|
} |
||||
|
|
||||
|
FUNCTION {format.authors} |
||||
|
{ author empty$ |
||||
|
{editor format.names} {author format.names} |
||||
|
if$ |
||||
|
} |
||||
|
|
||||
|
FUNCTION {format.title} |
||||
|
{ title |
||||
|
duplicate$ empty$ 'skip$ |
||||
|
{ "t" change.case$ } |
||||
|
if$ |
||||
|
} |
||||
|
FUNCTION {output.label} |
||||
|
{ newline$ |
||||
|
%"{" cite$ * write$ |
||||
|
cite$ write$ |
||||
|
"" |
||||
|
} |
||||
|
|
||||
|
|
||||
|
FUNCTION {format.date} |
||||
|
{ |
||||
|
"" |
||||
|
duplicate$ empty$ |
||||
|
year duplicate$ empty$ |
||||
|
{ swap$ 'skip$ |
||||
|
{ "there's a month but no year in " cite$ * warning$ } |
||||
|
if$ |
||||
|
* |
||||
|
} |
||||
|
{ swap$ 'skip$ |
||||
|
{ |
||||
|
swap$ |
||||
|
" " * swap$ |
||||
|
} |
||||
|
if$ |
||||
|
* |
||||
|
} |
||||
|
if$ |
||||
|
} |
||||
|
|
||||
|
FUNCTION {output.entry} |
||||
|
{ 's := |
||||
|
output.label |
||||
|
s output |
||||
|
format.authors output |
||||
|
format.date output |
||||
|
format.title output |
||||
|
fin.entry |
||||
|
} |
||||
|
|
||||
|
FUNCTION {default.type} {"?" output.entry} |
||||
|
|
||||
|
FUNCTION {article} {"a" output.entry} |
||||
|
FUNCTION {book} {"B" output.entry} |
||||
|
FUNCTION {booklet} {"k" output.entry} |
||||
|
FUNCTION {conference} {"f" output.entry} |
||||
|
FUNCTION {inbook} {"b" output.entry} |
||||
|
FUNCTION {incollection} {"c" output.entry} |
||||
|
FUNCTION {inproceedings} {"p" output.entry} |
||||
|
FUNCTION {manual} {"m" output.entry} |
||||
|
FUNCTION {mastersthesis} {"Master" output.entry} |
||||
|
FUNCTION {misc} {"-" output.entry} |
||||
|
FUNCTION {phdthesis} {"PhD" output.entry} |
||||
|
FUNCTION {proceedings} {"P" output.entry} |
||||
|
FUNCTION {techreport} {"r" output.entry} |
||||
|
FUNCTION {unpublished} {"u" output.entry} |
||||
|
|
||||
|
|
||||
|
READ |
||||
|
FUNCTION {sortify} |
||||
|
{ purify$ |
||||
|
"l" change.case$ |
||||
|
} |
||||
|
INTEGERS { len } |
||||
|
FUNCTION {chop.word} |
||||
|
{ 's := |
||||
|
'len := |
||||
|
s #1 len substring$ = |
||||
|
{ s len #1 + global.max$ substring$ } |
||||
|
's |
||||
|
if$ |
||||
|
} |
||||
|
FUNCTION {sort.format.names} |
||||
|
{ 's := |
||||
|
#1 'nameptr := |
||||
|
"" |
||||
|
s num.names$ 'numnames := |
||||
|
numnames 'namesleft := |
||||
|
{ namesleft #0 > } |
||||
|
{ s nameptr |
||||
|
"{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" |
||||
|
format.name$ 't := |
||||
|
nameptr #1 > |
||||
|
{ |
||||
|
" " * |
||||
|
namesleft #1 = t "others" = and |
||||
|
{ "zzzzz" * } |
||||
|
{ t sortify * } |
||||
|
if$ |
||||
|
} |
||||
|
{ t sortify * } |
||||
|
if$ |
||||
|
nameptr #1 + 'nameptr := |
||||
|
namesleft #1 - 'namesleft := |
||||
|
} |
||||
|
while$ |
||||
|
} |
||||
|
|
||||
|
FUNCTION {sort.format.title} |
||||
|
{ 't := |
||||
|
"A " #2 |
||||
|
"An " #3 |
||||
|
"The " #4 t chop.word |
||||
|
chop.word |
||||
|
chop.word |
||||
|
sortify |
||||
|
#1 global.max$ substring$ |
||||
|
} |
||||
|
FUNCTION {author.sort} |
||||
|
{ author empty$ |
||||
|
{ key empty$ |
||||
|
{ "to sort, need author or key in " cite$ * warning$ |
||||
|
"" |
||||
|
} |
||||
|
{ key sortify } |
||||
|
if$ |
||||
|
} |
||||
|
{ author sort.format.names } |
||||
|
if$ |
||||
|
} |
||||
|
FUNCTION {author.editor.sort} |
||||
|
{ author empty$ |
||||
|
{ editor empty$ |
||||
|
{ key empty$ |
||||
|
{ "to sort, need author, editor, or key in " cite$ * warning$ |
||||
|
"" |
||||
|
} |
||||
|
{ key sortify } |
||||
|
if$ |
||||
|
} |
||||
|
{ editor sort.format.names } |
||||
|
if$ |
||||
|
} |
||||
|
{ author sort.format.names } |
||||
|
if$ |
||||
|
} |
||||
|
FUNCTION {author.organization.sort} |
||||
|
{ author empty$ |
||||
|
{ organization empty$ |
||||
|
{ key empty$ |
||||
|
{ "to sort, need author, organization, or key in " cite$ * warning$ |
||||
|
"" |
||||
|
} |
||||
|
{ key sortify } |
||||
|
if$ |
||||
|
} |
||||
|
{ "The " #4 organization chop.word sortify } |
||||
|
if$ |
||||
|
} |
||||
|
{ author sort.format.names } |
||||
|
if$ |
||||
|
} |
||||
|
FUNCTION {editor.organization.sort} |
||||
|
{ editor empty$ |
||||
|
{ organization empty$ |
||||
|
{ key empty$ |
||||
|
{ "to sort, need editor, organization, or key in " cite$ * warning$ |
||||
|
"" |
||||
|
} |
||||
|
{ key sortify } |
||||
|
if$ |
||||
|
} |
||||
|
{ "The " #4 organization chop.word sortify } |
||||
|
if$ |
||||
|
} |
||||
|
{ editor sort.format.names } |
||||
|
if$ |
||||
|
} |
||||
|
FUNCTION {presort} |
||||
|
{ type$ "book" = |
||||
|
type$ "inbook" = |
||||
|
or |
||||
|
'author.editor.sort |
||||
|
{ type$ "proceedings" = |
||||
|
'editor.organization.sort |
||||
|
{ type$ "manual" = |
||||
|
'author.organization.sort |
||||
|
'author.sort |
||||
|
if$ |
||||
|
} |
||||
|
if$ |
||||
|
} |
||||
|
if$ |
||||
|
" " |
||||
|
* |
||||
|
year field.or.null sortify |
||||
|
* |
||||
|
" " |
||||
|
* |
||||
|
title field.or.null |
||||
|
sort.format.title |
||||
|
* |
||||
|
#1 entry.max$ substring$ |
||||
|
'sort.key$ := |
||||
|
} |
||||
|
ITERATE {presort} |
||||
|
SORT |
||||
|
ITERATE {call.type$} |
||||
@ -0,0 +1,202 @@ |
|||||
|
" {{{1 Settings |
||||
|
setlocal buftype=nofile |
||||
|
setlocal bufhidden=wipe |
||||
|
setlocal nobuflisted |
||||
|
setlocal noswapfile |
||||
|
setlocal nowrap |
||||
|
setlocal nospell |
||||
|
setlocal cursorline |
||||
|
setlocal nonumber |
||||
|
setlocal nolist |
||||
|
setlocal tabstop=8 |
||||
|
setlocal cole=0 |
||||
|
setlocal cocu=nvic |
||||
|
if g:LatexBox_fold_toc |
||||
|
setlocal foldmethod=expr |
||||
|
setlocal foldexpr=TOCFoldLevel(v:lnum) |
||||
|
setlocal foldtext=TOCFoldText() |
||||
|
endif |
||||
|
" }}}1 |
||||
|
|
||||
|
" {{{1 Functions |
||||
|
" {{{2 TOCClose |
||||
|
function! s:TOCClose() |
||||
|
if g:LatexBox_split_resize |
||||
|
silent exe "set columns-=" . g:LatexBox_split_width |
||||
|
endif |
||||
|
bwipeout |
||||
|
endfunction |
||||
|
|
||||
|
" {{{2 TOCToggleNumbers |
||||
|
function! s:TOCToggleNumbers() |
||||
|
if b:toc_numbers |
||||
|
setlocal conceallevel=3 |
||||
|
let b:toc_numbers = 0 |
||||
|
else |
||||
|
setlocal conceallevel=0 |
||||
|
let b:toc_numbers = 1 |
||||
|
endif |
||||
|
endfunction |
||||
|
|
||||
|
" {{{2 EscapeTitle |
||||
|
function! s:EscapeTitle(titlestr) |
||||
|
let titlestr = substitute(a:titlestr, '\\[a-zA-Z@]*\>\s*{\?', '.*', 'g') |
||||
|
let titlestr = substitute(titlestr, '}', '', 'g') |
||||
|
let titlestr = substitute(titlestr, '\%(\.\*\s*\)\{2,}', '.*', 'g') |
||||
|
return titlestr |
||||
|
endfunction |
||||
|
|
||||
|
" {{{2 TOCActivate |
||||
|
function! s:TOCActivate(close) |
||||
|
let n = getpos('.')[1] - 1 |
||||
|
|
||||
|
if n >= len(b:toc) |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
let entry = b:toc[n] |
||||
|
|
||||
|
let titlestr = s:EscapeTitle(entry['text']) |
||||
|
|
||||
|
" Search for duplicates |
||||
|
" |
||||
|
let i=0 |
||||
|
let entry_hash = entry['level'].titlestr |
||||
|
let duplicates = 0 |
||||
|
while i<n |
||||
|
let i_entry = b:toc[n] |
||||
|
let i_hash = b:toc[i]['level'].s:EscapeTitle(b:toc[i]['text']) |
||||
|
if i_hash == entry_hash |
||||
|
let duplicates += 1 |
||||
|
endif |
||||
|
let i += 1 |
||||
|
endwhile |
||||
|
let toc_bnr = bufnr('%') |
||||
|
let toc_wnr = winnr() |
||||
|
|
||||
|
execute b:calling_win . 'wincmd w' |
||||
|
|
||||
|
let root = fnamemodify(entry['file'], ':h') . '/' |
||||
|
let files = [entry['file']] |
||||
|
for line in filter(readfile(entry['file']), 'v:val =~ ''\\input{''') |
||||
|
let file = matchstr(line, '{\zs.\{-}\ze\(\.tex\)\?}') . '.tex' |
||||
|
if file[0] != '/' |
||||
|
let file = root . file |
||||
|
endif |
||||
|
call add(files, file) |
||||
|
endfor |
||||
|
|
||||
|
" Find section in buffer (or inputted files) |
||||
|
if entry['level'] == 'label' |
||||
|
let re = '\(\\label\_\s*{\|label\s*=\s*\)' . titlestr . '\>' |
||||
|
else |
||||
|
let re = '\\' . entry['level'] . '\_\s*{' . titlestr . '}' |
||||
|
endif |
||||
|
call s:TOCFindMatch(re, duplicates, files) |
||||
|
|
||||
|
if a:close |
||||
|
if g:LatexBox_split_resize |
||||
|
silent exe "set columns-=" . g:LatexBox_split_width |
||||
|
endif |
||||
|
execute 'bwipeout ' . toc_bnr |
||||
|
else |
||||
|
execute toc_wnr . 'wincmd w' |
||||
|
endif |
||||
|
endfunction |
||||
|
|
||||
|
" {{{2 TOCFindMatch |
||||
|
function! s:TOCFindMatch(strsearch,duplicates,files) |
||||
|
if len(a:files) == 0 |
||||
|
echoerr "Could not find: " . a:strsearch |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
call s:TOCOpenBuf(a:files[0]) |
||||
|
let dups = a:duplicates |
||||
|
|
||||
|
" Skip duplicates |
||||
|
while dups > 0 |
||||
|
if search(a:strsearch, 'w') |
||||
|
let dups -= 1 |
||||
|
else |
||||
|
break |
||||
|
endif |
||||
|
endwhile |
||||
|
|
||||
|
if search(a:strsearch, 'w') |
||||
|
normal! zv |
||||
|
return |
||||
|
endif |
||||
|
|
||||
|
call s:TOCFindMatch(a:strsearch,dups,a:files[1:]) |
||||
|
endfunction |
||||
|
|
||||
|
" {{{2 TOCFoldLevel |
||||
|
function! TOCFoldLevel(lnum) |
||||
|
let line = getline(a:lnum) |
||||
|
let match_s1 = line =~# '^\w\+\s' |
||||
|
let match_s2 = line =~# '^\w\+\.\w\+\s' |
||||
|
let match_s3 = line =~# '^\w\+\.\w\+\.\w\+\s' |
||||
|
|
||||
|
if g:LatexBox_fold_toc_levels >= 3 |
||||
|
if match_s3 |
||||
|
return ">3" |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
if g:LatexBox_fold_toc_levels >= 2 |
||||
|
if match_s2 |
||||
|
return ">2" |
||||
|
endif |
||||
|
endif |
||||
|
|
||||
|
if match_s1 |
||||
|
return ">1" |
||||
|
endif |
||||
|
|
||||
|
" Don't fold options |
||||
|
if line =~# '^\s*$' |
||||
|
return 0 |
||||
|
endif |
||||
|
|
||||
|
" Return previous fold level |
||||
|
return "=" |
||||
|
endfunction |
||||
|
|
||||
|
" {{{2 TOCFoldText |
||||
|
function! TOCFoldText() |
||||
|
let parts = matchlist(getline(v:foldstart), '^\(.*\)\t\(.*\)$') |
||||
|
return printf('%-8s%-72s', parts[1], parts[2]) |
||||
|
endfunction |
||||
|
|
||||
|
" {{{2 TOCOpenBuf |
||||
|
function! s:TOCOpenBuf(file) |
||||
|
|
||||
|
let bnr = bufnr(a:file) |
||||
|
if bnr == -1 |
||||
|
execute 'badd ' . a:file |
||||
|
let bnr = bufnr(a:file) |
||||
|
endif |
||||
|
execute 'buffer! ' . bnr |
||||
|
normal! gg |
||||
|
|
||||
|
endfunction |
||||
|
|
||||
|
" }}}1 |
||||
|
|
||||
|
" {{{1 Mappings |
||||
|
nnoremap <buffer> <silent> s :call <SID>TOCToggleNumbers()<CR> |
||||
|
nnoremap <buffer> <silent> q :call <SID>TOCClose()<CR> |
||||
|
nnoremap <buffer> <silent> <Esc> :call <SID>TOCClose()<CR> |
||||
|
nnoremap <buffer> <silent> <Space> :call <SID>TOCActivate(0)<CR> |
||||
|
nnoremap <buffer> <silent> <CR> :call <SID>TOCActivate(1)<CR> |
||||
|
nnoremap <buffer> <silent> <leftrelease> :call <SID>TOCActivate(0)<cr> |
||||
|
nnoremap <buffer> <silent> <2-leftmouse> :call <SID>TOCActivate(1)<cr> |
||||
|
nnoremap <buffer> <silent> G G4k |
||||
|
nnoremap <buffer> <silent> <Esc>OA k |
||||
|
nnoremap <buffer> <silent> <Esc>OB j |
||||
|
nnoremap <buffer> <silent> <Esc>OC l |
||||
|
nnoremap <buffer> <silent> <Esc>OD h |
||||
|
" }}}1 |
||||
|
|
||||
|
" vim:fdm=marker:ff=unix:et:ts=4:sw=4 |
||||
@ -0,0 +1,33 @@ |
|||||
|
" LaTeX Box plugin for Vim |
||||
|
" Maintainer: David Munger |
||||
|
" Email: mungerd@gmail.com |
||||
|
" Version: 0.9.6 |
||||
|
|
||||
|
if exists('*fnameescape') |
||||
|
function! s:FNameEscape(s) |
||||
|
return fnameescape(a:s) |
||||
|
endfunction |
||||
|
else |
||||
|
function! s:FNameEscape(s) |
||||
|
return a:s |
||||
|
endfunction |
||||
|
endif |
||||
|
|
||||
|
if !exists('b:LatexBox_loaded') |
||||
|
|
||||
|
let prefix = expand('<sfile>:p:h') . '/latex-box/' |
||||
|
|
||||
|
execute 'source ' . s:FNameEscape(prefix . 'common.vim') |
||||
|
execute 'source ' . s:FNameEscape(prefix . 'complete.vim') |
||||
|
execute 'source ' . s:FNameEscape(prefix . 'motion.vim') |
||||
|
execute 'source ' . s:FNameEscape(prefix . 'latexmk.vim') |
||||
|
execute 'source ' . s:FNameEscape(prefix . 'folding.vim') |
||||
|
" added by AH to add main.tex file finder |
||||
|
execute 'source ' . s:FNameEscape(prefix . 'findmain.vim') |
||||
|
execute 'source ' . s:FNameEscape(prefix . 'mappings.vim') |
||||
|
|
||||
|
let b:LatexBox_loaded = 1 |
||||
|
|
||||
|
endif |
||||
|
|
||||
|
" vim:fdm=marker:ff=unix:noet:ts=4:sw=4 |
||||
@ -0,0 +1,136 @@ |
|||||
|
" LaTeX indent file (part of LaTeX Box) |
||||
|
" Maintainer: David Munger (mungerd@gmail.com) |
||||
|
|
||||
|
if exists("g:LatexBox_custom_indent") && ! g:LatexBox_custom_indent |
||||
|
finish |
||||
|
endif |
||||
|
if exists("b:did_indent") |
||||
|
finish |
||||
|
endif |
||||
|
|
||||
|
let b:did_indent = 1 |
||||
|
|
||||
|
setlocal indentexpr=LatexBox_TexIndent() |
||||
|
setlocal indentkeys=0=\\end,0=\\end{enumerate},0=\\end{itemize},0=\\end{description},0=\\right,0=\\item,0=\\),0=\\],0},o,O,0\\ |
||||
|
|
||||
|
let s:list_envs = ['itemize', 'enumerate', 'description'] |
||||
|
" indent on \left( and on \(, but not on ( |
||||
|
" indent on \left[ and on \[, but not on [ |
||||
|
" indent on \left\{ and on {, but not on \{ |
||||
|
let s:open_pat = '\\\@<!\%(\\begin\|\\left\a\@!\|\\(\|\\\[\|{\)' |
||||
|
let s:close_pat = '\\\@<!\%(\\end\|\\right\a\@!\|\\)\|\\\]\|}\)' |
||||
|
let s:list_open_pat = '\\\@<!\\begin{\%(' . join(s:list_envs, '\|') . '\)}' |
||||
|
let s:list_close_pat = '\\\@<!\\end{\%(' . join(s:list_envs, '\|') . '\)}' |
||||
|
|
||||
|
function! s:CountMatches(str, pat) |
||||
|
return len(substitute(substitute(a:str, a:pat, "\n", 'g'), "[^\n]", '', 'g')) |
||||
|
endfunction |
||||
|
|
||||
|
|
||||
|
" TexIndent {{{ |
||||
|
function! LatexBox_TexIndent() |
||||
|
|
||||
|
let lnum_curr = v:lnum |
||||
|
let lnum_prev = prevnonblank(lnum_curr - 1) |
||||
|
|
||||
|
if lnum_prev == 0 |
||||
|
return 0 |
||||
|
endif |
||||
|
|
||||
|
let line_curr = getline(lnum_curr) |
||||
|
let line_prev = getline(lnum_prev) |
||||
|
|
||||
|
" remove \\ |
||||
|
let line_curr = substitute(line_curr, '\\\\', '', 'g') |
||||
|
let line_prev = substitute(line_prev, '\\\\', '', 'g') |
||||
|
|
||||
|
" strip comments |
||||
|
let line_curr = substitute(line_curr, '\\\@<!%.*$', '', 'g') |
||||
|
let line_prev = substitute(line_prev, '\\\@<!%.*$', '', 'g') |
||||
|
|
||||
|
" find unmatched opening patterns on previous line |
||||
|
let n = s:CountMatches(line_prev, s:open_pat)-s:CountMatches(line_prev, s:close_pat) |
||||
|
let n += s:CountMatches(line_prev, s:list_open_pat)-s:CountMatches(line_prev, s:list_close_pat) |
||||
|
|
||||
|
" reduce indentation if current line starts with a closing pattern |
||||
|
if line_curr =~ '^\s*\%(' . s:close_pat . '\)' |
||||
|
let n -= 1 |
||||
|
endif |
||||
|
|
||||
|
" compensate indentation if previous line starts with a closing pattern |
||||
|
if line_prev =~ '^\s*\%(' . s:close_pat . '\)' |
||||
|
let n += 1 |
||||
|
endif |
||||
|
|
||||
|
" reduce indentation if current line starts with a closing list |
||||
|
if line_curr =~ '^\s*\%(' . s:list_close_pat . '\)' |
||||
|
let n -= 1 |
||||
|
endif |
||||
|
|
||||
|
" compensate indentation if previous line starts with a closing list |
||||
|
if line_prev =~ '^\s*\%(' . s:list_close_pat . '\)' |
||||
|
let n += 1 |
||||
|
endif |
||||
|
|
||||
|
" reduce indentation if previous line is \begin{document} |
||||
|
if line_prev =~ '\\begin\s*{document}' |
||||
|
let n -= 1 |
||||
|
endif |
||||
|
|
||||
|
" less shift for lines starting with \item |
||||
|
let item_here = line_curr =~ '^\s*\\item' |
||||
|
let item_above = line_prev =~ '^\s*\\item' |
||||
|
if !item_here && item_above |
||||
|
let n += 1 |
||||
|
elseif item_here && !item_above |
||||
|
let n -= 1 |
||||
|
endif |
||||
|
|
||||
|
return indent(lnum_prev) + n * &sw |
||||
|
endfunction |
||||
|
" }}} |
||||
|
|
||||
|
" Restore cursor position, window position, and last search after running a |
||||
|
" command. |
||||
|
function! Latexbox_CallIndent() |
||||
|
" Save the current cursor position. |
||||
|
let cursor = getpos('.') |
||||
|
|
||||
|
" Save the current window position. |
||||
|
normal! H |
||||
|
let window = getpos('.') |
||||
|
call setpos('.', cursor) |
||||
|
|
||||
|
" Get first non-whitespace character of current line. |
||||
|
let line_start_char = matchstr(getline('.'), '\S') |
||||
|
|
||||
|
" Get initial tab position. |
||||
|
let initial_tab = stridx(getline('.'), line_start_char) |
||||
|
|
||||
|
" Execute the command. |
||||
|
execute 'normal! ==' |
||||
|
|
||||
|
" Get tab position difference. |
||||
|
let difference = stridx(getline('.'), line_start_char) - initial_tab |
||||
|
|
||||
|
" Set new cursor Y position based on calculated difference. |
||||
|
let cursor[2] = cursor[2] + difference |
||||
|
|
||||
|
" Restore the previous window position. |
||||
|
call setpos('.', window) |
||||
|
normal! zt |
||||
|
|
||||
|
" Restore the previous cursor position. |
||||
|
call setpos('.', cursor) |
||||
|
endfunction |
||||
|
|
||||
|
" autocmd to call indent after completion |
||||
|
" 7.3.598 |
||||
|
if v:version > 703 || (v:version == 703 && has('patch598')) |
||||
|
augroup LatexBox_Completion |
||||
|
autocmd! |
||||
|
autocmd CompleteDone <buffer> call Latexbox_CallIndent() |
||||
|
augroup END |
||||
|
endif |
||||
|
|
||||
|
" vim:fdm=marker:ff=unix:noet:ts=4:sw=4 |
||||
@ -0,0 +1,9 @@ |
|||||
|
syntax match helpText /^.*: .*/ |
||||
|
syntax match secNum /^\S\+\(\.\S\+\)\?\s*/ contained conceal |
||||
|
syntax match secLine /^\S\+\t.\+/ contains=secNum |
||||
|
syntax match mainSecLine /^[^\.]\+\t.*/ contains=secNum |
||||
|
syntax match ssubSecLine /^[^\.]\+\.[^\.]\+\.[^\.]\+\t.*/ contains=secNum |
||||
|
highlight link helpText PreProc |
||||
|
highlight link secNum Number |
||||
|
highlight link mainSecLine Title |
||||
|
highlight link ssubSecLine Comment |
||||
@ -0,0 +1,14 @@ |
|||||
|
4,$MkVimball! %:p:h/LatexBox.vmb %:p:h |
||||
|
finish |
||||
|
|
||||
|
ftplugin/tex_LatexBox.vim |
||||
|
ftplugin/latex-box/common.vim |
||||
|
ftplugin/latex-box/complete.vim |
||||
|
ftplugin/latex-box/findman.vim |
||||
|
ftplugin/latex-box/folding.vim |
||||
|
ftplugin/latex-box/latexmk.vim |
||||
|
ftplugin/latex-box/mappings.vim |
||||
|
ftplugin/latex-box/motion.vim |
||||
|
ftplugin/latex-box/vimcomplete.bst |
||||
|
indent/tex.vim |
||||
|
doc/latex-box.txt |
||||
@ -1 +1 @@ |
|||||
Subproject commit cfd3b2d388a8c2e9903d7a9d80a65539aabfe933 |
Subproject commit 0ee36b26e127cda512a8f2852a59e5a5f374c87f |
||||
@ -1 +1 @@ |
|||||
Subproject commit d24ad6b301685cd3b9278420248cc780fdc8fc59 |
Subproject commit 8bc47fd1c40cdad9ea1f36c0cf13592c70ea65e9 |
||||
@ -1 +1 @@ |
|||||
Subproject commit 310a8d1ba9ed14db6126d2d979863e34f33f67ee |
Subproject commit ed2a3c2b07e10c208033feaa3e7956995d2923aa |
||||
@ -1 +1 @@ |
|||||
Subproject commit bcf3de4fdffae45fc7c85b6b84a01b37177924aa |
Subproject commit 0b44415a3302030b56755cc1135ca9ca57dc1ada |
||||
@ -1 +1 @@ |
|||||
Subproject commit 9c8468e83232c3e45b730d2d0b28d609053dec05 |
Subproject commit fd70ac2ab74a91fb049cb8e82237c34d88354673 |
||||
@ -1 +1 @@ |
|||||
Subproject commit bb095e897118ff7a86b60f6ee7df254fa2d39f18 |
Subproject commit f5a75d075d3c005ebe69e3f5e56cf99516e8aa3b |
||||
@ -1 +1 @@ |
|||||
Subproject commit fa018f38252f58073f2987f8bf0d2d4a61e07277 |
Subproject commit 8ff701a5bdb8d382431eb042e4faf3320883b020 |
||||
@ -1 +1 @@ |
|||||
Subproject commit e37b9358980d312c1f4fbbcb4a36d1a9d4bdb415 |
Subproject commit 146fe47ee6b2faf90d6dc1232ef1858883d798bb |
||||
@ -1 +1 @@ |
|||||
Subproject commit 64a40a916df0e3cd76fa11cc72a8bfaee4ef25a2 |
Subproject commit 6f886cdc48cf34c50eb723abca2f813a5de2c11b |
||||
Loading…
Reference in new issue