Skip to content

Commit

Permalink
Handle C# completion for non-ascii files better
Browse files Browse the repository at this point in the history
  • Loading branch information
metatheos committed Dec 28, 2014
1 parent dc4af48 commit 3d7cdd7
Show file tree
Hide file tree
Showing 12 changed files with 32 additions and 31 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
[submodule "third_party/waitress"]
path = third_party/waitress
url = https://github.com/Pylons/waitress
[submodule "third_party/requests"]
path = third_party/requests
url = https://github.com/kennethreitz/requests
1 change: 1 addition & 0 deletions third_party/requests
Submodule requests added at 431282
18 changes: 7 additions & 11 deletions ycmd/completers/cs/cs_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@
from ycmd.completers.completer import Completer
from ycmd import responses
from ycmd import utils
import urllib2
import urllib
import requests
import urlparse
import json
import logging
import solutiondetection

Expand Down Expand Up @@ -237,7 +235,7 @@ def _StartServer( self, request_data ):

if not path_to_solutionfile:
raise RuntimeError( 'Autodetection of solution file failed.\n' )
self._logger.info( 'Loading solution file {0}'.format( path_to_solutionfile ) )
self._logger.info( u'Loading solution file {0}'.format( path_to_solutionfile ) )

self._omnisharp_port = utils.GetUnusedLocalhostPort()

Expand All @@ -247,16 +245,16 @@ def _StartServer( self, request_data ):
'-p',
str( self._omnisharp_port ),
'-s',
'"{0}"'.format( path_to_solutionfile ) ] )
u'"{0}"'.format( path_to_solutionfile ) ] )

if not utils.OnWindows() and not utils.OnCygwin():
command = 'mono ' + command
command = u'mono ' + command

if utils.OnCygwin():
command = command + ' --client-path-mode Cygwin'

filename_format = os.path.join( utils.PathToTempDir(),
'omnisharp_{port}_{sln}_{std}.log' )
u'omnisharp_{port}_{sln}_{std}.log' )

solutionfile = os.path.basename( path_to_solutionfile )
self._filename_stdout = filename_format.format(
Expand Down Expand Up @@ -392,11 +390,9 @@ def _ServerLocation( self ):

def _GetResponse( self, handler, parameters = {}, silent = False ):
""" Handle communication with server """
# TODO: Replace usage of urllib with Requests
target = urlparse.urljoin( self._ServerLocation(), handler )
parameters = urllib.urlencode( parameters )
response = urllib2.urlopen( target, parameters )
return json.loads( response.read() )
response = requests.post( target, data = parameters )
return response.json()



Expand Down
28 changes: 14 additions & 14 deletions ycmd/completers/cs/solutiondetection.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ def PollModule( module, filepath ):
if module:
try:
module_hint = module.CSharpSolutionFile( filepath )
__logger.info( 'extra_conf_store suggests {0} as solution file'.format(
str( module_hint ) ) )
__logger.info( u'extra_conf_store suggests {0} as solution file'.format(
unicode( module_hint ) ) )
if module_hint:
# received a full path or one relative to the config's location?
candidates = [ module_hint,
Expand All @@ -41,22 +41,22 @@ def PollModule( module, filepath ):
# path seems to point to a solution
path_to_solutionfile = path
__logger.info(
'Using solution file {0} selected by extra_conf_store'.format(
u'Using solution file {0} selected by extra_conf_store'.format(
path_to_solutionfile ) )
break
except AttributeError as e:
# the config script might not provide solution file locations
__logger.error(
'Could not retrieve solution for {0} from extra_conf_store: {1}'.format(
filepath, str( e ) ) )
u'Could not retrieve solution for {0} from extra_conf_store: {1}'.format(
filepath, unicode( e ) ) )
return path_to_solutionfile

def GuessFile( filepath ):
""" Find solution files by searching upwards in the file tree """
tokens = _PathComponents( filepath )
for i in reversed( range( len( tokens ) - 1 ) ):
path = os.path.join( *tokens[ : i + 1 ] )
candidates = glob.glob1( path, "*.sln" )
candidates = glob.glob1( path, '*.sln' )
if len( candidates ) > 0:
# do the whole procedure only for the first solution file(s) you find
return _SolutionTestCheckHeuristics( candidates, tokens, i )
Expand All @@ -70,25 +70,25 @@ def _SolutionTestCheckHeuristics( candidates, tokens, i ):
if len( candidates ) == 1 :
selection = os.path.join( path, candidates[ 0 ] )
__logger.info(
'Selected solution file {0} as it is the first one found'.format(
u'Selected solution file {0} as it is the first one found'.format(
selection ) )
# there is more than one file, try some hints to decide
# 1. is there a solution named just like the subdirectory with the source?
if ( not selection and i < len( tokens ) - 1 and
"{0}.sln".format( tokens[ i + 1 ] ) in candidates ) :
selection = os.path.join( path, "{0}.sln".format( tokens[ i + 1 ] ) )
u'{0}.sln'.format( tokens[ i + 1 ] ) in candidates ) :
selection = os.path.join( path, u'{0}.sln'.format( tokens[ i + 1 ] ) )
__logger.info(
'Selected solution file {0} as it matches source subfolder'.format(
u'Selected solution file {0} as it matches source subfolder'.format(
selection ) )
# 2. is there a solution named just like the directory containing the solution?
if not selection and "{0}.sln".format( tokens[ i ] ) in candidates :
selection = os.path.join( path, "{0}.sln".format( tokens[ i ] ) )
if not selection and u'{0}.sln'.format( tokens[ i ] ) in candidates :
selection = os.path.join( path, u'{0}.sln'.format( tokens[ i ] ) )
__logger.info(
'Selected solution file {0} as it matches containing folder'.format(
u'Selected solution file {0} as it matches containing folder'.format(
selection ) )
if not selection:
__logger.error(
'Could not decide between multiple solution files:\n{0}'.format(
u'Could not decide between multiple solution files:\n{0}'.format(
candidates ) )
return selection

Expand Down
8 changes: 4 additions & 4 deletions ycmd/tests/diagnostics_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,16 +167,16 @@ def Diagnostics_CsCompleter_ZeroBasedLineAndColumn_test():
'text': contains_string(
"Unexpected symbol `}'', expecting identifier" ),
'location': has_entries( {
'line_num': 10,
'line_num': 11,
'column_num': 2
} ),
'location_extent': has_entries( {
'start': has_entries( {
'line_num': 10,
'line_num': 11,
'column_num': 2,
} ),
'end': has_entries( {
'line_num': 10,
'line_num': 11,
'column_num': 2,
} ),
} )
Expand Down Expand Up @@ -232,7 +232,7 @@ def GetDetailedDiagnostic_CsCompleter_Works_test():
diag_data = BuildRequest( filepath = filepath,
filetype = 'cs',
contents = contents,
line_num = 10,
line_num = 11,
column_num = 2 )

results = app.post_json( '/detailed_diagnostic', diag_data ).json
Expand Down
4 changes: 2 additions & 2 deletions ycmd/tests/get_completions_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def GetCompletions_CsCompleter_Works_test():
completion_data = BuildRequest( filepath = filepath,
filetype = 'cs',
contents = contents,
line_num = 9,
line_num = 10,
column_num = 12 )
response_data = app.post_json( '/completions', completion_data ).json
assert_that( response_data[ 'completions' ],
Expand All @@ -144,7 +144,7 @@ def GetCompletions_CsCompleter_PathWithSpace_test():
app = TestApp( handlers.app )
app.post_json( '/ignore_extra_conf_file',
{ 'filepath': PathToTestFile( '.ycm_extra_conf.py' ) } )
filepath = PathToTestFile( 'cs spacetest/Program.cs' )
filepath = PathToTestFile( 'неприличное слово/Program.cs' )
contents = open( filepath ).read()
event_data = BuildRequest( filepath = filepath,
filetype = 'cs',
Expand Down
1 change: 1 addition & 0 deletions ycmd/tests/testdata/testy/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class MainClass
{
public static void Main (string[] args)
{
int = 9;
Console.
}
}
Expand Down

0 comments on commit 3d7cdd7

Please sign in to comment.