xavierd / clang_complete

Vim plugin that use clang for completing C/C++ code.
http://www.vim.org/scripts/script.php?script_id=3302
1.95k stars 308 forks source link

Question: Unable to autocomplete header file names? #550

Closed stefanos82 closed 6 years ago

stefanos82 commented 6 years ago

I have hard time figuring this out for some reason.

I type a few characters and press Enter (I use mucomplete along with clang_complete) but it does not work with header names; the rest functionality works as expected, that is function / class names, variables, constants.

Is there anything I should do?

Please advice, thank you.

xaizek commented 6 years ago

clang_complete simply doesn't provide completion of #include-directives.

stefanos82 commented 6 years ago

OK. Should I close this ticket then?

xaizek commented 6 years ago

I'll close it. By the way, you might look for other plugins that complete headers, although I don't know how well mucomplete+clang_complete+other_plugin will behave in combination.

stefanos82 commented 6 years ago

It's alright. I will figure things out, cheers.

stefanos82 commented 6 years ago

@xaizek is there a particular reason you didn't mention your other plugin, vim-inccomplete, that does exactly what I wanted?

It works brilliantly!

xaizek commented 6 years ago

This one isn't mine, I'm a contributor. There were issues with integrating vim-inccomplete with some plugins and I think other plugins allow for more things (like multiple roots for completion and maybe discovering root of projects) which I didn't implement, so I thought I'd let you look for options and pick whichever works best for you.

stefanos82 commented 6 years ago

It works with system header files but it does not load my local headers, even though I have a .clang_complete with -I flags in it.

I'm trying to find workarounds.

Other than that, it's a very cool plugin.

xaizek commented 6 years ago

Did you notice that local paths are completed only for "" includes and not for <>?

stefanos82 commented 6 years ago

Yes, I read that but it seems I have a problem comprehending its meaning.

Can you provide an example if you don't mind so you can enlighten me?

xaizek commented 6 years ago

It's me who's wrong, <> does complete -I found in clang_complete's options. So it should work. Check values of g:clang_user_options and b:clang_user_options inside a buffer, maybe their aren't correct for some reason.

stefanos82 commented 6 years ago

Should I add the b:clang_user_options = '-Iinclude/' inside my .clang_complete or inside my .vimrc?

xaizek commented 6 years ago

clang_complete reads .clang_complete and fills b:clang_user_options. Setting b:clang_user_options in .vimrc wouldn't actually work, because it's a buffer-specific variable.

stefanos82 commented 6 years ago

I wonder why -Iinclude/ is not working with my .clang_complete.

It cannot find my include/hello.h file when I press tab key; it works with system headers though.

xaizek commented 6 years ago

Did you examine contents of b:clang_user_options (:echo b:clang_user_options)?

stefanos82 commented 6 years ago

It does not echo anything.

Should I declare it as empty under .vimrc?

xaizek commented 6 years ago

No. It means that .clang_complete wasn't loaded. Maybe it's not located in the right place? It should be on the same level where include/ directory is. And source file on the same level or deeper.

stefanos82 commented 6 years ago

OK, I think I might have found the error. I opened vim under my project directory and echoed the command you have suggested.

My .clang_complete looks like this:

-I.
-Iinclude/
-std=c99

My echoed message looks like this:

-I'/home/stefanos/tmp/c_projects/aprogram/'. -I'/home/stefanos/tmp/c_projects/a
program/'include/ -std=c99 -I'/usr/include'

Why does the include is excluded from my aprogram project?

xaizek commented 6 years ago

-I'/home/stefanos/tmp/c_projects/aprogram/'include/

That's escaping of path in clang_complete and inccomplete doesn't account for it.

Try using this .clang_complete until I verify this and fix it in inccomplete:

-I/home/stefanos/tmp/c_projects/aprogram/
-I/home/stefanos/tmp/c_projects/aprogram/include
-std=c99

I think absolute paths shouldn't get escaped.

stefanos82 commented 6 years ago

But I haven't escaped anything inside .clang_complete, only

let g:clang_user_options = '-I/usr/include/'
let g:clang_user_options .= '-I/usr/lib/gcc/x86_64-linux-gnu/7/include/'
let g:clang_user_options .= '-I/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed/'
let g:clang_user_options .= '-I/usr/include/c++/'

are escaped inside .vimrc.

stefanos82 commented 6 years ago

I have the impression that something is slightly wrong with the parsing. I echoed g:clang_user_options and got this for my global user options:

-I/usr/include/-I/usr/include/c++/-I/usr/lib/gcc/x86_64-linux-gnu/7/include/-I/u
sr/lib/gcc/x86_64-linux-gnu/7/include-fixed/

Shouldn't there be a space between each directory inclusion?

xaizek commented 6 years ago

But I haven't escaped anything inside .clang_complete

clang_complete did while turning relative paths into absolute ones.

Shouldn't there be a space between each directory inclusion?

This is a string variable and you didn't put the space anywhere, clang_complete doesn't rewrite g:clang_user_options.

stefanos82 commented 6 years ago

This is a string variable and you didn't put the space anywhere, clang_complete doesn't rewrite g:clang_user_options.

Well, I have attempted to, but it would trim them afterwards (during parsing I presume). I have tried on both sides and nothing would change.

xaizek commented 6 years ago

Like this? Space needs to be inside quotes.

let g:clang_user_options = '-I/usr/include/ '
let g:clang_user_options .= '-I/usr/lib/gcc/x86_64-linux-gnu/7/include/ '
let g:clang_user_options .= '-I/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed/ '
let g:clang_user_options .= '-I/usr/include/c++/ '
stefanos82 commented 6 years ago

Yes, yesterday was not working, but today this works, even though I have tested it only with spaces at the very beginning of -I.

What does not work though is -Iinclude/ inside .clang_complete; it appends it after current working directory which is enclosed inside single quotes.

That's why auto-completion does not work with local header files.

stefanos82 commented 6 years ago

I have also tried your suggestion about absolute paths should not get escaped and it still does not work...

This is what I get with echo b:clang_user_options

-std=c99 -I/home/stefanos/tmp/c_projects/aprogram/include -I'/usr/include'
xaizek commented 6 years ago

It did fix path from .clang_complete, so it worked partially. Anyways, I pushed an attempt to fix this in inccomplete and it seems to work here, please give it a try. It won't change contents of b:clang_user_options, but completion should list those paths with ' in them.

stefanos82 commented 6 years ago

OK, auto-completion works, but not for local header file names.

It would have been handy to have this option.

Anyway, I should have opened a ticket in inccomplete, not here; oops lol.

xaizek commented 6 years ago

OK, auto-completion works, but not for local header file names.

This terminology is confusing... Which type of include you're trying to use and what headers aren't being listed?

stefanos82 commented 6 years ago

Any header that is in double quotes; but clang_complete auto-completion works when I manually insert my header file name.

So, my issue is with inccomplete I would say.

xaizek commented 6 years ago

So you want to see headers from -I options in #include "-completion?

stefanos82 commented 6 years ago

Yes. With #include <> works just fine. When I attempt use local header file names, it does not.

xaizek commented 6 years ago

OK, I'll add an option to control sources of completion for #include "". I also sometimes expect to see -I completion when using double quotes.

stefanos82 commented 6 years ago

Very nice. I'm looking forward to use it :smile:

xaizek commented 6 years ago

New option (used it for a day it seems to work and don't break anything):

let g:inccomplete_localsources = [ 'relative-paths', 'clang-buffer' ]

You probably also want to do:

let g:clang_auto_user_options = '.clang_complete'

Otherwise clang_complete will add /usr/include in b:clang_user_options and it will be completed in ""-includes.

stefanos82 commented 6 years ago

Perfect! That seems to work @xaizek.

Good job mate :+1:

Suggestion: can you make this option obvious in README.md?

I'm sure many will find it handy.

xaizek commented 6 years ago

Thanks for reminding to add it there.