ycm-core / YouCompleteMe

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

YCM: Semantic completion from ECLIM for all (including 'c,cpp,c++') filetypes #1284

Closed ikcalB closed 9 years ago

ikcalB commented 9 years ago

Setup:

:ProjectInfo
Name:      S1471-00
Path:      /home/manamana/tmp/S1471-00
Workspace: /home/manamana/workspace/testing
Open:      true
Natures:   cpp, c, c++
vimrc:
...
let g:EclimCompletionMethod = 'omnifunc'
...

(both, Eclim & YCM enabled)

:set omnifunc?
youcompleteme#OmniComplete
:YcmCompleter
ValueError: No semantic completer exists for filetypes: [u'cpp']

:YcmDebugInfo
Printing YouCompleteMe debug information...
-- Server has Clang support compiled in: False
-- Server running at: http://127.0.0.1:38828
-- Server process ID: 11056
-- Server logfiles:
--   /tmp/ycm_temp/server_38828_stdout.log
--   /tmp/ycm_temp/server_38828_stderr.log

:YcmDiags
Forcing compilation, this will block Vim until done.
No warnings or errors detected

autoload/youcompleteme.vim:

427c427,429
<   if pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )

---
> " XXX: does return 1, even if it shouldnt
> "  if pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
>    if 0
set omnifunc?
eclim#c#complete#CodeComplete

Expected behavior

Valloric commented 9 years ago

Everything would work here if NativeFiletypeCompletionUsable() returned 0 when called in your setup. It should, since you compiled without the clang completer. I'll take a look.

ikcalB commented 9 years ago

@Valloric Thank you! Im happy to provide all further info you need.

mertzt89 commented 9 years ago

I have looked briefly in to this and it seems that YCM is determining that there is a completer available if the file third_party/ycmd/ycmd/completers/filetype/hook.py exists. In the case of c, it needs to be based on whether or not it was compiled with clang support. It seems that it needs to be first based on the file existing, then have a function in each hook.py that can evaluate any other requisites to say that the completer is available. If it can be expected that GetCompleter() for each complete will return None in the case that the completer isn't truly available or usable, then perhaps it would be viable to use that as a mechanism to determine if the completer is actually there.

ikcalB commented 9 years ago

@Valloric have you been able to make any progress on this? atm I don't have time to further investigate this problem - the answer of @mertzt89 sounds plausible though.

mertzt89 commented 9 years ago

@ikcalB if you are just looking to make it usable now, a simple work around is to rename or delete third_party/ycmd/ycmd/completers/c/hook.py

Valloric commented 9 years ago

In the case of c, it needs to be based on whether or not it was compiled with clang support. It seems that it needs to be first based on the file existing, then have a function in each hook.py that can evaluate any other requisites to say that the completer is available.

That's literally how it works. :) The GetCompleter function checks for clang support, and if there is none, doesn't return a ClangCompleter. Now there could be a bug here, but I don't see it.

mertzt89 commented 9 years ago

in autoload\youcompleteme.vim:

  if pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' ) "<-- evaluates true even if there is no completer
    let &omnifunc = 'youcompleteme#OmniComplete'
    let &l:omnifunc = 'youcompleteme#OmniComplete'

When digging down into how ycm_state.NativeFiletypeCompletionUsable() it eventually ends up at the following function in third_party/ycmd/ycmd/completers/completer_utils.py:

def FiletypeCompleterExistsForFiletype( filetype ):
  return os.path.exists( PathToFiletypeCompleterPluginLoader( filetype ) )

The function above returns True third_party/ycmd/ycmd/completers/c/hook.py exists. This causes the omnifunc and l:omnifunc variables to be set incorrectly.

To me it seems that NativeFiletypeCompletionUsable() (or the functions below it) need to check more than than just the existance of third_party/ycmd/ycmd/completers/<filetype>/hook.py in the case of 'c' it would also need to verify that there is a completer such as clang available.

Valloric commented 9 years ago

@mertzt89 You're right, the logic in YCM and ycmd got out of sync. YCM is using the old approach of checking for the existence of the file. Thanks for pointing this out!

quicknir commented 9 years ago

Has this been fixed? I think I am observing the same thing, but my version of YCM is slightly out of date, wanted to know whether upgrading would solve this problem for me.

Valloric commented 9 years ago

This hasn't yet been fixed. It's a bit tricky to do it right and I haven't had the time to do it.

ikcalB commented 9 years ago

@mertzt89 unfortunately deleting the hooks.py does not work either (failing imports from other .py files)

the diff I proposed does work as a workaround though disabling all third party completers

quicknir commented 9 years ago

Don't delete hooks.py, but rather individual hook.py files for specific languages. That is, don't delete ./third_party/ycmd/third_party/requests/requests/hooks.py, but rather (in my case) delete ./third_party/ycmd/ycmd/completers/cpp/hook.py. You can also remove the backend completer for specific languages. In my case, I only removed the backend completion for c++, but left it for python; PyDev has worse completion than both PyCharm and Jedi so I don't use it.

ikcalB commented 9 years ago

@quicknir I stand corrected. The correct way ofc is to remove (rename) the appropriate hooks.py (ie.: third_party/ycmd/ycmd/completers/<filetype>/hooks.py)

(I got that wrong, because I tried renaming the complete folder...)