ycm-core / YouCompleteMe

A code-completion engine for Vim
http://ycm-core.github.io/YouCompleteMe/
GNU General Public License v3.0
25.41k stars 2.8k forks source link

Filepath completion does not update according to changed working dir #1655

Closed mdriu closed 9 years ago

mdriu commented 9 years ago

In my vimrc, I set the variable g:ycm_filepath_completion_use_working_dir=1 in order to enable YCM to complete paths relative to working directory. This works as long as I do not change the pwd. Say, if the pwd of a newly opened vim buffer is /somepath1, YCM correctly interprets paths as relative to /somepath1. As soon as I change pwd to /somepath2 (using :cd /somepath2), YCM continues completing paths as relative to /somepath1. Not sure if this is a bug or a missing feature.

puremourning commented 9 years ago

It looks like paths are relative to the WD of the ycmd instance. I don't think it gets told the WD of the client.

https://github.com/Valloric/ycmd/blob/master/ycmd/completers/general/filename_completer.py#L136-L149

vheon commented 9 years ago

@puremourning then there's something wrong:

From the docs:

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

here we're talking about vim cwd or buffer cwd.

puremourning commented 9 years ago

@vheon hmm yeah. i suspect that should really read "Vim's working directory when Vim was started" :)

I can't see any evidence that the WD is ever passed to YCM. It would be possible, but it would be a change in behaviour which might infuriate users relying on the current behaviour (albeit not conforming to the documented behaviour). Tricky one.

@mdriu what's your use-case here? relative path completions seems naively to me somewhat of a niche case. can you elaborate on it a bit?

puremourning commented 9 years ago

here we're talking about vim cwd or buffer cwd

I can't seem to find info on buffer vs. Vim cwd, but there is certainly window vs. Vim cwd. from :help current-directory:

:cd[!] {path}      Change the current directory to {path}.
:lc[d][!] {path}   Like |:cd|, but only set the current directory for the
                        current window. 

but it basically still changes Vim's working directory. In both cases :!pwd returns the same as :pwd (for me).

mdriu commented 9 years ago

@puremourning a couple of cases that happen to me quite often. 1) Open a file e.g. from a terminal using gvim foo (if foo is in /somepath1, then YCM will complete relatively to /somepath1). Then from that gvim instance open in a tab another file which is somewhere else, using :tabe /somepath2/bar. Hence you will have /somepath1/foo opened in tab 1 and /somepath2/bar opened in tab 2, but YCM completing relatively to /somepath1 in both cases, even if you change WD. 2) Sometimes I simply need filepath completion relative to a path which is not the path where the edited file is, or where I opened the file from: think about editing the file ./figures/a_tikz_fig.tex which has to be included in ./main.tex, the paths in a_tikz_fig.tex must be relative to ./.

I think that it would be nice to have this "WD-adaptive" filepath completion implemented in YCM, don't you?

puremourning commented 9 years ago

Thanks for the info @mdriu.

I'm not against it. Just personally, filename completion relative to the cwd of the editor has never come up for me :)

I think you have a point, and as @vheon points out, this is supposed to be relative to Vim's "current" working directory according to YCM's docs. I don't think it currently behaves that way, and arguably if you've gone to the trouble of changing the default value of g:ycm_filepath_completion_use_working_dir then you probably read the doc section that @vheon is referring to and expect that behaviour.

So I would imagine this is one of those "PR's welcome" scenarios.

It's not completely trivial to solve, but the solution that springs to mind (off the top of my head) is to pass the return of Vim's getcwd() function (or preferably some python equivalent, because vimscript=bad) to the server in the /completions request (yam.client.completion_request.CompletionRequest and ycm.youcompleteme.YouCompleteMe.CreateCompletionRequest), and update the server's ycmd.completers.general.file_name_completer._GetPathsStandardCase to read it.

We'd have to assess the impact of the getcwd() or equivalent call on performance, because this will be called a lot. And the speed of completions is really key to YCM's appeal.

Well anyway having written this, i though i might as well try it.

YCM patch: https://github.com/puremourning/YouCompleteMe/tree/cwd-filetype-completer (https://github.com/puremourning/YouCompleteMe/commit/fa32819d4f273f50f872ed2d525bc842e6798155) ycmd patch: https://github.com/puremourning/ycmd-1/tree/cwd-filetype-completer (https://github.com/puremourning/ycmd-1/commit/deda47ea895e2d89f756415050587caa3e57c2bb)

With g:ycm_filepath_completion_use_working_dir=1 the wd changes when i :cd $HOME: ycm_relative_path

With g:ycm_filepath_completion_use_working_dir=0 it doesn't: ycm_relative_path_broken

Paths starting with / are absolute in both cases.

puremourning commented 9 years ago

Please note: that patch is far from production quality and is only tested as far as those 2 gifs go, so YMMV.

mdriu commented 9 years ago

@puremourning That was fast! Many thanks for the patches, they work also for me. I applied https://github.com/puremourning/YouCompleteMe/commit/fa32819d4f273f50f872ed2d525bc842e6798155 to python/ycm/youcompleteme.py and https://github.com/puremourning/ycmd-1/commit/deda47ea895e2d89f756415050587caa3e57c2bb to third_party/ycmd/ycmd/completers/generalfilename_completer.py, and I get the same behavior as yours, which is the one I expected reading the doc. Moreover, I tested both cases I referred in https://github.com/Valloric/YouCompleteMe/issues/1655#issuecomment-135193617, and I get the expected behavior, i.e., YCM completes filepaths as relative to actual Vim WD.

if you've gone to the trouble of changing the default value of g:ycm_filepath_completion_use_working_dir then you probably read the doc section that @vheon is referring to and expect that behaviour.

Yeah that's actually what happened.

puremourning commented 9 years ago

FYI I have submitted PRs for this change.

mdriu commented 9 years ago

@puremourning That's great thank you very much!

puremourning commented 9 years ago

No problem. Happy to :)

Fixed by above PR.

mdriu commented 9 years ago

@puremourning one last minor comment: atm last version of YCM includes the YCM patch but not the ycmd patch. Future updates to newest ycmd will fix this.

niva-xx-zz commented 6 years ago

Hi,

With this _vimrc configuration

_" {{{ YouCompleteMe

" turn on completion in comments let g:ycm_complete_in_comments=1 " load ycm conf by default let g:ycm_confirm_extra_conf= 1 let g:ycm_global_ycm_extra_conf = expand('$vim').'/awesomeplugins/vim/youcompleteme/.ycm_extra_conf.py' let g:ycm_filepath_completion_use_working_dir = 1 " turn on tag completion let g:ycm_collect_identifiers_from_tags_files=1 " only show completion as a list instead of a sub-window set completeopt-=preview " start completion from the first character let g:ycm_min_num_of_chars_for_completion=1 " don't cache completion items let g:ycm_cache_omnifunc=0 " complete syntax keywords let g:ycm_seed_identifiers_withsyntax=1 " }}}

And with this .ycm_extra_conf.py file that check all subdirectories and ycm_extra_conf.py.txt

I don't have recursive completion for all headers in regards of cpp files. And the GetType command fails for a basic std::string var.

Thank you in advance for help.