<s> import os <EOL> import re <EOL> from deoplete . sources . base import Base <EOL> from deoplete . util import load_external_module <EOL> current = __file__ <EOL> load_external_module ( current , '<STR_LIT>' ) <EOL> import clang . cindex as clang <EOL> load_external_module ( current , '<STR_LIT>' ) <EOL> from clang_data import index_h <EOL> class Source ( Base ) : <EOL> def __init__ ( self , vim ) : <EOL> Base . __init__ ( self , vim ) <EOL> self . name = '<STR_LIT>' <EOL> self . mark = '<STR_LIT>' <EOL> self . filetypes = [ '<STR_LIT:c>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> self . rank = <NUM_LIT> <EOL> self . input_pattern = ( r'<STR_LIT>' <EOL> r'<STR_LIT>' <EOL> r'<STR_LIT>' ) <EOL> self . debug_enabled = self . vim . vars [ "<STR_LIT>" ] <EOL> self . library_path = self . vim . vars [ '<STR_LIT>' ] <EOL> self . clang_header = self . vim . vars [ '<STR_LIT>' ] <EOL> self . completion_flags = self . vim . vars [ "<STR_LIT>" ] <EOL> self . sort_algo = self . vim . vars [ "<STR_LIT>" ] <EOL> self . std = self . vim . vars [ "<STR_LIT>" ] <EOL> self . std_c = self . std . get ( '<STR_LIT:c>' ) <EOL> self . std_cpp = self . std . get ( '<STR_LIT>' ) <EOL> self . std_objc = self . std . get ( '<STR_LIT>' ) <EOL> self . std_objcpp = self . std . get ( '<STR_LIT>' ) <EOL> clang_complete_database = self . vim . vars [ '<STR_LIT>' ] <EOL> if clang . Config . loaded and clang . Config . library_path != self . library_path : <EOL> clang . Config . loaded = False <EOL> clang . Config . set_library_file ( self . library_path ) <EOL> clang . Config . set_compatibility_check ( False ) <EOL> if clang_complete_database : <EOL> self . compilation_database = clang . CompilationDatabase . fromDirectory ( <EOL> clang_complete_database ) <EOL> else : <EOL> self . compilation_database = None <EOL> self . index = clang . Index . create ( ) <EOL> self . tu_data , self . params , self . database = dict ( ) , dict ( ) , dict ( ) <EOL> def get_complete_position ( self , context ) : <EOL> m = re . search ( r'<STR_LIT>' , context [ '<STR_LIT:input>' ] ) <EOL> return m . start ( ) if m else - <NUM_LIT:1> <EOL> def gather_candidates ( self , context ) : <EOL> line = context [ '<STR_LIT>' ] [ <NUM_LIT:1> ] <EOL> col = ( context [ '<STR_LIT>' ] + <NUM_LIT:1> ) <EOL> buf = self . vim . current . buffer <EOL> if self . compilation_database : <EOL> params = self . get_params ( buf . name ) <EOL> else : <EOL> params = self . completion_flags + self . get_minimum_flags ( context [ '<STR_LIT>' ] ) <EOL> params . append ( '<STR_LIT>' + self . get_builtin_clang_header ( ) ) <EOL> complete = self . get_completion ( <EOL> buf . name , line , col , <EOL> self . get_current_buffer ( buf ) , <EOL> params ) <EOL> if complete is None : <EOL> return [ ] <EOL> if self . sort_algo == '<STR_LIT>' : <EOL> get_priority = lambda x : x . string . priority <EOL> results = sorted ( complete . results , key = get_priority ) <EOL> elif self . sort_algo == '<STR_LIT>' : <EOL> get_abbrevation = lambda x : self . get_abbr ( x . string ) . lower ( ) <EOL> results = sorted ( complete . results , key = get_abbrevation ) <EOL> else : <EOL> results = complete . results <EOL> return list ( map ( self . parse_candidates , results ) ) <EOL> def get_current_buffer ( self , b ) : <EOL> return [ ( b . name , '<STR_LIT:\n>' . join ( b [ : ] ) ) ] <EOL> def get_abbr ( self , strings ) : <EOL> for chunks in strings : <EOL> if chunks . isKindTypedText ( ) : <EOL> return chunks . spelling <EOL> return "<STR_LIT>" <EOL> def get_minimum_flags ( self , filetype ) : <EOL> flags = [ '<STR_LIT>' ] <EOL> if filetype == '<STR_LIT:c>' : <EOL> flags += [ '<STR_LIT:c>' , '<STR_LIT>' + self . std_c ] <EOL> elif filetype == '<STR_LIT>' : <EOL> flags += [ '<STR_LIT>' , '<STR_LIT>' + self . std_cpp ] <EOL> elif filetype == '<STR_LIT>' : <EOL> flags += [ '<STR_LIT>' , '<STR_LIT>' + self . std_objc ] <EOL> elif filetype == '<STR_LIT>' : <EOL> flags += [ '<STR_LIT>' , '<STR_LIT>' + self . std_objcpp ] <EOL> return flags <EOL> def get_builtin_clang_header ( self ) : <EOL> include_dir = self . clang_header <EOL> if not include_dir : <EOL> return '<STR_LIT>' <EOL> versions = os . listdir ( include_dir ) <EOL> sorted ( versions ) <EOL> latest = versions [ - <NUM_LIT:1> ] <EOL> return os . path . join ( include_dir , latest , '<STR_LIT>' ) <EOL> def get_params ( self , fname ) : <EOL> if fname in self . params : <EOL> return self . params [ fname ] <EOL> else : <EOL> return self . get_compile_params ( fname ) <EOL> def get_compile_params ( self , fname ) : <EOL> if fname in self . database : <EOL> params = self . database [ fname ] <EOL> else : <EOL> params = self . get_compilation_database ( os . path . abspath ( fname ) ) <EOL> header = self . get_builtin_clang_header ( ) <EOL> if header : <EOL> params . append ( '<STR_LIT>' + header ) <EOL> self . params [ fname ] = params <EOL> return params <EOL> def get_compilation_database ( self , fname ) : <EOL> params = self . completion_flags <EOL> if self . compilation_database : <EOL> cmds = self . compilation_database . getCompileCommands ( fname ) [ <NUM_LIT:0> ] <EOL> if cmds is not None : <EOL> cwd = cmds . directory <EOL> skip = <NUM_LIT:1> <EOL> for arg in cmds . arguments : <EOL> if skip or arg in [ '<STR_LIT:-c>' , fname , <EOL> os . path . realpath ( os . path . join ( cwd , arg ) ) ] : <EOL> skip = <NUM_LIT:0> <EOL> continue <EOL> elif arg == '<STR_LIT>' : <EOL> skip = <NUM_LIT:1> <EOL> continue <EOL> elif arg . startswith ( '<STR_LIT>' ) : <EOL> include_path = arg [ <NUM_LIT:2> : ] <EOL> if not os . path . isabs ( include_path ) : <EOL> include_path = os . path . normpath ( <EOL> os . path . join ( cwd , include_path ) ) <EOL> params . append ( '<STR_LIT>' + include_path ) <EOL> continue <EOL> params . append ( arg ) <EOL> self . database [ fname ] = params <EOL> return params <EOL> def get_translation_unit ( self , fname , args , buf ) : <EOL> flags = <NUM_LIT:15> <EOL> ast_file = fname + "<STR_LIT>" <EOL> if os . path . exists ( ast_file ) : <EOL> tu = self . index . read ( ast_file ) <EOL> else : <EOL> tu = self . index . parse ( fname , args , buf , flags ) <EOL> tu . save ( ast_file ) <EOL> tu . reparse ( buf ) <EOL> os . remove ( ast_file ) <EOL> self . tu_data [ fname ] = tu <EOL> return tu <EOL> def get_completion ( self , fname , line , column , buf , args ) : <EOL> if fname in self . tu_data : <EOL> tu = self . tu_data [ fname ] <EOL> else : <EOL> tu = self . get_translation_unit ( fname , args , buf ) <EOL> return tu . codeComplete ( fname , line , column , buf , <EOL> include_macros = False , <EOL> include_code_patterns = False , <EOL> include_brief_comments = False ) <EOL> def parse_candidates ( self , result ) : <EOL> completion = { '<STR_LIT>' : <NUM_LIT:1> } <EOL> _type = "<STR_LIT>" <EOL> word = "<STR_LIT>" <EOL> placeholder = "<STR_LIT>" <EOL> for chunk in [ x for x in result . string if x . spelling ] : <EOL> chunk_spelling = chunk . spelling <EOL> if chunk . isKindTypedText ( ) : <EOL> word += chunk_spelling <EOL> placeholder += chunk_spelling <EOL> continue <EOL> elif chunk . isKindResultType ( ) : <EOL> _type += chunk_spelling <EOL> else : <EOL> placeholder += chunk_spelling <EOL> completion [ '<STR_LIT>' ] = word <EOL> completion [ '<STR_LIT>' ] = completion [ '<STR_LIT:info>' ] = placeholder <EOL> completion [ '<STR_LIT>' ] = '<STR_LIT:U+0020>' . join ( <EOL> [ ( index_h . kinds [ result . cursorKind ] <EOL> if ( result . cursorKind in index_h . kinds ) <EOL> else str ( result . cursorKind ) ) , _type ] ) <EOL> return completion </s>
