-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Idea: find classes from composer class map #7
Comments
Thanks for the suggestion. Note that navigation to class/interface/trait source files is already supported by
Yes, this would be useful for various things. Whatever mechanism we use, I do not want to create or modify files in the project's |
Yes, I've tried all features of the plugin! I'm telling about finding (guessing) full class path by class name only with use of class map generated by I can't make a whole PR now because I have no vim programming experience. |
So here is the script: https://gist.github.com/hiqsol/6c60b233816db0db8c324720e46f75dc Run script It just prints found class(es). |
You wrote:
This has the consequence of subsequent changes not being picked up by Composer until it's run again. All I'm saying is that the plug-in should not create/update this file automatically, and the user should not have to run
That's fine. The existing find feature already has a dependency on PHP, and PHP will be much faster than Vim Script anyway.
👍 |
You're right about not forcing user have optimized autoloader moreover it is not recommended in development (while highly recommended in production). I will study how to get class map outside of vendor. |
It seems there is no simple way to make composer dump-autoload to alternative directory. Also I can try to make composer PR for option to only write autoloading files to alternative directory while reading from original but I'm afraid the PR will not be taken. And there is non-composer solution with grep, here is example with ripgrep but any grep can be used: rg --no-heading --type php '^namespace ' . vendor It gives easy processable list of all class names with pathes. |
I've jury rigged almost working solution with ripgrep and fzf, and now I'm stuck and need help with vim. Here is script that prints all classes in the project in format: #!/usr/bin/env php
<?php
$rg = popen("rg --no-heading --type php '^namespace .*;' . vendor", 'r');
while($str = fgets($rg)){
if (preg_match('/^((.*)\.[a-z]+):namespace (.+);.*$/', $str, $ms)) {
$path = $ms[1];
$ns = $ms[3];
$fs = explode('/', $ms[2]);
$name = end($fs);
$class = "$ns\\$name";
printf("%s %s\n", $class, $path);
}
}
pclose($rg); I think it can be optimized but it is already very quick 0.142 seconds on a rather big project. And here is the simple completion script based on function! s:add_namespace(lines)
let s:full = split(join(a:lines), " ")[0]
let s:name = split(s:full, "\\")[-1]
call composer#namespace#use(1, s:full)
return s:name
endfunction
inoremap <expr> <C-]> fzf#complete({
\ 'source': '/home/sol/bin/listGreppedClasses.php',
\ 'reducer': function('<sid>add_namespace'),
\ 'down': 20}) It works the way I imagine ideal usage: I begin typing class name, then I press hotkey, then i find proper class with FZF menu then press enter and I have it - completed short class name and added use statement in the proper place. The script finds class with FZF completion and adds |
Very cool.
Yes, this function (intentionally) moves the cursor to the new execute "normal! \<C-o>" before the |
Now it puts short class name right under the use statement. |
I've tried getpos/setpos, and it gets even worse, it puts short class name in the middle of string two rows up from the initial position :) |
I failed to fix it with saving/restoring cursor position. So I've rewritten Will you take the PR? I wanted to add the But I think it would be better to fix it somehow with saving/restoring cursor position giving working sorting. |
Since this doesn't require PHP, I'd rather rewrite it in Vim Script. If you want to try yourself, look at I would also like to fall back to Feel free to open a pull request even if it isn't perfect. I haven't had a chance to look into the cursor positioning issue yet. I'll see what I can do.
I think it would be cleaner and more flexible to instruct users to add their own FZF mapping, something along the lines of: inoremap <expr> <C-]> fzf#complete({
\ 'source': composer#namespace#classes(),
\ 'reducer': function('composer#namespace#use'),
\ 'down': 20}) That way we don't depend on fzf.vim at all, and users can configure it exactly the way they like. |
If you don't like PHP ;) I also tried classes preparation script in plain shell with sed: #!/bin/sh
rg --no-heading --type php "^namespace .*;" . vendor | sed 's/^\(.*\/\(.*\)\.php\):namespace \(.*\);.*$/\3\\\2 \1/i' But strangely it is slightly slower then PHP. Agree about FZF mapping. About PR: are you ok to change |
I just found this issue. I experimented with this a while ago: master...adriaanzon:use-via-composer-classmap. It uses PHP to filter through the values of |
@adriaanzon Hey, that's pretty clean. I'd still prefer to invert the relationship so that we have a generic |
This plugin could use class map built with
composer dump-autoload -o
to look for class name under cursor and use it for navigation and inserting ofuse
statements.As far as I can see the plugin can't do it now.
Class map is written into file
vendor/composer/autoload_static.php
in $classMap property and holds list of all the classes found in the project like this:There could be classes that are available in several namespaces then plugin could show menu to select which class to proceed with.
Functionality like this is really missing now. There is no working solution for the moment.
Ctags way is not good because tags file is huge (hundreds of megabytes) for big (not huge) projects.
PHP language server is just not stable enough for the moment.
So this could be a killing feature :)
The text was updated successfully, but these errors were encountered: