Closed lauris closed 10 years ago
Truth. This is going to take some work...
Quick fix would be to allow \ in class name. However this does not solve cases when a class is called in current namespace, e.g. namespace app; $class = new controller();
Yeah, it also doesn't solve the situation of raw functions inside a namespace. Namespaces are a pretty big thing to tackle for completion because it's essentially an entirely new container construct that needs to be taken into account to search.
It's pretty necessary to have namespace support; it's good convention, and quickly becoming standard among most big frameworks.
:+1:
@shawncplus I would like to tackle this problem (as well as detecting inheritance) but I don't have any experience; I am planning to just take the plunge and see what I can make of what is already there but if you have the time and patience to offer me some useful information on the subject, I would be greatly appreciative.
My understanding of ctags is that there is no support for PHP namespaces; does that make all this an impossibility (until I write support for it into ctags =P)?
I'm unfamiliar with the namespace support in ctags, if it doesn't have support then yes, it's impossible unless someone updates ctags or write another script that does namespace parsing and writes to a file in the same fiel format as ctags
I've confirmed that ctags lacks support for namespaces in PHP. I'll be back after I fix ctags. Wish me luck. =P
@qstrahl Did you try the patched ctags? Does it generate the correct namespace tags for ctags? I try it with my project, it seems generate namespace information by default (it seems correct, but don't know format is right or not):
Command laravel/vendor/Symfony/Component/Console/Command/Command.php /^class Command$/;" c namespace:Symfony\Component\Console\Command
CommandTester laravel/vendor/Symfony/Component/Console/Tester/CommandTester.php /^class CommandTester$/;" c namespace:Symfony\Component\Console\Tester
@complex857 Is this enough for phpcomplete.vim to implement class namespace? If not, maybe we can discuss with @techlivezheng to implement namespace in phpctags, too.
I compare patched ctags and phpctags, it seems phpctags generate more detail and correct tags information. The only one problem is phpctags is really slow.
I've compiled a new ctags with the patch, running it against a vanilla Symfony with
time ~/ctags-trunk/ctags -R --fields=+aimsS ~/Symfony
took only 0m1.412s
in my system with warm disk caches (this as thinkpad x200 from 2009, with it's original samsung spinning disk).
Generates lines like this:
For classes:
Firewall vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall.php /^class Firewall implements EventSubscriberInterface$/;" c namespace:Symfony\Component\Security\Http inherits:EventSubscriberInterface
For methods:
abs vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr.php /^ public function abs($x)$/;" f class:Doctrine\ORM\Query::Expr access:public signature:($x)
For constants:
CASE_FIRST vendor/symfony/symfony/src/Symfony/Component/Locale/Stub/StubCollator.php /^ const CASE_FIRST = 2;$/;" d class:Symfony\Component\Locale\Stub::StubCollator
For namespaces:
Psr\Log vendor/psr/log/Psr/Log/LoggerAwareTrait.php /^namespace Psr\\Log;$/;" n
For attributes:
addedColumns vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php /^ public $addedColumns;$/;" v class:Doctrine\DBAL\Schema::TableDiff access:public
These look absolutely fantastic, and should be much enough for many namespace related scenarios.
The fact that there are n
kind for namespaces makes straightforward to implement completion for lines like namespace Psr\...
or use \Psr...
.
To make classname contexts like $foo = new ...
or Foo extends ...
or just static invocations (when you start to type the class name and we can't tell if it's going to be a function or constant or anything else without a $
) will have to have some parsing in the current file to get the active namespace (the first line with namesapce ...
or the imported namespaces (lines like use \Foo
or use \Foo as Bar
). As @shawncplus wrote a year ago, it's going to take some work.
Yeah, the new patched PHP module for ctags makes this problem solvable. There's a lot to be done with regard to namespaces for phpcomplete, but I'm pretty sure I can manage it, so if somebody doesn't beat me to it, I'll take a crack at it soon.
I am playing with phpctags, too. I already have namespace in my local branch.
@qstrahl I just add namespace & inherits support(extends and implements) for phpctags and wait for merge. If you want to play with it, you can try my repository https://github.com/markwu/phpctags/tree/test
I have to mention, it is really slow when compare to ctags.
I'll be trying to implement support with the patched ctags, since it's the official solution for Vim. Nice job on using PHP-Parser, though; it won't be easy to get accuracy like that out of a non-native solution.
That's why I follow the patched ctags's format, that can make sure the tags generate by phpctags can used in future version with more precise tags information. :)
I've started to work on namespace support. The first commit landed in the master branch, featuring support for use ...
contexts, completing namespaces and classes from tags with support for built-in class name imports.
To make this feature work properly you will have to have a tags file created with a patched ctags or other tags file generator that extracts namespaces with kind:'n'
and add namespace
field for classes.
I've wrote an installation guide in the wiki. Please test the code and the guide and report any difficulties or anything that could be improved. If someone could volunteer to write a homebrew formula (I don't have a mac) or create binaries for windows, linux that would be nice.
Awesome work! This is a huge step for PHP development in Vim. =)
Added namespace awareness when completing class names after new
and extends
(currently you will have to type out namespace names at this moment).
I've also made GetClassLocation
and GetClassContents
methods aware of namespaces. When completing class names the code will use the g:phpcomplete_min_num_of_chars_for_namespace_completion
option so by default you will have to type out at least one character (not required for built-in classes though).
I myself doesn't use namespaces in my day-to-day work so I encourage everyone to test the functionality and report any bugs or scenarios where the code doesn't work.
Added namespace awareness to the general completion case (this is the case when we don't have anything object related, not specifically looking for a class or namespace name, and not a variable). The completion now will list namespaces and understand when something starts with a \
.
The last main missing puzzle piece is supporting the imported and possibly aliased classes, interfaces, and other namespaces (the use ... as ....
lines).
Pushed support for imported class and namespace names. These imports touch many part of the completion. Support now includes completing renamed class names in various contexts, the plugin understands renamed class names and maps them to their original when completing properties and methods.
With this patch the namespace support is pretty much complete, all the major moving parts are in place. @everyone, please try the code in real life projects and report errors and limitations.
I've realized that GetClassName() was blissfully ignorant about the current namespace, even trough it changes every class name's meaning. Now this have been fixed.
The namespace support is generally implemented in every part of the plugin. I'll close this issue. New issues with errors in detection or namespace handling are always welcome.
It seems that it does not support PHP namespaces.