2012-08-04 20:46:54 -04:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# Copyright (C) 2011, 2012 Strahinja Val Markovic <val@markovic.io>
|
|
|
|
#
|
|
|
|
# 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/>.
|
|
|
|
|
2013-09-20 20:24:34 -04:00
|
|
|
import tempfile
|
|
|
|
import os
|
2013-09-23 16:27:32 -04:00
|
|
|
import sys
|
|
|
|
import signal
|
2013-10-03 13:14:31 -04:00
|
|
|
import functools
|
2013-09-20 20:24:34 -04:00
|
|
|
|
2013-10-11 14:11:02 -04:00
|
|
|
WIN_PYTHON27_PATH = 'C:\python27\pythonw.exe'
|
|
|
|
WIN_PYTHON26_PATH = 'C:\python26\pythonw.exe'
|
|
|
|
|
|
|
|
|
2012-08-04 20:46:54 -04:00
|
|
|
def IsIdentifierChar( char ):
|
|
|
|
return char.isalnum() or char == '_'
|
|
|
|
|
|
|
|
|
|
|
|
def SanitizeQuery( query ):
|
|
|
|
return query.strip()
|
2013-04-23 01:19:26 -04:00
|
|
|
|
2013-09-07 14:58:42 -04:00
|
|
|
|
|
|
|
def ToUtf8IfNeeded( string_or_unicode ):
|
|
|
|
if isinstance( string_or_unicode, unicode ):
|
|
|
|
return string_or_unicode.encode( 'utf8' )
|
|
|
|
return string_or_unicode
|
2013-09-20 20:24:34 -04:00
|
|
|
|
|
|
|
|
|
|
|
def PathToTempDir():
|
2013-10-06 21:27:47 -04:00
|
|
|
tempdir = os.path.join( tempfile.gettempdir(), 'ycm_temp' )
|
|
|
|
if not os.path.exists( tempdir ):
|
|
|
|
os.makedirs( tempdir )
|
|
|
|
return tempdir
|
2013-09-23 16:27:32 -04:00
|
|
|
|
|
|
|
|
2013-10-11 14:11:02 -04:00
|
|
|
def PathToPythonInterpreter():
|
|
|
|
# This is a bit tricky. Normally, sys.executable has the full path to the
|
|
|
|
# Python interpreter. But this code is also executed from inside Vim's
|
|
|
|
# embedded Python. On Unix machines, even that Python returns a good value for
|
|
|
|
# sys.executable, but on Windows it returns the path to the Vim binary, which
|
|
|
|
# is useless to us (issue #581). So we check the common install location for
|
|
|
|
# Python on Windows, first for Python 2.7 and then for 2.6.
|
|
|
|
#
|
|
|
|
# I'm open to better ideas on how to do this.
|
|
|
|
|
|
|
|
if OnWindows():
|
|
|
|
if os.path.exists( WIN_PYTHON27_PATH ):
|
|
|
|
return WIN_PYTHON27_PATH
|
|
|
|
elif os.path.exists( WIN_PYTHON26_PATH ):
|
|
|
|
return WIN_PYTHON26_PATH
|
|
|
|
raise RuntimeError( 'Python 2.7/2.6 not installed!' )
|
|
|
|
else:
|
|
|
|
return sys.executable
|
|
|
|
|
|
|
|
|
|
|
|
def OnWindows():
|
|
|
|
return sys.platform == 'win32'
|
|
|
|
|
|
|
|
|
2013-09-23 16:27:32 -04:00
|
|
|
# From here: http://stackoverflow.com/a/8536476/1672783
|
|
|
|
def TerminateProcess( pid ):
|
2013-10-11 14:11:02 -04:00
|
|
|
if OnWindows():
|
2013-09-23 16:27:32 -04:00
|
|
|
import ctypes
|
|
|
|
PROCESS_TERMINATE = 1
|
|
|
|
handle = ctypes.windll.kernel32.OpenProcess( PROCESS_TERMINATE,
|
|
|
|
False,
|
|
|
|
pid )
|
|
|
|
ctypes.windll.kernel32.TerminateProcess( handle, -1 )
|
|
|
|
ctypes.windll.kernel32.CloseHandle( handle )
|
|
|
|
else:
|
|
|
|
os.kill( pid, signal.SIGTERM )
|
2013-10-01 19:21:17 -04:00
|
|
|
|
|
|
|
|
|
|
|
def AddThirdPartyFoldersToSysPath():
|
|
|
|
path_to_third_party = os.path.join(
|
|
|
|
os.path.dirname( os.path.abspath( __file__ ) ),
|
|
|
|
'../../third_party' )
|
|
|
|
|
|
|
|
for folder in os.listdir( path_to_third_party ):
|
|
|
|
sys.path.insert( 0, os.path.realpath( os.path.join( path_to_third_party,
|
|
|
|
folder ) ) )
|
|
|
|
|
2013-10-03 13:14:31 -04:00
|
|
|
def Memoize( obj ):
|
|
|
|
cache = obj.cache = {}
|
2013-10-01 19:21:17 -04:00
|
|
|
|
2013-10-03 13:14:31 -04:00
|
|
|
@functools.wraps( obj )
|
|
|
|
def memoizer( *args, **kwargs ):
|
|
|
|
key = str( args ) + str( kwargs )
|
|
|
|
if key not in cache:
|
|
|
|
cache[ key ] = obj( *args, **kwargs )
|
|
|
|
return cache[ key ]
|
|
|
|
return memoizer
|
2013-10-07 16:09:34 -04:00
|
|
|
|
|
|
|
|
|
|
|
def ForceSemanticCompletion( request_data ):
|
|
|
|
return ( 'force_semantic' in request_data and
|
|
|
|
bool( request_data[ 'force_semantic' ] ) )
|