Commit de3c62ed authored by Onur Aslan's avatar Onur Aslan

Imported Upstream version 0+20150616+gitbc5f581

parent 69182410
......@@ -16,8 +16,6 @@ YouCompleteMe: a code-completion engine for Vim
- [Completion string ranking](#completion-string-ranking)
- [General semantic completion](#general-semantic-completion-engine-usage)
- [C-family semantic completion](#c-family-semantic-completion-engine-usage)
- [Python semantic completion](#python-semantic-completion)
- [C# semantic completion](#c-semantic-completion)
- [Semantic completion for other languages](#semantic-completion-for-other-languages)
- [Writing new semantic completers](#writing-new-semantic-completers)
- [Diagnostic display](#diagnostic-display)
......@@ -39,9 +37,10 @@ YouCompleteMe is a fast, as-you-type, fuzzy-search code completion engine for
works with every programming language, a semantic, [Clang][]-based engine that
provides native semantic code completion for C/C++/Objective-C/Objective-C++
(from now on referred to as "the C-family languages"), a [Jedi][]-based
completion engine for Python, an [OmniSharp][]-based completion engine for C#
and an omnifunc-based completer that uses data from Vim's omnicomplete system to
provide semantic completions for many other languages (Ruby, PHP etc.).
completion engine for Python, an [OmniSharp][]-based completion engine for C#,
a [Gocode][]-based completion engine for Go, and an omnifunc-based completer
that uses data from Vim's omnicomplete system to provide semantic completions
for many other languages (Ruby, PHP etc.).
![YouCompleteMe GIF demo](http://i.imgur.com/0OP4ood.gif)
......@@ -126,8 +125,9 @@ using Vundle and the ycm_support_libs library APIs have changed (happens
rarely), YCM will notify you to recompile it. You should then rerun the install
process.
It's recommended that you have the latest Xcode installed along with the latest
Command Line Tools (that you install from within Xcode).
**NOTE:** If you want C-family completion, you MUST have the latest Xcode
installed along with the latest Command Line Tools (they are installed when you
start Xcode for the first time).
Install CMake. Preferably with [Homebrew][brew], but here's the [stand-alone
CMake installer][cmake-download].
......@@ -146,7 +146,7 @@ Compiling YCM **without** semantic support for C-family languages:
./install.sh
If you want semantic C# support, you should add `--omnisharp-completer` to the
install script as well.
install script as well. If you want Go support, you should add `--gocode-completer`.
That's it. You're done. Refer to the _User Guide_ section on how to use YCM.
Don't forget that if you want the C-family semantic completion engine to work,
......@@ -189,7 +189,7 @@ Compiling YCM **without** semantic support for C-family languages:
./install.sh
If you want semantic C# support, you should add `--omnisharp-completer` to the
install script as well.
install script as well. If you want Go support, you should add `--gocode-completer`.
That's it. You're done. Refer to the _User Guide_ section on how to use YCM.
Don't forget that if you want the C-family semantic completion engine to work,
......@@ -242,7 +242,7 @@ Compiling YCM **without** semantic support for C-family languages:
./install.sh --system-boost
If you want semantic C# support, you should add `--omnisharp-completer` to the
install script as well.
install script as well. If you want Go support, you should add `--gocode-completer`.
That's it. You're done. Refer to the _User Guide_ section on how to use YCM.
Don't forget that if you want the C-family semantic completion engine to work,
......@@ -499,32 +499,13 @@ getting fast completions.
Call the `:YcmDiags` command to see if any errors or warnings were detected in
your file.
### Python semantic completion
YCM uses [Jedi][] to power its semantic completion for Python. This should "just
work" without any configuration from the user. You do NOT need to install Jedi
yourself; YCM uses it as a git subrepo. If you're installing YCM with Vundle
(which is the recommended way) then Vundle will make sure that the subrepo is
checked out when you do `:PluginInstall`. If you're installing YCM by hand, then
you need to run `git submodule update --init --recursive` when you're checking
out the YCM repository. That's it.
But again, installing YCM with Vundle takes care of all of this for you.
### C# semantic completion
YCM uses [OmniSharp][] to provide semantic completion for C#. It's used as a git
subrepo. If you're installing YCM with Vundle (which is the recommended way)
then Vundle will make sure that the subrepo is checked out when you do
`:PluginInstall`. If you're installing YCM by hand, then you need to run `git
submodule update --init --recursive` when you're checking out the YCM
repository.
OmniSharp is written in C# and has to be compiled. The `install.sh` script takes
care of this if you pass `--omnisharp-completer` as an argument.
### Semantic completion for other languages
Python, C#, and Go are supported natively by YouCompleteMe using the [Jedi][],
[Omnisharp][], and [Gocode][] engines, respectively. Check the
[installation](#installation) section for instructions to enable these features
if desired.
YCM will use your `omnifunc` (see `:h omnifunc` in Vim) as a source for semantic
completions if it does not have a native semantic completion engine for your
file's filetype. Vim comes with okayish omnifuncs for various languages like
......@@ -777,7 +758,7 @@ Supported in filetypes: `c, cpp, objc, objcpp`
### The `GetType` subcommand
Echos the type of the variable or method under the cursor, and where it differs,
the derived type.
the derived type.
For example:
......@@ -790,7 +771,7 @@ Invoking this command on `s` returns `std::string => std::basic_string<char>`
NOTE: Due to limitations of `libclang`, invoking this command on the word
`auto` typically returns `auto`. However, invoking it on a usage of the variable
with inferred type returns the correct type, but typically it is repeated due to
`libclang` returning that the types differ.
`libclang` returning that the types differ.
For example:
......@@ -818,16 +799,16 @@ class C {
void f();
};
void C::f() {
void C::f() {
}
```
In the out-of-line definition of `C::f`, the semantic parent is the class `C`,
In the out-of-line definition of `C::f`, the semantic parent is the class `C`,
of which this function is a member.
In the example above, both declarations of `C::f` have `C` as their semantic
context, while the lexical context of the first `C::f` is `C` and the lexical
In the example above, both declarations of `C::f` have `C` as their semantic
context, while the lexical context of the first `C::f` is `C` and the lexical
context of the second `C::f` is the translation unit.
For global declarations, the semantic parent is the translation unit.
......@@ -1928,12 +1909,15 @@ cases; if we find the request to be reasonable, we'll find a way to address it.
### Completion doesn't work with the C++ standard library headers
This is caused by an issue with libclang. Compiling from `clang` the binary uses
the correct default header search paths but compiling from `libclang.so` does
not. The issue seems to impact some OS's more than others. It appears that OS X
Mavericks in particular has problems with this.
This is caused by an issue with libclang that only affects some operating
systems. Compiling with `clang` the binary will use the correct default header
search paths but compiling with `libclang.so` (which YCM uses) does not.
Mac OS X is normally affected, but there's a workaround in YCM for that specific
OS. If you're not running that OS but still have the same problem, continue
reading.
The current workaround is to call `echo | clang -v -E -x c++ -` and look at the
The workaround is to call `echo | clang -v -E -x c++ -` and look at the
paths under the `#include <...> search starts here:` heading. You should take
those paths, prepend `-isystem` to each individual path and append them all to
the list of flags you return from your `FlagsForFile` function in your
......@@ -1941,6 +1925,24 @@ the list of flags you return from your `FlagsForFile` function in your
See [issue #303][issue-303] for details.
### Install YCM with [NeoBundle][NeoBundle]
[NeoBundle][NeoBundle] can do the compilation for you; just add the following to your vimrc:
NeoBundle 'Valloric/YouCompleteMe', {
\ 'build' : {
\ 'mac' : './install.sh --clang-completer --system-libclang --omnisharp-completer',
\ 'unix' : './install.sh --clang-completer --system-libclang --omnisharp-completer',
\ 'windows' : './install.sh --clang-completer --system-libclang --omnisharp-completer',
\ 'cygwin' : './install.sh --clang-completer --system-libclang --omnisharp-completer'
\ }
\ }
But you could have problems with the time needed to get the sub modules and
compile the whole thing.
To increase the Neobundle timeout to 1500 seconds, add the following to your vimrc:
let g:neobundle#install_process_timeout = 1500
Contact
-------
......@@ -1975,7 +1977,7 @@ This software is licensed under the [GPL v3 license][gpl].
[Clang]: http://clang.llvm.org/
[vundle]: https://github.com/gmarik/vundle#about
[pathogen]: https://github.com/tpope/vim-pathogen#pathogenvim
[clang-download]: http://llvm.org/releases/download.html#3.3
[clang-download]: http://llvm.org/releases/download.html
[brew]: http://mxcl.github.com/homebrew/
[cmake-download]: http://www.cmake.org/cmake/resources/software.html
[macvim]: http://code.google.com/p/macvim/#Download
......@@ -2009,3 +2011,5 @@ This software is licensed under the [GPL v3 license][gpl].
[bear]: https://github.com/rizsotto/Bear
[Options]: https://github.com/Valloric/YouCompleteMe#options
[ygen]: https://github.com/rdnetto/YCM-Generator
[Gocode]: https://github.com/nsf/gocode
[NeoBundle]: https://github.com/Shougo/neobundle.vim
......@@ -177,8 +177,8 @@ function! s:SetUpKeyMappings()
let invoke_key = g:ycm_key_invoke_completion
" Inside the console, <C-Space> is passed as <Nul> to Vim
if invoke_key ==# '<C-Space>' && !has('gui_running')
let invoke_key = '<Nul>'
if invoke_key ==# '<C-Space>'
imap <Nul> <C-Space>
endif
" <c-x><c-o> trigger omni completion, <c-p> deselects the first completion
......@@ -423,7 +423,10 @@ endfunction
function! s:SetCompleteFunc()
let &completefunc = 'youcompleteme#Complete'
let &l:completefunc = 'youcompleteme#Complete'
endfunction
function! s:SetOmnicompleteFunc()
if pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
let &omnifunc = 'youcompleteme#OmniComplete'
let &l:omnifunc = 'youcompleteme#OmniComplete'
......@@ -505,6 +508,11 @@ function! s:OnInsertEnter()
return
endif
if get( b:, 'ycm_omnicomplete', 0 )
let b:ycm_omnicomplete = 1
call s:SetOmnicompleteFunc()
endif
let s:old_cursor_position = []
endfunction
......@@ -559,8 +567,7 @@ endfunction
function! s:UpdateDiagnosticNotifications()
let should_display_diagnostics = g:ycm_show_diagnostics_ui &&
\ s:DiagnosticUiSupportedForCurrentFiletype() &&
\ pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
\ s:DiagnosticUiSupportedForCurrentFiletype()
if !should_display_diagnostics
return
......
This diff is collapsed.
......@@ -24,8 +24,8 @@ from retries import retries
from requests_futures.sessions import FuturesSession
from ycm.unsafe_thread_pool_executor import UnsafeThreadPoolExecutor
from ycm import vimsupport
from ycmd import utils
from ycmd.utils import ToUtf8Json
from ycmd.hmac_utils import CreateRequestHmac, CreateHmac, SecureStringsEqual
from ycmd.responses import ServerError, UnknownExtraConf
_HEADERS = {'content-type': 'application/json'}
......@@ -89,29 +89,37 @@ class BaseRequest( object ):
method,
timeout = _DEFAULT_TIMEOUT_SEC ):
def SendRequest( data, handler, method, timeout ):
request_uri = _BuildUri( handler )
if method == 'POST':
sent_data = ToUtf8Json( data )
return BaseRequest.session.post(
_BuildUri( handler ),
request_uri,
data = sent_data,
headers = BaseRequest._ExtraHeaders( sent_data ),
headers = BaseRequest._ExtraHeaders( method,
request_uri,
sent_data ),
timeout = timeout )
if method == 'GET':
return BaseRequest.session.get(
_BuildUri( handler ),
headers = BaseRequest._ExtraHeaders(),
request_uri,
headers = BaseRequest._ExtraHeaders( method, request_uri ),
timeout = timeout )
@retries( 5, delay = 0.5, backoff = 1.5 )
def DelayedSendRequest( data, handler, method ):
request_uri = _BuildUri( handler )
if method == 'POST':
sent_data = ToUtf8Json( data )
return requests.post( _BuildUri( handler ),
data = sent_data,
headers = BaseRequest._ExtraHeaders( sent_data ) )
return requests.post(
request_uri,
data = sent_data,
headers = BaseRequest._ExtraHeaders( method,
request_uri,
sent_data ) )
if method == 'GET':
return requests.get( _BuildUri( handler ),
headers = BaseRequest._ExtraHeaders() )
return requests.get(
request_uri,
headers = BaseRequest._ExtraHeaders( method, request_uri ) )
if not _CheckServerIsHealthyWithCache():
return _EXECUTOR.submit( DelayedSendRequest, data, handler, method )
......@@ -120,12 +128,15 @@ class BaseRequest( object ):
@staticmethod
def _ExtraHeaders( request_body = None ):
def _ExtraHeaders( method, request_uri, request_body = None ):
if not request_body:
request_body = ''
headers = dict( _HEADERS )
headers[ _HMAC_HEADER ] = b64encode(
utils.CreateHexHmac( request_body, BaseRequest.hmac_secret ) )
CreateRequestHmac( method,
urlparse.urlparse( request_uri ).path,
request_body,
BaseRequest.hmac_secret ) )
return headers
session = FuturesSession( executor = _EXECUTOR )
......@@ -174,10 +185,9 @@ def HandleServerException( exception ):
def _ValidateResponseObject( response ):
if not utils.ContentHexHmacValid(
response.content,
b64decode( response.headers[ _HMAC_HEADER ] ),
BaseRequest.hmac_secret ):
hmac = CreateHmac( response.content, BaseRequest.hmac_secret )
if not SecureStringsEqual( hmac,
b64decode( response.headers[ _HMAC_HEADER ] ) ):
raise RuntimeError( 'Received invalid HMAC for response!' )
return True
......@@ -191,8 +201,10 @@ def _CheckServerIsHealthyWithCache():
global SERVER_HEALTHY
def _ServerIsHealthy():
response = requests.get( _BuildUri( 'healthy' ),
headers = BaseRequest._ExtraHeaders() )
request_uri = _BuildUri( 'healthy' )
response = requests.get( request_uri,
headers = BaseRequest._ExtraHeaders(
'GET', request_uri, '' ) )
_ValidateResponseObject( response )
response.raise_for_status()
return response.json()
......
#!/usr/bin/env python
#
# Copyright (C) 2013 Google Inc.
#
# This file is part of YouCompleteMe.
#
# YouCompleteMe is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# YouCompleteMe is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
from ycm.client.base_request import ( BaseRequest, BuildRequestData,
HandleServerException )
class CompleterAvailableRequest( BaseRequest ):
def __init__( self, filetypes ):
super( CompleterAvailableRequest, self ).__init__()
self.filetypes = filetypes
self._response = None
def Start( self ):
request_data = BuildRequestData()
request_data.update( { 'filetypes': self.filetypes } )
try:
self._response = self.PostDataToHandler( request_data,
'semantic_completion_available' )
except Exception as e:
HandleServerException( e )
def Response( self ):
return self._response
def SendCompleterAvailableRequest( filetypes ):
request = CompleterAvailableRequest( filetypes )
# This is a blocking call.
request.Start()
return request.Response()
......@@ -100,7 +100,8 @@ def GetUnsavedAndCurrentBufferData():
continue
buffers_data[ GetBufferFilepath( buffer_object ) ] = {
'contents': '\n'.join( buffer_object ),
# Add a newline to match what gets saved to disk. See #1455 for details.
'contents': '\n'.join( buffer_object ) + '\n',
'filetypes': FiletypesForBuffer( buffer_object )
}
......
......@@ -30,9 +30,9 @@ from ycmd.request_wrap import RequestWrap
from ycm.diagnostic_interface import DiagnosticInterface
from ycm.omni_completer import OmniCompleter
from ycm import syntax_parse
from ycmd.completers.completer_utils import FiletypeCompleterExistsForFiletype
from ycm.client.ycmd_keepalive import YcmdKeepalive
from ycm.client.base_request import BaseRequest, BuildRequestData
from ycm.client.completer_available_request import SendCompleterAvailableRequest
from ycm.client.command_request import SendCommandRequest
from ycm.client.completion_request import CompletionRequest
from ycm.client.omni_completion_request import OmniCompletionRequest
......@@ -98,6 +98,7 @@ class YouCompleteMe( object ):
self._ycmd_keepalive.Start()
def _SetupServer( self ):
self._available_completers = {}
server_port = utils.GetUnusedLocalhostPort()
# The temp options file is deleted by ycmd during startup
with tempfile.NamedTemporaryFile( delete = False ) as options_file:
......@@ -217,8 +218,20 @@ class YouCompleteMe( object ):
return self._omnicomp
def FiletypeCompleterExistsForFiletype( self, filetype ):
try:
return self._available_completers[ filetype ]
except KeyError:
pass
exists_completer = ( self.IsServerAlive() and
bool( SendCompleterAvailableRequest( filetype ) ) )
self._available_completers[ filetype ] = exists_completer
return exists_completer
def NativeFiletypeCompletionAvailable( self ):
return any( [ FiletypeCompleterExistsForFiletype( x ) for x in
return any( [ self.FiletypeCompleterExistsForFiletype( x ) for x in
vimsupport.CurrentFiletypes() ] )
......@@ -299,10 +312,10 @@ class YouCompleteMe( object ):
def UpdateDiagnosticInterface( self ):
if not self.DiagnosticsForCurrentFileReady():
return
self._diag_interface.UpdateWithNewDiagnostics(
self.GetDiagnosticsFromStoredRequest() )
if ( self.DiagnosticsForCurrentFileReady() and
self.NativeFiletypeCompletionUsable() ):
self._diag_interface.UpdateWithNewDiagnostics(
self.GetDiagnosticsFromStoredRequest() )
def ShowDetailedDiagnostic( self ):
......@@ -341,7 +354,7 @@ class YouCompleteMe( object ):
if '*' in filetype_to_disable:
return False
else:
return not all([ x in filetype_to_disable for x in filetypes ])
return not any([ x in filetype_to_disable for x in filetypes ])
def _AddSyntaxDataIfNeeded( self, extra_data ):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment