pax_global_header 0000666 0000000 0000000 00000000064 12275675654 0014535 g ustar 00root root 0000000 0000000 52 comment=a662c816eeeb1c7dc104654ea2d2cc3815362fc0
vim-youcompleteme-0+20140207+git18be5c2/ 0000775 0000000 0000000 00000000000 12275675654 0017362 5 ustar 00root root 0000000 0000000 vim-youcompleteme-0+20140207+git18be5c2/CONTRIBUTING.md 0000664 0000000 0000000 00000013517 12275675654 0021622 0 ustar 00root root 0000000 0000000 Writing good issue reports
==========================
First things first: **the issue tracker is NOT for tech support**. It is for
reporting bugs and requesting features. If your issue amounts to "I can't get
YCM to work on my machine" and the reason why is obviously related to your
machine configuration and the problem would not be resolved with _reasonable_
changes to the YCM codebase, then the issue is likely to be closed.
**A good place to ask questions is the [ycm-users][] Google group**. Rule of
thumb: if you're not sure whether your problem is a real bug, ask on the group.
**YCM compiles just fine**; [the build bots say so][build-bots]. If the bots are
green and YCM doesn't compile on your machine, then _your machine is the root
cause_. Now read the first paragraph again.
Realize that quite literally _thousands_ of people have gotten YCM to work
successfully so if you can't, it's probably because you have a peculiar
system/Vim configuration or you didn't go through the docs carefully enough.
It's very unlikely to be caused by an actual bug in YCM because someone would
have already found it and reported it.
This leads us to point #2: **make sure you have checked the docs before
reporting an issue**. The docs are extensive and cover a ton of things; there's
also an FAQ at the bottom that quite possibly addresses your problem.
Further, **search the issue tracker for similar issues** before creating a new
one. There's no point in duplication; if an existing issue addresses your
problem, please comment there instead of creating a duplicate.
You should also **search the archives of the [ycm-users][] mailing list**.
Lastly, **make sure you are running the latest version of YCM**. The issue you
have encountered may have already been fixed. **Don't forget to recompile
ycm_core.so too** (usually by just running `install.sh` again).
OK, so we've reached this far. You need to create an issue. First realize that
the time it takes to fix your issue is a multiple of how long it takes the
developer to reproduce it. The easier it is to reproduce, the quicker it'll be
fixed.
Here are the things you should do when creating an issue:
1. **Write a step-by-step procedure that when performed repeatedly reproduces
your issue.** If we can't reproduce the issue, then we can't fix it. It's
that simple.
2. Put the following options in your vimrc:
```viml
let g:ycm_server_use_vim_stdout = 1
let g:ycm_server_log_level = 'debug'
```
Then start gvim/macvim (not console vim) from the console. As you use Vim,
you'll see the `ycmd` debug output stream in the console. Attach that to you
issue.
3. **Create a test case for your issue**. This is critical. Don't talk about how
"when I have X in my file" or similar, _create a file with X in it_ and put
the contents inside code blocks in your issue description. Try to make this
test file _as small as possible_. Don't just paste a huge, 500 line source
file you were editing and present that as a test. _Minimize_ the file so that
the problem is reproduced with the smallest possible amount of test data.
4. **Include your OS and OS version.**
5. **Include the output of `vim --version`.**
Creating good pull requests
===========================
1. **Follow the code style of the existing codebase.**
- The Python code **DOES NOT** follow PEP 8. This is not an oversight, this
is by choice. You can dislike this as much as you want, but you still need
to follow the existing style. Look at other Python files to see what the
style is.
- The C++ code has an automated formatter (`style_format.sh` that runs
`astyle`) but it's not perfect. Again, look at the other C++ files and
match the code style you see.
- Same thing for VimScript. Match the style of the existing code.
2. **Your code needs to be well written and easy to maintain**. This is of the
_utmost_ importance. Other people will have to maintain your code so don't
just throw stuff against the wall until things kinda work.
3. **Write tests for your code**. If you're changing the VimScript code then
you don't have to since it's hard to test that code. This is also why you
should strive to implement your change in Python if at all possible (and if
it makes sense to do so). Python is also _much_ faster than VimScript.
4. **Explain in detail why your pull request makes sense.** Ask yourself, would
this feature be helpful to others? Not just a few people, but a lot of YCM’s
users? See, good features are useful to many. If your feature is only useful
to you and _maybe_ a couple of others, then that’s not a good feature.
There is such a thing as “feature overload”. When software accumulates so
many features of which most are only useful to a handful, then that software
has become “bloated”. We don’t want that.
Requests for features that are obscure or are helpful to but a few, or are
not part of YCM's "vision" will be rejected. Yes, even if you provide a
patch that completely implements it.
Please include details on exactly what you would like to see, and why. The
why is important - it's not always clear why a feature is really useful. And
sometimes what you want can be done in a different way if the reason for the
change is known. _What goal is your change trying to accomplish?_
5. **Sign the Google [Contributor License Agreement][cla]** (you can sign
online at the bottom of that page). You _must_ sign this form, otherwise we
cannot merge in your changes. **_Always_ mention in the pull request that
you've signed it**, even if you signed it for a previous pull request (you
only need to sign the CLA once).
[build-bots]: https://travis-ci.org/Valloric/YouCompleteMe
[ycm-users]: https://groups.google.com/forum/?hl=en#!forum/ycm-users
[cla]: https://developers.google.com/open-source/cla/individual
vim-youcompleteme-0+20140207+git18be5c2/COPYING.txt 0000664 0000000 0000000 00000104513 12275675654 0021237 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
vim-youcompleteme-0+20140207+git18be5c2/README.md 0000664 0000000 0000000 00000215604 12275675654 0020651 0 ustar 00root root 0000000 0000000 YouCompleteMe: a code-completion engine for Vim
===============================================
[](https://travis-ci.org/Valloric/YouCompleteMe)
YouCompleteMe is a fast, as-you-type, fuzzy-search code completion engine for
[Vim][]. It has several completion engines: an identifier-based engine that
works with every programming language, a semantic, [Clang][]-based engine that
provides native semantic code completion for C/C++/Objective-C/Objective-C++
(from now on referred to as "the C-family languages"), a [Jedi][]-based
completion engine for Python, an [OmniSharp][]-based completion engine for C#
and an omnifunc-based completer that uses data from Vim's omnicomplete system to
provide semantic completions for many other languages (Ruby, PHP etc.).

Here's an explanation of what happens in the short GIF demo above.
First, realize that **no keyboard shortcuts had to be pressed** to get the list
of completion candidates at any point in the demo. The user just types and the
suggestions pop up by themselves. If the user doesn't find the completion
suggestions relevant and/or just wants to type, they can do so; the completion
engine will not interfere.
When the user sees a useful completion string being offered, they press the TAB
key to accept it. This inserts the completion string. Repeated presses of the
TAB key cycle through the offered completions.
If the offered completions are not relevant enough, the user can continue typing
to further filter out unwanted completions.
A critical thing to notice is that the completion **filtering is NOT based on
the input being a string prefix of the completion** (but that works too). The
input needs to be a _[subsequence][] match_ of a completion. This is a fancy way
of saying that any input characters need to be present in a completion string in
the order in which they appear in the input. So `abc` is a subsequence of
`xaybgc`, but not of `xbyxaxxc`. After the filter, a complicated sorting system
ranks the completion strings so that the most relevant ones rise to the top of
the menu (so you usually need to press TAB just once).
**All of the above works with any programming language** because of the
identifier-based completion engine. It collects all of the identifiers in the
current file and other files you visit (and your tags files) and searches them
when you type (identifiers are put into per-filetype groups).
The demo also shows the semantic engine in use. When the user presses `.`, `->`
or `::` while typing in insert mode (for C++; different triggers are used for
other languages), the semantic engine is triggered (it can also be triggered
with a keyboard shortcut; see the rest of the docs).
The last thing that you can see in the demo is YCM's diagnostic display features
(the little red X that shows up in the left gutter; inspired by [Syntastic][])
if you are editing a C-family file. As Clang compiles your file and detects
warnings or errors, they will be presented in various ways. You don't need to
save your file or press any keyboard shortcut to trigger this, it "just happens"
in the background.
In essence, YCM obsoletes the following Vim plugins because it has all of their
features plus extra:
- clang_complete
- AutoComplPop
- Supertab
- neocomplcache
YCM also provides semantic go-to-definition/declaration commands for C-family
languages & Python. Expect more IDE features powered by the various YCM semantic
engines in the future.
You'll also find that YCM has filepath completers (try typing `./` in a file)
and a completer that integrates with [UltiSnips][].
Mac OS X super-quick installation
---------------------------------
Please refer to the full Installation Guide below; the following commands are
provided on a best-effort basis and may not work for you.
Install the latest version of [MacVim][]. Yes, MacVim. And yes, the _latest_.
If you don't use the MacVim GUI, it is recommended to use the Vim binary that is
inside the MacVim.app package (`MacVim.app/Contents/MacOS/Vim`). To ensure it
works correctly copy the `mvim` script from the [MacVim][] download to your
local binary folder (for example `/usr/local/bin/mvim`) and then symlink it:
ln -s /usr/local/bin/mvim vim
Install YouCompleteMe with [Vundle][].
**Remember:** YCM is a plugin with a compiled component. If you **update** YCM
using Vundle and the ycm_support_libs library APIs have changed (happens
rarely), YCM will notify you to recompile it. You should then rerun the install
process.
It's recommended that you have the latest Xcode installed along with the latest
Command Line Tools (that you install from within Xcode).
Install CMake. Preferably with [Homebrew][brew], but here's the [stand-alone
CMake installer][cmake-download].
_If_ you have installed a Homebrew Python and/or Homebrew MacVim, see the _FAQ_
for details.
Compiling YCM **with** semantic support for C-family languages:
cd ~/.vim/bundle/YouCompleteMe
./install.sh --clang-completer
Compiling YCM **without** semantic support for C-family languages:
cd ~/.vim/bundle/YouCompleteMe
./install.sh
If you want semantic C# support, you should add `--omnisharp-completer` to the
install script as well.
That's it. You're done. Refer to the _User Guide_ section on how to use YCM.
Don't forget that if you want the C-family semantic completion engine to work,
you will need to provide the compilation flags for your project to YCM. It's all
in the User Guide.
YCM comes with sane defaults for its options, but you still may want to take a
look at what's available for configuration. There are a few interesting options
that are conservatively turned off by default that you may want to turn on.
Ubuntu Linux x64 super-quick installation
-----------------------------------------
Please refer to the full Installation Guide below; the following commands are
provided on a best-effort basis and may not work for you.
Make sure you have Vim 7.3.584 with python2 support. At the time of writing, the
version of Vim shipping with Ubuntu is too old. You may need to [compile Vim
from source][vim-build] (don't worry, it's easy).
Install YouCompleteMe with [Vundle][].
**Remember:** YCM is a plugin with a compiled component. If you **update** YCM
using Vundle and the ycm_support_libs library APIs have changed (happens
rarely), YCM will notify you to recompile it. You should then rerun the install
process.
Install development tools and CMake: `sudo apt-get install build-essential cmake`
Make sure you have Python headers installed: `sudo apt-get install python-dev`.
Compiling YCM **with** semantic support for C-family languages:
cd ~/.vim/bundle/YouCompleteMe
./install.sh --clang-completer
Compiling YCM **without** semantic support for C-family languages:
cd ~/.vim/bundle/YouCompleteMe
./install.sh
If you want semantic C# support, you should add `--omnisharp-completer` to the
install script as well.
That's it. You're done. Refer to the _User Guide_ section on how to use YCM.
Don't forget that if you want the C-family semantic completion engine to work,
you will need to provide the compilation flags for your project to YCM. It's all
in the User Guide.
YCM comes with sane defaults for its options, but you still may want to take a
look at what's available for configuration. There are a few interesting options
that are conservatively turned off by default that you may want to turn on.
Windows Installation
--------------------
YCM has **no official support for Windows**, but that doesn't mean you can't get
it to work there. See the [Windows Installation Guide][win-wiki] wiki page. Feel
free to add to it.
Full Installation Guide
-----------------------
These are the steps necessary to get YCM working on a Unix OS like Linux or
Mac OS X. My apologies to Windows users, but I don't have a guide for them. The
code is platform agnostic, so if everything is configured correctly, YCM
_should_ work on Windows without issues (but as of writing, it's untested on
that platform).
See the _FAQ_ if you have any issues.
**Remember:** YCM is a plugin with a compiled component. If you **update** YCM
using Vundle and the ycm_support_libs library APIs have changed (happens
rarely), YCM will notify you to recompile it. You should then rerun the install
process.
**Please follow the instructions carefully. Read EVERY WORD.**
1. **Ensure that your version of Vim is _at least_ 7.3.584 _and_ that it has
support for python2 scripting**.
Inside Vim, type `:version`. Look at the first two to three lines of output;
it should say `Vi IMproved 7.3` and then below that, `Included patches:
1-X`, where X will be some number. That number needs to be 584 or higher.
If your version of Vim is not recent enough, you may need to [compile Vim
from source][vim-build] (don't worry, it's easy).
After you have made sure that you have Vim 7.3.584+, type the following in
Vim: `:echo has('python')`. The output should be 1. If it's 0, then get a
version of Vim with Python support.
2. **Install YCM** with [Vundle][] (or [Pathogen][], but Vundle is a better
idea). With Vundle, this would mean adding a `Bundle
'Valloric/YouCompleteMe'` line to your [vimrc][].
If you don't install YCM with Vundle, make sure you have run
`git submodule update --init --recursive` after checking out the YCM
repository (Vundle will do this for you) to fetch YCM's dependencies.
3. [Complete this step ONLY if you care about semantic completion support for
C-family languages. Otherwise it's not neccessary.]
**Download the latest version of `libclang`**. Clang is an open-source
compiler that can compile C/C++/Objective-C/Objective-C++. The `libclang`
library it provides is used to power the YCM semantic completion engine for
those languages. YCM is designed to work with libclang version 3.4 or
higher, but can in theory work with any 3.2+ version as well.
You can use the system libclang _only if you are sure it is version 3.3 or
higher_, otherwise don't. Even if it is, I recommend using the [official
binaries from llvm.org][clang-download] if at all possible. Make sure you
download the correct archive file for your OS.
4. **Compile the `ycm_support_libs` libraries** that YCM needs. These libs
are the C++ engines that YCM uses to get fast completions.
You will need to have `cmake` installed in order to generate the required
makefiles. Linux users can install cmake with their package manager (`sudo
apt-get install cmake` for Ubuntu) whereas other users can [download and
install][cmake-download] cmake from its project site. Mac users can also get
it through [Homebrew][brew] with `brew install cmake`.
You also need to make sure you have Python headers installed. On a
Debian-like Linux distro, this would be `sudo apt-get install python-dev`.
On Mac they should already be present.
Here we'll assume you installed YCM with Vundle. That means that the
top-level YCM directory is in `~/.vim/bundle/YouCompleteMe`.
We'll create a new folder where build files will be placed. Run the
following:
cd ~
mkdir ycm_build
cd ycm_build
Now we need to generate the makefiles. If you DON'T care about semantic
support for C-family languages, run the following command in the `ycm_build`
directory:
cmake -G "Unix Makefiles" . ~/.vim/bundle/YouCompleteMe/cpp
If you DO care about semantic support for C-family languages, then your
`cmake` call will be a bit more complicated. We'll assume you downloaded a
binary distribution of LLVM+Clang from llvm.org in step 3 and that you
extracted the archive file to folder `~/ycm_temp/llvm_root_dir` (with `bin`,
`lib`, `include` etc. folders right inside that folder). With that in mind,
run the following command in the `ycm_build` directory:
cmake -G "Unix Makefiles" -DPATH_TO_LLVM_ROOT=~/ycm_temp/llvm_root_dir . ~/.vim/bundle/YouCompleteMe/cpp
Now that makefiles have been generated, simply run:
make ycm_support_libs
For those who want to use the system version of libclang, you would pass
`-DUSE_SYSTEM_LIBCLANG=ON` to cmake _instead of_ the
`-DPATH_TO_LLVM_ROOT=...` flag.
You could also force the use of a custom libclang library with
`-DEXTERNAL_LIBCLANG_PATH=/path/to/libclang.so` flag (the library would end
with `.dylib` on a Mac). Again, this flag would be used _instead of_ the
other flags.
Running the `make` command will also place the `libclang.[so|dylib]` in the
`YouCompleteMe/python` folder for you if you compiled with clang support (it
needs to be there for YCM to work).
That's it. You're done. Refer to the _User Guide_ section on how to use YCM.
Don't forget that if you want the C-family semantic completion engine to work,
you will need to provide the compilation flags for your project to YCM. It's all
in the User Guide.
YCM comes with sane defaults for its options, but you still may want to take a
look at what's available for configuration. There are a few interesting options
that are conservatively turned off by default that you may want to turn on.
User Guide
----------
### General Usage
- If the offered completions are too broad, keep typing characters; YCM will
continue refining the offered completions based on your input.
- Filtering is "smart-case" sensitive; if you are typing only lowercase letters,
then it's case-insensitive. If your input contains uppercase letters, then the
uppercase letters in your query must match uppercase letters in the completion
strings (the lowercase letters still match both). So, "foo" matches "Foo" and
"foo", "Foo" matches "Foo" and "FOO" but not "foo".
- Use the TAB key to accept a completion and continue pressing TAB to cycle
through the completions. Use Shift-TAB to cycle backwards. Note that if you're
using console Vim (that is, not Gvim or MacVim) then it's likely that the
Shift-TAB binding will not work because the console will not pass it to Vim.
You can remap the keys; see the _Options_ section below.
Knowing a little bit about how YCM works internally will prevent confusion. YCM
has several completion engines: an identifier-based completer that collects all
of the identifiers in the current file and other files you visit (and your tags
files) and searches them when you type (identifiers are put into per-filetype
groups).
There are also several semantic engines in YCM. There's a libclang-based
completer that provides semantic completion for C-family languages. There's a
Jedi-based completer for semantic completion for Python. There's also an
omnifunc-based completer that uses data from Vim's omnicomplete system to
provide semantic completions when no native completer exists for that language
in YCM.
There are also other completion engines, like the UltiSnips completer and the
filepath completer.
YCM automatically detects which completion engine would be the best in any
situation. On occasion, it queries several of them at once, merges the
outputs and presents the results to you.
### Client-server architecture
YCM has a client-server architecture; the Vim part of YCM is only a thin client
that talks to the `ycmd` HTTP+JSON server that has the vast majority of YCM
logic and functionality. The server is started and stopped automatically as you
start and stop Vim.
### Completion string ranking
The subsequence filter removes any completions that do not match the input, but
then the sorting system kicks in. It's actually very complicated and uses lots
of factors, but suffice it to say that "word boundary" (WB) subsequence
character matches are "worth" more than non-WB matches. In effect, this means
given an input of "gua", the completion "getUserAccount" would be ranked higher
in the list than the "Fooguxa" completion (both of which are subsequence
matches). A word-boundary character are all capital characters, characters
preceded by an underscore and the first letter character in the completion
string.
### General Semantic Completion Engine Usage
- You can use Ctrl+Space to trigger the completion suggestions anywhere, even
without a string prefix. This is useful to see which top-level functions are
available for use.
### C-family Semantic Completion Engine Usage
YCM looks for a `.ycm_extra_conf.py` file in the directory of the opened file or
in any directory above it in the hierarchy (recursively); when the file is
found, it is loaded (only once!) as a Python module. YCM calls a `FlagsForFile`
method in that module which should provide it with the information necessary to
compile the current file. You can also provide a path to a global
`.ycm_extra_conf.py` file, which will be used as a fallback. To prevent the
execution of malicious code from a file you didn't write YCM will ask you once
per `.ycm_extra_conf.py` if it is safe to load. This can be disabled and you can
white-/blacklist files. See the _Options_ section for more details.
This system was designed this way so that the user can perform any arbitrary
sequence of operations to produce a list of compilation flags YCM should hand
to Clang.
[See YCM's own `.ycm_extra_conf.py`][flags_example] for details on how this
works. You should be able to use it _as a starting point_. **Don't** just
copy/paste that file somewhere and expect things to magically work; **your project
needs different flags**. Hint: just replace the strings in the `flags` variable
with compilation flags necessary for your project. That should be enough for 99%
of projects.
Yes, [Clang's `CompilationDatabase` system][compdb] is also supported. Again, see the
above linked example file.
If Clang encounters errors when compiling the header files that your file
includes, then it's probably going to take a long time to get completions. When
the completion menu finally appears, it's going to have a large number of
unrelated completion strings (type/function names that are not actually
members). This is because Clang fails to build a precompiled preamble for your
file if there are any errors in the included headers and that preamble is key to
getting fast completions.
Call the `:YcmDiags` command to see if any errors or warnings were detected in
your file.
### Python semantic completion
YCM uses [Jedi][] to power its semantic completion for Python. This should "just
work" without any configuration from the user. You do NOT need to install Jedi
yourself; YCM uses it as a git subrepo. If you're installing YCM with Vundle
(which is the recommended way) then Vundle will make sure that the subrepo is
checked out when you do `:BundleInstall`. If you're installing YCM by hand, then
you need to run `git submodule update --init --recursive` when you're checking
out the YCM repository. That's it.
But again, installing YCM with Vundle takes care of all of this for you.
In the future expect to see features like go-to-definition for Python as well.
### C# semantic completion
YCM uses [OmniSharp][] to provide semantic completion for C#. It's used as a git
subrepo. If you're installing YCM with Vundle (which is the recommended way)
then Vundle will make sure that the subrepo is checked out when you do
`:BundleInstall`. If you're installing YCM by hand, then you need to run `git
submodule update --init --recursive` when you're checking out the YCM
repository.
OmniSharp is written in C# and has to be compiled. The `install.sh` script takes
care of this if you pass `--omnisharp-completer` as an argument.
### Semantic completion for other languages
YCM will use your `omnifunc` (see `:h omnifunc` in Vim) as a source for semantic
completions if it does not have a native semantic completion engine for your
file's filetype. Vim comes with okayish omnifuncs for various languages like
Ruby, PHP etc. It depends on the language.
You can get stellar omnifuncs for Java and Ruby with [Eclim][]. Just make sure
you have the _latest_ Eclim installed and configured (this means Eclim `>= 2.2.*`
and Eclipse `>= 4.2.*`).
After installing Eclim remember to create a new Eclipse project within your
application by typing `:ProjectCreate -n ruby` (or `-n java`)
inside vim and don't forget to have `let g:EclimCompletionMethod = 'omnifunc'`
in your vimrc. This will make YCM and Eclim play nice; YCM will use Eclim's omnifuncs
as the data source for semantic completions and provide the auto-triggering
and subsequence-based matching (and other YCM features) on top of it.
### Writing New Semantic Completers
You have two options here: writing an `omnifunc` for Vim's omnicomplete system
that YCM will then use through its omni-completer, or a custom completer for YCM
using the [Completer API][completer-api].
Here are the differences between the two approaches:
- You have to use VimScript to write the omnifunc, but get to use Python to
write for the Completer API; this by itself should make you want to use the
API.
- The Completer API is a _much_ more powerful way to integrate with YCM and it
provides a wider set of features. For instance, you can make your Completer
query your semantic back-end in an asynchronous fashion, thus not blocking
Vim's GUI thread while your completion system is processing stuff. This is
impossible with VimScript. All of YCM's completers use the Completer API.
- Performance with the Completer API is better since Python executes faster than
VimScript.
If you want to use the `omnifunc` system, see the relevant Vim docs with `:h
complete-functions`. For the Completer API, see [the API docs][completer-api].
If you want to upstream your completer into YCM's source, you should use the
Completer API.
### Diagnostic display
YCM will display diagnostic notifications if you compiled YCM with Clang
support. Since YCM continuously recompiles your file as you type, you'll get
notified of errors and warnings in your file as fast as possible.
Here are the various pieces of the diagnostic UI:
- Icons show up in the Vim gutter on lines that have a diagnostic.
- Regions of text related to diagnostics are highlighted (by default, a red
wavy underline in `gvim` and a red background in `vim`).
- Moving the cursor to a line with a diagnostic echoes the diagnostic text.
- Vim's location list is automatically populated with diagnostic data (off by
default, see options).
The new diagnostics (if any) will be displayed the next time you press any key
on the keyboard. So if you stop typing and just wait for the new diagnostics to
come in, that _will not work_. You need to press some key for the GUI to update.
Having to press a key to get the updates is unfortunate, but cannot be changed
due to the way Vim internals operate; there is no way that a background task can
update Vim's GUI after it has finished running. You _have to_ press a key. This
will make YCM check for any pending diagnostics updates.
You _can_ force a full, blocking compilation cycle with the
`:YcmForceCompileAndDiagnostics` command (you may want to map that command to a
key; try putting `nnoremap :YcmForceCompileAndDiagnostics` in your
vimrc). Calling this command will force YCM to immediately recompile your file
and display any new diagnostics it encounters. Do note that recompilation with
this command may take a while and during this time the Vim GUI _will_ be
blocked.
YCM will display a short diagnostic message when you move your cursor to the
line with the error. You can get a detailed diagnostic message with the
`d` key mapping (can be changed in the options) YCM provides when your
cursor is on the line with the diagnostic.
You can also see the full diagnostic message for all the diagnostics in the
current file in Vim's `locationlist`, which can be opened with the `:lopen` and
`:lclose` commands (make sure you have set `let
g:ycm_always_populate_location_list = 1` in your vimrc). A good way to toggle
the display of the `locationlist` with a single key mapping is provided by
another (very small) Vim plugin called [ListToggle][] (which also makes it
possible to change the height of the `locationlist` window), also written by
yours truly.
#### Diagnostic highlighting groups
You can change the styling for the highlighting groups YCM uses. For the signs
in the Vim gutter, the relevant groups are:
- `YcmErrorSign`, which falls back to group `SyntasticErrorSign` and then
`error` if they exist
- `YcmWarningSign`, which falls back to group `SyntasticWarningSign` and then
`todo` if they exist
You can also style the line that has the warning/error with these groups:
- `YcmErrorLine`, which falls back to group `SyntasticErrorLine` if it exists
- `YcmWarningLine`, which falls back to group `SyntasticWarningLine` if it
exists
Note that the line highlighting groups only work when gutter signs are turned
on.
Here's how you'd change the style for a group:
```
highlight YcmErrorLine guibg=#3f0000
```
Commands
--------
### The `:YcmRestartServer` command
If the `ycmd` completion server suddenly stops for some reason, you can restart
it with this command.
### The `:YcmForceCompileAndDiagnostics` command
Calling this command will force YCM to immediately recompile your file
and display any new diagnostics it encounters. Do note that recompilation with
this command may take a while and during this time the Vim GUI _will_ be
blocked.
You may want to map this command to a key; try putting `nnoremap
:YcmForceCompileAndDiagnostics` in your vimrc.
### The `:YcmDiags` command
Calling this command will fill Vim's `locationlist` with errors or warnings if
any were detected in your file and then open it.
The `g:ycm_open_loclist_on_ycm_diags` option can be used to prevent the location
list from opening, but still have it filled with new diagnostic data. See the
_Options_ section for details.
### The `:YcmShowDetailedDiagnostic` command
This command shows the full diagnostic text when the user's cursor is on the
line with the diagnostic.
### The `:YcmDebugInfo` command
This will print out various debug information for the current file. Useful to
see what compile commands will be used for the file if you're using the semantic
completion engine.
### The `:YcmCompleter` command
This command can be used to invoke completer-specific commands. If the first
argument is of the form `ft=...` the completer for that file type will be used
(for example `ft=cpp`), else the native completer of the current buffer will be
used.
Call `YcmCompleter` without further arguments for information about the
commands you can call for the selected completer.
See the _YcmCompleter subcommands_ section for more information on the available
subcommands.
YcmCompleter subcommands
------------------------
[See the docs for the `YcmCompleter` command before tackling this section.]
The invoked subcommand is automatically routed to the currently active semantic
completer, so `:YcmCompleter GoToDefinition` will invoke the `GoToDefinition`
subcommand on the Python semantic completer if the currently active file is a
Python one and on the Clang completer if the currently active file is a
C/C++/Objective-C one.
You may also want to map the subcommands to something less verbose; for
instance, `nnoremap jd :YcmCompleter GoToDefinitionElseDeclaration`
maps the `jd` sequence to the longer subcommand invocation.
The various `GoTo*` subcommands add entries to Vim's `jumplist` so you can use
`CTRL-O` to jump back to where you where before invoking the command (and
`CTRL-I` to jump forward; see `:h jumplist` for details).
### The `GoToDeclaration` subcommand
Looks up the symbol under the cursor and jumps to its declaration.
Supported in filetypes: `c, cpp, objc, objcpp, python, cs`
### The `GoToDefinition` subcommand
Looks up the symbol under the cursor and jumps to its definition.
NOTE: For C-family languages **this only works in certain situations**, namely when
the definition of the symbol is in the current translation unit. A translation
unit consists of the file you are editing and all the files you are including
with `#include` directives (directly or indirectly) in that file.
Supported in filetypes: `c, cpp, objc, objcpp, python, cs`
### The `GoToDefinitionElseDeclaration` subcommand
Looks up the symbol under the cursor and jumps to its definition if possible; if
the definition is not accessible from the current translation unit, jumps to the
symbol's declaration.
Supported in filetypes: `c, cpp, objc, objcpp, python, cs`
### The `ClearCompilationFlagCache` subcommand
YCM caches the flags it gets from the `FlagsForFile` function in your
`ycm_extra_conf.py` file if you return them with the `do_cache` parameter set to
`True`. The cache is in memory and is never invalidated (unless you restart Vim
of course).
This command clears that cache entirely. YCM will then re-query your
`FlagsForFile` function as needed in the future.
Supported in filetypes: `c, cpp, objc, objcpp`
### The `StartServer` subcommand
Starts the semantic-engine-as-localhost-server for those semantic engines that
work as separate servers that YCM talks to.
Supported in filetypes: `cs`
### The `StopServer` subcommand
Stops the semantic-engine-as-localhost-server for those semantic engines that
work as separate servers that YCM talks to.
Supported in filetypes: `cs`
### The `RestartServer` subcommand
Restarts the semantic-engine-as-localhost-server for those semantic engines that
work as separate servers that YCM talks to.
Supported in filetypes: `cs`
Options
-------
All options have reasonable defaults so if the plug-in works after installation
you don't need to change any options. These options can be configured in your
[vimrc script][vimrc] by including a line like this:
let g:ycm_min_num_of_chars_for_completion = 1
Note that after changing an option in your [vimrc script] [vimrc] you have to
restart Vim for the changes to take effect.
### The `g:ycm_min_num_of_chars_for_completion` option
This option controls the number of characters the user needs to type before
identifier-based completion suggestions are triggered. For example, if the
option is set to `2`, then when the user types a second alphanumeric character
after a whitespace character, completion suggestions will be triggered. This
option is NOT used for semantic completion.
Setting this option to a high number like `99` effectively turns off the
identifier completion engine and just leaves the semantic engine.
Default: `2`
let g:ycm_min_num_of_chars_for_completion = 2
### The `g:ycm_min_num_identifier_candidate_chars` option
This option controls the minimum number of characters that a completion
candidate coming from the identifier completer must have to be shown in the
popup menu.
A special value of `0` means there is no limit.
NOTE: This option only applies to the identifier completer; it has no effect on
the various semantic completers.
Default: `0`
let g:ycm_min_num_identifier_candidate_chars = 0
### The `g:ycm_auto_trigger` option
When set to `0`, this option turns off YCM's identifier completer (the
as-you-type popup) _and_ the semantic triggers (the popup you'd get after typing
`.` or `->` in say C++). You can still force semantic completion with the
`` shortcut.
If you want to just turn off the identifier completer but keep the semantic
triggers, you should set `g:ycm_min_num_of_chars_for_completion` to a high
number like `99`.
Default: `1`
let g:ycm_auto_trigger = 1
### The `g:ycm_filetype_whitelist` option
This option controls for which Vim filetypes (see `:h filetype`) should YCM be
turned on. The option value should be a Vim dictionary with keys being filetype
strings (like `python`, `cpp` etc) and values being unimportant (the dictionary
is used like a hash set, meaning that only the keys matter).
The `*` key is special and matches all filetypes. By default, the whitelist
contains only this `*` key.
YCM also has a `g:ycm_filetype_blacklist` option that lists filetypes for which
YCM shouldn't be turned on. YCM will work only in filetypes that both the
whitelist and the blacklist allow (the blacklist "allows" a filetype by _not_
having it as a key).
For example, let's assume you want YCM to work in files with the `cpp` filetype.
The filetype should then be present in the whitelist either directly (`cpp` key
in the whitelist) or indirectly through the special `*` key. It should _not_ be
present in the blacklist.
Filetypes that are blocked by the either of the lists will be completely ignored
by YCM, meaning that neither the identifier-based completion engine nor the
semantic engine will operate in them.
You can get the filetype of the current file in Vim with `:set ft?`.
Default: `{'*' : 1}`
let g:ycm_filetype_whitelist = { '*': 1 }
### The `g:ycm_filetype_blacklist` option
This option controls for which Vim filetypes (see `:h filetype`) should YCM be
turned off. The option value should be a Vim dictionary with keys being filetype
strings (like `python`, `cpp` etc) and values being unimportant (the dictionary
is used like a hash set, meaning that only the keys matter).
See the `g:ycm_filetype_whitelist` option for more details on how this works.
Default: `[see next line]`
let g:ycm_filetype_blacklist = {
\ 'tagbar' : 1,
\ 'qf' : 1,
\ 'notes' : 1,
\ 'markdown' : 1,
\ 'unite' : 1,
\ 'text' : 1,
\ 'vimwiki' : 1,
\ 'pandoc' : 1
\}
### The `g:ycm_filetype_specific_completion_to_disable` option
This option controls for which Vim filetypes (see `:h filetype`) should the YCM
semantic completion engine be turned off. The option value should be a Vim
dictionary with keys being filetype strings (like `python`, `cpp` etc) and
values being unimportant (the dictionary is used like a hash set, meaning that
only the keys matter). The listed filetypes will be ignored by the YCM semantic
completion engine, but the identifier-based completion engine will still trigger
in files of those filetypes.
Note that even if semantic completion is not turned off for a specific filetype,
you will not get semantic completion if the semantic engine does not support
that filetype.
You can get the filetype of the current file in Vim with `:set ft?`.
Default: `{}`
let g:ycm_filetype_specific_completion_to_disable = {}
### The `g:ycm_show_diagnostics_ui` option
When set, this option turns on YCM's diagnostic display features. See the
_Diagnostic display_ section in the _User Manual_ for more details.
Specific parts of the diagnostics UI (like the gutter signs, text highlighting,
diagnostic echo and auto location list population) can be individually turned on
or off. See the other options below for details.
Note that YCM's diagnostics UI is only supported for C-family languages.
When set, this option also makes YCM remove all Syntastic checkers set for the
`c`, `cpp`, `objc` and `objcpp` filetypes since this would conflict with YCM's
own diagnostics UI.
If you're using YCM's identifier completer in C-family languages but cannot use
the clang-based semantic completer for those languages _and_ want to use the GCC
Syntastic checkers, unset this option.
Default: `1`
let g:ycm_show_diagnostics_ui = 1
### The `g:ycm_error_symbol` option
YCM will use the value of this option as the symbol for errors in the Vim
gutter.
This option is part of the Syntastic compatibility layer; if the option is not
set, YCM will fall back to the value of the `g:syntastic_error_symbol` option
before using this option's default.
Default: `>>`
let g:ycm_error_symbol = '>>'
### The `g:ycm_warning_symbol` option
YCM will use the value of this option as the symbol for warnings in the Vim
gutter.
This option is part of the Syntastic compatibility layer; if the option is not
set, YCM will fall back to the value of the `g:syntastic_warning_symbol` option
before using this option's default.
Default: `>>`
let g:ycm_warning_symbol = '>>'
### The `g:ycm_enable_diagnostic_signs` option
When this option is set, YCM will put icons in Vim's gutter on lines that have a
diagnostic set. Turning this off will also turn off the `YcmErrorLine` and
`YcmWarningLine` highlighting.
This option is part of the Syntastic compatibility layer; if the option is not
set, YCM will fall back to the value of the `g:syntastic_enable_signs` option
before using this option's default.
Default: `1`
let g:ycm_enable_diagnostic_signs = 1
### The `g:ycm_enable_diagnostic_highlighting` option
When this option is set, YCM will highlight regions of text that are related to
the diagnostic that is present on a line, if any.
This option is part of the Syntastic compatibility layer; if the option is not
set, YCM will fall back to the value of the `g:syntastic_enable_highlighting`
option before using this option's default.
Default: `1`
let g:ycm_enable_diagnostic_highlighting = 1
### The `g:ycm_echo_current_diagnostic` option
When this option is set, YCM will echo the text of the diagnostic present on the
current line when you move your cursor to that line.
This option is part of the Syntastic compatibility layer; if the option is not
set, YCM will fall back to the value of the `g:syntastic_echo_current_error`
option before using this option's default.
Default: `1`
let g:ycm_echo_current_diagnostic = 1
### The `g:ycm_always_populate_location_list` option
When this option is set, YCM will populate the location list automatically every
time it gets new diagnostic data. This option is off by default so as not to
interfere with other data you might have placed in the location list.
See `:help location-list` in Vim to learn more about the location list.
This option is part of the Syntastic compatibility layer; if the option is not
set, YCM will fall back to the value of the
`g:syntastic_always_populate_loc_list` option before using this option's
default.
Default: `0`
let g:ycm_always_populate_location_list = 0
### The `g:ycm_open_loclist_on_ycm_diags` option
When this option is set, `:YcmDiags` will automatically open the location list
after forcing a compilation and filling the list with diagnostic data.
See `:help location-list` in Vim to learn more about the location list.
Default: `1`
let g:ycm_open_loclist_on_ycm_diags = 1
### The `g:ycm_allow_changing_updatetime` option
When this option is set to `1`, YCM will change the `updatetime` Vim option to
`2000` (see `:h updatetime`). This may conflict with some other plugins you have
(but it's unlikely). The `updatetime` option is the number of milliseconds that
have to pass before Vim's `CursorHold` (see `:h CursorHold`) event fires. YCM
runs the completion engines' "file comprehension" systems in the background on
every such event; the identifier-based engine collects the identifiers whereas
the semantic engine compiles the file to build an AST.
The Vim default of `4000` for `updatetime` is a bit long, so YCM reduces
this. Set this option to `0` to force YCM to leave your `updatetime` setting
alone.
Default: `1`
let g:ycm_allow_changing_updatetime = 1
### The `g:ycm_complete_in_comments` option
When this option is set to `1`, YCM will show the completion menu even when
typing inside comments.
Default: `0`
let g:ycm_complete_in_comments = 0
### The `g:ycm_complete_in_strings` option
When this option is set to `1`, YCM will show the completion menu even when
typing inside strings.
Note that this is turned on by default so that you can use the filename
completion inside strings. This is very useful for instance in C-family files
where typing `#include "` will trigger the start of filename completion. If you
turn off this option, you will turn off filename completion in such situations
as well.
Default: `1`
let g:ycm_complete_in_strings = 1
### The `g:ycm_collect_identifiers_from_comments_and_strings` option
When this option is set to `1`, YCM's identifier completer will also collect
identifiers from strings and comments. Otherwise, the text in comments and
strings will be ignored.
Default: `0`
let g:ycm_collect_identifiers_from_comments_and_strings = 0
### The `g:ycm_collect_identifiers_from_tags_files` option
When this option is set to `1`, YCM's identifier completer will also collect
identifiers from tags files. The list of tags files to examine is retrieved from
the `tagfiles()` Vim function which examines the `tags` Vim option. See `:h
'tags'` for details.
YCM will re-index your tags files if it detects that they have been modified.
The only supported tag format is the [Exuberant Ctags format][ctags-format]. The
format from "plain" ctags is NOT supported. Ctags needs to be called with the
`--fields=+l` option (that's a lowercase `L`, not a one) because YCM needs the
`language:` field in the tags output.
See the _FAQ_ for pointers if YCM does not appear to read your tag files.
This option is off by default because it makes Vim slower if your tags are on a
network directory.
Default: `0`
let g:ycm_collect_identifiers_from_tags_files = 0
### The `g:ycm_seed_identifiers_with_syntax` option
When this option is set to `1`, YCM's identifier completer will seed its
identifier database with the keywords of the programming language you're
writing.
Since the keywords are extracted from the Vim syntax file for the filetype, all
keywords may not be collected, depending on how the syntax file was written.
Usually at least 95% of the keywords are successfully extracted.
Default: `0`
let g:ycm_seed_identifiers_with_syntax = 0
### The `g:ycm_extra_conf_vim_data` option
If you're using semantic completion for C-family files, this option might come
handy; it's a way of sending data from Vim to your `FlagsForFile` function in
your `.ycm_extra_conf.py` file.
This option is supposed to be a list of VimScript expression strings that are
evaluated for every request to the `ycmd` server and then passed to your
`FlagsForFile` function as a `client_data` keyword argument.
For instance, if you set this option to `['v:version']`, your `FlagsForFile`
function will be called like this:
```python
# The '704' value is of course contingent on Vim 7.4; in 7.3 it would be '703'
FlagsForFile(filename, client_data = {'v:version': 704})
```
So the `client_data` parameter is a dictionary mapping Vim expression strings to
their values at the time of the request.
The correct way to define parameters for your `FlagsForFile` function:
```python
def FlagsForFile(filename, **kwargs):
```
You can then get to `client_data` with `kwargs['client_data']`.
Default: `[]`
let g:ycm_extra_conf_vim_data = []
### The `g:ycm_path_to_python_interpreter` option
YCM will by default search for an appropriate Python interpreter on your system.
You can use this option to override that behavior and force the use of a
specific interpreter of your choosing.
NOTE: This interpreter is only used for the `ycmd` server. The YCM client
running inside Vim always uses the Python interpreter that's embedded inside
Vim.
Default: `''`
let g:ycm_path_to_python_interpreter = ''
### The `g:ycm_server_use_vim_stdout` option
By default, the `ycmd` completion server writes logs to logfiles. When this
option is set to `1`, the server writes logs to Vim's stdout (so you'll see them
in the console).
Default: `0`
let g:ycm_server_use_vim_stdout = 0
### The `g:ycm_server_keep_logfiles` option
When this option is set to `1`, the `ycmd` completion server will keep the
logfiles around after shutting down (they are deleted on shutdown by default).
To see where the logfiles are, call `:YcmDebugInfo`.
Default: `0`
let g:ycm_server_keep_logfiles = 0
### The `g:ycm_server_log_level` option
The logging level that the `ycmd` completion server uses. Valid values are the
following, from most verbose to least verbose:
- `debug`
- `info`
- `warning`
- `error`
- `critical`
Note that `debug` is _very_ verbose.
Default: `info`
let g:ycm_server_log_level = 'info'
### The `g:ycm_csharp_server_port` option
The port number (on `localhost`) on which the OmniSharp server should be
started.
Default: `2000`
let g:ycm_csharp_server_port = 2000
### The `g:ycm_auto_start_csharp_server` option
When set to `1`, the OmniSharp server will be automatically started (once per
Vim session) when you open a C# file.
Default: `1`
let g:ycm_auto_start_csharp_server = 1
### The `g:ycm_auto_stop_csharp_server` option
When set to `1`, the OmniSharp server will be automatically stopped upon
closing Vim.
Default: `1`
let g:ycm_auto_stop_csharp_server = 1
### The `g:ycm_add_preview_to_completeopt` option
When this option is set to `1`, YCM will add the `preview` string to Vim's
`completeopt` option (see `:h completeopt`). If your `completeopt` option
already has `preview` set, there will be no effect. You can see the current
state of your `completeopt` setting with `:set completeopt?` (yes, the question
mark is important).
When `preview` is present in `completeopt`, YCM will use the `preview` window at
the top of the file to store detailed information about the current completion
candidate (but only if the candidate came from the semantic engine). For
instance, it would show the full function prototype and all the function
overloads in the window if the current completion is a function name.
Default: `0`
let g:ycm_add_preview_to_completeopt = 0
### The `g:ycm_autoclose_preview_window_after_completion` option
When this option is set to `1`, YCM will auto-close the `preview` window after
the user accepts the offered completion string. If there is no `preview` window
triggered because there is no `preview` string in `completeopt`, this option is
irrelevant. See the `g:ycm_add_preview_to_completeopt` option for more details.
Default: `0`
let g:ycm_autoclose_preview_window_after_completion = 0
### The `g:ycm_autoclose_preview_window_after_insertion` option
When this option is set to `1`, YCM will auto-close the `preview` window after
the user leaves insert mode. This option is irrelevant if
`g:ycm_autoclose_preview_window_after_completion` is set or if no `preview`
window is triggered. See the `g:ycm_add_preview_to_completeopt` option for more
details.
Default: `0`
let g:ycm_autoclose_preview_window_after_insertion = 0
### The `g:ycm_max_diagnostics_to_display` option
This option controls the maximum number of diagnostics shown to the user when
errors or warnings are detected in the file. This option is only relevant if you
are using the C-family semantic completion engine.
Default: `30`
let g:ycm_max_diagnostics_to_display = 30
### The `g:ycm_key_list_select_completion` option
This option controls the key mappings used to select the first completion
string. Invoking any of them repeatedly cycles forward through the completion
list.
Some users like adding `` to this list.
Default: `['', '']`
let g:ycm_key_list_select_completion = ['', '']
### The `g:ycm_key_list_previous_completion` option
This option controls the key mappings used to select the previous completion
string. Invoking any of them repeatedly cycles backwards through the completion
list.
Note that one of the defaults is `` which means Shift-TAB. That mapping
will probably only work in GUI Vim (Gvim or MacVim) and not in plain console Vim
because the terminal usually does not forward modifier key combinations to Vim.
Default: `['', '']`
let g:ycm_key_list_previous_completion = ['', '']
### The `g:ycm_key_invoke_completion` option
This option controls the key mapping used to invoke the completion menu for
semantic completion. By default, semantic completion is trigged automatically
after typing `.`, `->` and `::` in insert mode (if semantic completion support
has been compiled in). This key mapping can be used to trigger semantic
completion anywhere. Useful for searching for top-level functions and classes.
Console Vim (not Gvim or MacVim) passes `` to Vim when the user types
`` so YCM will make sure that `` is used in the map command when
you're editing in console Vim, and `` in GUI Vim. This means that you
can just press `` in both console and GUI Vim and YCM will do the right
thing.
Setting this option to an empty string will make sure no mapping is created.
Default: ``
let g:ycm_key_invoke_completion = ''
### The `g:ycm_key_detailed_diagnostics` option
This option controls the key mapping used to show the full diagnostic text when
the user's cursor is on the line with the diagnostic. It basically calls
`:YcmShowDetailedDiagnostic`.
Setting this option to an empty string will make sure no mapping is created.
Default: `d`
let g:ycm_key_detailed_diagnostics = 'd'
### The `g:ycm_global_ycm_extra_conf` option
Normally, YCM searches for a `.ycm_extra_conf.py` file for compilation flags
(see the User Guide for more details on how this works). This option specifies
a fallback path to a config file which is used if no `.ycm_extra_conf.py` is
found.
You can place such a global file anywhere in your filesystem.
Default: `''`
let g:ycm_global_ycm_extra_conf = ''
### The `g:ycm_confirm_extra_conf` option
When this option is set to `1` YCM will ask once per `.ycm_extra_conf.py` file
if it is safe to be loaded. This is to prevent execution of malicious code
from a `.ycm_extra_conf.py` file you didn't write.
To selectively get YCM to ask/not ask about loading certain `.ycm_extra_conf.py`
files, see the `g:ycm_extra_conf_globlist` option.
Default: `1`
let g:ycm_confirm_extra_conf = 1
### The `g:ycm_extra_conf_globlist` option
This option is a list that may contain several globbing patterns. If a pattern
starts with a `!` all `.ycm_extra_conf.py` files matching that pattern will be
blacklisted, that is they won't be loaded and no confirmation dialog will be
shown. If a pattern does not start with a `!` all files matching that pattern
will be whitelisted. Note that this option is not used when confirmation is
disabled using `g:ycm_confirm_extra_conf` and that items earlier in the list
will take precedence over the later ones.
Rules:
* `*` matches everything
* `?` matches any single character
* `[seq]` matches any character in seq
* `[!seq]` matches any char not in seq
Example:
let g:ycm_extra_conf_globlist = ['~/dev/*','!~/*']
* The first rule will match everything contained in the `~/dev` directory so
`.ycm_extra_conf.py` files from there will be loaded.
* The second rule will match everything in the home directory so a
`.ycm_extra_conf.py` file from there won't be loaded.
* As the first rule takes precedence everything in the home directory excluding
the `~/dev` directory will be blacklisted.
Default: `[]`
let g:ycm_extra_conf_globlist = []
### The `g:ycm_filepath_completion_use_working_dir` option
By default, YCM's filepath completion will interpret relative paths like `../`
as being relative to the folder of the file of the currently active buffer.
Setting this option will force YCM to always interpret relative paths as being
relative to Vim's current working directory.
Default: `0`
let g:ycm_filepath_completion_use_working_dir = 0
### The `g:ycm_semantic_triggers` option
This option controls the character-based triggers for the various semantic
completion engines. The option holds a dictionary of key-values, where the keys
are Vim's filetype strings delimited by commas and values are lists of strings,
where the strings are the triggers.
Setting key-value pairs on the dictionary _adds_ semantic triggers to the
internal default set (listed below). You cannot remove the default triggers,
only add new ones.
A "trigger" is a sequence of one or more characters that trigger semantic
completion when typed. For instance, C++ (`cpp` filetype) has `.` listed as a
trigger. So when the user types `foo.`, the semantic engine will trigger and
serve `foo`'s list of member functions and variables. Since C++ also has `->`
listed as a trigger, the same thing would happen when the user typed `foo->`.
Default: `[see next line]`
let g:ycm_semantic_triggers = {
\ 'c' : ['->', '.'],
\ 'objc' : ['->', '.'],
\ 'ocaml' : ['.', '#'],
\ 'cpp,objcpp' : ['->', '.', '::'],
\ 'perl' : ['->'],
\ 'php' : ['->', '::'],
\ 'cs,java,javascript,d,vim,python,perl6,scala,vb,elixir,go' : ['.'],
\ 'ruby' : ['.', '::'],
\ 'lua' : ['.', ':'],
\ 'erlang' : [':'],
\ }
### The `g:ycm_cache_omnifunc` option
Some omnicompletion engines do not work well with the YCM cache—in particular,
they might not produce all possible results for a given prefix. By unsetting
this option you can ensure that the omnicompletion engine is requeried on every
keypress. That will ensure all completions will be presented, but might cause
stuttering and lagginess if the omnifunc is slow.
Default: `1`
let g:ycm_cache_omnifunc = 1
### The `g:ycm_use_ultisnips_completer` option
By default, YCM will query the UltiSnips plugin for possible completions of
snippet triggers. This option can turn that behavior off.
Default: `1`
let g:ycm_use_ultisnips_completer = 1
FAQ
---
### I used to be able to `import vim` in `.ycm_extra_conf.py`, but now can't
YCM was rewritten to use a client-server architecture where most of the logic is
in the `ycmd` server. So the magic `vim` module you could have previously
imported in your `.ycm_extra_conf.py` files doesn't exist anymore.
To be fair, importing the magic `vim` module in extra conf files was never
supported in the first place; it only ever worked by accident and was never a
part of the extra conf API.
But fear not, you should be able to tweak your extra conf files to continue
working by using the `g:ycm_extra_conf_vim_data` option. See the docs on that
option for details.
### On very rare occasions Vim crashes when I tab through the completion menu
That's a very rare Vim bug most users never encounter. It's fixed in Vim
7.4.72. Update to that version (or above) to resolve the issue.
### I get a linker warning regarding `libpython` on Mac when compiling YCM
If the warning is `ld: warning: path '/usr/lib/libpython2.7.dylib' following -L
not a directory`, then feel free to ignore it; it's caused by a limitation of
CMake and is not an issue. Everything should still work fine.
### I get a weird window at the top of my file when I use the semantic engine
This is Vim's `preview` window. Vim uses it to show you extra information about
something if such information is available. YCM provides Vim with such extra
information. For instance, when you select a function in the completion list,
the `preview` window will hold that function's prototype and the prototypes of
any overloads of the function. It will stay there after you select the
completion so that you can use the information about the parameters and their
types to write the function call.
If you would like this window to auto-close after you select a completion
string, set the `g:ycm_autoclose_preview_window_after_completion` option to `1`
in your `vimrc` file. Similarly, the `g:ycm_autoclose_preview_window_after_insertion`
option can be set to close the `preview` window after leaving insert mode.
If you don't want this window to ever show up, add `set completeopt-=preview` to
your `vimrc`. Also make sure that the `g:ycm_add_preview_to_completeopt` option
is set to `0`.
### It appears that YCM is not working
In Vim, run `:messages` and carefully read the output. YCM will echo messages to
the message log if it encounters problems. It's likely you misconfigured
something and YCM is complaining about it.
Also, you may want to run the `:YcmDebugInfo` command; it will make YCM spew out
various debugging information, including the compile flags for the file if the
file is a C-family language file and you have compiled in Clang support.
### Sometimes it takes much longer to get semantic completions than normal
This means that libclang (which YCM uses for C-family semantic completion)
failed to pre-compile your file's preamble. In other words, there was an error
compiling some of the source code you pulled in through your header files. I
suggest calling the `:YcmDiags` command to see what they were.
Bottom line, if libclang can't pre-compile your file's preamble because there
were errors in it, you're going to get slow completions because there's no AST
cache.
### YCM auto-inserts completion strings I don't want!
This means you probably have some mappings that interfere with YCM's internal
ones. Make sure you don't have something mapped to ``, `` or ``
(in insert mode).
YCM _never_ selects something for you; it just shows you a menu and the user has
to explicitly select something. If something is being selected automatically,
this means there's a bug or a misconfiguration somewhere.
### I get a `E227: mapping already exists for ` error when I start Vim
This means that YCM tried to set up a key mapping but failed because you already
had something mapped to that key combination. The `` part of the message
will tell you what was the key combination that failed.
Look in the _Options_ section and see if any of the default mappings conflict
with your own. Then change that option value to something else so that the
conflict goes away.
### I get `'GLIBC_2.XX' not found (required by libclang.so)` when starting Vim
Your system is too old for the precompiled binaries from llvm.org. Compile
Clang on your machine and then link against the `libclang.so` you just produced.
See the full installation guide for help.
### I'm trying to use a Homebrew Vim with YCM and I'm getting segfaults
Something (I don't know what) is wrong with the way that Homebrew configures and
builds Vim. I recommend using [MacVim][]. Even if you don't like the MacVim GUI,
you can use the Vim binary that is inside the MacVim.app package (it's
`MacVim.app/Contents/MacOS/Vim`) and get the Vim console experience.
### I have a Homebrew Python and/or MacVim; can't compile/SIGABRT when starting
You should probably run `brew rm python; brew install python` to get the latest
fixes that should make YCM work with such a configuration. Also rebuild Macvim
then. If you still get problems with this, see [issue #18][issue18] for
suggestions.
### Vim segfaults when I use the semantic completer in Ruby files
This was caused by a Vim bug. Update your version of Vim (Vim 7.3.874 is known
to work, earlier versions may also fix this issue).
### I get `LONG_BIT definition appears wrong for platform` when compiling
Look at the output of your CMake call. There should be a line in it like the
following (with `.dylib` in place of `.so` on a Mac):
```
-- Found PythonLibs: /usr/lib/libpython2.7.so (Required is at least version "2.5")
```
That would be the **correct** output. An example of **incorrect** output would
be the following:
```
-- Found PythonLibs: /usr/lib/libpython2.7.so (found suitable version "2.5.1", minimum required is "2.5")
```
Notice how there's an extra bit of output there, the `found suitable version
""` part, where `` is not the same as the version of the
dynamic library. In the example shown, the library is version 2.7 but the second
string is version `2.5.1`.
This means that CMake found one version of Python headers and a different
version for the library. This is wrong. It can happen when you have multiple
versions of Python installed on your machine.
You should probably add the following flags to your cmake call (again, `dylib`
instead of `so` on a Mac):
```
-DPYTHON_INCLUDE_DIR=/usr/include/python2.7 -DPYTHON_LIBRARY=/usr/lib/libpython2.7.so
```
This will force the paths to the Python include directory and the Python library
to use. You may need to set these flags to something else, but you need to make
sure you use the same version of Python that your Vim binary is built against,
which is highly likely to be the system's default Python.
### I get `libpython2.7.a [...] relocation R_X86_64_32` when compiling
The error is usually encountered when compiling YCM on Centos or RHEL. The full
error looks something like the following:
```
/usr/bin/ld: /usr/local/lib/libpython2.7.a(abstract.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
```
It's possible to get a slightly different error that's similar to the one above.
Here's the problem and how you solve it:
Your `libpython2.7.a` was not compiled with `-fPIC` so it can't be linked into
`ycm_core.so`. Use the `-DPYTHON_LIBRARY=` CMake flag to point it to a `.so`
version of libpython on your machine (for instance,
`-DPYTHON_LIBRARY=/usr/lib/libpython2.7.so`). Naturally, this means you'll have
to go through the full installation guide by hand.
### I get `Vim: Caught deadly signal SEGV` on Vim startup
This can happen on some Linux distros. If you encounter this situation, run Vim
under `gdb`. You'll probably see something like this in the output when Vim
crashes:
```
undefined symbol: clang_CompileCommands_dispose
```
This means that Vim is trying to load a `libclang.so` that is too old. You need
at least a 3.2 libclang. Some distros ship with a system `libclang.so` that
identifies itself as 3.2 but is not; it was cut from the upstream sources before
the official 3.2 release and some API changes (like the addition of the
CompileCommands API) were added after their cut.
So just go through the installation guide and make sure you are using a correct
`libclang.so`. I recommend downloading prebuilt binaries from llvm.org.
### YCM does not read identifiers from my tags files
First, put `let g:ycm_collect_identifiers_from_tags_files = 1` in your vimrc.
Make sure you are using [Exuberant Ctags][exuberant-ctags] to produce your tags
files since the only supported tag format is the [Exuberant Ctags
format][ctags-format]. The format from "plain" ctags is NOT supported. The
output of `ctags --version` should list "Exuberant Ctags".
Ctags needs to be called with the `--fields=+l` (that's a lowercase `L`, not a
one) option because YCM needs the `language:` field in the tags output.
NOTE: Mac OS X comes with "plain" ctags installed by default. `brew install
ctags` will get you the Exuberant Ctags version.
Also make sure that your Vim `tags` option is set correctly. See `:h 'tags'` for
details. If you want to see which tag files YCM will read for a given buffer,
run `:echo tagfiles()` with the relevant buffer active. Note that that function
will only list tag files that already exist.
### `CTRL-U` in insert mode does not work
YCM keeps you in a `completefunc` completion mode when you're typing in insert
mode and Vim disables `` in completion mode as a "feature." Sadly there's
nothing I can do about this.
### YCM conflicts with UltiSnips TAB key usage
YCM comes with support for UltiSnips (snippet suggestions in the popup menu),
but you'll have to change the UltiSnips mappings. See `:h UltiSnips-triggers` in
Vim for details. You'll probably want to change some/all of the following
options:
g:UltiSnipsExpandTrigger
g:UltiSnipsJumpForwardTrigger
g:UltiSnipsJumpBackwardTrigger
### Why isn't YCM just written in plain VimScript, FFS?
Because of the identifier completion engine and subsequence-based filtering.
Let's say you have _many_ dozens of files open in a single Vim instance (I often
do); the identifier-based engine then needs to store thousands (if not tens of
thousands) of identifiers in its internal data-structures. When the user types,
YCM needs to perform subsequence-based filtering on _all_ of those identifiers
(every single one!) in less than 10 milliseconds.
I'm sorry, but that level of performance is just plain impossible to achieve
with VimScript. I've tried, and the language is just too slow. No, you can't get
acceptable performance even if you limit yourself to just the identifiers in the
current file and simple prefix-based fitering.
### Why does YCM demand such a recent version of Vim?
During YCM's development several show-stopper bugs were encountered in Vim.
Those needed to be fixed upstream (and were). A few months after those bugs were
fixed, Vim trunk landed the `pyeval()` function which improved YCM performance
even more since less time was spent serializing and deserializing data between
Vim and the embedded Python interpreter. A few critical bugfixes for `pyeval()`
landed in Vim 7.3.584 (and a few commits before that).
### I get annoying messages in Vim's status area when I type
If you're referring to the `User defined completion back at original`
and similar, then sadly there's no fix for those. Vim will emit them no matter
how hard I try to silence them.
You'll have to learn to ignore them. It's a shitty "solution", I know.
There's an [outstanding patch for Vim that fixes this issue][status-mes], but at
the time of writing Vim upstream hasn't yet merged it in.
### Nasty bugs happen if I have the `vim-autoclose` plugin installed
Use the [delimitMate][] plugin instead. It does the same thing without
conflicting with YCM.
### Is there some sort of YCM mailing list? I have questions
If you have questions about the plugin or need help, please use the
[ycm-users][] mailing list, _don't_ create issues on the tracker. The tracker is
for bug reports and feature requests.
### I get an internal compiler error when installing
This can be a problem on virtual servers with limited memory. A possible
solution is to add more swap memory.
### I get weird errors when I press `Ctrl-C` in Vim
_Never_ use `Ctrl-C` in Vim.
Using `Ctrl-C` to exit insert mode in Vim is a bad idea. The main issue here is
that `Ctrl-C` in Vim doesn't just leave insert mode, it leaves it without
triggering `InsertLeave` autocommands (as per Vim docs). This is a bad idea and
is likely to break many other things and not just YCM.
Bottom line, if you use `Ctrl-C` to exit insert mode in Vim, you're gonna have a
bad time.
If pressing `` is too annoying (agreed, it is), we suggest mapping it to
something more convenient. On a QWERTY keyboard, a good pick for the `` map
is `inoremap jk `. This is right on the home row, it's an incredibly rare
digraph in English and if you ever need to type those two chars in sequence in
insert mode, you just type `j`, then wait 500ms, then type `k`.
### Why did YCM stop using Syntastic for diagnostics display?
Previously, YCM would send any diagnostics it would receive from the libclang
semantic engine to Syntastic for display as signs in the gutter, red squiggles
etc. Today, YCM uses its own code to do that.
Using Syntastic for this was always a kludge. Syntastic assumes its "checker"
plugins behave in a certain way; those assumptions have never fit YCM. For
instance, YCM continuously recompiles your code in the background for C-family
languages and tries to push new diagnostics to the user as fast as possible,
even while the user types.
Syntastic assumes that a checker only runs on file save ("active" mode) or even
less frequently, when the user explicitly invokes it ("passive" mode). This
mismatch in assumptions causes performance problems since Syntastic code isn't
optimized for this use case of constant diagnostic refreshing.
Poor support for this use case also led to crash bugs in Vim caused by
Syntastic-Vim interactions ([issue #593][issue-593]) and other problems, like
random Vim flickering. Attempts were made to resolve these issues in
Syntastic, but ultimately some of them failed (for various reasons).
Implementing diagnostic display code directly in YCM resolves all of these
problems. Performance also improved substantially since the relevant code is now
written in Python instead of VimScript (which is very slow) and is tailored only
for YCM's use-cases. We were also able to introduce new features in this area
since we're now not limited to the Syntastic checker API.
We've tried to implement this in the most backwards-compatible way possible; YCM
options that control diagnostic display fall back to Syntastic options that
control the same concepts if the user has those set.
Still, some Syntastic-specific configuration you might have had might not
be supported by the new code. Please file issues on the tracker in such
cases; if we find the request to be reasonable, we'll find a way to address it.
### Completion doesn't work with the C++ standard library headers
This is caused by an issue with libclang. Compiling from `clang` the binary uses
the correct default header search paths but compiling from `libclang.so` does
not. The issue seems to impact some OS's more than others. It appears that OS X
Mavericks in particular has problems with this.
The current workaround is to call `echo | clang -v -E -x c++ -` and look at the
paths under the `#include <...> search starts here:` heading. You should take
those paths, prepend `-isystem` to each individual path and append them all to
the list of flags you return from your `FlagsForFile` function in your
`.ycm_extra_conf.py` file.
See [issue #303][issue-303] for details.
Contact
-------
If you have questions about the plugin or need help, please use the
[ycm-users][] mailing list.
If you have bug reports or feature suggestions, please use the [issue
tracker][tracker].
The latest version of the plugin is available at
.
The author's homepage is .
Project Management
------------------
This open-source project is run by me, Strahinja Val Markovic. I also happen to
work for Google and the code I write here is under Google copyright (for the
sake of simplicity and other reasons). This does **NOT** mean that this is an
official Google product (it isn't) or that Google has (or wants to have)
anything to do with it.
License
-------
This software is licensed under the [GPL v3 license][gpl].
© 2013 Google Inc.
[](https://bitdeli.com/free "Bitdeli Badge")
[Clang]: http://clang.llvm.org/
[vundle]: https://github.com/gmarik/vundle#about
[pathogen]: https://github.com/tpope/vim-pathogen#pathogenvim
[clang-download]: http://llvm.org/releases/download.html#3.3
[brew]: http://mxcl.github.com/homebrew/
[cmake-download]: http://www.cmake.org/cmake/resources/software.html
[macvim]: http://code.google.com/p/macvim/#Download
[vimrc]: http://vimhelp.appspot.com/starting.txt.html#vimrc
[gpl]: http://www.gnu.org/copyleft/gpl.html
[vim]: http://www.vim.org/
[syntastic]: https://github.com/scrooloose/syntastic
[flags_example]: https://github.com/Valloric/YouCompleteMe/blob/master/cpp/ycm/.ycm_extra_conf.py
[compdb]: http://clang.llvm.org/docs/JSONCompilationDatabase.html
[subsequence]: http://en.wikipedia.org/wiki/Subsequence
[listtoggle]: https://github.com/Valloric/ListToggle
[vim-build]: https://github.com/Valloric/YouCompleteMe/wiki/Building-Vim-from-source
[tracker]: https://github.com/Valloric/YouCompleteMe/issues?state=open
[issue18]: https://github.com/Valloric/YouCompleteMe/issues/18
[delimitMate]: https://github.com/Raimondi/delimitMate
[completer-api]: https://github.com/Valloric/YouCompleteMe/blob/master/python/ycm/completers/completer.py
[win-wiki]: https://github.com/Valloric/YouCompleteMe/wiki/Windows-Installation-Guide
[eclim]: http://eclim.org/
[jedi]: https://github.com/davidhalter/jedi
[ultisnips]: https://github.com/SirVer/ultisnips/blob/master/doc/UltiSnips.txt
[exuberant-ctags]: http://ctags.sourceforge.net/
[ctags-format]: http://ctags.sourceforge.net/FORMAT
[vundle-bug]: https://github.com/gmarik/vundle/issues/48
[ycm-users]: https://groups.google.com/forum/?hl=en#!forum/ycm-users
[omnisharp]: https://github.com/nosami/OmniSharpServer
[issue-303]: https://github.com/Valloric/YouCompleteMe/issues/303
[issue-593]: https://github.com/Valloric/YouCompleteMe/issues/593
[issue-669]: https://github.com/Valloric/YouCompleteMe/issues/669
[status-mes]: https://groups.google.com/forum/#!topic/vim_dev/WeBBjkXE8H8
vim-youcompleteme-0+20140207+git18be5c2/autoload/ 0000775 0000000 0000000 00000000000 12275675654 0021172 5 ustar 00root root 0000000 0000000 vim-youcompleteme-0+20140207+git18be5c2/autoload/youcompleteme.vim 0000664 0000000 0000000 00000057215 12275675654 0024610 0 ustar 00root root 0000000 0000000 " Copyright (C) 2011, 2012 Google Inc.
"
" This file is part of YouCompleteMe.
"
" YouCompleteMe 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.
"
" YouCompleteMe 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 YouCompleteMe. If not, see .
" This is basic vim plugin boilerplate
let s:save_cpo = &cpo
set cpo&vim
" This needs to be called outside of a function
let s:script_folder_path = escape( expand( ':p:h' ), '\' )
let s:searched_and_results_found = 0
let s:omnifunc_mode = 0
let s:old_cursor_position = []
let s:cursor_moved = 0
let s:moved_vertically_in_insert_mode = 0
let s:previous_num_chars_on_current_line = -1
let s:diagnostic_ui_filetypes = {
\ 'cpp': 1,
\ 'c': 1,
\ 'objc': 1,
\ 'objcpp': 1,
\ }
function! youcompleteme#Enable()
" When vim is in diff mode, don't run
if &diff
return
endif
call s:SetUpBackwardsCompatibility()
py import sys
py import vim
exe 'python sys.path.insert( 0, "' . s:script_folder_path . '/../python" )'
py from ycm import utils
py utils.AddThirdPartyFoldersToSysPath()
py from ycm import base
py base.LoadJsonDefaultsIntoVim()
py from ycm import vimsupport
py from ycm import user_options_store
py user_options_store.SetAll( base.BuildServerConf() )
if !pyeval( 'base.CompatibleWithYcmCore()')
echohl WarningMsg |
\ echomsg "YouCompleteMe unavailable: YCM support libs too old, PLEASE RECOMPILE" |
\ echohl None
return
endif
py from ycm.youcompleteme import YouCompleteMe
py ycm_state = YouCompleteMe( user_options_store.GetAll() )
call s:SetUpCpoptions()
call s:SetUpCompleteopt()
call s:SetUpKeyMappings()
if g:ycm_show_diagnostics_ui
call s:TurnOffSyntasticForCFamily()
endif
call s:SetUpSigns()
call s:SetUpSyntaxHighlighting()
if g:ycm_allow_changing_updatetime
set ut=2000
endif
augroup youcompleteme
autocmd!
autocmd CursorMovedI * call s:OnCursorMovedInsertMode()
autocmd CursorMoved * call s:OnCursorMovedNormalMode()
" Note that these events will NOT trigger for the file vim is started with;
" so if you do "vim foo.cc", these events will not trigger when that buffer
" is read. This is because youcompleteme#Enable() is called on VimEnter and
" that happens *after" BufRead/BufEnter has already triggered for the
" initial file.
" We also need to trigger buf init code on the FileType event because when
" the user does :enew and then :set ft=something, we need to run buf init
" code again.
autocmd BufRead,BufEnter,FileType * call s:OnBufferVisit()
autocmd BufUnload * call s:OnBufferUnload( expand( ':p' ) )
autocmd CursorHold,CursorHoldI * call s:OnCursorHold()
autocmd InsertLeave * call s:OnInsertLeave()
autocmd InsertEnter * call s:OnInsertEnter()
autocmd VimLeave * call s:OnVimLeave()
augroup END
" Calling this once solves the problem of BufRead/BufEnter not triggering for
" the first loaded file. This should be the last command executed in this
" function!
call s:OnBufferVisit()
endfunction
function! s:SetUpKeyMappings()
" The g:ycm_key_select_completion and g:ycm_key_previous_completion used to
" exist and are now here purely for the sake of backwards compatibility; we
" don't want to break users if we can avoid it.
if exists('g:ycm_key_select_completion') &&
\ index(g:ycm_key_list_select_completion,
\ g:ycm_key_select_completion) == -1
call add(g:ycm_key_list_select_completion, g:ycm_key_select_completion)
endif
if exists('g:ycm_key_previous_completion') &&
\ index(g:ycm_key_list_previous_completion,
\ g:ycm_key_previous_completion) == -1
call add(g:ycm_key_list_previous_completion, g:ycm_key_previous_completion)
endif
for key in g:ycm_key_list_select_completion
" With this command, when the completion window is visible, the tab key
" (default) will select the next candidate in the window. In vim, this also
" changes the typed-in text to that of the candidate completion.
exe 'inoremap ' . key .
\ ' pumvisible() ? "\" : "\' . key .'"'
endfor
for key in g:ycm_key_list_previous_completion
" This selects the previous candidate for shift-tab (default)
exe 'inoremap ' . key .
\ ' pumvisible() ? "\" : "\' . key .'"'
endfor
if !empty( g:ycm_key_invoke_completion )
let invoke_key = g:ycm_key_invoke_completion
" Inside the console, is passed as to Vim
if invoke_key ==# '' && !has('gui_running')
let invoke_key = ''
endif
" trigger omni completion, deselects the first completion
" candidate that vim selects by default
silent! exe 'inoremap ' . invoke_key . ' '
endif
if !empty( g:ycm_key_detailed_diagnostics )
silent! exe 'nnoremap ' . g:ycm_key_detailed_diagnostics .
\ ' :YcmShowDetailedDiagnostic'
endif
endfunction
function! s:SetUpSigns()
" We try to ensure backwards compatibility with Syntastic if the user has
" already defined styling for Syntastic highlight groups.
if !hlexists( 'YcmErrorSign' )
if hlexists( 'SyntasticErrorSign')
highlight link YcmErrorSign SyntasticErrorSign
else
highlight link YcmErrorSign error
endif
endif
if !hlexists( 'YcmWarningSign' )
if hlexists( 'SyntasticWarningSign')
highlight link YcmWarningSign SyntasticWarningSign
else
highlight link YcmWarningSign todo
endif
endif
if !hlexists( 'YcmErrorLine' )
highlight link YcmErrorLine SyntasticErrorLine
endif
if !hlexists( 'YcmWarningLine' )
highlight link YcmWarningLine SyntasticWarningLine
endif
exe 'sign define YcmError text=' . g:ycm_error_symbol .
\ ' texthl=YcmErrorSign linehl=YcmErrorLine'
exe 'sign define YcmWarning text=' . g:ycm_warning_symbol .
\ ' texthl=YcmWarningSign linehl=YcmWarningLine'
endfunction
function! s:SetUpSyntaxHighlighting()
" We try to ensure backwards compatibility with Syntastic if the user has
" already defined styling for Syntastic highlight groups.
if !hlexists( 'YcmErrorSection' )
if hlexists( 'SyntasticError' )
highlight link YcmErrorSection SyntasticError
else
highlight link YcmErrorSection SpellBad
endif
endif
if !hlexists( 'YcmWarningSection' )
if hlexists( 'SyntasticWarning' )
highlight link YcmWarningSection SyntasticWarning
else
highlight link YcmWarningSection SpellCap
endif
endif
endfunction
function! s:SetUpBackwardsCompatibility()
let complete_in_comments_and_strings =
\ get( g:, 'ycm_complete_in_comments_and_strings', 0 )
if complete_in_comments_and_strings
let g:ycm_complete_in_strings = 1
let g:ycm_complete_in_comments = 1
endif
" ycm_filetypes_to_completely_ignore is the old name for fileype_blacklist
if has_key( g:, 'ycm_filetypes_to_completely_ignore' )
let g:filetype_blacklist = g:ycm_filetypes_to_completely_ignore
endif
endfunction
" Needed so that YCM is used instead of Syntastic
function! s:TurnOffSyntasticForCFamily()
let g:syntastic_cpp_checkers = []
let g:syntastic_c_checkers = []
let g:syntastic_objc_checkers = []
let g:syntastic_objcpp_checkers = []
endfunction
function! s:DiagnosticUiSupportedForCurrentFiletype()
return get( s:diagnostic_ui_filetypes, &filetype, 0 )
endfunction
function! s:AllowedToCompleteInCurrentFile()
if empty( &filetype ) ||
\ getbufvar( winbufnr( winnr() ), "&buftype" ) ==# 'nofile' ||
\ &filetype ==# 'qf'
return 0
endif
let whitelist_allows = has_key( g:ycm_filetype_whitelist, '*' ) ||
\ has_key( g:ycm_filetype_whitelist, &filetype )
let blacklist_allows = !has_key( g:ycm_filetype_blacklist, &filetype )
return whitelist_allows && blacklist_allows
endfunction
function! s:SetUpCpoptions()
" Without this flag in cpoptions, critical YCM mappings do not work. There's
" no way to not have this and have YCM working, so force the flag.
set cpoptions+=B
" This prevents the display of "Pattern not found" & similar messages during
" completion.
" Patch: https://groups.google.com/forum/#!topic/vim_dev/WeBBjkXE8H8
" At the time of writing, the patch hasn't been merged into Vim upstream, but
" will at some point.
" TODO: Check the Vim version (when patch lands) instead of doing try-catch
" here.
try
set shortmess+=c
catch
endtry
endfunction
function! s:SetUpCompleteopt()
" Some plugins (I'm looking at you, vim-notes) change completeopt by for
" instance adding 'longest'. This breaks YCM. So we force our settings.
" There's no two ways about this: if you want to use YCM then you have to
" have these completeopt settings, otherwise YCM won't work at all.
" We need menuone in completeopt, otherwise when there's only one candidate
" for completion, the menu doesn't show up.
set completeopt-=menu
set completeopt+=menuone
" This is unnecessary with our features. People use this option to insert
" the common prefix of all the matches and then add more differentiating chars
" so that they can select a more specific match. With our features, they
" don't need to insert the prefix; they just type the differentiating chars.
" Also, having this option set breaks the plugin.
set completeopt-=longest
if g:ycm_add_preview_to_completeopt
set completeopt+=preview
endif
endfunction
" For various functions/use-cases, we want to keep track of whether the buffer
" has changed since the last time they were invoked. We keep the state of
" b:changedtick of the last time the specific function was called in
" b:ycm_changedtick.
function! s:SetUpYcmChangedTick()
let b:ycm_changedtick =
\ get( b:, 'ycm_changedtick', {
\ 'file_ready_to_parse' : -1,
\ } )
endfunction
function! s:OnVimLeave()
py ycm_state.OnVimLeave()
endfunction
function! s:OnBufferVisit()
" We need to do this even when we are not allowed to complete in the current
" file because we might be allowed to complete in the future! The canonical
" example is creating a new buffer with :enew and then setting a filetype.
call s:SetUpYcmChangedTick()
if !s:AllowedToCompleteInCurrentFile()
return
endif
call s:SetUpCompleteopt()
call s:SetCompleteFunc()
py ycm_state.OnBufferVisit()
call s:OnFileReadyToParse()
endfunction
function! s:OnBufferUnload( deleted_buffer_file )
if !s:AllowedToCompleteInCurrentFile() || empty( a:deleted_buffer_file )
return
endif
py ycm_state.OnBufferUnload( vim.eval( 'a:deleted_buffer_file' ) )
endfunction
function! s:OnCursorHold()
if !s:AllowedToCompleteInCurrentFile()
return
endif
call s:SetUpCompleteopt()
call s:OnFileReadyToParse()
endfunction
function! s:OnFileReadyToParse()
" We need to call this just in case there is no b:ycm_changetick; this can
" happen for special buffers.
call s:SetUpYcmChangedTick()
" Order is important here; we need to extract any done diagnostics before
" reparsing the file again. If we sent the new parse request first, then
" the response would always be pending when we called
" UpdateDiagnosticNotifications.
call s:UpdateDiagnosticNotifications()
let buffer_changed = b:changedtick != b:ycm_changedtick.file_ready_to_parse
if buffer_changed
py ycm_state.OnFileReadyToParse()
endif
let b:ycm_changedtick.file_ready_to_parse = b:changedtick
endfunction
function! s:SetCompleteFunc()
let &completefunc = 'youcompleteme#Complete'
let &l:completefunc = 'youcompleteme#Complete'
if pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
let &omnifunc = 'youcompleteme#OmniComplete'
let &l:omnifunc = 'youcompleteme#OmniComplete'
" If we don't have native filetype support but the omnifunc is set to YCM's
" omnifunc because the previous file the user was editing DID have native
" support, we remove our omnifunc.
elseif &omnifunc == 'youcompleteme#OmniComplete'
let &omnifunc = ''
let &l:omnifunc = ''
endif
endfunction
function! s:OnCursorMovedInsertMode()
if !s:AllowedToCompleteInCurrentFile()
return
endif
py ycm_state.OnCursorMoved()
call s:UpdateCursorMoved()
" Basically, we need to only trigger the completion menu when the user has
" inserted or deleted a character, NOT just when the user moves in insert mode
" (with, say, the arrow keys). If we trigger the menu even on pure moves, then
" it's impossible to move in insert mode since the up/down arrows start moving
" the selected completion in the completion menu. Yeah, people shouldn't be
" moving in insert mode at all (that's what normal mode is for) but explain
" that to the users who complain...
if !s:BufferTextChangedSinceLastMoveInInsertMode()
return
endif
call s:IdentifierFinishedOperations()
if g:ycm_autoclose_preview_window_after_completion
call s:ClosePreviewWindowIfNeeded()
endif
if g:ycm_auto_trigger || s:omnifunc_mode
call s:InvokeCompletion()
endif
" We have to make sure we correctly leave omnifunc mode even when the user
" inserts something like a "operator[]" candidate string which fails
" CurrentIdentifierFinished check.
if s:omnifunc_mode && !pyeval( 'base.LastEnteredCharIsIdentifierChar()')
let s:omnifunc_mode = 0
endif
endfunction
function! s:OnCursorMovedNormalMode()
if !s:AllowedToCompleteInCurrentFile()
return
endif
call s:OnFileReadyToParse()
py ycm_state.OnCursorMoved()
endfunction
function! s:OnInsertLeave()
if !s:AllowedToCompleteInCurrentFile()
return
endif
let s:omnifunc_mode = 0
call s:OnFileReadyToParse()
py ycm_state.OnInsertLeave()
if g:ycm_autoclose_preview_window_after_completion ||
\ g:ycm_autoclose_preview_window_after_insertion
call s:ClosePreviewWindowIfNeeded()
endif
endfunction
function! s:OnInsertEnter()
if !s:AllowedToCompleteInCurrentFile()
return
endif
let s:old_cursor_position = []
endfunction
function! s:UpdateCursorMoved()
let current_position = getpos('.')
let s:cursor_moved = current_position != s:old_cursor_position
let s:moved_vertically_in_insert_mode = s:old_cursor_position != [] &&
\ current_position[ 1 ] != s:old_cursor_position[ 1 ]
let s:old_cursor_position = current_position
endfunction
function! s:BufferTextChangedSinceLastMoveInInsertMode()
if s:moved_vertically_in_insert_mode
let s:previous_num_chars_on_current_line = -1
return 0
endif
let num_chars_in_current_cursor_line = strlen( getline('.') )
if s:previous_num_chars_on_current_line == -1
let s:previous_num_chars_on_current_line = num_chars_in_current_cursor_line
return 0
endif
let changed_text_on_current_line = num_chars_in_current_cursor_line !=
\ s:previous_num_chars_on_current_line
let s:previous_num_chars_on_current_line = num_chars_in_current_cursor_line
return changed_text_on_current_line
endfunction
function! s:ClosePreviewWindowIfNeeded()
let current_buffer_name = bufname('')
" We don't want to try to close the preview window in special buffers like
" "[Command Line]"; if we do, Vim goes bonkers. Special buffers always start
" with '['.
if current_buffer_name[ 0 ] == '['
return
endif
if s:searched_and_results_found
" This command does the actual closing of the preview window. If no preview
" window is shown, nothing happens.
pclose
endif
endfunction
function! s:UpdateDiagnosticNotifications()
let should_display_diagnostics = g:ycm_show_diagnostics_ui &&
\ s:DiagnosticUiSupportedForCurrentFiletype() &&
\ pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
if !should_display_diagnostics
return
endif
py ycm_state.UpdateDiagnosticInterface()
endfunction
function! s:IdentifierFinishedOperations()
if !pyeval( 'base.CurrentIdentifierFinished()' )
return
endif
py ycm_state.OnCurrentIdentifierFinished()
let s:omnifunc_mode = 0
endfunction
" Returns 1 when inside comment and 2 when inside string
function! s:InsideCommentOrString()
" Has to be col('.') -1 because col('.') doesn't exist at this point. We are
" in insert mode when this func is called.
let syntax_group = synIDattr( synIDtrans( synID( line( '.' ), col( '.' ) - 1, 1 ) ), 'name')
if stridx(syntax_group, 'Comment') > -1
return 1
endif
if stridx(syntax_group, 'String') > -1
return 2
endif
return 0
endfunction
function! s:InsideCommentOrStringAndShouldStop()
let retval = s:InsideCommentOrString()
let inside_comment = retval == 1
let inside_string = retval == 2
if inside_comment && g:ycm_complete_in_comments ||
\ inside_string && g:ycm_complete_in_strings
return 0
endif
return retval
endfunction
function! s:OnBlankLine()
return pyeval( 'not vim.current.line or vim.current.line.isspace()' )
endfunction
function! s:InvokeCompletion()
if &completefunc != "youcompleteme#Complete"
return
endif
if s:InsideCommentOrStringAndShouldStop() || s:OnBlankLine()
return
endif
" This is tricky. First, having 'refresh' set to 'always' in the dictionary
" that our completion function returns makes sure that our completion function
" is called on every keystroke. Second, when the sequence of characters the
" user typed produces no results in our search an infinite loop can occur. The
" problem is that our feedkeys call triggers the OnCursorMovedI event which we
" are tied to. We prevent this infinite loop from starting by making sure that
" the user has moved the cursor since the last time we provided completion
" results.
if !s:cursor_moved
return
endif
" invokes the user's completion function (which we have set to
" youcompleteme#Complete), and tells Vim to select the previous
" completion candidate. This is necessary because by default, Vim selects the
" first candidate when completion is invoked, and selecting a candidate
" automatically replaces the current text with it. Calling forces Vim to
" deselect the first candidate and in turn preserve the user's current text
" until he explicitly chooses to replace it with a completion.
call feedkeys( "\\\", 'n' )
endfunction
python << EOF
def GetCompletions( query ):
request = ycm_state.GetCurrentCompletionRequest()
request.Start( query )
while not request.Done():
if bool( int( vim.eval( 'complete_check()' ) ) ):
return { 'words' : [], 'refresh' : 'always'}
results = base.AdjustCandidateInsertionText( request.Response() )
return { 'words' : results, 'refresh' : 'always' }
EOF
function! s:CompletionsForQuery( query )
py results = GetCompletions( vim.eval( 'a:query' ) )
let results = pyeval( 'results' )
let s:searched_and_results_found = len( results.words ) != 0
return results
endfunction
" This is our main entry point. This is what vim calls to get completions.
function! youcompleteme#Complete( findstart, base )
" After the user types one character after the call to the omnifunc, the
" completefunc will be called because of our mapping that calls the
" completefunc on every keystroke. Therefore we need to delegate the call we
" 'stole' back to the omnifunc
if s:omnifunc_mode
return youcompleteme#OmniComplete( a:findstart, a:base )
endif
if a:findstart
" InvokeCompletion has this check but we also need it here because of random
" Vim bugs and unfortunate interactions with the autocommands of other
" plugins
if !s:cursor_moved
" for vim, -2 means not found but don't trigger an error message
" see :h complete-functions
return -2
endif
py request = ycm_state.CreateCompletionRequest()
if !pyeval( 'bool(request)' )
return -2
endif
return pyeval( 'request.CompletionStartColumn()' )
else
return s:CompletionsForQuery( a:base )
endif
endfunction
function! youcompleteme#OmniComplete( findstart, base )
if a:findstart
let s:omnifunc_mode = 1
py request = ycm_state.CreateCompletionRequest( force_semantic = True )
return pyeval( 'request.CompletionStartColumn()' )
else
return s:CompletionsForQuery( a:base )
endif
endfunction
function! youcompleteme#ServerPid()
return pyeval( 'ycm_state.ServerPid()' )
endfunction
function! s:RestartServer()
py ycm_state.RestartServer()
endfunction
command! YcmRestartServer call s:RestartServer()
function! s:ShowDetailedDiagnostic()
py ycm_state.ShowDetailedDiagnostic()
endfunction
command! YcmShowDetailedDiagnostic call s:ShowDetailedDiagnostic()
function! s:DebugInfo()
echom "Printing YouCompleteMe debug information..."
let debug_info = pyeval( 'ycm_state.DebugInfo()' )
for line in split( debug_info, "\n" )
echom '-- ' . line
endfor
endfunction
command! YcmDebugInfo call s:DebugInfo()
function! s:CompleterCommand(...)
" CompleterCommand will call the OnUserCommand function of a completer.
" If the first arguments is of the form "ft=..." it can be used to specify the
" completer to use (for example "ft=cpp"). Else the native filetype completer
" of the current buffer is used. If no native filetype completer is found and
" no completer was specified this throws an error. You can use
" "ft=ycm:ident" to select the identifier completer.
" The remaining arguments will be passed to the completer.
let arguments = copy(a:000)
let completer = ''
if a:0 > 0 && strpart(a:1, 0, 3) == 'ft='
if a:1 == 'ft=ycm:ident'
let completer = 'identifier'
endif
let arguments = arguments[1:]
endif
py ycm_state.SendCommandRequest( vim.eval( 'l:arguments' ),
\ vim.eval( 'l:completer' ) )
endfunction
function! youcompleteme#OpenGoToList()
set lazyredraw
cclose
execute 'belowright copen 3'
set nolazyredraw
au WinLeave q " automatically leave, if an option is chosen
redraw!
endfunction
command! -nargs=* -complete=custom,youcompleteme#SubCommandsComplete
\ YcmCompleter call s:CompleterCommand()
function! youcompleteme#SubCommandsComplete( arglead, cmdline, cursorpos )
return join( pyeval( 'ycm_state.GetDefinedSubcommands()' ),
\ "\n")
endfunction
function! s:ForceCompile()
if !pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
echom "Native filetype completion not supported for current file, "
\ . "cannot force recompilation."
return 0
endif
echom "Forcing compilation, this will block Vim until done."
py ycm_state.OnFileReadyToParse()
while 1
let diagnostics_ready = pyeval(
\ 'ycm_state.DiagnosticsForCurrentFileReady()' )
if diagnostics_ready
break
endif
sleep 100m
endwhile
return 1
endfunction
function! s:ForceCompileAndDiagnostics()
let compilation_succeeded = s:ForceCompile()
if !compilation_succeeded
return
endif
call s:UpdateDiagnosticNotifications()
echom "Diagnostics refreshed."
endfunction
command! YcmForceCompileAndDiagnostics call s:ForceCompileAndDiagnostics()
function! s:ShowDiagnostics()
let compilation_succeeded = s:ForceCompile()
if !compilation_succeeded
return
endif
let diags = pyeval(
\ 'ycm_state.GetDiagnosticsFromStoredRequest( qflist_format = True )' )
if !empty( diags )
call setloclist( 0, diags )
if g:ycm_open_loclist_on_ycm_diags
lopen
endif
else
echom "No warnings or errors detected"
endif
endfunction
command! YcmDiags call s:ShowDiagnostics()
" This is basic vim plugin boilerplate
let &cpo = s:save_cpo
unlet s:save_cpo
vim-youcompleteme-0+20140207+git18be5c2/cpp/ 0000775 0000000 0000000 00000000000 12275675654 0020144 5 ustar 00root root 0000000 0000000 vim-youcompleteme-0+20140207+git18be5c2/cpp/CMakeLists.txt 0000664 0000000 0000000 00000014453 12275675654 0022713 0 ustar 00root root 0000000 0000000 # Copyright (C) 2011, 2012 Google Inc.
#
# This file is part of YouCompleteMe.
#
# YouCompleteMe 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.
#
# YouCompleteMe 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 YouCompleteMe. If not, see .
cmake_minimum_required( VERSION 2.8 )
project( YouCompleteMe )
option( UNIVERSAL "Build universal mac binary" OFF )
if ( CMAKE_GENERATOR STREQUAL Xcode )
set( CMAKE_GENERATOR_IS_XCODE true )
endif()
if ( ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" )
set( SYSTEM_IS_FREEBSD true )
endif()
if ( ${CMAKE_SYSTEM_NAME} MATCHES "SunOS" )
set( SYSTEM_IS_SUNOS true )
endif()
# Check if platform is 64 bit
if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
set( 64_BIT_PLATFORM 0 )
else()
set( 64_BIT_PLATFORM 1 )
endif()
#############################################################################
# Turning on this flag tells cmake to emit a compile_commands.json file.
# This file can be used to load compilation flags into YCM. See here for more
# details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
#############################################################################
# This is needed so that on macs, the library is built in both 32 bit and 64 bit
# versions. Without this python might refuse to load the module, depending on
# how python was built.
# On Mac, boost needs to be compiled universal as well, if used instead of the
# included BoostParts lib. For brew, that's
# "brew install boost --universal"
# If the user chose to use the system libclang.dylib (or the libclang.dylib
# binary downloaded from llvm.org) on a mac, then we don't specify universal
# binary building since the system libclang on macs is not universal (and thus
# linking would fail with universal).
if ( UNIVERSAL AND NOT USE_SYSTEM_LIBCLANG )
set( CMAKE_OSX_ARCHITECTURES "i386;x86_64" )
endif()
#############################################################################
if ( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
set( COMPILER_IS_CLANG true )
# Linux machines don't necessarily have libc++ installed alongside clang,
# but HAS_LIBCXX11 doesn't always trigger for machines that DO have libc++. We
# know that at least all the Mac OS versions we support that use Clang have
# libc++, so we're safe there. On FreeBSD 9 libc++ is an optional build
# toggle. On FreeBSD 10 it is the default.
if ( HAS_LIBCXX11 OR APPLE OR SYSTEM_IS_FREEBSD )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" )
endif()
# Ninja will by default prevent Clang from outputting diagnostics in color, so
# we force color output
if ( CMAKE_GENERATOR STREQUAL "Ninja" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics" )
endif()
endif()
#############################################################################
# Force release build by default, speed is of the essence
if ( NOT CMAKE_BUILD_TYPE )
set( CMAKE_BUILD_TYPE Release )
endif()
#############################################################################
# Determining the presence of C++11 support in the compiler
set( CPP11_AVAILABLE false )
if ( CMAKE_COMPILER_IS_GNUCXX )
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if ( GCC_VERSION VERSION_GREATER 4.6 OR GCC_VERSION VERSION_EQUAL 4.6 )
set( CPP11_AVAILABLE true )
endif()
elseif( COMPILER_IS_CLANG )
set( CPP11_AVAILABLE true )
set( CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11" )
set( CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++" )
endif()
#############################################################################
# For MSVC enable UNICODE and compilation on multiple processors
if ( MSVC )
add_definitions( /DUNICODE /D_UNICODE /Zc:wchar_t- )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP" )
endif()
# Solves the conflict in names of hypot in python sources and boost::python
if ( MINGW )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include cmath")
endif()
# Due to a bug/misconfiguration/stupidity, boost 1.52 and libc++ don't like each
# other much: a compilation error "Constexpr function never produces a constant
# expression" pops up when trying to compile anything that uses
# boost/chrono/duration.hpp (namely boost/thread for us). This is a workaround
# that prevents this from happening. Also present in cpp/BoostParts/CMakeLists.txt.
# See here for more details: https://svn.boost.org/trac/boost/ticket/7671
# TODO: remove this when it's fixed upstream (probably boost 1.53).
add_definitions( -DBOOST_THREAD_DONT_USE_CHRONO )
if( MSVC OR CYGWIN )
# BOOST_ALL_NO_LIB turns off MSVC library autolinking
add_definitions( -DBOOST_ALL_NO_LIB )
endif()
if( WIN32 OR CYGWIN )
# BOOST_PYTHON_SOURCE makes boost use the correct __declspec
add_definitions( -DBOOST_PYTHON_SOURCE -DBOOST_THREAD_USE_LIB )
if ( 64_BIT_PLATFORM )
# Enables python compilation for 64-bit Windows
add_definitions( -DMS_WIN64 )
endif()
endif()
#############################################################################
# When used with Clang, adding the -std=c++0x flag to CMAKE_CXX_FLAGS will cause
# the compiler to output a warning during linking:
# clang: warning: argument unused during compilation: '-std=c++0x'
# This is caused by cmake passing this flag to the linking stage which it
# shouldn't do. It's ignored so it does no harm, but the warning is annoying.
#
# Putting the flag in add_definitions() works around the issue, even though it
# shouldn't in theory go there.
if ( CPP11_AVAILABLE )
message( "Your C++ compiler supports C++11, compiling in that mode." )
# Cygwin needs its hand held a bit; see issue #473
if ( CYGWIN AND CMAKE_COMPILER_IS_GNUCXX )
add_definitions( -std=gnu++0x )
else()
add_definitions( -std=c++0x )
endif()
else()
message(
"Your C++ compiler does NOT support C++11, compiling in C++03 mode." )
endif()
add_subdirectory( BoostParts )
add_subdirectory( ycm )
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ 0000775 0000000 0000000 00000000000 12275675654 0020734 5 ustar 00root root 0000000 0000000 vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/.ycm_extra_conf.py 0000664 0000000 0000000 00000014563 12275675654 0024375 0 ustar 00root root 0000000 0000000 # This file is NOT licensed under the GPLv3, which is the license for the rest
# of YouCompleteMe.
#
# Here's the license text for this file:
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to
import os
import ycm_core
# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wc++98-compat',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-DNDEBUG',
# You 100% do NOT need -DUSE_CLANG_COMPLETER in your flags; only the YCM
# source code needs it.
'-DUSE_CLANG_COMPLETER',
# THIS IS IMPORTANT! Without a "-std=" flag, clang won't know which
# language to use when compiling headers. So it will guess. Badly. So C++
# headers will be compiled as C headers. You don't want that so ALWAYS specify
# a "-std=".
# For a C project, you would set this to something like 'c99' instead of
# 'c++11'.
'-std=c++11',
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x',
'c++',
'-isystem',
'../BoostParts',
'-isystem',
# This path will only work on OS X, but extra paths that don't exist are not
# harmful
'/System/Library/Frameworks/Python.framework/Headers',
'-isystem',
'../llvm/include',
'-isystem',
'../llvm/tools/clang/include',
'-I',
'.',
'-I',
'./ClangCompleter',
'-isystem',
'./tests/gmock/gtest',
'-isystem',
'./tests/gmock/gtest/include',
'-isystem',
'./tests/gmock',
'-isystem',
'./tests/gmock/include',
'-isystem',
'/usr/include',
'-isystem',
'/usr/local/include',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include',
]
# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''
if os.path.exists( compilation_database_folder ):
database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
database = None
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
def DirectoryOfThisScript():
return os.path.dirname( os.path.abspath( __file__ ) )
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
if not working_directory:
return list( flags )
new_flags = []
make_next_absolute = False
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
for flag in flags:
new_flag = flag
if make_next_absolute:
make_next_absolute = False
if not flag.startswith( '/' ):
new_flag = os.path.join( working_directory, flag )
for path_flag in path_flags:
if flag == path_flag:
make_next_absolute = True
break
if flag.startswith( path_flag ):
path = flag[ len( path_flag ): ]
new_flag = path_flag + os.path.join( working_directory, path )
break
if new_flag:
new_flags.append( new_flag )
return new_flags
def IsHeaderFile( filename ):
extension = os.path.splitext( filename )[ 1 ]
return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
def GetCompilationInfoForFile( filename ):
# The compilation_commands.json file generated by CMake does not have entries
# for header files. So we do our best by asking the db for flags for a
# corresponding source file, if any. If one exists, the flags for that file
# should be good enough.
if IsHeaderFile( filename ):
basename = os.path.splitext( filename )[ 0 ]
for extension in SOURCE_EXTENSIONS:
replacement_file = basename + extension
if os.path.exists( replacement_file ):
compilation_info = database.GetCompilationInfoForFile(
replacement_file )
if compilation_info.compiler_flags_:
return compilation_info
return None
return database.GetCompilationInfoForFile( filename )
def FlagsForFile( filename, **kwargs ):
if database:
# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object
compilation_info = GetCompilationInfoForFile( filename )
if not compilation_info:
return None
final_flags = MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_ )
# NOTE: This is just for YouCompleteMe; it's highly likely that your project
# does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR
# ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT.
try:
final_flags.remove( '-stdlib=libc++' )
except ValueError:
pass
else:
relative_to = DirectoryOfThisScript()
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
return {
'flags': final_flags,
'do_cache': True
}
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/CMakeLists.txt 0000664 0000000 0000000 00000031624 12275675654 0023502 0 ustar 00root root 0000000 0000000 # Copyright (C) 2011, 2012 Google Inc.
#
# This file is part of YouCompleteMe.
#
# YouCompleteMe 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.
#
# YouCompleteMe 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 YouCompleteMe. If not, see .
cmake_minimum_required( VERSION 2.8 )
project( ycm_support_libs )
set( CLIENT_LIB "ycm_client_support" )
set( SERVER_LIB "ycm_core" )
set( Python_ADDITIONAL_VERSIONS 2.7 2.6 )
find_package( PythonLibs 2.6 REQUIRED )
if ( NOT PYTHONLIBS_VERSION_STRING VERSION_LESS "3.0.0" )
message( FATAL_ERROR
"CMake found python3 libs instead of python2 libs. YCM works only with "
"python2.\n" )
endif()
option( USE_DEV_FLAGS "Use compilation flags meant for YCM developers" OFF )
option( USE_CLANG_COMPLETER "Use Clang semantic completer for C/C++/ObjC" OFF )
option( USE_SYSTEM_LIBCLANG "Set to ON to use the system libclang library" OFF )
set( PATH_TO_LLVM_ROOT "" CACHE PATH "Path to the root of a LLVM+Clang binary distribution" )
set( EXTERNAL_LIBCLANG_PATH "" CACHE PATH "Path libclang library to use" )
if ( USE_CLANG_COMPLETER AND NOT USE_SYSTEM_LIBCLANG AND NOT PATH_TO_LLVM_ROOT )
message( "Downloading Clang 3.4" )
set( CLANG_URL "http://llvm.org/releases/3.4" )
if ( APPLE )
set( CLANG_DIRNAME "clang+llvm-3.4-x86_64-apple-darwin10.9" )
set( CLANG_MD5 "4f43ea0e87090ae5e7bec12373ca4927" )
set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.gz" )
else()
if ( 64_BIT_PLATFORM )
set( CLANG_DIRNAME "clang+llvm-3.4-x86_64-unknown-ubuntu12.04" )
set( CLANG_MD5 "6077459d20a7ff412eefc6ce3b9f5c85" )
set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.xz" )
else()
message( "No pre-built Clang 3.4 binaries for 32 bit linux, "
"downloading Clang 3.3" )
set( CLANG_URL "http://llvm.org/releases/3.3" )
set( CLANG_DIRNAME "clang+llvm-3.3-i386-debian6" )
set( CLANG_MD5 "415d033b60659433d4631df894673802" )
set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.bz2" )
endif()
endif()
file(
DOWNLOAD "${CLANG_URL}/${CLANG_FILENAME}" "./${CLANG_FILENAME}"
SHOW_PROGRESS EXPECTED_MD5 "${CLANG_MD5}"
)
if ( CLANG_FILENAME MATCHES ".+bz2" )
execute_process( COMMAND tar -xjf ${CLANG_FILENAME} )
elseif( CLANG_FILENAME MATCHES ".+xz" )
execute_process( COMMAND tar -xJf ${CLANG_FILENAME} )
else()
execute_process( COMMAND tar -xzf ${CLANG_FILENAME} )
endif()
# And set PATH_TO_LLVM_ROOT
set( PATH_TO_LLVM_ROOT "${CMAKE_CURRENT_BINARY_DIR}/../${CLANG_DIRNAME}" )
endif()
if ( PATH_TO_LLVM_ROOT OR USE_SYSTEM_LIBCLANG OR EXTERNAL_LIBCLANG_PATH )
set( USE_CLANG_COMPLETER TRUE )
endif()
if ( USE_CLANG_COMPLETER AND
NOT PATH_TO_LLVM_ROOT AND
NOT USE_SYSTEM_LIBCLANG AND
NOT EXTERNAL_LIBCLANG_PATH )
message( FATAL_ERROR
"You have not specified which libclang to use. You have several options:\n"
" 1. Set PATH_TO_LLVM_ROOT to a path to the root of a LLVM+Clang binary "
"distribution. You can download such a binary distro from llvm.org. This "
"is the recommended approach.\n"
" 2. Set USE_SYSTEM_LIBCLANG to ON; this makes YCM search for the system "
"version of libclang.\n"
" 3. Set EXTERNAL_LIBCLANG_PATH to a path to whatever "
"libclang.[so|dylib|dll] you wish to use.\n"
"You HAVE to pick one option. See the docs for more information.")
endif()
if ( USE_CLANG_COMPLETER )
message( "Using libclang to provide semantic completion for C/C++/ObjC" )
else()
message( "NOT using libclang, no semantic completion for C/C++/ObjC will be "
"available" )
endif()
if ( PATH_TO_LLVM_ROOT )
set( CLANG_INCLUDES_DIR "${PATH_TO_LLVM_ROOT}/include" )
else()
set( CLANG_INCLUDES_DIR "${CMAKE_SOURCE_DIR}/llvm/include" )
endif()
if ( NOT IS_ABSOLUTE "${CLANG_INCLUDES_DIR}" )
get_filename_component(CLANG_INCLUDES_DIR
"${CMAKE_BINARY_DIR}/${CLANG_INCLUDES_DIR}" ABSOLUTE)
endif()
if ( NOT EXTERNAL_LIBCLANG_PATH AND PATH_TO_LLVM_ROOT )
if ( MINGW )
set( LIBCLANG_SEARCH_PATH "${PATH_TO_LLVM_ROOT}/bin" )
else()
set( LIBCLANG_SEARCH_PATH "${PATH_TO_LLVM_ROOT}/lib" )
endif()
# Need TEMP because find_library does not work with an option variable
find_library( TEMP NAMES clang libclang
PATHS ${LIBCLANG_SEARCH_PATH}
NO_DEFAULT_PATH )
set( EXTERNAL_LIBCLANG_PATH ${TEMP} )
endif()
# This is a workaround for a CMake bug with include_directories(SYSTEM ...)
# on Mac OS X. Bug report: http://public.kitware.com/Bug/view.php?id=10837
if ( APPLE )
set( CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem " )
endif()
# The SYSTEM flag makes sure that -isystem[header path] is passed to the
# compiler instead of the standard -I[header path]. Headers included with
# -isystem do not generate warnings (and they shouldn't; e.g. boost warnings are
# just noise for us since we won't be changing them).
include_directories(
SYSTEM
${BoostParts_SOURCE_DIR}
${PYTHON_INCLUDE_DIRS}
${CLANG_INCLUDES_DIR}
)
file( GLOB_RECURSE SERVER_SOURCES *.h *.cpp )
# The test sources are a part of a different target, so we remove them
# The CMakeFiles cpp file is picked up when the user creates an in-source build,
# and we don't want that. We also remove client-specific code
file( GLOB_RECURSE to_remove tests/*.h tests/*.cpp CMakeFiles/*.cpp *client* )
if( to_remove )
list( REMOVE_ITEM SERVER_SOURCES ${to_remove} )
endif()
if ( USE_CLANG_COMPLETER )
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/ClangCompleter" )
add_definitions( -DUSE_CLANG_COMPLETER )
else()
file( GLOB_RECURSE to_remove_clang ClangCompleter/*.h ClangCompleter/*.cpp )
if( to_remove_clang )
list( REMOVE_ITEM SERVER_SOURCES ${to_remove_clang} )
endif()
endif()
#############################################################################
# One can use the system libclang.[so|dylib] like so:
# cmake -DUSE_SYSTEM_LIBCLANG=1 [...]
# One can also explicitely pick the external libclang.[so|dylib] for use like so:
# cmake -DEXTERNAL_LIBCLANG_PATH=/path/to/libclang.so [...]
# The final .so we build will then first look in the same dir in which it is
# located for libclang.so. This is provided by the rpath = $ORIGIN feature.
if ( EXTERNAL_LIBCLANG_PATH OR USE_SYSTEM_LIBCLANG )
if ( USE_SYSTEM_LIBCLANG )
if ( APPLE )
set( ENV_LIB_PATHS ENV DYLD_LIBRARY_PATH )
elseif ( UNIX )
set( ENV_LIB_PATHS ENV LD_LIBRARY_PATH )
elseif ( WIN32 )
set( ENV_LIB_PATHS ENV PATH )
else ()
set( ENV_LIB_PATHS "" )
endif()
# On Debian-based systems, llvm installs into /usr/lib/llvm-x.y.
file( GLOB SYS_LLVM_PATHS "/usr/lib/llvm*/lib" )
# Need TEMP because find_library does not work with an option variable
find_library( TEMP clang
PATHS
${ENV_LIB_PATHS}
/usr/lib
/usr/lib/llvm
${SYS_LLVM_PATHS}
/Library/Developer/CommandLineTools/usr/lib,
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib )
set( EXTERNAL_LIBCLANG_PATH ${TEMP} )
else()
# For Macs, we do things differently; look further in this file.
if ( NOT APPLE )
# Setting this to true makes sure that libraries we build will have our rpath
# set even without having to do "make install"
set( CMAKE_BUILD_WITH_INSTALL_RPATH TRUE )
set( CMAKE_INSTALL_RPATH "\$ORIGIN" )
endif()
endif()
set( LIBCLANG_TARGET ${EXTERNAL_LIBCLANG_PATH} )
message(
"Using external libclang: ${EXTERNAL_LIBCLANG_PATH}" )
else()
set( LIBCLANG_TARGET )
endif()
if ( EXTRA_RPATH )
set( CMAKE_INSTALL_RPATH "${EXTRA_RPATH}:${CMAKE_INSTALL_RPATH}" )
endif()
# Needed on Linux machines, but not on Macs
if ( UNIX AND NOT APPLE )
set( EXTRA_LIBS rt )
endif()
#############################################################################
# We don't actually need all of the files this picks up, just the ones needed by
# PythonSupport.cpp. But this is easier to maintain and dead code elemination
# will remove unused code.
file( GLOB CLIENT_SOURCES *.h *.cpp )
file( GLOB SERVER_SPECIFIC *ycm_core* )
if( SERVER_SPECIFIC )
list( REMOVE_ITEM CLIENT_SOURCES ${SERVER_SPECIFIC} )
endif()
add_library( ${CLIENT_LIB} SHARED
${CLIENT_SOURCES}
)
target_link_libraries( ${CLIENT_LIB}
BoostParts
${PYTHON_LIBRARIES}
${EXTRA_LIBS}
)
#############################################################################
add_library( ${SERVER_LIB} SHARED
${SERVER_SOURCES}
)
target_link_libraries( ${SERVER_LIB}
BoostParts
${PYTHON_LIBRARIES}
${LIBCLANG_TARGET}
${EXTRA_LIBS}
)
if( LIBCLANG_TARGET )
if( NOT WIN32 )
add_custom_command(
TARGET ${SERVER_LIB}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${LIBCLANG_TARGET}" "$"
)
else()
add_custom_command(
TARGET ${SERVER_LIB}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${PATH_TO_LLVM_ROOT}/bin/libclang.dll" "$")
endif()
endif()
#############################################################################
# Convenience target that builds both support libs.
add_custom_target( ${PROJECT_NAME}
DEPENDS ${CLIENT_LIB} ${SERVER_LIB} )
#############################################################################
# Things are a bit different on Macs when using an external libclang.dylib; here
# we want to make sure we use @loader_path/libclang.dylib instead of
# @rpath/libclang.dylib in the final ycm_core.so. If we use the
# @rpath version, then it may load the system libclang which the user
# explicitely does not want (otherwise the user would specify
# USE_SYSTEM_LIBCLANG). With @loader_path, we make sure that only the
# libclang.dylib present in the same directory as our ycm_core.so
# is used.
if ( EXTERNAL_LIBCLANG_PATH AND APPLE )
add_custom_command( TARGET ${SERVER_LIB}
POST_BUILD
COMMAND install_name_tool
"-change"
"@rpath/libclang.dylib"
"@loader_path/libclang.dylib"
"$"
)
endif()
#############################################################################
# We don't want the "lib" prefix, it can screw up python when it tries to search
# for our module
set_target_properties( ${CLIENT_LIB} PROPERTIES PREFIX "")
set_target_properties( ${SERVER_LIB} PROPERTIES PREFIX "")
if ( WIN32 OR CYGWIN )
# This is the extension for compiled Python modules on Windows
set_target_properties( ${CLIENT_LIB} PROPERTIES SUFFIX ".pyd")
set_target_properties( ${SERVER_LIB} PROPERTIES SUFFIX ".pyd")
else()
# Even on macs, we want a .so extension instead of a .dylib which is what
# cmake would give us by default. Python won't recognize a .dylib as a module,
# but it will recognize a .so
set_target_properties( ${CLIENT_LIB} PROPERTIES SUFFIX ".so")
set_target_properties( ${SERVER_LIB} PROPERTIES SUFFIX ".so")
endif()
set_target_properties( ${CLIENT_LIB} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../python )
set_target_properties( ${SERVER_LIB} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../python )
#############################################################################
# For some reason, Xcode is too dumb to understand the -isystem flag and thus
# borks on warnings in Boost.
if ( USE_DEV_FLAGS AND ( CMAKE_COMPILER_IS_GNUCXX OR COMPILER_IS_CLANG ) AND
NOT CMAKE_GENERATOR_IS_XCODE )
# We want all warnings, and warnings should be treated as errors
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror" )
endif()
#############################################################################
# We want warnings if we accidentally use C++11 features
# We can't use this warning on FreeBSD because std headers on that OS are dumb.
# See here: https://github.com/Valloric/YouCompleteMe/issues/260
if ( USE_DEV_FLAGS AND COMPILER_IS_CLANG AND NOT CMAKE_GENERATOR_IS_XCODE AND
NOT SYSTEM_IS_FREEBSD )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wc++98-compat" )
endif()
#############################################################################
if( SYSTEM_IS_SUNOS )
# SunOS needs this setting for thread support
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthreads" )
endif()
add_subdirectory( tests )
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/Candidate.cpp 0000664 0000000 0000000 00000006637 12275675654 0023330 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "standard.h"
#include "Candidate.h"
#include "Result.h"
#include
#include
using boost::algorithm::all;
using boost::algorithm::is_lower;
namespace YouCompleteMe {
namespace {
LetterNode *FirstUppercaseNode( const std::list< LetterNode *> &list ) {
LetterNode *node = NULL;
foreach( LetterNode * current_node, list ) {
if ( current_node->LetterIsUppercase() ) {
node = current_node;
break;
}
}
return node;
}
} // unnamed namespace
std::string GetWordBoundaryChars( const std::string &text ) {
std::string result;
for ( uint i = 0; i < text.size(); ++i ) {
bool is_first_char_but_not_underscore = i == 0 && text[ i ] != '_';
bool is_good_uppercase = i > 0 &&
IsUppercase( text[ i ] ) &&
!IsUppercase( text[ i - 1 ] );
bool is_alpha_after_underscore = i > 0 &&
text[ i - 1 ] == '_' &&
isalpha( text[ i ] );
if ( is_first_char_but_not_underscore ||
is_good_uppercase ||
is_alpha_after_underscore ) {
result.push_back( tolower( text[ i ] ) );
}
}
return result;
}
Bitset LetterBitsetFromString( const std::string &text ) {
Bitset letter_bitset;
foreach ( char letter, text ) {
letter_bitset.set( IndexForChar( letter ) );
}
return letter_bitset;
}
Candidate::Candidate( const std::string &text )
:
text_( text ),
word_boundary_chars_( GetWordBoundaryChars( text ) ),
text_is_lowercase_( all( text, is_lower() ) ),
letters_present_( LetterBitsetFromString( text ) ),
root_node_( new LetterNode( text ) ) {
}
Result Candidate::QueryMatchResult( const std::string &query,
bool case_sensitive ) const {
LetterNode *node = root_node_.get();
int index_sum = 0;
foreach ( char letter, query ) {
const std::list< LetterNode *> *list = node->NodeListForLetter( letter );
if ( !list )
return Result( false );
if ( case_sensitive ) {
// When the query letter is uppercase, then we force an uppercase match
// but when the query letter is lowercase, then it can match both an
// uppercase and a lowercase letter. This is by design and it's much
// better than forcing lowercase letter matches.
node = IsUppercase( letter ) ?
FirstUppercaseNode( *list ) :
list->front();
if ( !node )
return Result( false );
} else {
node = list->front();
}
index_sum += node->Index();
}
return Result( true, &text_, text_is_lowercase_, index_sum,
word_boundary_chars_, query );
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/Candidate.h 0000664 0000000 0000000 00000003604 12275675654 0022764 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef CANDIDATE_H_R5LZH6AC
#define CANDIDATE_H_R5LZH6AC
#include "LetterNode.h"
#include
#include
#include
#include
namespace YouCompleteMe {
class Result;
typedef std::bitset< NUM_LETTERS > Bitset;
Bitset LetterBitsetFromString( const std::string &text );
// Public for tests
std::string GetWordBoundaryChars( const std::string &text );
class Candidate : boost::noncopyable {
public:
explicit Candidate( const std::string &text );
inline const std::string &Text() const {
return text_;
}
// Returns true if the candidate contains the bits from the query (it may also
// contain other bits)
inline bool MatchesQueryBitset( const Bitset &query_bitset ) const {
return ( letters_present_ & query_bitset ) == query_bitset;
}
Result QueryMatchResult( const std::string &query,
bool case_sensitive ) const;
private:
std::string text_;
std::string word_boundary_chars_;
bool text_is_lowercase_;
Bitset letters_present_;
boost::scoped_ptr< LetterNode > root_node_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: CANDIDATE_H_R5LZH6AC */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/CandidateRepository.cpp 0000664 0000000 0000000 00000006576 12275675654 0025432 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "CandidateRepository.h"
#include "Candidate.h"
#include "standard.h"
#include "Utils.h"
#include
#include
#include
#ifdef USE_CLANG_COMPLETER
# include "ClangCompleter/CompletionData.h"
#endif // USE_CLANG_COMPLETER
namespace YouCompleteMe {
using boost::all;
using boost::is_print;
boost::mutex CandidateRepository::singleton_mutex_;
CandidateRepository *CandidateRepository::instance_ = NULL;
CandidateRepository &CandidateRepository::Instance() {
boost::lock_guard< boost::mutex > locker( singleton_mutex_ );
if ( !instance_ ) {
static CandidateRepository repo;
instance_ = &repo;
}
return *instance_;
}
int CandidateRepository::NumStoredCandidates() {
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
return candidate_holder_.size();
}
std::vector< const Candidate * > CandidateRepository::GetCandidatesForStrings(
const std::vector< std::string > &strings ) {
std::vector< const Candidate * > candidates;
candidates.reserve( strings.size() );
{
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
foreach ( const std::string & candidate_text, strings ) {
const std::string &validated_candidate_text =
all( candidate_text, is_print( std::locale::classic() ) ) ?
candidate_text :
empty_;
const Candidate *&candidate = GetValueElseInsert(
candidate_holder_,
validated_candidate_text,
NULL );
if ( !candidate )
candidate = new Candidate( validated_candidate_text );
candidates.push_back( candidate );
}
}
return candidates;
}
#ifdef USE_CLANG_COMPLETER
std::vector< const Candidate * > CandidateRepository::GetCandidatesForStrings(
const std::vector< CompletionData > &datas ) {
std::vector< const Candidate * > candidates;
candidates.reserve( datas.size() );
{
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
foreach ( const CompletionData & data, datas ) {
const Candidate *&candidate = GetValueElseInsert( candidate_holder_,
data.original_string_,
NULL );
if ( !candidate )
candidate = new Candidate( data.original_string_ );
candidates.push_back( candidate );
}
}
return candidates;
}
#endif // USE_CLANG_COMPLETER
CandidateRepository::~CandidateRepository() {
foreach ( const CandidateHolder::value_type & pair,
candidate_holder_ ) {
delete pair.second;
}
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/CandidateRepository.h 0000664 0000000 0000000 00000004311 12275675654 0025060 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef CANDIDATEREPOSITORY_H_K9OVCMHG
#define CANDIDATEREPOSITORY_H_K9OVCMHG
#include
#include
#include
#include
#include
namespace YouCompleteMe {
class Candidate;
struct CompletionData;
typedef boost::unordered_map< std::string, const Candidate * >
CandidateHolder;
// This singleton stores already built Candidate objects for candidate strings
// that were already seen. If Candidates are requested for previously unseen
// strings, new Candidate objects are built.
//
// This is shared by the identifier completer and the clang completer so that
// work is not repeated.
//
// This class is thread-safe.
class CandidateRepository : boost::noncopyable {
public:
static CandidateRepository &Instance();
int NumStoredCandidates();
std::vector< const Candidate * > GetCandidatesForStrings(
const std::vector< std::string > &strings );
#ifdef USE_CLANG_COMPLETER
std::vector< const Candidate * > GetCandidatesForStrings(
const std::vector< CompletionData > &datas );
#endif // USE_CLANG_COMPLETER
private:
CandidateRepository() {};
~CandidateRepository();
boost::mutex holder_mutex_;
static boost::mutex singleton_mutex_;
static CandidateRepository *instance_;
const std::string empty_;
// This data structure owns all the Candidate pointers
CandidateHolder candidate_holder_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: CANDIDATEREPOSITORY_H_K9OVCMHG */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/ 0000775 0000000 0000000 00000000000 12275675654 0023633 5 ustar 00root root 0000000 0000000 vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/ClangCompleter.cpp 0000664 0000000 0000000 00000012362 12275675654 0027242 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011-2013 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "ClangCompleter.h"
#include "exceptions.h"
#include "Result.h"
#include "Candidate.h"
#include "TranslationUnit.h"
#include "standard.h"
#include "CandidateRepository.h"
#include "CompletionData.h"
#include "Utils.h"
#include "ClangUtils.h"
#include "ReleaseGil.h"
#include
#include
using boost::shared_ptr;
using boost::unordered_map;
namespace YouCompleteMe {
ClangCompleter::ClangCompleter()
: clang_index_( clang_createIndex( 0, 0 ) ),
translation_unit_store_( clang_index_ ) {
// The libclang docs don't say what is the default value for crash recovery.
// I'm pretty sure it's turned on by default, but I'm not going to take any
// chances.
clang_toggleCrashRecovery( true );
}
ClangCompleter::~ClangCompleter() {
// We need to destroy all TUs before calling clang_disposeIndex because
// the translation units need to be destroyed before the index is destroyed.
// Technically, a thread could still be holding onto a shared_ptr object
// when we destroy the clang index, but since we're shutting down, we don't
// really care.
// In practice, this situation shouldn't happen because the server threads are
// Python deamon threads and will all be killed before the main thread exits.
translation_unit_store_.RemoveAll();
clang_disposeIndex( clang_index_ );
}
bool ClangCompleter::UpdatingTranslationUnit( const std::string &filename ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit = translation_unit_store_.Get( filename );
if ( !unit )
return false;
// Thankfully, an invalid, sentinel TU always returns true for
// IsCurrentlyUpdating, so no caller will try to rely on the TU object, even
// if unit is currently pointing to a sentinel.
return unit->IsCurrentlyUpdating();
}
std::vector< Diagnostic > ClangCompleter::UpdateTranslationUnit(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags ) {
ReleaseGil unlock;
bool translation_unit_created;
shared_ptr< TranslationUnit > unit = translation_unit_store_.GetOrCreate(
filename,
unsaved_files,
flags,
translation_unit_created );
if ( !unit )
return std::vector< Diagnostic >();
try {
// There's no point in reparsing a TU that was just created, it was just
// parsed in the TU constructor
if ( !translation_unit_created )
return unit->Reparse( unsaved_files );
return unit->LatestDiagnostics();
}
catch ( ClangParseError & ) {
// If unit->Reparse fails, then the underlying TranslationUnit object is not
// valid anymore and needs to be destroyed and removed from the filename ->
// TU map.
translation_unit_store_.Remove( filename );
}
return std::vector< Diagnostic >();
}
std::vector< CompletionData >
ClangCompleter::CandidatesForLocationInFile(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
if ( !unit )
return std::vector< CompletionData >();
return unit->CandidatesForLocation( line,
column,
unsaved_files );
}
Location ClangCompleter::GetDeclarationLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
if ( !unit ) {
return Location();
}
return unit->GetDeclarationLocation( line, column, unsaved_files );
}
Location ClangCompleter::GetDefinitionLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags ) {
ReleaseGil unlock;
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
if ( !unit ) {
return Location();
}
return unit->GetDefinitionLocation( line, column, unsaved_files );
}
void ClangCompleter::DeleteCachesForFile( const std::string &filename ) {
ReleaseGil unlock;
translation_unit_store_.Remove( filename );
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/ClangCompleter.h 0000664 0000000 0000000 00000004672 12275675654 0026714 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef CLANGCOMPLETE_H_WLKDU0ZV
#define CLANGCOMPLETE_H_WLKDU0ZV
#include "UnsavedFile.h"
#include "Diagnostic.h"
#include "TranslationUnitStore.h"
#include
#include
typedef struct CXTranslationUnitImpl *CXTranslationUnit;
namespace YouCompleteMe {
class TranslationUnit;
struct CompletionData;
struct Location;
typedef std::vector< CompletionData > CompletionDatas;
// All filename parameters must be absolute paths.
class ClangCompleter : boost::noncopyable {
public:
ClangCompleter();
~ClangCompleter();
bool UpdatingTranslationUnit( const std::string &filename );
std::vector< Diagnostic > UpdateTranslationUnit(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags );
std::vector< CompletionData > CandidatesForLocationInFile(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags );
Location GetDeclarationLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags );
Location GetDefinitionLocation(
const std::string &filename,
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags );
void DeleteCachesForFile( const std::string &filename );
private:
/////////////////////////////
// PRIVATE MEMBER VARIABLES
/////////////////////////////
CXIndex clang_index_;
TranslationUnitStore translation_unit_store_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: CLANGCOMPLETE_H_WLKDU0ZV */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/ClangHelpers.cpp 0000664 0000000 0000000 00000016203 12275675654 0026710 0 ustar 00root root 0000000 0000000 // Copyright (C) 2013 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "standard.h"
#include "ClangHelpers.h"
#include "ClangUtils.h"
#include "Utils.h"
#include "UnsavedFile.h"
#include "Location.h"
#include "Range.h"
#include
using boost::unordered_map;
namespace YouCompleteMe {
namespace {
// NOTE: The passed in pointer should never be NULL!
std::string FullDiagnosticText( CXDiagnostic cxdiagnostic ) {
std::string full_text = CXStringToString(
clang_formatDiagnostic(
cxdiagnostic,
clang_defaultDiagnosticDisplayOptions() ) );
// Note: clang docs say that a CXDiagnosticSet retrieved with
// clang_getChildDiagnostics do NOT need to be released with
// clang_diposeDiagnosticSet
CXDiagnosticSet diag_set = clang_getChildDiagnostics( cxdiagnostic );
if ( !diag_set )
return full_text;
uint num_child_diagnostics = clang_getNumDiagnosticsInSet( diag_set );
if ( !num_child_diagnostics )
return full_text;
for ( uint i = 0; i < num_child_diagnostics; ++i ) {
CXDiagnostic diagnostic = clang_getDiagnosticInSet( diag_set, i );
if ( !diagnostic )
continue;
full_text.append( FullDiagnosticText( diagnostic ) );
}
return full_text;
}
char DiagnosticSeverityToType( CXDiagnosticSeverity severity ) {
switch ( severity ) {
case CXDiagnostic_Ignored:
case CXDiagnostic_Note:
return 'I';
case CXDiagnostic_Warning:
return 'W';
case CXDiagnostic_Error:
case CXDiagnostic_Fatal:
return 'E';
default:
return 'E';
}
}
// Returns true when the provided completion string is available to the user;
// unavailable completion strings refer to entities that are private/protected,
// deprecated etc.
bool CompletionStringAvailable( CXCompletionString completion_string ) {
if ( !completion_string )
return false;
return clang_getCompletionAvailability( completion_string ) ==
CXAvailability_Available;
}
std::vector< Range > GetRanges( const DiagnosticWrap &diagnostic_wrap ) {
std::vector< Range > ranges;
uint num_ranges = clang_getDiagnosticNumRanges( diagnostic_wrap.get() );
ranges.reserve( num_ranges );
for ( uint i = 0; i < num_ranges; ++i ) {
ranges.push_back(
Range( clang_getDiagnosticRange( diagnostic_wrap.get(), i ) ) );
}
return ranges;
}
Range GetLocationExtent( CXSourceLocation source_location,
CXTranslationUnit translation_unit ) {
// If you think the below code is an idiotic way of getting the source range
// for an identifier at a specific source location, you are not the only one.
// I cannot believe that this is the only way to achieve this with the
// libclang API in a robust way.
// I've tried many simpler ways of doing this and they all fail in various
// situations.
CXSourceRange range = clang_getCursorExtent(
clang_getCursor( translation_unit, source_location ) );
CXToken *tokens;
uint num_tokens;
clang_tokenize( translation_unit, range, &tokens, &num_tokens );
Location location( source_location );
Range final_range;
for ( uint i = 0; i < num_tokens; ++i ) {
Location token_location( clang_getTokenLocation( translation_unit,
tokens[ i ] ) );
if ( token_location == location ) {
std::string name = CXStringToString(
clang_getTokenSpelling( translation_unit, tokens[ i ] ) );
Location end_location = location;
end_location.column_number_ += name.length();
final_range = Range( location, end_location );
break;
}
}
clang_disposeTokens( translation_unit, tokens, num_tokens );
return final_range;
}
} // unnamed namespace
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
const std::vector< UnsavedFile > &unsaved_files ) {
std::vector< CXUnsavedFile > clang_unsaved_files( unsaved_files.size() );
for ( uint i = 0; i < unsaved_files.size(); ++i ) {
clang_unsaved_files[ i ].Filename = unsaved_files[ i ].filename_.c_str();
clang_unsaved_files[ i ].Contents = unsaved_files[ i ].contents_.c_str();
clang_unsaved_files[ i ].Length = unsaved_files[ i ].length_;
}
return clang_unsaved_files;
}
std::vector< CompletionData > ToCompletionDataVector(
CXCodeCompleteResults *results ) {
std::vector< CompletionData > completions;
if ( !results || !results->Results )
return completions;
completions.reserve( results->NumResults );
unordered_map< std::string, uint > seen_data;
for ( uint i = 0; i < results->NumResults; ++i ) {
CXCompletionResult completion_result = results->Results[ i ];
if ( !CompletionStringAvailable( completion_result.CompletionString ) )
continue;
CompletionData data( completion_result );
uint index = GetValueElseInsert( seen_data,
data.original_string_,
completions.size() );
if ( index == completions.size() ) {
completions.push_back( boost::move( data ) );
}
else {
// If we have already seen this completion, then this is an overload of a
// function we have seen. We add the signature of the overload to the
// detailed information.
completions[ index ].detailed_info_
.append( data.return_type_ )
.append( " " )
.append( data.everything_except_return_type_ )
.append( "\n" );
}
}
return completions;
}
Diagnostic BuildDiagnostic( DiagnosticWrap diagnostic_wrap,
CXTranslationUnit translation_unit ) {
Diagnostic diagnostic;
if ( !diagnostic_wrap )
return diagnostic;
diagnostic.kind_ = DiagnosticSeverityToType(
clang_getDiagnosticSeverity( diagnostic_wrap.get() ) );
// If this is an "ignored" diagnostic, there's no point in continuing since we
// won't display those to the user
if ( diagnostic.kind_ == 'I' )
return diagnostic;
CXSourceLocation source_location =
clang_getDiagnosticLocation( diagnostic_wrap.get() );
diagnostic.location_ = Location( source_location );
diagnostic.location_extent_ = GetLocationExtent( source_location,
translation_unit );
diagnostic.ranges_ = GetRanges( diagnostic_wrap );
diagnostic.text_ = CXStringToString(
clang_getDiagnosticSpelling( diagnostic_wrap.get() ) );
diagnostic.long_formatted_text_ = FullDiagnosticText( diagnostic_wrap.get() );
return diagnostic;
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/ClangHelpers.h 0000664 0000000 0000000 00000003151 12275675654 0026353 0 ustar 00root root 0000000 0000000 // Copyright (C) 2013 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef CLANGHELPERS_H_T3ME71LG
#define CLANGHELPERS_H_T3ME71LG
#include "Diagnostic.h"
#include "CompletionData.h"
#include "UnsavedFile.h"
#include
#include
#include
#include
namespace YouCompleteMe {
typedef boost::shared_ptr <
boost::remove_pointer< CXDiagnostic >::type > DiagnosticWrap;
std::vector< CompletionData > ToCompletionDataVector(
CXCodeCompleteResults *results );
// NOTE: CXUnsavedFiles store pointers to data in UnsavedFiles, so UnsavedFiles
// need to outlive CXUnsavedFiles!
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
const std::vector< UnsavedFile > &unsaved_files );
Diagnostic BuildDiagnostic( DiagnosticWrap diagnostic_wrap,
CXTranslationUnit translation_unit );
} // namespace YouCompleteMe
#endif /* end of include guard: CLANGHELPERS_H_T3ME71LG */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/ClangUtils.cpp 0000664 0000000 0000000 00000003142 12275675654 0026404 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "ClangUtils.h"
#include "standard.h"
namespace YouCompleteMe {
std::string CXStringToString( CXString text ) {
std::string final_string;
if ( !text.data )
return final_string;
final_string = std::string( clang_getCString( text ) );
clang_disposeString( text );
return final_string;
}
bool CursorIsValid( CXCursor cursor ) {
return !clang_Cursor_isNull( cursor ) &&
!clang_isInvalid( clang_getCursorKind( cursor ) );
}
bool CursorIsReference( CXCursor cursor ) {
return clang_isReference( clang_getCursorKind( cursor ) );
}
bool CursorIsDeclaration( CXCursor cursor ) {
return clang_isDeclaration( clang_getCursorKind( cursor ) );
}
std::string CXFileToFilepath( CXFile file ) {
return CXStringToString( clang_getFileName( file ) );
}
std::string ClangVersion() {
return CXStringToString( clang_getClangVersion() );
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/ClangUtils.h 0000664 0000000 0000000 00000002273 12275675654 0026055 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef CLANGUTILS_H_9MVHQLJS
#define CLANGUTILS_H_9MVHQLJS
#include
#include
namespace YouCompleteMe {
std::string CXStringToString( CXString text );
bool CursorIsValid( CXCursor cursor );
bool CursorIsReference( CXCursor cursor );
bool CursorIsDeclaration( CXCursor cursor );
std::string CXFileToFilepath( CXFile file );
std::string ClangVersion();
} // namespace YouCompleteMe
#endif /* end of include guard: CLANGUTILS_H_9MVHQLJS */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/CompilationDatabase.cpp 0000664 0000000 0000000 00000006144 12275675654 0030247 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "CompilationDatabase.h"
#include "ClangUtils.h"
#include "standard.h"
#include "ReleaseGil.h"
#include
#include
#include
#include
using boost::lock_guard;
using boost::unique_lock;
using boost::try_to_lock_t;
using boost::remove_pointer;
using boost::shared_ptr;
using boost::mutex;
namespace YouCompleteMe {
typedef shared_ptr <
remove_pointer< CXCompileCommands >::type > CompileCommandsWrap;
CompilationDatabase::CompilationDatabase(
const std::string &path_to_directory )
: is_loaded_( false ) {
CXCompilationDatabase_Error status;
compilation_database_ = clang_CompilationDatabase_fromDirectory(
path_to_directory.c_str(),
&status );
is_loaded_ = status == CXCompilationDatabase_NoError;
}
CompilationDatabase::~CompilationDatabase() {
clang_CompilationDatabase_dispose( compilation_database_ );
}
bool CompilationDatabase::DatabaseSuccessfullyLoaded() {
return is_loaded_;
}
bool CompilationDatabase::AlreadyGettingFlags() {
unique_lock< mutex > lock( compilation_database_mutex_, try_to_lock_t() );
return !lock.owns_lock();
}
CompilationInfoForFile CompilationDatabase::GetCompilationInfoForFile(
const std::string &path_to_file ) {
ReleaseGil unlock;
CompilationInfoForFile info;
if ( !is_loaded_ )
return info;
lock_guard< mutex > lock( compilation_database_mutex_ );
CompileCommandsWrap commands(
clang_CompilationDatabase_getCompileCommands(
compilation_database_,
path_to_file.c_str() ), clang_CompileCommands_dispose );
uint num_commands = clang_CompileCommands_getSize( commands.get() );
if ( num_commands < 1 ) {
return info;
}
// We always pick the first command offered
CXCompileCommand command = clang_CompileCommands_getCommand(
commands.get(),
0 );
info.compiler_working_dir_ = CXStringToString(
clang_CompileCommand_getDirectory( command ) );
uint num_flags = clang_CompileCommand_getNumArgs( command );
info.compiler_flags_.reserve( num_flags );
for ( uint i = 0; i < num_flags; ++i ) {
info.compiler_flags_.push_back(
CXStringToString( clang_CompileCommand_getArg( command, i ) ) );
}
return info;
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/CompilationDatabase.h 0000664 0000000 0000000 00000003725 12275675654 0027716 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef COMPILATIONDATABASE_H_ZT7MQXPG
#define COMPILATIONDATABASE_H_ZT7MQXPG
#include
#include
#include
#include
#include
#include
namespace YouCompleteMe {
struct CompilationInfoForFile {
std::vector< std::string > compiler_flags_;
std::string compiler_working_dir_;
};
// Access to Clang's internal CompilationDatabase. This class is thread-safe.
class CompilationDatabase : boost::noncopyable {
public:
CompilationDatabase( const std::string &path_to_directory );
~CompilationDatabase();
bool DatabaseSuccessfullyLoaded();
// Returns true when a separate thread is already getting flags; this is
// useful so that the caller doesn't need to block.
bool AlreadyGettingFlags();
// NOTE: Multiple calls to this function from separate threads will be
// serialized since Clang internals are not thread-safe.
CompilationInfoForFile GetCompilationInfoForFile(
const std::string &path_to_file );
private:
bool is_loaded_;
CXCompilationDatabase compilation_database_;
boost::mutex compilation_database_mutex_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: COMPILATIONDATABASE_H_ZT7MQXPG */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/CompletionData.cpp 0000664 0000000 0000000 00000016140 12275675654 0027244 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "CompletionData.h"
#include "ClangUtils.h"
#include
#include
namespace {
char CursorKindToVimKind( CXCursorKind kind ) {
switch ( kind ) {
case CXCursor_StructDecl:
return 's';
case CXCursor_ClassDecl:
case CXCursor_ClassTemplate:
return 'c';
case CXCursor_EnumDecl:
return 'e';
case CXCursor_UnexposedDecl:
case CXCursor_UnionDecl:
case CXCursor_TypedefDecl:
return 't';
case CXCursor_FieldDecl:
return 'm';
case CXCursor_FunctionDecl:
case CXCursor_CXXMethod:
case CXCursor_FunctionTemplate:
case CXCursor_ConversionFunction:
case CXCursor_Constructor:
case CXCursor_Destructor:
return 'f';
case CXCursor_VarDecl:
return 'v';
case CXCursor_MacroDefinition:
return 'd';
case CXCursor_ParmDecl:
return 'p';
case CXCursor_Namespace:
case CXCursor_NamespaceAlias:
return 'n';
default:
return 'u'; // for 'unknown', 'unsupported'... whatever you like
}
}
bool IsMainCompletionTextInfo( CXCompletionChunkKind kind ) {
return
kind == CXCompletionChunk_Optional ||
kind == CXCompletionChunk_TypedText ||
kind == CXCompletionChunk_Placeholder ||
kind == CXCompletionChunk_LeftParen ||
kind == CXCompletionChunk_RightParen ||
kind == CXCompletionChunk_RightBracket ||
kind == CXCompletionChunk_LeftBracket ||
kind == CXCompletionChunk_LeftBrace ||
kind == CXCompletionChunk_RightBrace ||
kind == CXCompletionChunk_RightAngle ||
kind == CXCompletionChunk_LeftAngle ||
kind == CXCompletionChunk_Comma ||
kind == CXCompletionChunk_Colon ||
kind == CXCompletionChunk_SemiColon ||
kind == CXCompletionChunk_Equal ||
kind == CXCompletionChunk_Informative ||
kind == CXCompletionChunk_HorizontalSpace;
}
std::string ChunkToString( CXCompletionString completion_string,
uint chunk_num ) {
if ( !completion_string )
return std::string();
return YouCompleteMe::CXStringToString(
clang_getCompletionChunkText( completion_string, chunk_num ) );
}
std::string OptionalChunkToString( CXCompletionString completion_string,
uint chunk_num ) {
std::string final_string;
if ( !completion_string )
return final_string;
CXCompletionString optional_completion_string =
clang_getCompletionChunkCompletionString( completion_string, chunk_num );
if ( !optional_completion_string )
return final_string;
uint optional_num_chunks = clang_getNumCompletionChunks(
optional_completion_string );
for ( uint j = 0; j < optional_num_chunks; ++j ) {
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
optional_completion_string, j );
if ( kind == CXCompletionChunk_Optional ) {
final_string.append( OptionalChunkToString( optional_completion_string,
j ) );
}
else {
final_string.append( ChunkToString( optional_completion_string, j ) );
}
}
return final_string;
}
// NOTE: this function accepts the text param by value on purpose; it internally
// needs a copy before processing the text so the copy might as well be made on
// the parameter BUT if this code is compiled in C++11 mode a move constructor
// can be called on the passed-in value. This is not possible if we accept the
// param by const ref.
std::string RemoveTwoConsecutiveUnderscores( std::string text ) {
boost::erase_all( text, "__" );
return text;
}
} // unnamed namespace
namespace YouCompleteMe {
CompletionData::CompletionData( const CXCompletionResult &completion_result ) {
CXCompletionString completion_string = completion_result.CompletionString;
if ( !completion_string )
return;
uint num_chunks = clang_getNumCompletionChunks( completion_string );
bool saw_left_paren = false;
bool saw_function_params = false;
for ( uint j = 0; j < num_chunks; ++j ) {
ExtractDataFromChunk( completion_string,
j,
saw_left_paren,
saw_function_params );
}
kind_ = CursorKindToVimKind( completion_result.CursorKind );
// We remove any two consecutive underscores from the function definition
// since identifiers with them are ugly, compiler-reserved names. Functions
// from the standard library use parameter names like "__pos" and we want to
// show them as just "pos". This will never interfere with client code since
// ANY C++ identifier with two consecutive underscores in it is
// compiler-reserved.
everything_except_return_type_ =
RemoveTwoConsecutiveUnderscores(
boost::move( everything_except_return_type_ ) );
detailed_info_.append( return_type_ )
.append( " " )
.append( everything_except_return_type_ )
.append( "\n" );
}
void CompletionData::ExtractDataFromChunk( CXCompletionString completion_string,
uint chunk_num,
bool &saw_left_paren,
bool &saw_function_params ) {
CXCompletionChunkKind kind = clang_getCompletionChunkKind(
completion_string, chunk_num );
if ( IsMainCompletionTextInfo( kind ) ) {
if ( kind == CXCompletionChunk_LeftParen ) {
saw_left_paren = true;
}
else if ( saw_left_paren &&
!saw_function_params &&
kind != CXCompletionChunk_RightParen &&
kind != CXCompletionChunk_Informative ) {
saw_function_params = true;
everything_except_return_type_.append( " " );
}
else if ( saw_function_params && kind == CXCompletionChunk_RightParen ) {
everything_except_return_type_.append( " " );
}
if ( kind == CXCompletionChunk_Optional ) {
everything_except_return_type_.append(
OptionalChunkToString( completion_string, chunk_num ) );
}
else {
everything_except_return_type_.append(
ChunkToString( completion_string, chunk_num ) );
}
}
if ( kind == CXCompletionChunk_ResultType )
return_type_ = ChunkToString( completion_string, chunk_num );
if ( kind == CXCompletionChunk_TypedText )
original_string_ = ChunkToString( completion_string, chunk_num );
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/CompletionData.h 0000664 0000000 0000000 00000007726 12275675654 0026723 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef COMPLETIONDATA_H_2JCTF1NU
#define COMPLETIONDATA_H_2JCTF1NU
#include "standard.h"
#include
#include
namespace YouCompleteMe {
// This class holds pieces of information about a single completion coming from
// clang. These pieces are shown in Vim's UI in different ways.
//
// Normally, the completion menu looks like this (without square brackets):
//
// [main completion text] [kind] [extra menu info]
// [main completion text] [kind] [extra menu info]
// [main completion text] [kind] [extra menu info]
// ... (etc.) ...
//
// The user can also enable a "preview" window that will show extra information
// about a completion at the top of the buffer.
struct CompletionData {
CompletionData() {}
CompletionData( const CXCompletionResult &completion_result );
// What should actually be inserted into the buffer. For a function like
// "int foo(int x)", this is just "foo". Same for a data member like "foo_":
// we insert just "foo_".
std::string TextToInsertInBuffer() {
return original_string_;
}
// Currently, here we show the full function signature (without the return
// type) if the current completion is a function or just the raw TypedText if
// the completion is, say, a data member. So for a function like "int foo(int
// x)", this would be "foo(int x)". For a data member like "count_", it would
// be just "count_".
std::string MainCompletionText() {
return everything_except_return_type_;
}
// This is extra info shown in the pop-up completion menu, after the
// completion text and the kind. Currently we put the return type of the
// function here, if any.
std::string ExtraMenuInfo() {
return return_type_;
}
// This is used to show extra information in vim's preview window. This is the
// window that vim usually shows at the top of the buffer. This should be used
// for extra information about the completion.
std::string DetailedInfoForPreviewWindow() {
return detailed_info_;
}
bool operator== ( const CompletionData &other ) const {
return
kind_ == other.kind_ &&
everything_except_return_type_ == other.everything_except_return_type_ &&
return_type_ == other.return_type_ &&
original_string_ == other.original_string_;
// detailed_info_ doesn't matter
}
std::string detailed_info_;
std::string return_type_;
// Vim's completion string "kind"
// 'v' -> variable
// 'f' -> function or method
// 'm' -> member of struct/class (data member)
// 't' -> typedef (but we're going to use it for types in general)
// 'd' -> #define or macro
char kind_;
// The original, raw completion string. For a function like "int foo(int x)",
// the original string is "foo". For a member data variable like "foo_", this
// is just "foo_". This corresponds to clang's TypedText chunk of the
// completion string.
std::string original_string_;
std::string everything_except_return_type_;
private:
void ExtractDataFromChunk( CXCompletionString completion_string,
uint chunk_num,
bool &saw_left_paren,
bool &saw_function_params );
};
} // namespace YouCompleteMe
#endif /* end of include guard: COMPLETIONDATA_H_2JCTF1NU */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/Diagnostic.h 0000664 0000000 0000000 00000002651 12275675654 0026074 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef DIAGNOSTIC_H_BZH3BWIZ
#define DIAGNOSTIC_H_BZH3BWIZ
#include "standard.h"
#include "Range.h"
#include "Location.h"
#include
#include
namespace YouCompleteMe {
struct Diagnostic {
bool operator== ( const Diagnostic &other ) const {
return
location_ == other.location_ &&
kind_ == other.kind_ &&
text_ == other.text_;
}
Location location_;
Range location_extent_;
std::vector< Range > ranges_;
// Vim's error "kind"
// 'I' -> informational
// 'W' -> warning
// 'E' -> error
char kind_;
std::string text_;
std::string long_formatted_text_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: DIAGNOSTIC_H_BZH3BWIZ */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/Location.h 0000664 0000000 0000000 00000003740 12275675654 0025560 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef LOCATION_H_6TLFQH4I
#define LOCATION_H_6TLFQH4I
#include "standard.h"
#include "ClangUtils.h"
#include
#include
namespace YouCompleteMe {
struct Location {
// Creates an invalid location
Location()
: line_number_( 0 ),
column_number_( 0 ),
filename_( "" ) {}
Location( const std::string &filename, uint line, uint column )
: line_number_( line ),
column_number_( column ),
filename_( filename ) {}
Location( const CXSourceLocation &location ) {
CXFile file;
uint unused_offset;
clang_getExpansionLocation( location,
&file,
&line_number_,
&column_number_,
&unused_offset );
filename_ = CXFileToFilepath( file );
}
bool operator== ( const Location &other ) const {
return
line_number_ == other.line_number_ &&
column_number_ == other.column_number_ &&
filename_ == other.filename_;
}
bool IsValid() {
return !filename_.empty();
}
uint line_number_;
uint column_number_;
// The full, absolute path
std::string filename_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: LOCATION_H_6TLFQH4I */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/Range.cpp 0000664 0000000 0000000 00000001725 12275675654 0025400 0 ustar 00root root 0000000 0000000 // Copyright (C) 2013 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "Range.h"
#include "ClangUtils.h"
namespace YouCompleteMe {
Range::Range( const CXSourceRange &range ) {
start_ = Location( clang_getRangeStart( range ) );
end_ = Location( clang_getRangeEnd( range ) );
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/Range.h 0000664 0000000 0000000 00000002453 12275675654 0025044 0 ustar 00root root 0000000 0000000 // Copyright (C) 2013 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef RANGE_H_4MFTIGQK
#define RANGE_H_4MFTIGQK
#include "standard.h"
#include "Location.h"
namespace YouCompleteMe {
// Half-open, [start, end>
struct Range {
Range() {}
Range( const Location &start_location, const Location &end_location )
: start_( start_location ), end_( end_location ) {}
Range( const CXSourceRange &range );
bool operator== ( const Range &other ) const {
return
start_ == other.start_ &&
end_ == other.end_;
}
Location start_;
Location end_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: RANGE_H_4MFTIGQK */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/TranslationUnit.cpp 0000664 0000000 0000000 00000022616 12275675654 0027504 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "TranslationUnit.h"
#include "CompletionData.h"
#include "standard.h"
#include "exceptions.h"
#include "ClangUtils.h"
#include "ClangHelpers.h"
#include
#include
using boost::unique_lock;
using boost::mutex;
using boost::try_to_lock_t;
using boost::shared_ptr;
using boost::remove_pointer;
namespace YouCompleteMe {
typedef shared_ptr <
remove_pointer< CXCodeCompleteResults >::type > CodeCompleteResultsWrap;
TranslationUnit::TranslationUnit()
: filename_( "" ),
clang_translation_unit_( NULL ) {
}
TranslationUnit::TranslationUnit(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
CXIndex clang_index )
: filename_( filename ),
clang_translation_unit_( NULL ) {
std::vector< const char * > pointer_flags;
pointer_flags.reserve( flags.size() );
foreach ( const std::string & flag, flags ) {
pointer_flags.push_back( flag.c_str() );
}
std::vector< CXUnsavedFile > cxunsaved_files =
ToCXUnsavedFiles( unsaved_files );
const CXUnsavedFile *unsaved = cxunsaved_files.size() > 0
? &cxunsaved_files[ 0 ] : NULL;
clang_translation_unit_ = clang_parseTranslationUnit(
clang_index,
filename.c_str(),
&pointer_flags[ 0 ],
pointer_flags.size(),
const_cast( unsaved ),
cxunsaved_files.size(),
clang_defaultEditingTranslationUnitOptions() );
if ( !clang_translation_unit_ )
boost_throw( ClangParseError() );
// Only with a reparse is the preable precompiled. I do not know why...
// TODO: report this bug on the clang tracker
Reparse( cxunsaved_files );
}
TranslationUnit::~TranslationUnit() {
Destroy();
}
void TranslationUnit::Destroy() {
unique_lock< mutex > lock( clang_access_mutex_ );
if ( clang_translation_unit_ ) {
clang_disposeTranslationUnit( clang_translation_unit_ );
clang_translation_unit_ = NULL;
}
}
std::vector< Diagnostic > TranslationUnit::LatestDiagnostics() {
if ( !clang_translation_unit_ )
return std::vector< Diagnostic >();
unique_lock< mutex > lock( diagnostics_mutex_ );
return latest_diagnostics_;
}
bool TranslationUnit::IsCurrentlyUpdating() const {
// We return true when the TU is invalid; an invalid TU also acts a sentinel,
// preventing other threads from trying to use it.
if ( !clang_translation_unit_ )
return true;
unique_lock< mutex > lock( clang_access_mutex_, try_to_lock_t() );
return !lock.owns_lock();
}
std::vector< Diagnostic > TranslationUnit::Reparse(
const std::vector< UnsavedFile > &unsaved_files ) {
std::vector< CXUnsavedFile > cxunsaved_files =
ToCXUnsavedFiles( unsaved_files );
Reparse( cxunsaved_files );
unique_lock< mutex > lock( diagnostics_mutex_ );
return latest_diagnostics_;
}
void TranslationUnit::ReparseForIndexing(
const std::vector< UnsavedFile > &unsaved_files ) {
std::vector< CXUnsavedFile > cxunsaved_files =
ToCXUnsavedFiles( unsaved_files );
Reparse( cxunsaved_files,
CXTranslationUnit_PrecompiledPreamble |
CXTranslationUnit_SkipFunctionBodies );
}
std::vector< CompletionData > TranslationUnit::CandidatesForLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files ) {
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return std::vector< CompletionData >();
std::vector< CXUnsavedFile > cxunsaved_files =
ToCXUnsavedFiles( unsaved_files );
const CXUnsavedFile *unsaved = cxunsaved_files.size() > 0
? &cxunsaved_files[ 0 ] : NULL;
// codeCompleteAt reparses the TU if the underlying source file has changed on
// disk since the last time the TU was updated and there are no unsaved files.
// If there are unsaved files, then codeCompleteAt will parse the in-memory
// file contents we are giving it. In short, it is NEVER a good idea to call
// clang_reparseTranslationUnit right before a call to clang_codeCompleteAt.
// This only makes clang reparse the whole file TWICE, which has a huge impact
// on latency. At the time of writing, it seems that most users of libclang
// in the open-source world don't realize this (I checked). Some don't even
// call reparse*, but parse* which is even less efficient.
CodeCompleteResultsWrap results(
clang_codeCompleteAt( clang_translation_unit_,
filename_.c_str(),
line,
column,
const_cast( unsaved ),
cxunsaved_files.size(),
clang_defaultCodeCompleteOptions() ),
clang_disposeCodeCompleteResults );
std::vector< CompletionData > candidates = ToCompletionDataVector(
results.get() );
return candidates;
}
Location TranslationUnit::GetDeclarationLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files ) {
ReparseForIndexing( unsaved_files );
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return Location();
CXCursor cursor = GetCursor( line, column );
if ( !CursorIsValid( cursor ) )
return Location();
CXCursor referenced_cursor = clang_getCursorReferenced( cursor );
if ( !CursorIsValid( referenced_cursor ) )
return Location();
return Location( clang_getCursorLocation( referenced_cursor ) );
}
Location TranslationUnit::GetDefinitionLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files ) {
ReparseForIndexing( unsaved_files );
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return Location();
CXCursor cursor = GetCursor( line, column );
if ( !CursorIsValid( cursor ) )
return Location();
CXCursor definition_cursor = clang_getCursorDefinition( cursor );
if ( !CursorIsValid( definition_cursor ) )
return Location();
return Location( clang_getCursorLocation( definition_cursor ) );
}
// Argument taken as non-const ref because we need to be able to pass a
// non-const pointer to clang. This function (and clang too) will not modify the
// param though.
void TranslationUnit::Reparse(
std::vector< CXUnsavedFile > &unsaved_files ) {
Reparse( unsaved_files, clang_defaultEditingTranslationUnitOptions() );
}
// Argument taken as non-const ref because we need to be able to pass a
// non-const pointer to clang. This function (and clang too) will not modify the
// param though.
void TranslationUnit::Reparse( std::vector< CXUnsavedFile > &unsaved_files,
uint parse_options ) {
int failure = 0;
{
unique_lock< mutex > lock( clang_access_mutex_ );
if ( !clang_translation_unit_ )
return;
CXUnsavedFile *unsaved = unsaved_files.size() > 0
? &unsaved_files[ 0 ] : NULL;
failure = clang_reparseTranslationUnit( clang_translation_unit_,
unsaved_files.size(),
unsaved,
parse_options );
}
if ( failure ) {
Destroy();
boost_throw( ClangParseError() );
}
UpdateLatestDiagnostics();
}
void TranslationUnit::UpdateLatestDiagnostics() {
unique_lock< mutex > lock1( clang_access_mutex_ );
unique_lock< mutex > lock2( diagnostics_mutex_ );
latest_diagnostics_.clear();
uint num_diagnostics = clang_getNumDiagnostics( clang_translation_unit_ );
latest_diagnostics_.reserve( num_diagnostics );
for ( uint i = 0; i < num_diagnostics; ++i ) {
Diagnostic diagnostic =
BuildDiagnostic(
DiagnosticWrap( clang_getDiagnostic( clang_translation_unit_, i ),
clang_disposeDiagnostic ),
clang_translation_unit_ );
if ( diagnostic.kind_ != 'I' )
latest_diagnostics_.push_back( diagnostic );
}
}
CXCursor TranslationUnit::GetCursor( int line, int column ) {
// ASSUMES A LOCK IS ALREADY HELD ON clang_access_mutex_!
if ( !clang_translation_unit_ )
return clang_getNullCursor();
CXFile file = clang_getFile( clang_translation_unit_, filename_.c_str() );
CXSourceLocation source_location = clang_getLocation(
clang_translation_unit_,
file,
line,
column );
return clang_getCursor( clang_translation_unit_, source_location );
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/TranslationUnit.h 0000664 0000000 0000000 00000005550 12275675654 0027147 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef TRANSLATIONUNIT_H_XQ7I6SVA
#define TRANSLATIONUNIT_H_XQ7I6SVA
#include "UnsavedFile.h"
#include "Diagnostic.h"
#include "Location.h"
#include
#include
#include
#include
#include
namespace YouCompleteMe {
struct CompletionData;
typedef boost::shared_ptr< std::vector< CompletionData > > AsyncCompletions;
class TranslationUnit : boost::noncopyable {
public:
// This constructor creates an invalid, sentinel TU. All of it's methods
// return empty vectors, and IsCurrentlyUpdating always returns true so that
// no callers try to rely on the invalid TU.
TranslationUnit();
TranslationUnit(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
CXIndex clang_index );
~TranslationUnit();
void Destroy();
std::vector< Diagnostic > LatestDiagnostics();
bool IsCurrentlyUpdating() const;
std::vector< Diagnostic > Reparse(
const std::vector< UnsavedFile > &unsaved_files );
void ReparseForIndexing( const std::vector< UnsavedFile > &unsaved_files );
std::vector< CompletionData > CandidatesForLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files );
Location GetDeclarationLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files );
Location GetDefinitionLocation(
int line,
int column,
const std::vector< UnsavedFile > &unsaved_files );
private:
void Reparse( std::vector< CXUnsavedFile > &unsaved_files );
void Reparse( std::vector< CXUnsavedFile > &unsaved_files,
uint parse_options );
void UpdateLatestDiagnostics();
CXCursor GetCursor( int line, int column );
/////////////////////////////
// PRIVATE MEMBER VARIABLES
/////////////////////////////
std::string filename_;
boost::mutex diagnostics_mutex_;
std::vector< Diagnostic > latest_diagnostics_;
mutable boost::mutex clang_access_mutex_;
CXTranslationUnit clang_translation_unit_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: TRANSLATIONUNIT_H_XQ7I6SVA */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/TranslationUnitStore.cpp 0000664 0000000 0000000 00000010436 12275675654 0030516 0 ustar 00root root 0000000 0000000 // Copyright (C) 2013 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "TranslationUnitStore.h"
#include "TranslationUnit.h"
#include "Utils.h"
#include "exceptions.h"
#include
#include
#include
using boost::lock_guard;
using boost::shared_ptr;
using boost::make_shared;
using boost::mutex;
namespace YouCompleteMe {
namespace {
std::size_t HashForFlags( const std::vector< std::string > &flags ) {
return boost::hash< std::vector< std::string > >()( flags );
}
} // unnamed namespace
TranslationUnitStore::TranslationUnitStore( CXIndex clang_index )
: clang_index_( clang_index ) {
}
TranslationUnitStore::~TranslationUnitStore() {
RemoveAll();
}
shared_ptr< TranslationUnit > TranslationUnitStore::GetOrCreate(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags ) {
bool dont_care;
return GetOrCreate( filename, unsaved_files, flags, dont_care );
}
shared_ptr< TranslationUnit > TranslationUnitStore::GetOrCreate(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool &translation_unit_created ) {
translation_unit_created = false;
{
lock_guard< mutex > lock( filename_to_translation_unit_and_flags_mutex_ );
shared_ptr< TranslationUnit > current_unit = GetNoLock( filename );
if ( current_unit &&
HashForFlags( flags ) == filename_to_flags_hash_[ filename ] ) {
return current_unit;
}
// We create and store an invalid, sentinel TU so that other threads don't
// try to create a TU for the same file while we are trying to create this
// TU object. When we are done creating the TU, we will overwrite this value
// with the valid object.
filename_to_translation_unit_[ filename ] =
make_shared< TranslationUnit >();
// We need to store the flags for the sentinel TU so that other threads end
// up returning the sentinel TU while the real one is being created.
filename_to_flags_hash_[ filename ] = HashForFlags( flags );
}
boost::shared_ptr< TranslationUnit > unit;
try {
unit = boost::make_shared< TranslationUnit >( filename,
unsaved_files,
flags,
clang_index_ );
} catch ( ClangParseError & ) {
Remove( filename );
return unit;
}
{
lock_guard< mutex > lock( filename_to_translation_unit_and_flags_mutex_ );
filename_to_translation_unit_[ filename ] = unit;
// Flags have already been stored.
}
translation_unit_created = true;
return unit;
}
shared_ptr< TranslationUnit > TranslationUnitStore::Get(
const std::string &filename ) {
lock_guard< mutex > lock( filename_to_translation_unit_and_flags_mutex_ );
return GetNoLock( filename );
}
bool TranslationUnitStore::Remove( const std::string &filename ) {
lock_guard< mutex > lock( filename_to_translation_unit_and_flags_mutex_ );
Erase( filename_to_flags_hash_, filename );
return Erase( filename_to_translation_unit_, filename );
}
void TranslationUnitStore::RemoveAll() {
lock_guard< mutex > lock( filename_to_translation_unit_and_flags_mutex_ );
filename_to_translation_unit_.clear();
filename_to_flags_hash_.clear();
}
shared_ptr< TranslationUnit > TranslationUnitStore::GetNoLock(
const std::string &filename ) {
return FindWithDefault( filename_to_translation_unit_,
filename,
shared_ptr< TranslationUnit >() );
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/TranslationUnitStore.h 0000664 0000000 0000000 00000005440 12275675654 0030162 0 ustar 00root root 0000000 0000000 // Copyright (C) 2013 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef TRANSLATIONUNITSTORE_H_NGN0MCKB
#define TRANSLATIONUNITSTORE_H_NGN0MCKB
#include "TranslationUnit.h"
#include "UnsavedFile.h"
#include
#include
#include
#include
#include
#include
typedef void *CXIndex;
namespace YouCompleteMe {
class TranslationUnitStore : boost::noncopyable {
public:
TranslationUnitStore( CXIndex clang_index );
~TranslationUnitStore();
// You can even call this function for the same filename from multiple
// threads; the TU store will ensure only one TU is created.
boost::shared_ptr< TranslationUnit > GetOrCreate(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags );
boost::shared_ptr< TranslationUnit > GetOrCreate(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
const std::vector< std::string > &flags,
bool &translation_unit_created );
// Careful here! While GetOrCreate makes sure to take into account the flags
// for the file before returning a stored TU (if the flags changed, the TU is
// not really valid anymore and a new one should be built), this function does
// not. You might end up getting a stale TU.
boost::shared_ptr< TranslationUnit > Get( const std::string &filename );
bool Remove( const std::string &filename );
void RemoveAll();
private:
// WARNING: This accesses filename_to_translation_unit_ without a lock!
boost::shared_ptr< TranslationUnit > GetNoLock( const std::string &filename );
typedef boost::unordered_map < std::string,
boost::shared_ptr< TranslationUnit > > TranslationUnitForFilename;
typedef boost::unordered_map < std::string,
std::size_t > FlagsHashForFilename;
CXIndex clang_index_;
TranslationUnitForFilename filename_to_translation_unit_;
FlagsHashForFilename filename_to_flags_hash_;
boost::mutex filename_to_translation_unit_and_flags_mutex_;
};
} // namespace YouCompleteMe
#endif // TRANSLATIONUNITSTORE_H_NGN0MCKB
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/ClangCompleter/UnsavedFile.h 0000664 0000000 0000000 00000002735 12275675654 0026220 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef UNSAVEDFILE_H_0GIYZQL4
#define UNSAVEDFILE_H_0GIYZQL4
#include
struct UnsavedFile {
UnsavedFile() : filename_( "" ), contents_( "" ), length_( 0 ) {}
std::string filename_;
std::string contents_;
unsigned long length_;
// We need this to be able to export this struct to Python via Boost.Python's
// methods. I have no clue why, but it won't compile without it.
// TODO: report this problem on the Boost bug tracker, the default equality
// operator should be more than adequate here
bool operator== ( const UnsavedFile &other ) const {
return
filename_ == other.filename_ &&
contents_ == other.contents_ &&
length_ == other.length_;
}
};
#endif /* end of include guard: UNSAVEDFILE_H_0GIYZQL4 */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/CustomAssert.cpp 0000664 0000000 0000000 00000006002 12275675654 0024072 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2008, Power of Two Games LLC
* 2013, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Power of Two Games LLC nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY POWER OF TWO GAMES LLC ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL POWER OF TWO GAMES LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "CustomAssert.h"
#include
#include
namespace assert_ns
{
namespace
{
Assert::FailBehavior DefaultHandler(const char* condition,
const char* msg,
const char* file,
const int line)
{
std::printf("%s(%d): Assert Failure: ", file, line);
if (condition != NULL)
std::printf("'%s' ", condition);
if (msg != NULL)
std::printf("%s", msg);
std::printf("\n");
return Assert::Halt;
}
Assert::Handler& GetAssertHandlerInstance()
{
static Assert::Handler s_handler = &DefaultHandler;
return s_handler;
}
}
Assert::Handler Assert::GetHandler()
{
return GetAssertHandlerInstance();
}
void Assert::SetHandler(Assert::Handler newHandler)
{
GetAssertHandlerInstance() = newHandler;
}
Assert::FailBehavior Assert::ReportFailure(const char* condition,
const char* file,
const int line,
const char* msg, ...)
{
const char* message = NULL;
if (msg != NULL)
{
char messageBuffer[1024];
{
va_list args;
va_start(args, msg);
#if defined(_MSC_VER)
vsnprintf_s(messageBuffer, 1024, 1024, msg, args);
#else
vsnprintf(messageBuffer, 1024, msg, args);
#endif
va_end(args);
}
message = messageBuffer;
}
return GetAssertHandlerInstance()(condition, message, file, line);
}
}
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/CustomAssert.h 0000664 0000000 0000000 00000007226 12275675654 0023550 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2008, Power of Two Games LLC
* 2013, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Power of Two Games LLC nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY POWER OF TWO GAMES LLC ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL POWER OF TWO GAMES LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CUSTOM_ASSERT_H
#define CUSTOM_ASSERT_H
namespace assert_ns { namespace Assert
{
enum FailBehavior
{
Halt,
Continue,
};
typedef FailBehavior (*Handler)(const char* condition,
const char* msg,
const char* file,
int line);
Handler GetHandler();
void SetHandler(Handler newHandler);
FailBehavior ReportFailure(const char* condition,
const char* file,
int line,
const char* msg, ...);
}}
#if defined(_MSC_VER)
# define X_HALT() __debugbreak()
#elif defined(__GNUC__) || defined(__clang__)
# define X_HALT() __builtin_trap()
#else
# define X_HALT() exit(__LINE__)
#endif
#define X_UNUSED(x) do { (void)sizeof(x); } while(0)
#ifndef NDEBUG
#define X_ASSERT(cond) \
do \
{ \
if (!(cond)) \
{ \
if (assert_ns::Assert::ReportFailure(#cond, __FILE__, __LINE__, 0) == \
assert_ns::Assert::Halt) \
X_HALT(); \
} \
} while(0)
#define X_ASSERT_MSG(cond, msg, ...) \
do \
{ \
if (!(cond)) \
{ \
if (assert_ns::Assert::ReportFailure(#cond, __FILE__, __LINE__, (msg), __VA_ARGS__) == \
assert_ns::Assert::Halt) \
X_HALT(); \
} \
} while(0)
#define X_ASSERT_FAIL(msg, ...) \
do \
{ \
if (assert_ns::Assert::ReportFailure(0, __FILE__, __LINE__, (msg), __VA_ARGS__) == \
assert_ns::Assert::Halt) \
X_HALT(); \
} while(0)
#define X_VERIFY(cond) X_ASSERT(cond)
#define X_VERIFY_MSG(cond, msg, ...) X_ASSERT_MSG(cond, msg, ##__VA_ARGS__)
#else
#define X_ASSERT(condition) \
do { X_UNUSED(condition); } while(0)
#define X_ASSERT_MSG(condition, msg, ...) \
do { X_UNUSED(condition); X_UNUSED(msg); } while(0)
#define X_ASSERT_FAIL(msg, ...) \
do { X_UNUSED(msg); } while(0)
#define X_VERIFY(cond) (void)(cond)
#define X_VERIFY_MSG(cond, msg, ...) \
do { (void)(cond); X_UNUSED(msg); } while(0)
#endif
#define X_STATIC_ASSERT(x) \
typedef char StaticAssert[(x) ? 1 : -1];
#endif // CUSTOM_ASSERT_H
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/IdentifierCompleter.cpp 0000664 0000000 0000000 00000006334 12275675654 0025403 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "IdentifierCompleter.h"
#include "standard.h"
#include "Candidate.h"
#include "IdentifierUtils.h"
#include "Result.h"
#include "Utils.h"
#include "ReleaseGil.h"
#include
namespace YouCompleteMe {
IdentifierCompleter::IdentifierCompleter() {}
IdentifierCompleter::IdentifierCompleter(
const std::vector< std::string > &candidates ) {
identifier_database_.AddIdentifiers( candidates, "", "" );
}
IdentifierCompleter::IdentifierCompleter(
const std::vector< std::string > &candidates,
const std::string &filetype,
const std::string &filepath ) {
identifier_database_.AddIdentifiers( candidates, filetype, filepath );
}
void IdentifierCompleter::AddIdentifiersToDatabase(
const std::vector< std::string > &new_candidates,
const std::string &filetype,
const std::string &filepath ) {
ReleaseGil unlock;
identifier_database_.AddIdentifiers( new_candidates,
filetype,
filepath );
}
void IdentifierCompleter::AddIdentifiersToDatabaseFromTagFiles(
const std::vector< std::string > &absolute_paths_to_tag_files ) {
ReleaseGil unlock;
foreach( const std::string & path, absolute_paths_to_tag_files ) {
identifier_database_.AddIdentifiers(
ExtractIdentifiersFromTagsFile( path ) );
}
}
void IdentifierCompleter::AddIdentifiersToDatabaseFromBuffer(
const std::string &buffer_contents,
const std::string &filetype,
const std::string &filepath,
bool collect_from_comments_and_strings ) {
ReleaseGil unlock;
identifier_database_.ClearCandidatesStoredForFile( filetype, filepath );
std::string new_contents =
collect_from_comments_and_strings ?
buffer_contents :
RemoveIdentifierFreeText( buffer_contents );
identifier_database_.AddIdentifiers(
ExtractIdentifiersFromText( new_contents ),
filetype,
filepath );
}
std::vector< std::string > IdentifierCompleter::CandidatesForQuery(
const std::string &query ) const {
return CandidatesForQueryAndType( query, "" );
}
std::vector< std::string > IdentifierCompleter::CandidatesForQueryAndType(
const std::string &query,
const std::string &filetype ) const {
ReleaseGil unlock;
std::vector< Result > results;
identifier_database_.ResultsForQueryAndType( query, filetype, results );
std::vector< std::string > candidates;
candidates.reserve( results.size() );
foreach ( const Result & result, results ) {
candidates.push_back( *result.Text() );
}
return candidates;
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/IdentifierCompleter.h 0000664 0000000 0000000 00000004421 12275675654 0025043 0 ustar 00root root 0000000 0000000 // Copyright (C) 2011, 2012 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef COMPLETER_H_7AR4UGXE
#define COMPLETER_H_7AR4UGXE
#include "IdentifierDatabase.h"
#include
#include
#include
#include
#include
#include
namespace YouCompleteMe {
class Candidate;
class IdentifierCompleter : boost::noncopyable {
public:
IdentifierCompleter();
IdentifierCompleter( const std::vector< std::string > &candidates );
IdentifierCompleter( const std::vector< std::string > &candidates,
const std::string &filetype,
const std::string &filepath );
void AddIdentifiersToDatabase(
const std::vector< std::string > &new_candidates,
const std::string &filetype,
const std::string &filepath );
void AddIdentifiersToDatabaseFromTagFiles(
const std::vector< std::string > &absolute_paths_to_tag_files );
void AddIdentifiersToDatabaseFromBuffer(
const std::string &buffer_contents,
const std::string &filetype,
const std::string &filepath,
bool collect_from_comments_and_strings );
// Only provided for tests!
std::vector< std::string > CandidatesForQuery(
const std::string &query ) const;
std::vector< std::string > CandidatesForQueryAndType(
const std::string &query,
const std::string &filetype ) const;
private:
/////////////////////////////
// PRIVATE MEMBER VARIABLES
/////////////////////////////
IdentifierDatabase identifier_database_;
};
} // namespace YouCompleteMe
#endif /* end of include guard: COMPLETER_H_7AR4UGXE */
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/IdentifierDatabase.cpp 0000664 0000000 0000000 00000012056 12275675654 0025153 0 ustar 00root root 0000000 0000000 // Copyright (C) 2013 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#include "IdentifierDatabase.h"
#include "standard.h"
#include "Candidate.h"
#include "CandidateRepository.h"
#include "IdentifierUtils.h"
#include "Result.h"
#include "Utils.h"
#include
#include
#include
#include
using boost::algorithm::any_of;
using boost::algorithm::is_upper;
namespace YouCompleteMe {
IdentifierDatabase::IdentifierDatabase()
: candidate_repository_( CandidateRepository::Instance() ) {
}
void IdentifierDatabase::AddIdentifiers(
const FiletypeIdentifierMap &filetype_identifier_map ) {
boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
foreach ( const FiletypeIdentifierMap::value_type & filetype_and_map,
filetype_identifier_map ) {
foreach( const FilepathToIdentifiers::value_type & filepath_and_identifiers,
filetype_and_map.second ) {
AddIdentifiersNoLock( filepath_and_identifiers.second,
filetype_and_map.first,
filepath_and_identifiers.first );
}
}
}
void IdentifierDatabase::AddIdentifiers(
const std::vector< std::string > &new_candidates,
const std::string &filetype,
const std::string &filepath ) {
boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
AddIdentifiersNoLock( new_candidates, filetype, filepath );
}
void IdentifierDatabase::ClearCandidatesStoredForFile(
const std::string &filetype,
const std::string &filepath ) {
boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
GetCandidateSet( filetype, filepath ).clear();
}
void IdentifierDatabase::ResultsForQueryAndType(
const std::string &query,
const std::string &filetype,
std::vector< Result > &results ) const {
FiletypeCandidateMap::const_iterator it;
{
boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
it = filetype_candidate_map_.find( filetype );
if ( it == filetype_candidate_map_.end() || query.empty() )
return;
}
Bitset query_bitset = LetterBitsetFromString( query );
bool query_has_uppercase_letters = any_of( query, is_upper() );
boost::unordered_set< const Candidate * > seen_candidates;
seen_candidates.reserve( candidate_repository_.NumStoredCandidates() );
{
boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
foreach ( const FilepathToCandidates::value_type & path_and_candidates,
*it->second ) {
foreach ( const Candidate * candidate, *path_and_candidates.second ) {
if ( ContainsKey( seen_candidates, candidate ) )
continue;
else
seen_candidates.insert( candidate );
if ( !candidate->MatchesQueryBitset( query_bitset ) )
continue;
Result result = candidate->QueryMatchResult(
query, query_has_uppercase_letters );
if ( result.IsSubsequence() )
results.push_back( result );
}
}
}
std::sort( results.begin(), results.end() );
}
// WARNING: You need to hold the filetype_candidate_map_mutex_ before calling
// this function and while using the returned set.
std::set< const Candidate * > &IdentifierDatabase::GetCandidateSet(
const std::string &filetype,
const std::string &filepath ) {
boost::shared_ptr< FilepathToCandidates > &path_to_candidates =
filetype_candidate_map_[ filetype ];
if ( !path_to_candidates )
path_to_candidates.reset( new FilepathToCandidates() );
boost::shared_ptr< std::set< const Candidate * > > &candidates =
( *path_to_candidates )[ filepath ];
if ( !candidates )
candidates.reset( new std::set< const Candidate * >() );
return *candidates;
}
// WARNING: You need to hold the filetype_candidate_map_mutex_ before calling
// this function and while using the returned set.
void IdentifierDatabase::AddIdentifiersNoLock(
const std::vector< std::string > &new_candidates,
const std::string &filetype,
const std::string &filepath ) {
std::set< const Candidate *> &candidates =
GetCandidateSet( filetype, filepath );
std::vector< const Candidate * > repository_candidates =
candidate_repository_.GetCandidatesForStrings( new_candidates );
candidates.insert( repository_candidates.begin(),
repository_candidates.end() );
}
} // namespace YouCompleteMe
vim-youcompleteme-0+20140207+git18be5c2/cpp/ycm/IdentifierDatabase.h 0000664 0000000 0000000 00000006362 12275675654 0024623 0 ustar 00root root 0000000 0000000 // Copyright (C) 2013 Google Inc.
//
// This file is part of YouCompleteMe.
//
// YouCompleteMe 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.
//
// YouCompleteMe 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 YouCompleteMe. If not, see .
#ifndef IDENTIFIERDATABASE_H_ZESX3CVR
#define IDENTIFIERDATABASE_H_ZESX3CVR
#include
#include
#include
#include
#include
#include
#include