Auto merge of #3023 - micbou:mutable-user-options, r=puremourning

[READY] Allow users to change the options by restarting the server

Closes https://github.com/Valloric/YouCompleteMe/issues/3021.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/3023)
<!-- Reviewable:end -->
This commit is contained in:
zzbot 2018-05-15 15:05:55 -07:00 committed by GitHub
commit 8e448920c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 233 additions and 227 deletions

View File

@ -2021,7 +2021,8 @@ let g:ycm_min_num_of_chars_for_completion = 1
``` ```
Note that after changing an option in your [vimrc script][vimrc] you have to Note that after changing an option in your [vimrc script][vimrc] you have to
restart Vim for the changes to take effect. restart [ycmd][] with the `:YcmRestartServer` command for the changes to take
effect.
### The `g:ycm_min_num_of_chars_for_completion` option ### The `g:ycm_min_num_of_chars_for_completion` option

View File

@ -98,15 +98,7 @@ function! s:ReceiveMessages( timer_id )
endfunction endfunction
function! youcompleteme#Enable() function! s:SetUpOptions()
call s:SetUpBackwardsCompatibility()
" This can be 0 if YCM libs are old or -1 if an exception occured while
" executing the function.
if s:SetUpPython() != 1
return
endif
call s:SetUpCommands() call s:SetUpCommands()
call s:SetUpCpoptions() call s:SetUpCpoptions()
call s:SetUpCompleteopt() call s:SetUpCompleteopt()
@ -118,6 +110,17 @@ function! youcompleteme#Enable()
call s:SetUpSigns() call s:SetUpSigns()
call s:SetUpSyntaxHighlighting() call s:SetUpSyntaxHighlighting()
endfunction
function! youcompleteme#Enable()
call s:SetUpBackwardsCompatibility()
if !s:SetUpPython()
return
endif
call s:SetUpOptions()
call youcompleteme#EnableCursorMovedAutocommands() call youcompleteme#EnableCursorMovedAutocommands()
augroup youcompleteme augroup youcompleteme
@ -191,17 +194,20 @@ import vim
# Add python sources folder to the system path. # Add python sources folder to the system path.
script_folder = vim.eval( 's:script_folder_path' ) script_folder = vim.eval( 's:script_folder_path' )
sys.path.insert( 0, os.path.join( script_folder, '..', 'python' ) ) sys.path.insert( 0, os.path.join( script_folder, '..', 'python' ) )
sys.path.insert( 0, os.path.join( script_folder, '..', 'third_party', 'ycmd' ) )
from ycm.setup import SetUpSystemPaths, SetUpYCM
# We enclose this code in a try/except block to avoid backtraces in Vim. # We enclose this code in a try/except block to avoid backtraces in Vim.
try: try:
SetUpSystemPaths() from ycmd import server_utils as su
su.AddNearestThirdPartyFoldersToSysPath( script_folder )
# We need to import ycmd's third_party folders as well since we import and
# use ycmd code in the client.
su.AddNearestThirdPartyFoldersToSysPath( su.__file__ )
# Import the modules used in this file. # Import the modules used in this file.
from ycm import base, vimsupport from ycm import base, vimsupport, youcompleteme
ycm_state = SetUpYCM() ycm_state = youcompleteme.YouCompleteMe()
except Exception as error: except Exception as error:
# We don't use PostVimMessage or EchoText from the vimsupport module because # We don't use PostVimMessage or EchoText from the vimsupport module because
# importing this module may fail. # importing this module may fail.
@ -849,6 +855,8 @@ endfunction
function! s:RestartServer() function! s:RestartServer()
call s:SetUpOptions()
exec s:python_command "ycm_state.RestartServer()" exec s:python_command "ycm_state.RestartServer()"
call timer_stop( s:pollers.receive_messages.id ) call timer_stop( s:pollers.receive_messages.id )

View File

@ -718,10 +718,9 @@ Make sure you have Vim 7.4.1578 with Python 2 or Python 3 support.
OpenBSD 5.5 and later have a Vim that's recent enough. You can see the version OpenBSD 5.5 and later have a Vim that's recent enough. You can see the version
of Vim installed by running 'vim --version'. of Vim installed by running 'vim --version'.
FreeBSD 10.x comes with clang compiler but not the libraries needed to install. For FreeBSD 11.x, the requirement is cmake:
> >
pkg install llvm38 boost-all boost-python-libs clang38 pkg install cmake
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/llvm38/lib/
< <
Install YouCompleteMe with Vundle [26]. Install YouCompleteMe with Vundle [26].
@ -729,17 +728,20 @@ Install YouCompleteMe with Vundle [26].
using Vundle and the ycm_core library APIs have changed (happens rarely), YCM using Vundle and the ycm_core library APIs have changed (happens rarely), YCM
will notify you to recompile it. You should then rerun the install process. will notify you to recompile it. You should then rerun the install process.
Install dependencies and CMake: 'sudo pkg_add llvm boost cmake'
Compiling YCM **with** semantic support for C-family languages: Compiling YCM **with** semantic support for C-family languages:
> >
cd ~/.vim/bundle/YouCompleteMe cd ~/.vim/bundle/YouCompleteMe
./install.py --clang-completer --system-libclang --system-boost ./install.py --clang-completer
< <
Compiling YCM **without** semantic support for C-family languages: Compiling YCM **without** semantic support for C-family languages:
> >
cd ~/.vim/bundle/YouCompleteMe cd ~/.vim/bundle/YouCompleteMe
./install.py --system-boost ./install.py
<
If the 'python' executable is not present, or the default 'python' is not the
one that should be compiled against, specify the python interpreter explicitly:
>
python3 install.py --clang-completer
< <
The following additional language support options are available: The following additional language support options are available:
@ -2309,7 +2311,8 @@ vimrc script [38] by including a line like this:
let g:ycm_min_num_of_chars_for_completion = 1 let g:ycm_min_num_of_chars_for_completion = 1
< <
Note that after changing an option in your vimrc script [38] you have to Note that after changing an option in your vimrc script [38] you have to
restart Vim for the changes to take effect. restart ycmd [49] with the |:YcmRestartServer| command for the changes to take
effect.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
The *g:ycm_min_num_of_chars_for_completion* option The *g:ycm_min_num_of_chars_for_completion* option

View File

@ -1,4 +1,4 @@
# Copyright (C) 2013 Google Inc. # Copyright (C) 2013-2018 YouCompleteMe contributors
# #
# This file is part of YouCompleteMe. # This file is part of YouCompleteMe.
# #
@ -36,7 +36,6 @@ class DiagnosticInterface( object ):
self._diag_filter = DiagnosticFilter.CreateFromOptions( user_options ) self._diag_filter = DiagnosticFilter.CreateFromOptions( user_options )
# Line and column numbers are 1-based # Line and column numbers are 1-based
self._line_to_diags = defaultdict( list ) self._line_to_diags = defaultdict( list )
self._next_sign_id = vimsupport.SIGN_BUFFER_ID_INITIAL_VALUE
self._previous_diag_line_number = -1 self._previous_diag_line_number = -1
self._diag_message_needs_clearing = False self._diag_message_needs_clearing = False
@ -183,16 +182,12 @@ class DiagnosticInterface( object ):
# are sorted by errors in priority and Vim can only display one sign by # are sorted by errors in priority and Vim can only display one sign by
# line. # line.
name = 'YcmError' if _DiagnosticIsError( diags[ 0 ] ) else 'YcmWarning' name = 'YcmError' if _DiagnosticIsError( diags[ 0 ] ) else 'YcmWarning'
sign = vimsupport.DiagnosticSign( self._next_sign_id, sign = vimsupport.CreateSign( line, name, self._bufnr )
line,
name,
self._bufnr )
try: try:
signs_to_unplace.remove( sign ) signs_to_unplace.remove( sign )
except ValueError: except ValueError:
vimsupport.PlaceSign( sign ) vimsupport.PlaceSign( sign )
self._next_sign_id += 1
for sign in signs_to_unplace: for sign in signs_to_unplace:
vimsupport.UnplaceSign( sign ) vimsupport.UnplaceSign( sign )

View File

@ -1,53 +0,0 @@
# Copyright (C) 2016 YouCompleteMe contributors
#
# 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 __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
# No imports from `future` because when this is loaded, sys.path hasn't been set
# up yet!
import sys
import os
# Can't import these from paths.py because that uses `future` imports
DIR_OF_CURRENT_SCRIPT = os.path.dirname( os.path.abspath( __file__ ) )
DIR_OF_YCMD = os.path.join( DIR_OF_CURRENT_SCRIPT, '..', '..', 'third_party',
'ycmd' )
def SetUpSystemPaths():
sys.path.insert( 0, os.path.join( DIR_OF_YCMD ) )
from ycmd import server_utils as su
su.AddNearestThirdPartyFoldersToSysPath( DIR_OF_CURRENT_SCRIPT )
# We need to import ycmd's third_party folders as well since we import and
# use ycmd code in the client.
su.AddNearestThirdPartyFoldersToSysPath( su.__file__ )
def SetUpYCM():
from ycm import base
from ycmd import user_options_store
from ycm.youcompleteme import YouCompleteMe
base.LoadJsonDefaultsIntoVim()
user_options_store.SetAll( base.BuildServerConf() )
return YouCompleteMe( user_options_store.GetAll() )

View File

@ -1,4 +1,4 @@
# Copyright (C) 2016 YouCompleteMe contributors # Copyright (C) 2016-2018 YouCompleteMe contributors
# #
# This file is part of YouCompleteMe. # This file is part of YouCompleteMe.
# #
@ -25,6 +25,7 @@ from builtins import * # noqa
from ycm.tests.test_utils import MockVimModule from ycm.tests.test_utils import MockVimModule
MockVimModule() MockVimModule()
import contextlib
import functools import functools
import os import os
import requests import requests
@ -32,22 +33,23 @@ import time
import warnings import warnings
from ycm.client.base_request import BaseRequest from ycm.client.base_request import BaseRequest
from ycm.tests import test_utils
from ycm.youcompleteme import YouCompleteMe from ycm.youcompleteme import YouCompleteMe
from ycmd import user_options_store
from ycmd.utils import CloseStandardStreams, WaitUntilProcessIsTerminated from ycmd.utils import CloseStandardStreams, WaitUntilProcessIsTerminated
# The default options which are only relevant to the client, not the server and # The default options which are only relevant to the client, not the server and
# thus are not part of default_options.json, but are required for a working # thus are not part of default_options.json, but are required for a working
# YouCompleteMe object. # YouCompleteMe object.
DEFAULT_CLIENT_OPTIONS = { DEFAULT_CLIENT_OPTIONS = {
'log_level': 'info', 'g:ycm_server_python_interpreter': '',
'keep_logfiles': 0, 'g:ycm_log_level': 'info',
'extra_conf_vim_data': [], 'g:ycm_keep_logfiles': 0,
'show_diagnostics_ui': 1, 'g:ycm_extra_conf_vim_data': [],
'echo_current_diagnostic': 1, 'g:ycm_show_diagnostics_ui': 1,
'enable_diagnostic_signs': 1, 'g:ycm_echo_current_diagnostic': 1,
'enable_diagnostic_highlighting': 0, 'g:ycm_enable_diagnostic_signs': 1,
'always_populate_location_list': 0, 'g:ycm_enable_diagnostic_highlighting': 0,
'g:ycm_always_populate_location_list': 0,
} }
@ -56,11 +58,15 @@ def PathToTestFile( *args ):
return os.path.join( dir_of_current_script, 'testdata', *args ) return os.path.join( dir_of_current_script, 'testdata', *args )
def MakeUserOptions( custom_options = {} ): @contextlib.contextmanager
options = dict( user_options_store.DefaultOptions() ) def UserOptions( options ):
options.update( DEFAULT_CLIENT_OPTIONS ) old_vim_options = test_utils.VIM_OPTIONS.copy()
options.update( custom_options ) test_utils.VIM_OPTIONS.update( DEFAULT_CLIENT_OPTIONS )
return options test_utils.VIM_OPTIONS.update( options )
try:
yield
finally:
test_utils.VIM_OPTIONS = old_vim_options
def _IsReady(): def _IsReady():
@ -123,7 +129,8 @@ def YouCompleteMeInstance( custom_options = {} ):
def Decorator( test ): def Decorator( test ):
@functools.wraps( test ) @functools.wraps( test )
def Wrapper( *args, **kwargs ): def Wrapper( *args, **kwargs ):
ycm = YouCompleteMe( MakeUserOptions( custom_options ) ) with UserOptions( custom_options ):
ycm = YouCompleteMe()
WaitUntilReady() WaitUntilReady()
ycm.CheckIfServerIsReady() ycm.CheckIfServerIsReady()
try: try:

View File

@ -31,7 +31,7 @@ from mock import patch
from ycm.tests import YouCompleteMeInstance from ycm.tests import YouCompleteMeInstance
@YouCompleteMeInstance( { 'extra_conf_vim_data': [ 'tempname()' ] } ) @YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'tempname()' ] } )
def SendCommandRequest_ExtraConfVimData_Works_test( ycm ): def SendCommandRequest_ExtraConfVimData_Works_test( ycm ):
current_buffer = VimBuffer( 'buffer' ) current_buffer = VimBuffer( 'buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], current_buffer ):
@ -56,7 +56,7 @@ def SendCommandRequest_ExtraConfVimData_Works_test( ycm ):
) )
@YouCompleteMeInstance( { 'extra_conf_vim_data': [ 'undefined_value' ] } ) @YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'undefined_value' ] } )
def SendCommandRequest_ExtraConfData_UndefinedValue_test( ycm ): def SendCommandRequest_ExtraConfData_UndefinedValue_test( ycm ):
current_buffer = VimBuffer( 'buffer' ) current_buffer = VimBuffer( 'buffer' )
with MockVimBuffers( [ current_buffer ], current_buffer ): with MockVimBuffers( [ current_buffer ], current_buffer ):

View File

@ -351,7 +351,7 @@ def _Check_FileReadyToParse_Diagnostic_Warning( ycm ):
assert_that( assert_that(
test_utils.VIM_SIGNS, test_utils.VIM_SIGNS,
contains( contains(
VimSign( SIGN_BUFFER_ID_INITIAL_VALUE + 1, 2, 'YcmWarning', 1 ) VimSign( SIGN_BUFFER_ID_INITIAL_VALUE + 2, 2, 'YcmWarning', 1 )
) )
) )
eq_( ycm.GetErrorCount(), 0 ) eq_( ycm.GetErrorCount(), 0 )
@ -363,7 +363,7 @@ def _Check_FileReadyToParse_Diagnostic_Warning( ycm ):
assert_that( assert_that(
test_utils.VIM_SIGNS, test_utils.VIM_SIGNS,
contains( contains(
VimSign( SIGN_BUFFER_ID_INITIAL_VALUE + 1, 2, 'YcmWarning', 1 ) VimSign( SIGN_BUFFER_ID_INITIAL_VALUE + 2, 2, 'YcmWarning', 1 )
) )
) )
eq_( ycm.GetErrorCount(), 0 ) eq_( ycm.GetErrorCount(), 0 )
@ -390,7 +390,7 @@ def _Check_FileReadyToParse_Diagnostic_Clean( ycm ):
@patch( 'ycm.youcompleteme.YouCompleteMe._AddUltiSnipsDataIfNeeded' ) @patch( 'ycm.youcompleteme.YouCompleteMe._AddUltiSnipsDataIfNeeded' )
@YouCompleteMeInstance( { 'collect_identifiers_from_tags_files': 1 } ) @YouCompleteMeInstance( { 'g:ycm_collect_identifiers_from_tags_files': 1 } )
def EventNotification_FileReadyToParse_TagFiles_UnicodeWorkingDirectory_test( def EventNotification_FileReadyToParse_TagFiles_UnicodeWorkingDirectory_test(
ycm, *args ): ycm, *args ):
unicode_dir = PathToTestFile( 'uni¢𐍈d€' ) unicode_dir = PathToTestFile( 'uni¢𐍈d€' )
@ -534,7 +534,7 @@ def EventNotification_BufferUnload_BuildRequestForDeletedAndUnsavedBuffers_test(
@patch( 'ycm.vimsupport.CaptureVimCommand', return_value = """ @patch( 'ycm.vimsupport.CaptureVimCommand', return_value = """
fooGroup xxx foo bar fooGroup xxx foo bar
links to Statement""" ) links to Statement""" )
@YouCompleteMeInstance( { 'seed_identifiers_with_syntax': 1 } ) @YouCompleteMeInstance( { 'g:ycm_seed_identifiers_with_syntax': 1 } )
def EventNotification_FileReadyToParse_SyntaxKeywords_SeedWithCache_test( def EventNotification_FileReadyToParse_SyntaxKeywords_SeedWithCache_test(
ycm, *args ): ycm, *args ):
@ -569,7 +569,7 @@ def EventNotification_FileReadyToParse_SyntaxKeywords_SeedWithCache_test(
@patch( 'ycm.vimsupport.CaptureVimCommand', return_value = """ @patch( 'ycm.vimsupport.CaptureVimCommand', return_value = """
fooGroup xxx foo bar fooGroup xxx foo bar
links to Statement""" ) links to Statement""" )
@YouCompleteMeInstance( { 'seed_identifiers_with_syntax': 1 } ) @YouCompleteMeInstance( { 'g:ycm_seed_identifiers_with_syntax': 1 } )
def EventNotification_FileReadyToParse_SyntaxKeywords_ClearCacheIfRestart_test( def EventNotification_FileReadyToParse_SyntaxKeywords_ClearCacheIfRestart_test(
ycm, *args ): ycm, *args ):

View File

@ -1,6 +1,6 @@
# encoding: utf-8 # encoding: utf-8
# #
# Copyright (C) 2016 YouCompleteMe contributors # Copyright (C) 2016-2018 YouCompleteMe contributors
# #
# This file is part of YouCompleteMe. # This file is part of YouCompleteMe.
# #
@ -39,7 +39,8 @@ TRIGGERS = {
} }
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_Cache_List_test( ycm ): def OmniCompleter_GetCompletions_Cache_List_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -62,7 +63,8 @@ def OmniCompleter_GetCompletions_Cache_List_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_Cache_ListFilter_test( ycm ): def OmniCompleter_GetCompletions_Cache_ListFilter_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -85,7 +87,8 @@ def OmniCompleter_GetCompletions_Cache_ListFilter_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 0, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_NoCache_List_test( ycm ): def OmniCompleter_GetCompletions_NoCache_List_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -108,7 +111,8 @@ def OmniCompleter_GetCompletions_NoCache_List_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 0, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_NoCache_ListFilter_test( ycm ): def OmniCompleter_GetCompletions_NoCache_ListFilter_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -133,7 +137,8 @@ def OmniCompleter_GetCompletions_NoCache_ListFilter_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 0, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_NoCache_UseFindStart_test( ycm ): def OmniCompleter_GetCompletions_NoCache_UseFindStart_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -158,7 +163,8 @@ def OmniCompleter_GetCompletions_NoCache_UseFindStart_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_Cache_UseFindStart_test( ycm ): def OmniCompleter_GetCompletions_Cache_UseFindStart_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -183,7 +189,8 @@ def OmniCompleter_GetCompletions_Cache_UseFindStart_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_Cache_Object_test( ycm ): def OmniCompleter_GetCompletions_Cache_Object_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -206,7 +213,8 @@ def OmniCompleter_GetCompletions_Cache_Object_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_Cache_ObjectList_test( ycm ): def OmniCompleter_GetCompletions_Cache_ObjectList_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -250,7 +258,8 @@ def OmniCompleter_GetCompletions_Cache_ObjectList_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 0, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_NoCache_ObjectList_test( ycm ): def OmniCompleter_GetCompletions_NoCache_ObjectList_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -302,7 +311,8 @@ def OmniCompleter_GetCompletions_NoCache_ObjectList_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_Cache_ObjectListObject_test( ycm ): def OmniCompleter_GetCompletions_Cache_ObjectListObject_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -346,7 +356,8 @@ def OmniCompleter_GetCompletions_Cache_ObjectListObject_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 0, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_NoCache_ObjectListObject_test( ycm ): def OmniCompleter_GetCompletions_NoCache_ObjectListObject_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -398,7 +409,8 @@ def OmniCompleter_GetCompletions_NoCache_ObjectListObject_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_Cache_List_Unicode_test( ycm ): def OmniCompleter_GetCompletions_Cache_List_Unicode_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -423,7 +435,8 @@ def OmniCompleter_GetCompletions_Cache_List_Unicode_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 0, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_NoCache_List_Unicode_test( ycm ): def OmniCompleter_GetCompletions_NoCache_List_Unicode_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -448,7 +461,8 @@ def OmniCompleter_GetCompletions_NoCache_List_Unicode_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_Cache_List_Filter_Unicode_test( ycm ): def OmniCompleter_GetCompletions_Cache_List_Filter_Unicode_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -471,7 +485,8 @@ def OmniCompleter_GetCompletions_Cache_List_Filter_Unicode_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 0, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_NoCache_List_Filter_Unicode_test( ycm ): def OmniCompleter_GetCompletions_NoCache_List_Filter_Unicode_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -494,7 +509,8 @@ def OmniCompleter_GetCompletions_NoCache_List_Filter_Unicode_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_Cache_ObjectList_Unicode_test( ycm ): def OmniCompleter_GetCompletions_Cache_ObjectList_Unicode_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -538,7 +554,8 @@ def OmniCompleter_GetCompletions_Cache_ObjectList_Unicode_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_Cache_ObjectListObject_Unicode_test( ycm ): def OmniCompleter_GetCompletions_Cache_ObjectListObject_Unicode_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -597,7 +614,8 @@ def OmniCompleter_GetCompletions_Cache_ObjectListObject_Unicode_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 1, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_RestoreCursorPositionAfterOmnifuncCall_test( def OmniCompleter_GetCompletions_RestoreCursorPositionAfterOmnifuncCall_test(
ycm ): ycm ):
@ -631,7 +649,8 @@ def OmniCompleter_GetCompletions_RestoreCursorPositionAfterOmnifuncCall_test(
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 0, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_NoCache_NoSemanticTrigger_test( ycm ): def OmniCompleter_GetCompletions_NoCache_NoSemanticTrigger_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -654,7 +673,8 @@ def OmniCompleter_GetCompletions_NoCache_NoSemanticTrigger_test( ycm ):
) )
@YouCompleteMeInstance( { 'cache_omnifunc': 0, 'semantic_triggers': TRIGGERS } ) @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_NoCache_ForceSemantic_test( ycm ): def OmniCompleter_GetCompletions_NoCache_ForceSemantic_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -678,9 +698,9 @@ def OmniCompleter_GetCompletions_NoCache_ForceSemantic_test( ycm ):
@YouCompleteMeInstance( { @YouCompleteMeInstance( {
'cache_omnifunc': 0, 'g:ycm_cache_omnifunc': 0,
'filetype_specific_completion_to_disable': { FILETYPE: 1 }, 'g:ycm_filetype_specific_completion_to_disable': { FILETYPE: 1 },
'semantic_triggers': TRIGGERS } ) 'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_FiletypeDisabled_SemanticTrigger_test( ycm ): def OmniCompleter_GetCompletions_FiletypeDisabled_SemanticTrigger_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -704,9 +724,9 @@ def OmniCompleter_GetCompletions_FiletypeDisabled_SemanticTrigger_test( ycm ):
@YouCompleteMeInstance( { @YouCompleteMeInstance( {
'cache_omnifunc': 0, 'g:ycm_cache_omnifunc': 0,
'filetype_specific_completion_to_disable': { '*': 1 }, 'g:ycm_filetype_specific_completion_to_disable': { '*': 1 },
'semantic_triggers': TRIGGERS } ) 'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_AllFiletypesDisabled_SemanticTrigger_test( def OmniCompleter_GetCompletions_AllFiletypesDisabled_SemanticTrigger_test(
ycm ): ycm ):
@ -732,9 +752,9 @@ def OmniCompleter_GetCompletions_AllFiletypesDisabled_SemanticTrigger_test(
@YouCompleteMeInstance( { @YouCompleteMeInstance( {
'cache_omnifunc': 0, 'g:ycm_cache_omnifunc': 0,
'filetype_specific_completion_to_disable': { FILETYPE: 1 }, 'g:ycm_filetype_specific_completion_to_disable': { FILETYPE: 1 },
'semantic_triggers': TRIGGERS } ) 'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_FiletypeDisabled_ForceSemantic_test( ycm ): def OmniCompleter_GetCompletions_FiletypeDisabled_ForceSemantic_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:
@ -758,9 +778,9 @@ def OmniCompleter_GetCompletions_FiletypeDisabled_ForceSemantic_test( ycm ):
@YouCompleteMeInstance( { @YouCompleteMeInstance( {
'cache_omnifunc': 0, 'g:ycm_cache_omnifunc': 0,
'filetype_specific_completion_to_disable': { '*': 1 }, 'g:ycm_filetype_specific_completion_to_disable': { '*': 1 },
'semantic_triggers': TRIGGERS } ) 'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_AllFiletypesDisabled_ForceSemantic_test( ycm ): def OmniCompleter_GetCompletions_AllFiletypesDisabled_ForceSemantic_test( ycm ):
def Omnifunc( findstart, base ): def Omnifunc( findstart, base ):
if findstart: if findstart:

View File

@ -22,11 +22,12 @@ from __future__ import absolute_import
# Not installing aliases from python-future; it's unreliable and slow. # Not installing aliases from python-future; it's unreliable and slow.
from builtins import * # noqa from builtins import * # noqa
from future.utils import PY2 from future.utils import iteritems, PY2
from mock import DEFAULT, MagicMock, patch from mock import DEFAULT, MagicMock, patch
from hamcrest import assert_that, equal_to from hamcrest import assert_that, equal_to
import contextlib import contextlib
import functools import functools
import json
import nose import nose
import os import os
import re import re
@ -56,6 +57,8 @@ SIGN_UNPLACE_REGEX = re.compile(
'^sign unplace (?P<id>\d+) buffer=(?P<bufnr>\d+)$' ) '^sign unplace (?P<id>\d+) buffer=(?P<bufnr>\d+)$' )
REDIR_START_REGEX = re.compile( '^redir => (?P<variable>[\w:]+)$' ) REDIR_START_REGEX = re.compile( '^redir => (?P<variable>[\w:]+)$' )
REDIR_END_REGEX = re.compile( '^redir END$' ) REDIR_END_REGEX = re.compile( '^redir END$' )
EXISTS_REGEX = re.compile( '^exists\( \'(?P<option>[\w:]+)\' \)$' )
LET_REGEX = re.compile( '^let (?P<option>[\w:]+) = (?P<value>.*)$' )
# One-and only instance of mocked Vim object. The first 'import vim' that is # One-and only instance of mocked Vim object. The first 'import vim' that is
# executed binds the vim module to the instance of MagicMock that is created, # executed binds the vim module to the instance of MagicMock that is created,
@ -70,6 +73,15 @@ VIM_MOCK = MagicMock()
VIM_MATCHES = [] VIM_MATCHES = []
VIM_SIGNS = [] VIM_SIGNS = []
VIM_OPTIONS = {
'&previewheight': 12,
'&columns': 80,
'&ruler': 0,
'&showcmd': 1,
'&hidden': 0,
'&expandtab': 1
}
REDIR = { REDIR = {
'status': False, 'status': False,
'variable': '', 'variable': '',
@ -153,23 +165,21 @@ def _MockVimBufferEval( value ):
def _MockVimOptionsEval( value ): def _MockVimOptionsEval( value ):
if value == '&previewheight': result = VIM_OPTIONS.get( value )
return 12 if result is not None:
return result
if value == '&columns': if value == 'keys( g: )':
return 80 global_options = {}
for key, value in iteritems( VIM_OPTIONS ):
if key.startswith( 'g:' ):
global_options[ key[ 2: ] ] = value
return global_options
if value == '&ruler': match = EXISTS_REGEX.search( value )
return 0 if match:
option = match.group( 'option' )
if value == '&showcmd': return option in VIM_OPTIONS
return 1
if value == '&hidden':
return 0
if value == '&expandtab':
return 1
return None return None
@ -213,23 +223,12 @@ def _MockVimMatchEval( value ):
return None return None
# This variable exists to easily mock the 'g:ycm_server_python_interpreter'
# option in tests.
server_python_interpreter = ''
def _MockVimEval( value ): def _MockVimEval( value ):
if value == 'g:ycm_min_num_of_chars_for_completion': result = _MockVimOptionsEval( value )
return 0
if value == 'g:ycm_server_python_interpreter':
return server_python_interpreter
result = _MockVimFunctionsEval( value )
if result is not None: if result is not None:
return result return result
result = _MockVimOptionsEval( value ) result = _MockVimFunctionsEval( value )
if result is not None: if result is not None:
return result return result
@ -317,6 +316,13 @@ def _MockVimCommand( command ):
if result: if result:
return return
match = LET_REGEX.search( command )
if match:
option = match.group( 'option' )
value = json.loads( match.group( 'value' ) )
VIM_OPTIONS[ option ] = value
return
return DEFAULT return DEFAULT

View File

@ -33,11 +33,11 @@ from hamcrest import ( assert_that, contains, empty, equal_to, is_in, is_not,
from mock import call, MagicMock, patch from mock import call, MagicMock, patch
from ycm.paths import _PathToPythonUsedDuringBuild from ycm.paths import _PathToPythonUsedDuringBuild
from ycm.vimsupport import SIGN_BUFFER_ID_INITIAL_VALUE from ycm.vimsupport import SetVariableValue, SIGN_BUFFER_ID_INITIAL_VALUE
from ycm.youcompleteme import YouCompleteMe from ycm.tests import ( StopServer, test_utils, UserOptions, WaitUntilReady,
from ycm.tests import ( MakeUserOptions, StopServer, test_utils, YouCompleteMeInstance )
WaitUntilReady, YouCompleteMeInstance )
from ycm.client.base_request import _LoadExtraConfFile from ycm.client.base_request import _LoadExtraConfFile
from ycm.youcompleteme import YouCompleteMe
from ycmd.responses import ServerError from ycmd.responses import ServerError
from ycm.tests.mock_utils import ( MockAsyncServerResponseDone, from ycm.tests.mock_utils import ( MockAsyncServerResponseDone,
MockAsyncServerResponseInProgress, MockAsyncServerResponseInProgress,
@ -54,10 +54,11 @@ def YouCompleteMe_YcmCoreNotImported_test( ycm ):
@patch( 'ycm.vimsupport.PostVimMessage' ) @patch( 'ycm.vimsupport.PostVimMessage' )
def YouCompleteMe_InvalidPythonInterpreterPath_test( post_vim_message ): def YouCompleteMe_InvalidPythonInterpreterPath_test( post_vim_message ):
with UserOptions( {
'g:ycm_server_python_interpreter': '/invalid/python/path' } ):
try: try:
with patch( 'ycm.tests.test_utils.server_python_interpreter', ycm = YouCompleteMe()
'/invalid/path/to/python' ):
ycm = YouCompleteMe( MakeUserOptions() )
assert_that( ycm.IsServerAlive(), equal_to( False ) ) assert_that( ycm.IsServerAlive(), equal_to( False ) )
post_vim_message.assert_called_once_with( post_vim_message.assert_called_once_with(
"Unable to start the ycmd server. " "Unable to start the ycmd server. "
@ -67,8 +68,8 @@ def YouCompleteMe_InvalidPythonInterpreterPath_test( post_vim_message ):
post_vim_message.reset_mock() post_vim_message.reset_mock()
with patch( 'ycm.tests.test_utils.server_python_interpreter', SetVariableValue( 'g:ycm_server_python_interpreter',
_PathToPythonUsedDuringBuild() ): _PathToPythonUsedDuringBuild() )
ycm.RestartServer() ycm.RestartServer()
assert_that( ycm.IsServerAlive(), equal_to( True ) ) assert_that( ycm.IsServerAlive(), equal_to( True ) )
@ -82,10 +83,11 @@ def YouCompleteMe_InvalidPythonInterpreterPath_test( post_vim_message ):
@patch( 'ycm.paths._EndsWithPython', return_value = False ) @patch( 'ycm.paths._EndsWithPython', return_value = False )
@patch( 'ycm.vimsupport.PostVimMessage' ) @patch( 'ycm.vimsupport.PostVimMessage' )
def YouCompleteMe_NoPythonInterpreterFound_test( post_vim_message, *args ): def YouCompleteMe_NoPythonInterpreterFound_test( post_vim_message, *args ):
with UserOptions( {} ):
try: try:
with patch( 'ycmd.utils.ReadFile', side_effect = IOError ): with patch( 'ycmd.utils.ReadFile', side_effect = IOError ):
ycm = YouCompleteMe()
ycm = YouCompleteMe( MakeUserOptions() )
assert_that( ycm.IsServerAlive(), equal_to( False ) ) assert_that( ycm.IsServerAlive(), equal_to( False ) )
post_vim_message.assert_called_once_with( post_vim_message.assert_called_once_with(
"Unable to start the ycmd server. Cannot find Python 2.7 or 3.4+. " "Unable to start the ycmd server. Cannot find Python 2.7 or 3.4+. "
@ -95,8 +97,8 @@ def YouCompleteMe_NoPythonInterpreterFound_test( post_vim_message, *args ):
post_vim_message.reset_mock() post_vim_message.reset_mock()
with patch( 'ycm.tests.test_utils.server_python_interpreter', SetVariableValue( 'g:ycm_server_python_interpreter',
_PathToPythonUsedDuringBuild() ): _PathToPythonUsedDuringBuild() )
ycm.RestartServer() ycm.RestartServer()
assert_that( ycm.IsServerAlive(), equal_to( True ) ) assert_that( ycm.IsServerAlive(), equal_to( True ) )
@ -185,7 +187,7 @@ def YouCompleteMe_NotifyUserIfServerCrashed_UnexpectedExitCode_test():
} ) } )
@YouCompleteMeInstance( { 'extra_conf_vim_data': [ 'tempname()' ] } ) @YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'tempname()' ] } )
def YouCompleteMe_DebugInfo_ServerRunning_test( ycm ): def YouCompleteMe_DebugInfo_ServerRunning_test( ycm ):
dir_of_script = os.path.dirname( os.path.abspath( __file__ ) ) dir_of_script = os.path.dirname( os.path.abspath( __file__ ) )
buf_name = os.path.join( dir_of_script, 'testdata', 'test.cpp' ) buf_name = os.path.join( dir_of_script, 'testdata', 'test.cpp' )
@ -246,7 +248,7 @@ def YouCompleteMe_OnVimLeave_RemoveClientLogfileByDefault_test( ycm ):
'Logfile {0} was not removed.'.format( client_logfile ) ) 'Logfile {0} was not removed.'.format( client_logfile ) )
@YouCompleteMeInstance( { 'keep_logfiles': 1 } ) @YouCompleteMeInstance( { 'g:ycm_keep_logfiles': 1 } )
def YouCompleteMe_OnVimLeave_KeepClientLogfile_test( ycm ): def YouCompleteMe_OnVimLeave_KeepClientLogfile_test( ycm ):
client_logfile = ycm._client_logfile client_logfile = ycm._client_logfile
assert_that( os.path.isfile( client_logfile ), assert_that( os.path.isfile( client_logfile ),
@ -421,9 +423,9 @@ def YouCompleteMe_ShowDiagnostics_NoDiagnosticsDetected_test(
set_location_list_for_window.assert_called_once_with( 0, [] ) set_location_list_for_window.assert_called_once_with( 0, [] )
@YouCompleteMeInstance( { 'log_level': 'debug', @YouCompleteMeInstance( { 'g:ycm_log_level': 'debug',
'keep_logfiles': 1, 'g:ycm_keep_logfiles': 1,
'open_loclist_on_ycm_diags': 0 } ) 'g:ycm_open_loclist_on_ycm_diags': 0 } )
@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype', @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
return_value = True ) return_value = True )
@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock ) @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
@ -465,7 +467,7 @@ def YouCompleteMe_ShowDiagnostics_DiagnosticsFound_DoNotOpenLocationList_test(
} ] ) } ] )
@YouCompleteMeInstance( { 'open_loclist_on_ycm_diags': 1 } ) @YouCompleteMeInstance( { 'g:ycm_open_loclist_on_ycm_diags': 1 } )
@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype', @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
return_value = True ) return_value = True )
@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock ) @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
@ -513,9 +515,9 @@ def YouCompleteMe_ShowDiagnostics_DiagnosticsFound_OpenLocationList_test(
open_location_list.assert_called_once_with( focus = True ) open_location_list.assert_called_once_with( focus = True )
@YouCompleteMeInstance( { 'echo_current_diagnostic': 1, @YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
'enable_diagnostic_signs': 1, 'g:ycm_enable_diagnostic_signs': 1,
'enable_diagnostic_highlighting': 1 } ) 'g:ycm_enable_diagnostic_highlighting': 1 } )
@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype', @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
return_value = True ) return_value = True )
@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock ) @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
@ -665,7 +667,7 @@ def YouCompleteMe_UpdateDiagnosticInterface_PrioritizeErrorsOverWarnings_test(
) )
@YouCompleteMeInstance( { 'enable_diagnostic_highlighting': 1 } ) @YouCompleteMeInstance( { 'g:ycm_enable_diagnostic_highlighting': 1 } )
def YouCompleteMe_UpdateMatches_ClearDiagnosticMatchesInNewBuffer_test( ycm ): def YouCompleteMe_UpdateMatches_ClearDiagnosticMatchesInNewBuffer_test( ycm ):
current_buffer = VimBuffer( 'buffer', current_buffer = VimBuffer( 'buffer',
filetype = 'c', filetype = 'c',
@ -684,8 +686,8 @@ def YouCompleteMe_UpdateMatches_ClearDiagnosticMatchesInNewBuffer_test( ycm ):
assert_that( test_utils.VIM_MATCHES, empty() ) assert_that( test_utils.VIM_MATCHES, empty() )
@YouCompleteMeInstance( { 'echo_current_diagnostic': 1, @YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
'always_populate_location_list': 1 } ) 'g:ycm_always_populate_location_list': 1 } )
@patch.object( ycm_buffer_module, @patch.object( ycm_buffer_module,
'DIAGNOSTIC_UI_ASYNC_FILETYPES', 'DIAGNOSTIC_UI_ASYNC_FILETYPES',
[ 'ycmtest' ] ) [ 'ycmtest' ] )
@ -799,8 +801,8 @@ def YouCompleteMe_AsyncDiagnosticUpdate_SingleFile_test( ycm,
] ) ] )
@YouCompleteMeInstance( { 'echo_current_diagnostic': 1, @YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
'always_populate_location_list': 1 } ) 'g:ycm_always_populate_location_list': 1 } )
@patch.object( ycm_buffer_module, @patch.object( ycm_buffer_module,
'DIAGNOSTIC_UI_ASYNC_FILETYPES', 'DIAGNOSTIC_UI_ASYNC_FILETYPES',
[ 'ycmtest' ] ) [ 'ycmtest' ] )

View File

@ -49,6 +49,8 @@ NO_SELECTION_MADE_MSG = "No valid selection was made; aborting."
# value is then incremented for each new sign. This should prevent conflicts # value is then incremented for each new sign. This should prevent conflicts
# with other plugins using signs. # with other plugins using signs.
SIGN_BUFFER_ID_INITIAL_VALUE = 100000000 SIGN_BUFFER_ID_INITIAL_VALUE = 100000000
# This holds the next sign's id to assign for each buffer.
SIGN_ID_FOR_BUFFER = defaultdict( lambda: SIGN_BUFFER_ID_INITIAL_VALUE )
SIGN_PLACE_REGEX = re.compile( SIGN_PLACE_REGEX = re.compile(
r"^.*=(?P<line>\d+).*=(?P<id>\d+).*=(?P<name>Ycm\w+)$" ) r"^.*=(?P<line>\d+).*=(?P<id>\d+).*=(?P<name>Ycm\w+)$" )
@ -204,6 +206,12 @@ def GetSignsInBuffer( buffer_number ):
return signs return signs
def CreateSign( line, name, buffer_number ):
sign_id = SIGN_ID_FOR_BUFFER[ buffer_number ]
SIGN_ID_FOR_BUFFER[ buffer_number ] += 1
return DiagnosticSign( sign_id, line, name, buffer_number )
def UnplaceSign( sign ): def UnplaceSign( sign ):
vim.command( 'sign unplace {0} buffer={1}'.format( sign.id, vim.command( 'sign unplace {0} buffer={1}'.format( sign.id,
sign.buffer_number ) ) sign.buffer_number ) )

View File

@ -35,8 +35,7 @@ from ycm import base, paths, vimsupport
from ycm.buffer import ( BufferDict, from ycm.buffer import ( BufferDict,
DIAGNOSTIC_UI_FILETYPES, DIAGNOSTIC_UI_FILETYPES,
DIAGNOSTIC_UI_ASYNC_FILETYPES ) DIAGNOSTIC_UI_ASYNC_FILETYPES )
from ycmd import utils from ycmd import server_utils, user_options_store, utils
from ycmd import server_utils
from ycmd.request_wrap import RequestWrap from ycmd.request_wrap import RequestWrap
from ycm.omni_completer import OmniCompleter from ycm.omni_completer import OmniCompleter
from ycm import syntax_parse from ycm import syntax_parse
@ -107,12 +106,12 @@ HANDLE_FLAG_INHERIT = 0x00000001
class YouCompleteMe( object ): class YouCompleteMe( object ):
def __init__( self, user_options ): def __init__( self ):
self._available_completers = {} self._available_completers = {}
self._user_options = user_options self._user_options = None
self._user_notified_about_crash = False self._user_notified_about_crash = False
self._omnicomp = OmniCompleter( user_options ) self._omnicomp = None
self._buffers = BufferDict( user_options ) self._buffers = None
self._latest_completion_request = None self._latest_completion_request = None
self._logger = logging.getLogger( 'ycm' ) self._logger = logging.getLogger( 'ycm' )
self._client_logfile = None self._client_logfile = None
@ -134,6 +133,14 @@ class YouCompleteMe( object ):
self._server_is_ready_with_cache = False self._server_is_ready_with_cache = False
self._message_poll_request = None self._message_poll_request = None
base.LoadJsonDefaultsIntoVim()
user_options_store.SetAll( base.BuildServerConf() )
self._user_options = user_options_store.GetAll()
self._omnicomp = OmniCompleter( self._user_options )
self._buffers = BufferDict( self._user_options )
self._SetLogLevel()
hmac_secret = os.urandom( HMAC_SECRET_LENGTH ) hmac_secret = os.urandom( HMAC_SECRET_LENGTH )
options_dict = dict( self._user_options ) options_dict = dict( self._user_options )
options_dict[ 'hmac_secret' ] = utils.ToUnicode( options_dict[ 'hmac_secret' ] = utils.ToUnicode(
@ -196,12 +203,6 @@ class YouCompleteMe( object ):
self._client_logfile = utils.CreateLogfile( CLIENT_LOGFILE_FORMAT ) self._client_logfile = utils.CreateLogfile( CLIENT_LOGFILE_FORMAT )
log_level = self._user_options[ 'log_level' ]
numeric_level = getattr( logging, log_level.upper(), None )
if not isinstance( numeric_level, int ):
raise ValueError( 'Invalid log level: {0}'.format( log_level ) )
self._logger.setLevel( numeric_level )
handler = logging.FileHandler( self._client_logfile ) handler = logging.FileHandler( self._client_logfile )
# On Windows and Python prior to 3.4, file handles are inherited by child # On Windows and Python prior to 3.4, file handles are inherited by child
@ -221,6 +222,14 @@ class YouCompleteMe( object ):
self._logger.addHandler( handler ) self._logger.addHandler( handler )
def _SetLogLevel( self ):
log_level = self._user_options[ 'log_level' ]
numeric_level = getattr( logging, log_level.upper(), None )
if not isinstance( numeric_level, int ):
raise ValueError( 'Invalid log level: {0}'.format( log_level ) )
self._logger.setLevel( numeric_level )
def IsServerAlive( self ): def IsServerAlive( self ):
# When the process hasn't finished yet, poll() returns None. # When the process hasn't finished yet, poll() returns None.
return bool( self._server_popen ) and self._server_popen.poll() is None return bool( self._server_popen ) and self._server_popen.poll() is None