Passing user options to server now

This commit is contained in:
Strahinja Val Markovic 2013-09-24 12:53:44 -07:00
parent 387621d957
commit 10469d318d
6 changed files with 129 additions and 15 deletions

View File

@ -41,7 +41,8 @@ class BaseRequest( object ):
return {} return {}
def PostDataToHandler( self, data, handler ): @staticmethod
def PostDataToHandler( data, handler ):
response = requests.post( _BuildUri( handler ), response = requests.post( _BuildUri( handler ),
data = json.dumps( data ), data = json.dumps( data ),
headers = HEADERS ) headers = HEADERS )

80
python/ycm/retries.py Normal file
View File

@ -0,0 +1,80 @@
#!/usr/bin/env python
#
# Copyright 2012 by Jeff Laughlin Consulting LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import sys
from time import sleep
# Source: https://gist.github.com/n1ywb/2570004
def example_exc_handler(tries_remaining, exception, delay):
"""Example exception handler; prints a warning to stderr.
tries_remaining: The number of tries remaining.
exception: The exception instance which was raised.
"""
print >> sys.stderr, "Caught '%s', %d tries remaining, sleeping for %s seconds" % (exception, tries_remaining, delay)
def retries(max_tries, delay=1, backoff=2, exceptions=(Exception,), hook=None):
"""Function decorator implementing retrying logic.
delay: Sleep this many seconds * backoff * try number after failure
backoff: Multiply delay by this factor after each failure
exceptions: A tuple of exception classes; default (Exception,)
hook: A function with the signature myhook(tries_remaining, exception);
default None
The decorator will call the function up to max_tries times if it raises
an exception.
By default it catches instances of the Exception class and subclasses.
This will recover after all but the most fatal errors. You may specify a
custom tuple of exception classes with the 'exceptions' argument; the
function will only be retried if it raises one of the specified
exceptions.
Additionally you may specify a hook function which will be called prior
to retrying with the number of remaining tries and the exception instance;
see given example. This is primarily intended to give the opportunity to
log the failure. Hook is not called after failure if no retries remain.
"""
def dec(func):
def f2(*args, **kwargs):
mydelay = delay
tries = range(max_tries)
tries.reverse()
for tries_remaining in tries:
try:
return func(*args, **kwargs)
except exceptions as e:
if tries_remaining > 0:
if hook is not None:
hook(tries_remaining, e, mydelay)
sleep(mydelay)
mydelay = mydelay * backoff
else:
raise
else:
break
return f2
return dec

View File

@ -1 +1 @@
{ "filepath_completion_use_working_dir": 0, "min_num_of_chars_for_completion": 2, "semantic_triggers": {}, "collect_identifiers_from_comments_and_strings": 0, "filetype_specific_completion_to_disable": {}, "collect_identifiers_from_tags_files": 0, "extra_conf_globlist": [ "~\/repos\/*", "\/home\/strahinja\/googrepos\/*", "~\/local_googrepos\/*", "~\/.ycm_extra_conf.py" ], "global_ycm_extra_conf": "\/usr\/lib\/youcompleteme\/ycm_extra_conf.py", "confirm_extra_conf": 1, "complete_in_comments": 0, "complete_in_strings": 1, "min_num_identifier_candidate_chars": 0, "max_diagnostics_to_display": 30, "auto_stop_csharp_server": 1, "seed_identifiers_with_syntax": 0, "csharp_server_port": 2000, "filetype_whitelist": { "*": "1" }, "auto_start_csharp_server": 1, "filetype_blacklist": { "tagbar": "1", "notes": "1", "markdown": "1", "unite": "1", "text": "1" } } { "filepath_completion_use_working_dir": 0, "min_num_of_chars_for_completion": 2, "semantic_triggers": {}, "collect_identifiers_from_comments_and_strings": 0, "filetype_specific_completion_to_disable": {}, "collect_identifiers_from_tags_files": 0, "extra_conf_globlist": [ "~\/repos\/*", "\/home\/strahinja\/googrepos\/*", "~\/local_googrepos\/*", "~\/.ycm_extra_conf.py" ], "global_ycm_extra_conf": "", "confirm_extra_conf": 1, "complete_in_comments": 0, "complete_in_strings": 1, "min_num_identifier_candidate_chars": 0, "max_diagnostics_to_display": 30, "auto_stop_csharp_server": 1, "seed_identifiers_with_syntax": 0, "csharp_server_port": 2000, "filetype_whitelist": { "*": "1" }, "auto_start_csharp_server": 1, "filetype_blacklist": { "tagbar": "1", "notes": "1", "markdown": "1", "unite": "1", "text": "1" } }

View File

@ -32,7 +32,6 @@ sys.path.insert( 0, os.path.join(
import logging import logging
import time import time
import httplib
import json import json
import bottle import bottle
from bottle import run, request, response from bottle import run, request, response
@ -107,20 +106,20 @@ def GetCompletions():
return _JsonResponse( completer.CandidatesFromStoredRequest() ) return _JsonResponse( completer.CandidatesFromStoredRequest() )
@app.route( '/user_options' ) @app.get( '/user_options' )
def UserOptions(): def GetUserOptions():
LOGGER.info( 'Received user options GET request')
return _JsonResponse( dict( SERVER_STATE.user_options ) )
@app.post( '/user_options' )
def SetUserOptions():
global SERVER_STATE global SERVER_STATE
if request.method == 'GET': LOGGER.info( 'Received user options POST request')
LOGGER.info( 'Received user options GET request') data = request.json
return SERVER_STATE.user_options SERVER_STATE = server_state.ServerState( data )
elif request.method == 'POST': user_options_store.SetAll( data )
LOGGER.info( 'Received user options POST request')
data = request.json
SERVER_STATE = server_state.ServerState( data )
user_options_store.SetAll( data )
else:
response.status = httplib.BAD_REQUEST
@app.post( '/filetype_completion_available') @app.post( '/filetype_completion_available')

View File

@ -95,3 +95,15 @@ def FiletypeCompletionAvailable_Works_test():
ok_( app.post_json( '/filetype_completion_available', ok_( app.post_json( '/filetype_completion_available',
request_data ).json ) request_data ).json )
def UserOptions_Works_test():
app = TestApp( server.app )
options = app.get( '/user_options' ).json
ok_( len( options ) )
options[ 'foobar' ] = 'zoo'
app.post_json( '/user_options', options )
eq_( options, app.get( '/user_options' ).json )

View File

@ -21,6 +21,8 @@ import os
import vim import vim
import ycm_core import ycm_core
import subprocess import subprocess
import threading
from ycm.retries import retries
from ycm import vimsupport from ycm import vimsupport
from ycm import utils from ycm import utils
from ycm.completers.all.omni_completer import OmniCompleter from ycm.completers.all.omni_completer import OmniCompleter
@ -41,6 +43,7 @@ class YouCompleteMe( object ):
self._server_stderr = None self._server_stderr = None
self._server_popen = None self._server_popen = None
self._filetypes_with_keywords_loaded = set() self._filetypes_with_keywords_loaded = set()
self._options_thread = None
self._SetupServer() self._SetupServer()
@ -73,6 +76,25 @@ class YouCompleteMe( object ):
stderr = fstderr, stderr = fstderr,
shell = True ) shell = True )
self._StartOptionsThread()
def _StartOptionsThread( self ):
def OptionsThreadMain( options ):
@retries( 5, delay = 0.5 )
def PostOptionsToServer():
BaseRequest.PostDataToHandler( options, 'user_options' )
PostOptionsToServer()
self._options_thread = threading.Thread(
target = OptionsThreadMain,
args = ( dict( self._user_options ), ) )
self._options_thread.daemon = True
self._options_thread.start()
def CreateCompletionRequest( self ): def CreateCompletionRequest( self ):
# We have to store a reference to the newly created CompletionRequest # We have to store a reference to the newly created CompletionRequest