def __init__(self, vim: Nvim): self.name = 'core' self._vim = vim self._runtimepath = '' self._runtimepath_list: typing.List[str] = [] self._custom: typing.Dict[str, typing.Dict[str, typing.Any]] = {} self._loaded_paths: typing.Set[str] = set() self._prev_results: typing.Dict[int, Candidates] = {} self._prev_input = '' self._prev_next_input = '' self._context: typing.Optional[Context] = None self._parents: typing.List[Parent] = [] self._parent_count = 0 self._max_parents = self._vim.call('deoplete#custom#_get_option', 'num_processes') if self._max_parents != 1 and not hasattr(self._vim, 'loop'): msg = ('pynvim 0.3.0+ is required for %d parents. ' 'Using single process.' % self._max_parents) error(self._vim, msg) self._max_parents = 1 # Enable logging for more information, and e.g. # deoplete-jedi picks up the log filename from deoplete's handler in # its on_init. if self._vim.vars['deoplete#_logging']: self.enable_logging() if hasattr(self._vim, 'channel_id'): self._vim.vars['deoplete#_channel_id'] = self._vim.channel_id self._vim.vars['deoplete#_initialized'] = True
def filter(self, context): if (not context['candidates'] or not context['input'] or self.fruzzy is False): return context['candidates'] if self.fruzzy is None: errmsg = self._init_fruzzy(context) if errmsg: error(self.vim, 'matcher_fruzzy: %s' % errmsg) return [] qry = context['complete_str'] if context['ignorecase']: qry = qry.lower() candidates = context['candidates'] key = None ispath = candidates and 'action__path' in candidates[0] buf = context['bufnr'] buf = int(buf) if isinstance(buf, str) else buf sort_on_empty_query = self.vim.vars.get("fruzzy#sortonempty", 1) results = self.get_fruzzy_result(qry, candidates, 1000, key=key, ispath=ispath, buf=buf, sortonempty=sort_on_empty_query) return [w[0] for w in results]
def completion_begin(self, context): pos = self.vim.current.window.cursor try: complete_position, candidates = self.gather_candidates(context) except Exception: for line in traceback.format_exc().splitlines(): error(self.vim, line) error(self.vim, 'An error has occurred. Please execute :messages command.') candidates = [] if not candidates or self.vim.funcs.mode() != 'i' \ or pos != self.vim.current.window.cursor: self.vim.vars['deoplete#_context'] = {} return var_context = {} var_context['complete_position'] = complete_position var_context['changedtick'] = context['changedtick'] var_context['candidates'] = candidates self.vim.vars['deoplete#_context'] = var_context # Set (and store) current &completeopt setting. This cannot be done # (currently) from the deoplete_start_complete mapping's function. self.vim.call('deoplete#mappings#_set_completeopt') # Note: cannot use vim.feedkeys() self.vim.command( 'call feedkeys("\<Plug>(deoplete_start_complete)")')
def completion_begin(self, context): pos = self.__vim.current.window.cursor if context["event"] != "Manual" and context["delay"] > 0: time.sleep(context["delay"] / 1000.0) if self.position_has_changed(pos): return try: complete_position, candidates = self.gather_candidates(context) except Exception: for line in traceback.format_exc().splitlines(): error(self.__vim, line) error(self.__vim, "An error has occurred. Please execute :messages command.") candidates = [] if not candidates or self.position_has_changed(pos): self.__vim.vars["deoplete#_context"] = {} return self.__vim.vars["deoplete#_context"] = { "complete_position": complete_position, "changedtick": context["changedtick"], "candidates": candidates, "event": context["event"], } if context["rpc"] != "deoplete_manual_completion_begin": # Set (and store) current &completeopt setting. This cannot be # done (currently) from the deoplete_start_complete mapping's # function. self.__vim.call("deoplete#mappings#_set_completeopt") # Note: cannot use vim.feedkeys() self.__vim.command('call feedkeys("\<Plug>(deoplete_start_complete)")')
def __init__(self, vim): self.name = 'core' self._vim = vim self._runtimepath = '' self._custom = [] self._loaded_paths = set() self._prev_merged_results = {} self._prev_pos = [] self._prev_next_input = '' self._parents = [] self._parent_count = 0 self._max_parents = self._vim.call('deoplete#custom#_get_option', 'num_processes') if self._max_parents != 1 and not hasattr(self._vim, 'loop'): error(self._vim, 'neovim-python 0.2.4+ is required.') return # Enable logging for more information, and e.g. # deoplete-jedi picks up the log filename from deoplete's handler in # its on_init. if self._vim.vars['deoplete#_logging']: self.enable_logging() # Initialization context = self._vim.call('deoplete#init#_context', 'Init', []) context['rpc'] = 'deoplete_on_event' self._check_recache(context) if hasattr(self._vim, 'channel_id'): self._vim.vars['deoplete#_channel_id'] = self._vim.channel_id self._vim.vars['deoplete#_initialized'] = True
def filter(self, context): if not context['candidates'] or not context['input'] or self._disabled: return context['candidates'] if not self._initialized: # cpsm installation check ext = '.pyd' if context['is_windows'] else '.so' if globruntime(context['runtimepath'], 'bin/cpsm_py' + ext): # Add path sys.path.append( os.path.dirname( globruntime(context['runtimepath'], 'bin/cpsm_py' + ext)[0])) self._initialized = True else: error( self.vim, 'matcher_cpsm: bin/cpsm_py' + ext + ' is not found in your runtimepath.') error( self.vim, 'matcher_cpsm: You must install/build' + ' Python3 support enabled cpsm.') self._disabled = True return [] cpsm_result = self._get_cpsm_result(context['candidates'], context['complete_str']) return [ x for x in context['candidates'] if x['word'] in sorted(cpsm_result, key=cpsm_result.index) ]
def get_complete_position(self, context): if self.__use_previous_result(context): return self.__prev_pos omnifunc = get_buffer_config( self.vim, context, "b:deoplete_omni_functions", "g:deoplete#omni#functions", "g:deoplete#omni#_functions" ) if omnifunc == "": omnifunc = self.vim.eval("&l:omnifunc") if omnifunc == "" or omnifunc == "ccomplete#Complete": return -1 for input_pattern in convert2list( get_buffer_config( self.vim, context, "b:deoplete_omni_input_patterns", "g:deoplete#omni#input_patterns", "g:deoplete#omni#_input_patterns", ) ): m = re.search("(" + input_pattern + ")$", context["input"]) if input_pattern == "" or (context["event"] != "Manual" and m is None): continue try: complete_pos = self.vim.call(omnifunc, 1, "") except: error(self.vim, "Error occurred calling omnifunction: " + omnifunc) return -1 return complete_pos return -1
def filter(self, context): if not context['candidates'] or not context[ 'input'] or self._disabled: return context['candidates'] if not self._initialized: # cpsm installation check ext = '.pyd' if context['is_windows'] else '.so' if globruntime(context['runtimepath'], 'bin/cpsm_py' + ext): # Add path sys.path.append(os.path.dirname( globruntime(context['runtimepath'], 'bin/cpsm_py' + ext)[0])) self._initialized = True else: error(self.vim, 'matcher_cpsm: bin/cpsm_py' + ext + ' is not found in your runtimepath.') error(self.vim, 'matcher_cpsm: You must install/build' + ' Python3 support enabled cpsm.') self._disabled = True return [] cpsm_result = self._get_cpsm_result( context['candidates'], context['complete_str']) return [x for x in context['candidates'] if x['word'] in sorted(cpsm_result, key=cpsm_result.index)]
def get_complete_position(self, context): # Check member prefix pattern. if self.vim.eval('&l:omnifunc') == '': return -1 for input_pattern in convert2list( get_default_buffer_config( self.vim, context, 'b:deoplete_omni_input_patterns', 'g:deoplete#omni#input_patterns', 'g:deoplete#omni#_input_patterns')): m = re.search('(' + input_pattern + ')$', context['input']) if m is None or input_pattern == '': continue try: complete_pos = self.vim.call( self.vim.eval('&l:omnifunc'), 1, '') except: error(self.vim, 'Error occurred calling omnifunction: ' + self.vim.eval('&l:omnifunc')) return -1 return complete_pos return -1
def __init__(self, vim): self.name = 'core' self._vim = vim self._runtimepath = '' self._runtimepath_list = [] self._custom = [] self._loaded_paths = set() self._prev_results = {} self._prev_input = '' self._prev_next_input = '' self._context = None self._parents = [] self._parent_count = 0 self._max_parents = self._vim.call('deoplete#custom#_get_option', 'num_processes') if self._max_parents != 1 and not hasattr(self._vim, 'loop'): msg = ('pynvim 0.3.0+ is required for %d parents. ' 'Using single process.' % self._max_parents) error(self._vim, msg) self._max_parents = 1 # Enable logging for more information, and e.g. # deoplete-jedi picks up the log filename from deoplete's handler in # its on_init. if self._vim.vars['deoplete#_logging']: self.enable_logging() if hasattr(self._vim, 'channel_id'): self._vim.vars['deoplete#_channel_id'] = self._vim.channel_id self._vim.vars['deoplete#_initialized'] = True
def get_complete_position(self, context): if self.__use_previous_result(context): return self.__prev_pos omnifunc = get_buffer_config(self.vim, context, 'b:deoplete_omni_functions', 'g:deoplete#omni#functions', 'g:deoplete#omni#_functions') if omnifunc == '': omnifunc = self.vim.eval('&l:omnifunc') if omnifunc == '' or omnifunc == 'ccomplete#Complete': return -1 for input_pattern in convert2list( get_buffer_config(self.vim, context, 'b:deoplete_omni_input_patterns', 'g:deoplete#omni#input_patterns', 'g:deoplete#omni#_input_patterns')): m = re.search('(' + input_pattern + ')$', context['input']) if input_pattern == '' or (context['event'] != 'Manual' and m is None): continue try: complete_pos = self.vim.call(omnifunc, 1, '') except: error(self.vim, 'Error occurred calling omnifunction: ' + omnifunc) return -1 return complete_pos return -1
def completion_begin(self, context): if context['event'] != 'Manual' and context['delay'] > 0: time.sleep(context['delay'] / 1000.0) if self.position_has_changed(context['changedtick']): return try: complete_position, candidates = self.gather_candidates(context) except Exception: for line in traceback.format_exc().splitlines(): error(self.__vim, line) error(self.__vim, 'An error has occurred. Please execute :messages command.') candidates = [] if not candidates or self.position_has_changed( context['changedtick']): return self.__vim.vars['deoplete#_context'] = { 'complete_position': complete_position, 'changedtick': context['changedtick'], 'candidates': candidates, 'event': context['event'], } self.__vim.feedkeys(context['start_complete'])
def _itersource(self, context): filetypes = context['filetypes'] ignore_sources = set(self._ignore_sources) for ft in filetypes: ignore_sources.update( self._vim.call('deoplete#custom#_get_filetype_option', 'ignore_sources', ft, [])) for source_name, source in self._get_sources().items(): if source.filetypes is None or source_name in ignore_sources: continue if context['sources'] and source_name not in context['sources']: continue if source.filetypes and not any(x in filetypes for x in source.filetypes): continue if not source.is_initialized and hasattr(source, 'on_init'): self.debug('on_init Source: %s', source.name) try: source.on_init(context) except Exception as exc: if isinstance(exc, SourceInitError): error(self._vim, 'Error when loading source ' f'{source_name}: {exc}. Ignoring.') else: error_tb(self._vim, 'Error when loading source ' f'{source_name}: {exc}. Ignoring.') self._ignore_sources.append(source_name) continue else: source.is_initialized = True yield source_name, source
def _itersource(self, context): filetypes = context['filetypes'] ignore_sources = set(self._ignore_sources) for ft in filetypes: ignore_sources.update( self._vim.call('deoplete#custom#_get_filetype_option', 'ignore_sources', ft, [])) for source_name, source in self._get_sources().items(): if source.filetypes is None or source_name in ignore_sources: continue if context['sources'] and source_name not in context['sources']: continue if source.filetypes and not any(x in filetypes for x in source.filetypes): continue if not source.is_initialized and hasattr(source, 'on_init'): self.debug('on_init Source: %s', source.name) try: source.on_init(context) except Exception as exc: if isinstance(exc, SourceInitError): error( self._vim, 'Error when loading source ' f'{source_name}: {exc}. Ignoring.') else: error_tb( self._vim, 'Error when loading source ' f'{source_name}: {exc}. Ignoring.') self._ignore_sources.append(source_name) continue else: source.is_initialized = True yield source_name, source
def gather_candidates(self, context): buffer = self.vim.current.buffer if self.cgo and re.search(r'[^\W\d]*C\.', context['input']): if self.cgo_get_include_header(buffer)[0] == 0: pass elif self.cgo_headers == self.cgo_get_include_header(buffer)[1]: return self.cgo_cache[self.cgo_headers] else: count, self.cgo_headers = self.cgo_get_include_header(buffer) return self.cgo_complete(count, self.cgo_headers) result = self.get_cache(context, buffer) if result is None: result = self.get_complete_result(buffer, context) try: if result[1][0]['class'] == 'PANIC': error(self.vim, 'gocode panicked') return [] if self.sort_class: class_dict = OrderedDict((x, []) for x in self.sort_class) out = [] sep = ' ' for complete in result[1]: word = complete['name'] info = complete['type'] _class = complete['class'] abbr = str(word + sep + info).replace(' func', '', 1) kind = _class if _class == 'package' and self.package_dot: word += '.' if self.pointer and \ str(context['input'] [context['complete_position']:]) == '*': word = '*' + word candidates = dict(word=word, abbr=abbr, kind=kind, info=info, dup=1) if not self.sort_class or _class == 'import': out.append(candidates) else: class_dict[_class].append(candidates) if self.sort_class: for v in class_dict.values(): out += v return out except Exception: return []
def _set_source_attributes(self, context: UserContext) -> None: """Set source attributes from the context. Each item in `attrs` is the attribute name. """ attrs = ( 'camel_case', 'converters', 'disabled_syntaxes', 'dup', 'filetypes', 'ignore_case', 'input_pattern', 'input_patterns', 'is_debug_enabled', 'is_silent', 'is_volatile', 'mark', 'matchers', 'max_abbr_width', 'max_candidates', 'max_info_width', 'max_kind_width', 'max_menu_width', 'max_pattern_length', 'min_pattern_length', 'smart_case', 'sorters', ) for name, source in self._get_sources().items(): self.debug('Set Source attributes: %s', name) # type: ignore source.dup = bool(source.filetypes) for attr in attrs: source_attr = getattr(source, attr, None) custom = get_custom(context['custom'], name, attr, source_attr) if type(getattr(source, attr)) != type(custom): # Type check error( self._vim, f'source {source.name}: ' f'custom attr "{attr}" is wrong type.') elif custom and isinstance(source_attr, dict): # Update values if it is dict source_attr.update(custom) else: setattr(source, attr, custom) self.debug( 'Attribute: %s (%s)', # type: ignore attr, getattr(source, attr)) # Default min_pattern_length if source.min_pattern_length < 0: source.min_pattern_length = self._vim.call( 'deoplete#custom#_get_option', 'min_pattern_length')
def gather_candidates(self, context): """ Main deoplete method returns completions from client.py """ # reload if last reload expired or input completion is a method extraction # pylint: disable=locally-disabled, line-too-long try: if time() - self._last_input_reload > RELOAD_INTERVAL or re.search( r"\w*\.", context["input"]): self._last_input_reload = time() self.reload() data = self._client.completions( file=self.relative_file(), line=context["position"][1], offset=context["complete_position"] + 1, prefix=context["complete_str"]) # self.log(data) if len(data) == 0: return [] if len(data) > self._max_completion_detail: filtered = [] for entry in data: if entry["kind"] != "warning": filtered.append(entry) return [self._convert_completion_data(e) for e in filtered] names = [] maxNameLength = 0 for entry in data: if entry["kind"] != "warning": names.append(entry["name"]) maxNameLength = max(maxNameLength, len(entry["name"])) detailed_data = self._client.completion_entry_details( file=self.relative_file(), line=context["position"][1], offset=context["complete_position"] + 1, entry_names=names) if len(detailed_data) == 0: return [] return [ self._convert_detailed_completion_data(e, padding=maxNameLength) for e in detailed_data ] except: e = sys.exc_info()[0] error(self.vim, "<p>Error: %s</p>" % e) return []
def gather_candidates(self, context): # If enabled self.cgo, and matched self.cgo_complete_pattern pattern if self.cgo and self.cgo_complete_pattern.search(context['input']): return self.cgo_completion(getlines(self.vim)) result = self.get_cache(context, getlines(self.vim)) if result is None: bufname = self.vim.current.buffer.name if not os.path.isfile(bufname): bufname = self.vim.call('tempname') result = self.get_complete_result(context, getlines(self.vim), bufname) try: if result[1][0]['class'] == 'PANIC': error(self.vim, 'gocode panicked') return [] if self.sort_class: class_dict = OrderedDict((x, []) for x in self.sort_class) out = [] sep = ' ' for complete in result[1]: word = complete['name'] info = complete['type'] _class = complete['class'] abbr = str(word + sep + info).replace(' func', '', 1) kind = _class if _class == 'package' and self.package_dot: word += '.' if self.pointer and \ str(context['input'] [context['complete_position']:]) == '*': word = '*' + word candidates = dict(word=word, abbr=abbr, kind=kind, info=info, dup=1) if not self.sort_class or _class == 'import': out.append(candidates) elif _class in class_dict.keys(): class_dict[_class].append(candidates) if self.sort_class: for v in class_dict.values(): out += v return out except Exception: return []
def gather_candidates(self, context): try: candidates = self.vim.call( self.vim.eval('&l:omnifunc'), 0, context['complete_str']) except: error(self.vim, 'Error occurred calling omnifunction: ' + self.vim.eval('&l:omnifunc')) candidates = [] return candidates
def gather_candidates(self, context): # If enabled self.cgo, and matched self.cgo_complete_pattern pattern if self.cgo and self.cgo_complete_pattern.search(context['input']): return self.cgo_completion(getlines(self.vim)) result = self.get_cache(context, getlines(self.vim)) if result is None: bufname = self.vim.current.buffer.name if not os.path.isfile(bufname): bufname = self.vim.call('tempname') result = self.get_complete_result( context, getlines(self.vim), bufname) try: if result[1][0]['class'] == 'PANIC': error(self.vim, 'gocode panicked') return [] if self.sort_class: class_dict = OrderedDict((x, []) for x in self.sort_class) out = [] sep = ' ' for complete in result[1]: word = complete['name'] info = complete['type'] _class = complete['class'] abbr = str(word + sep + info).replace(' func', '', 1) kind = _class if _class == 'package' and self.package_dot: word += '.' if self.pointer and \ str(context['input'] [context['complete_position']:]) == '*': word = '*' + word candidates = dict( word=word, abbr=abbr, kind=kind, info=info, dup=1 ) if not self.sort_class or _class == 'import': out.append(candidates) elif _class in class_dict.keys(): class_dict[_class].append(candidates) if self.sort_class: for v in class_dict.values(): out += v return out except Exception: return []
def _set_source_attributes(self, context): """Set source attributes from the context. Each item in `attrs` is the attribute name. """ attrs = ( 'converters', 'disabled_syntaxes', 'dup', 'filetypes', 'input_pattern', 'is_debug_enabled', 'is_silent', 'is_volatile', 'mark', 'matchers', 'max_abbr_width', 'max_candidates', 'max_info_width', 'max_kind_width', 'max_menu_width', 'max_pattern_length', 'min_pattern_length', 'sorters', ) for name, source in self._get_sources().items(): self.debug('Set Source attributes: %s', name) source.dup = bool(source.filetypes) for attr in attrs: source_attr = getattr(source, attr, None) custom = get_custom(context['custom'], name, attr, source_attr) if type(getattr(source, attr)) != type(custom): # Type check error(self._vim, f'source {source.name}: ' f'custom attr "{attr}" is wrong type.') elif custom and isinstance(source_attr, dict): # Update values if it is dict source_attr.update(custom) else: setattr(source, attr, custom) self.debug('Attribute: %s (%s)', attr, getattr(source, attr)) # Default min_pattern_length if source.min_pattern_length < 0: source.min_pattern_length = self._vim.call( 'deoplete#custom#_get_option', 'min_pattern_length') if not source.is_volatile: source.is_volatile = bool(source.filetypes)
def _args_from_clang(self, context, name): clang_file = self.vim.call('findfile', name, '.;') if not clang_file: return [] try: with open(context['cwd'] + "/" + clang_file) as f: return shlex.split(' '.join(f.readlines())) except Exception as e: error(self.vim, 'Parse Failed: ' + clang_file) return []
def _args_from_clang(self, clang_file): if not clang_file: return [] try: with open(clang_file) as f: args = shlex.split(' '.join(f.readlines())) args = [expanduser(expandvars(p)) for p in args] return args except Exception as e: error(self.vim, 'Parse Failed: ' + clang_file) return []
def gather_candidates(self, context): try: candidates = self.vim.call(self.vim.eval('&l:omnifunc'), 0, context['complete_str']) except: error( self.vim, 'Error occurred calling omnifunction: ' + self.vim.eval('&l:omnifunc')) candidates = [] return candidates
def get_complete_position(self, context): if self.__use_previous_result(context): return self.__prev_pos current_ft = self.vim.eval('&filetype') for filetype in context['filetypes']: for omnifunc in convert2list( get_buffer_config(context, filetype, 'deoplete_omni_functions', 'deoplete#omni#functions', {'_': ''})): if omnifunc == '' and (filetype == current_ft or filetype in ['css', 'javascript']): omnifunc = context['omni__omnifunc'] if omnifunc == '' or not self.vim.call( 'deoplete#util#exists_omnifunc', omnifunc): continue self.__omnifunc = omnifunc for input_pattern in convert2list( get_buffer_config(context, filetype, 'deoplete_omni_input_patterns', 'deoplete#omni#input_patterns', self.__input_patterns)): m = re.search('(' + input_pattern + ')$', context['input']) # self.debug(filetype) # self.debug(input_pattern) if input_pattern == '' or (context['event'] != 'Manual' and m is None): continue if filetype == current_ft and self.__omnifunc in [ 'ccomplete#Complete', 'htmlcomplete#CompleteTags', 'phpcomplete#CompletePHP']: # In the blacklist error(self.vim, 'omni source does not support: ' + self.__omnifunc) error(self.vim, 'You must use g:deoplete#omni_patterns' + ' instead.') return -1 try: complete_pos = self.vim.call(self.__omnifunc, 1, '') except: error_vim(self.vim, 'Error occurred calling omnifunction: ' + self.__omnifunc) return -1 return complete_pos return -1
def get_complete_position(self, context): if self.__use_previous_result(context): return self.__prev_pos current_ft = self.vim.eval('&filetype') for filetype in context['filetypes']: for omnifunc in convert2list( get_buffer_config(context, filetype, 'deoplete_omni_functions', 'deoplete#omni#functions', {'_': ''})): if omnifunc == '' and filetype == current_ft: omnifunc = context['omni__omnifunc'] if omnifunc == '' or not self.vim.call( 'deoplete#util#exists_omnifunc', omnifunc): continue self.__omnifunc = omnifunc for input_pattern in convert2list( get_buffer_config(context, filetype, 'deoplete_omni_input_patterns', 'deoplete#omni#input_patterns', self.__input_patterns)): m = re.search('(' + input_pattern + ')$', context['input']) # self.debug(filetype) # self.debug(input_pattern) if input_pattern == '' or (context['event'] != 'Manual' and m is None): continue if self.__omnifunc in [ 'ccomplete#Complete', 'htmlcomplete#CompleteTags', 'phpcomplete#CompletePHP']: # In the blacklist error(self.vim, 'omni source does not support: ' + self.__omnifunc) error(self.vim, 'You must use g:deoplete#omni_patterns' + ' instead.') return -1 try: complete_pos = self.vim.call(self.__omnifunc, 1, '') except: error_vim(self.vim, 'Error occurred calling omnifunction: ' + self.__omnifunc) return -1 return complete_pos return -1
def __init__(self, vim): Base.__init__(self, vim) self.name = 'Swift' self.mark = '[Swift]' self.filetypes = ['swift'] self.input_pattern = r'(?:\b[^\W\d]\w*|[\]\)])(?:\.(?:[^\W\d]\w*)?)*\(?' self.rank = 500 try: self.__source_kitten = SourceKitten( path=vim.vars['deoplete#sources#swift#source_kitten_binary']) except SourceKittenNotFound as exception: error(vim, '{} binary not found'.format(exception.path))
def __init__(self, vim): Base.__init__(self, vim) self.name = 'Swift' self.mark = '[Swift]' self.filetypes = ['swift'] self.input_pattern = r'(?:\b[^\W\d]\w*|[\]\)])(?:\.(?:[^\W\d]\w*)?)*\(?' self.rank = 500 try: self.__source_kitten = SourceKitten( path=vim.vars['deoplete#sources#swift#source_kitten_binary'] ) except SourceKittenNotFound as exception: error(vim, '{} binary not found'.format(exception.path))
def _get_complete_position(self, context, current_ft, filetype): for omnifunc in convert2list( get_buffer_config(context, filetype, 'deoplete_omni_functions', 'deoplete#omni#functions', {'_': ''})): if omnifunc == '' and (filetype == current_ft or filetype in ['css', 'javascript']): omnifunc = context['omni__omnifunc'] if omnifunc == '': continue self.__omnifunc = omnifunc for input_pattern in convert2list( get_buffer_config(context, filetype, 'deoplete_omni_input_patterns', 'deoplete#omni#input_patterns', self._input_patterns)): m = re.search('(' + input_pattern + ')$', context['input']) # self.debug(filetype) # self.debug(input_pattern) if input_pattern == '' or (context['event'] != 'Manual' and m is None): continue if filetype == current_ft and self.__omnifunc in [ 'ccomplete#Complete', 'htmlcomplete#CompleteTags', 'phpcomplete#CompletePHP']: # In the blacklist error(self.vim, 'omni source does not support: ' + self.__omnifunc) error(self.vim, 'You must use g:deoplete#omni_patterns' + ' instead.') return -1 try: complete_pos = self.vim.call(self.__omnifunc, 1, '') except: error_vim(self.vim, 'Error occurred calling omnifunction: ' + self.__omnifunc) return -1 return complete_pos return -1
def _handle_source_exception(self, source, exc): if isinstance(exc, SourceInitError): error(self._vim, f'Error when loading source {source.name}: {exc}. ' 'Ignoring.') self._ignore_sources.append(source.name) return self._source_errors[source.name] += 1 if source.is_silent: return if self._source_errors[source.name] > 2: error(self._vim, f'Too many errors from "{source.name}". ' 'This source is disabled until Neovim is restarted.') self._ignore_sources.append(source.name) else: error_tb(self._vim, f'Error from {source.name}: {exc}')
def _handle_source_exception(self, source, exc): if isinstance(exc, SourceInitError): error(self._vim, 'Error when loading source {}: {}. ' 'Ignoring.'.format(source.name, exc)) self._ignore_sources.append(source.name) return self._source_errors[source.name] += 1 if source.is_silent: return if self._source_errors[source.name] > 2: error(self._vim, 'Too many errors from "%s". ' 'This source is disabled until Neovim ' 'is restarted.' % source.name) self._ignore_sources.append(source.name) else: error_tb(self._vim, 'Error from %s: %r' % (source.name, exc))
def gather_candidates(self, context): if self.__use_previous_result(context): return self.__prev_candidates try: candidates = self.vim.call( self.__omnifunc, 0, context['complete_str']) except: error(self.vim, 'Error occurred calling omnifunction: ' + self.__omnifunc) candidates = [] self.__prev_linenr = self.vim.funcs.line('.') self.__prev_pos = context['complete_position'] self.__prev_input = context['input'] self.__prev_candidates = candidates return candidates
def itersource(self, context): sources = sorted(self._sources.items(), key=lambda x: get_custom( context['custom'], x[1].name, 'rank', x[1].rank), reverse=True) filetypes = context['filetypes'] ignore_sources = set() for ft in filetypes: ignore_sources.update( get_buffer_config(context, ft, 'deoplete_ignore_sources', 'deoplete#ignore_sources', {})) for source_name, source in sources: if source.limit > 0 and context['bufsize'] > source.limit: continue if source.filetypes is None or source_name in ignore_sources: continue if context['sources'] and source_name not in context['sources']: continue if source.filetypes and not any(x in filetypes for x in source.filetypes): continue if not source.is_initialized and hasattr(source, 'on_init'): self.debug('on_init Source: %s', source.name) try: source.on_init(context) except Exception as exc: if isinstance(exc, SourceInitError): error(self._vim, 'Error when loading source {}: {}. ' 'Ignoring.'.format(source_name, exc)) else: error_tb(self._vim, 'Error when loading source {}: {}. ' 'Ignoring.'.format(source_name, exc)) self._ignored_sources.add(source.path) self._sources.pop(source_name) continue else: source.is_initialized = True yield source_name, source
def _handle_source_exception(self, source, exc): if isinstance(exc, SourceInitError): error( self._vim, 'Error when loading source {}: {}. ' 'Ignoring.'.format(source.name, exc)) self._ignore_sources.append(source.name) return self._source_errors[source.name] += 1 if source.is_silent: return if self._source_errors[source.name] > 2: error( self._vim, 'Too many errors from "%s". ' 'This source is disabled until Neovim ' 'is restarted.' % source.name) self._ignore_sources.append(source.name) else: error_tb(self._vim, 'Error from %s: %r' % (source.name, exc))
def filter(self, context): if (not context['candidates'] or not context['input'] or self._cpsm is False): return context['candidates'] if self._cpsm is None: errmsg = self._init_cpsm(context) if errmsg: error(self.vim, 'matcher_cpsm: %s' % errmsg) return [] complete_str = context['complete_str'] if context['ignorecase']: complete_str = complete_str.lower() cpsm_result = self._get_cpsm_result( context['candidates'], complete_str) return [x for x in context['candidates'] if x['word'] in sorted(cpsm_result, key=cpsm_result.index)]
def _put(self, name, args): if not self._hnd: return None queue_id = str(time.time()) msg = self._packer.pack({ 'name': name, 'args': args, 'queue_id': queue_id }) self._queue_in.put(msg) if self._stdin: try: while not self._queue_in.empty(): self._stdin.write(self._queue_in.get_nowait()) except BrokenPipeError: error_tb(self._vim, 'Crash in child process') error(self._vim, 'stderr=' + str(self._proc.read_error())) self._hnd = None return queue_id
def _put(self, name, args): queue_id = str(time.time()) if self._proc: try: self._proc.write({ 'name': name, 'args': args, 'queue_id': queue_id }) except BrokenPipeError as e: error_tb(self._vim, 'Crash in child process') error(self._vim, 'stderr=' + str(self._proc.read_error())) self._proc.kill() return queue_id elif self._child: return self._child.main(name, args, queue_id) else: return None
def __init__(self, vim): self.name = 'core' self._vim = vim self._runtimepath = '' self._custom = [] self._loaded_paths = set() self._prev_merged_results = {} self._prev_pos = [] self._parents = [] self._parent_count = 0 self._max_parents = max( [1, self._vim.vars['deoplete#num_processes']]) if self._max_parents > 1 and not hasattr(self._vim, 'loop'): error(self._vim, 'neovim-python 0.2.4+ is required.') return # Enable logging before "Init" for more information, and e.g. # deoplete-jedi picks up the log filename from deoplete's handler in # its on_init. if self._vim.vars['deoplete#_logging']: self.enable_logging() # Init context context = self._vim.call('deoplete#init#_context', 'Init', []) context['rpc'] = 'deoplete_on_event' # Init processes for n in range(0, self._max_parents): self._parents.append(Parent(vim, context)) if self._vim.vars['deoplete#_logging']: for parent in self._parents: parent.enable_logging() # on_init() call self.on_event(context) if hasattr(self._vim, 'channel_id'): self._vim.vars['deoplete#_channel_id'] = self._vim.channel_id self._vim.vars['deoplete#_initialized'] = True
def _gather_async_results(self, result, source): try: context = result['context'] context['is_refresh'] = False async_candidates = source.gather_candidates(context) result['is_async'] = context['is_async'] if async_candidates is None: return context['candidates'] += convert2candidates(async_candidates) except Exception: self._source_errors[source.name] += 1 if source.is_silent: return if self._source_errors[source.name] > 2: error(self._vim, 'Too many errors from "%s". ' 'This source is disabled until Neovim ' 'is restarted.' % source.name) self._ignore_sources.append(source.name) else: error_tb(self._vim, 'Errors from: %s' % source.name)
def _gather_async_results(self, result, source): try: context = result['context'] context['is_refresh'] = False async_candidates = source.gather_candidates(context) result['is_async'] = context['is_async'] if async_candidates is None: return context['candidates'] += convert2candidates(async_candidates) except Exception as exc: self._source_errors[source.name] += 1 if source.is_silent: return if self._source_errors[source.name] > 2: error(self._vim, 'Too many errors from "%s". ' 'This source is disabled until Neovim ' 'is restarted.' % source.name) self._ignore_sources.append(source.name) else: error_tb(self._vim, 'Error from %s: %r' % (source.name, exc))
def gather_candidates(self, context): if self.__use_previous_result(context): return self.__prev_candidates omnifunc = get_buffer_config( self.vim, context, "b:deoplete_omni_functions", "g:deoplete#omni#functions", "g:deoplete#omni#_functions" ) if omnifunc == "": omnifunc = self.vim.eval("&l:omnifunc") try: self.debug(omnifunc) candidates = self.vim.call(omnifunc, 0, context["complete_str"]) except: error(self.vim, "Error occurred calling omnifunction: " + omnifunc) candidates = [] self.__prev_pos = context["complete_position"] self.__prev_input = context["input"] self.__prev_candidates = candidates return candidates
def repo_homepage(self): """Return the repo homepage, akin to rhubarb#repo_request function :returns: String like "https://github.com/user/repo" """ proc = Popen(["git", "config", "--get", "remote.origin.url"], stdout=PIPE) out, err = proc.communicate() if err is not None: error(self.vim, 'Theres been an error') repoConfig = str(out.decode('utf-8')) if 'https' in repoConfig: self.log('repoConfig: ' + repoConfig) url_fragments = repoConfig.strip(".git\n") homepage = url_fragments else: url_fragments = repoConfig.strip("git\n").strip('.').split(':') homepage = 'https://github.com/' + url_fragments[1] return homepage
def get_complete_position(self, context): if self.__use_previous_result(context): return self.__prev_pos for filetype in context['filetypes']: omnifunc = get_buffer_config(context, filetype, 'deoplete_omni_functions', 'deoplete#omni#functions', 'deoplete#omni#_functions') if omnifunc == '': omnifunc = context['omni__omnifunc'] if omnifunc == '' or [ x for x in ['ccomplete#Complete', 'htmlcomplete#CompleteTags'] if x == omnifunc ]: continue self.__omnifunc = omnifunc for input_pattern in convert2list( get_buffer_config(context, filetype, 'deoplete_omni_input_patterns', 'deoplete#omni#input_patterns', 'deoplete#omni#_input_patterns')): m = re.search('(' + input_pattern + ')$', context['input']) # self.debug(filetype) # self.debug(input_pattern) if input_pattern == '' or (context['event'] != 'Manual' and m is None): continue try: complete_pos = self.vim.call(self.__omnifunc, 1, '') except: error( self.vim, 'Error occurred calling omnifunction: ' + self.__omnifunc) return -1 return complete_pos return -1
def get_complete_position(self, context): # Check member prefix pattern. if self.vim.eval('&l:omnifunc') == '': return -1 for input_pattern in convert2list( get_default_buffer_config( self.vim, context, 'b:deoplete_omni_input_patterns', 'g:deoplete#omni#input_patterns', 'g:deoplete#omni#_input_patterns')): m = re.search('('+input_pattern+')$', context['input']) if m is None or input_pattern == '': continue pos = self.vim.current.window.cursor try: complete_pos = self.vim.call( self.vim.eval('&l:omnifunc'), 1, '') except: error(self.vim, 'Error occurred calling omnifunction: ' + self.vim.eval('&l:omnifunc')) return -1 finally: if pos != self.vim.current.window.cursor: error(self.vim, 'omnifunction: ' + self.vim.eval('&l:omnifunc') + ' moves cursor!') error(self.vim, 'Deoplete cannot support it in omni source.' + ' You should use g:deoplete#omni_patterns.') return complete_pos return -1
def gather_candidates(self, context): if self.__use_previous_result(context): return self.__prev_candidates try: candidates = self.vim.call(self.__omnifunc, 0, context['complete_str']) if candidates is dict: candidates = candidates['words'] elif candidates is int: candidates = [] except: error(self.vim, 'Error occurred calling omnifunction: ' + self.__omnifunc) candidates = [] self.__prev_linenr = context['position'][1] self.__prev_pos = context['complete_position'] self.__prev_input = context['input'] self.__prev_candidates = candidates return candidates
def __init__(self, vim): self.name = 'core' self._vim = vim self._runtimepath = '' self._runtimepath_list = [] self._custom = [] self._loaded_paths = set() self._prev_results = {} self._prev_input = '' self._prev_next_input = '' self._context = Context(self._vim) self._parents = [] self._parent_count = 0 self._max_parents = self._vim.call('deoplete#custom#_get_option', 'num_processes') if self._max_parents != 1 and not hasattr(self._vim, 'loop'): msg = ('neovim-python 0.2.4+ is required for %d parents. ' 'Using single process.' % self._max_parents) error(self._vim, msg) self._max_parents = 1 # Enable logging for more information, and e.g. # deoplete-jedi picks up the log filename from deoplete's handler in # its on_init. if self._vim.vars['deoplete#_logging']: self.enable_logging() # Initialization context = self._context.get('Init') context['rpc'] = 'deoplete_on_event' self.on_event(context) if hasattr(self._vim, 'channel_id'): self._vim.vars['deoplete#_channel_id'] = self._vim.channel_id self._vim.vars['deoplete#_initialized'] = True
def get_complete_position(self, context): if self.__use_previous_result(context): return self.__prev_pos for filetype in context['filetypes']: omnifunc = get_buffer_config(self.vim, filetype, 'b:deoplete_omni_functions', 'g:deoplete#omni#functions', 'g:deoplete#omni#_functions') if omnifunc == '': omnifunc = self.vim.eval('&l:omnifunc') if omnifunc == '' or [x for x in [ 'ccomplete#Complete', 'htmlcomplete#CompleteTags'] if x == omnifunc]: continue self.__omnifunc = omnifunc for input_pattern in convert2list( get_buffer_config(self.vim, filetype, 'b:deoplete_omni_input_patterns', 'g:deoplete#omni#input_patterns', 'g:deoplete#omni#_input_patterns')): m = re.search('(' + input_pattern + ')$', context['input']) # self.debug(filetype) # self.debug(input_pattern) if input_pattern == '' or (context['event'] != 'Manual' and m is None): continue try: complete_pos = self.vim.call(self.__omnifunc, 1, '') except: error(self.vim, 'Error occurred calling omnifunction: ' + self.__omnifunc) return -1 return complete_pos return -1
def gather_candidates(self, context): if self.__use_previous_result(context): return self.__prev_candidates omnifunc = get_buffer_config(self.vim, context, 'b:deoplete_omni_functions', 'g:deoplete#omni#functions', 'g:deoplete#omni#_functions') if omnifunc == '': omnifunc = self.vim.eval('&l:omnifunc') try: self.debug(omnifunc) candidates = self.vim.call( omnifunc, 0, context['complete_str']) except: error(self.vim, 'Error occurred calling omnifunction: ' + omnifunc) candidates = [] self.__prev_pos = context['complete_position'] self.__prev_input = context['input'] self.__prev_candidates = candidates return candidates
def gather_candidates(self, context): if self.__use_previous_result(context): return self.__prev_candidates try: candidates = self.vim.call( self.__omnifunc, 0, context['complete_str']) if candidates is dict: candidates = candidates['words'] elif candidates is int: candidates = [] except: error(self.vim, 'Error occurred calling omnifunction: ' + self.__omnifunc) candidates = [] self.__prev_linenr = context['position'][1] self.__prev_pos = context['complete_position'] self.__prev_input = context['input'] self.__prev_candidates = candidates return candidates
def completion_begin(self, context): pos = self.__vim.current.window.cursor if context['event'] != 'Manual' and context['delay'] > 0: time.sleep(context['delay'] / 1000.0) if self.check_position(pos): return try: complete_position, candidates = self.gather_candidates(context) except Exception: for line in traceback.format_exc().splitlines(): error(self.__vim, line) error(self.__vim, 'An error has occurred. Please execute :messages command.') candidates = [] if not candidates or self.check_position(pos): self.__vim.vars['deoplete#_context'] = {} return self.__vim.vars['deoplete#_context'] = { 'complete_position': complete_position, 'changedtick': context['changedtick'], 'candidates': candidates, 'event': context['event'], } if context['rpc'] != 'deoplete_manual_completion_begin': # Set (and store) current &completeopt setting. This cannot be # done (currently) from the deoplete_start_complete mapping's # function. self.__vim.call('deoplete#mappings#_set_completeopt') # Note: cannot use vim.feedkeys() self.__vim.command( 'call feedkeys("\<Plug>(deoplete_start_complete)")')
def completion_begin(self, context): pos = self.__vim.current.window.cursor if context['event'] != 'Manual' and context['delay'] > 0: time.sleep(context['delay'] / 1000.0) if self.check_position(pos): return try: complete_position, candidates = self.gather_candidates(context) except Exception: for line in traceback.format_exc().splitlines(): error(self.__vim, line) error(self.__vim, 'An error has occurred. Please execute :messages command.') candidates = [] if not candidates or self.check_position(pos): self.__vim.vars['deoplete#_context'] = {} return self.__vim.vars['deoplete#_context'] = { 'complete_position': complete_position, 'changedtick': context['changedtick'], 'candidates': candidates, 'event': context['event'], } if context['rpc'] != 'deoplete_manual_completion_begin': # Set (and store) current &completeopt setting. This cannot be # done (currently) from the deoplete_start_complete mapping's # function. self.__vim.call('deoplete#mappings#_set_completeopt') # Note: cannot use vim.feedkeys() self.__vim.command('call feedkeys("\<Plug>(deoplete_start_complete)")')
def find_binary_path(self, path): def is_exec(bin_path): return os.path.isfile(bin_path) and os.access(bin_path, os.X_OK) dirpath, binary = os.path.split(path) if dirpath: if is_exec(path): return path else: for p in os.environ["PATH"].split(os.pathsep): p = p.strip('"') binary = os.path.join(p, path) if is_exec(binary): return binary return error(self.vim, path + ' binary not found')
def _process_filter(self, f, context): try: self._profile_start(context, f.name) if (isinstance(context['candidates'], dict) and 'sorted_candidates' in context['candidates']): context_candidates = [] context['is_sorted'] = True for candidates in context['candidates']['sorted_candidates']: context['candidates'] = candidates context_candidates += f.filter(context) context['candidates'] = context_candidates else: context['candidates'] = f.filter(context) self._profile_end(f.name) except Exception: self._filter_errors[f.name] += 1 if self._source_errors[f.name] > 2: error( self._vim, 'Too many errors from "%s". ' 'This filter is disabled until Neovim ' 'is restarted.' % f.name) self._filters.pop(f.name) return error_tb(self._vim, 'Errors from: %s' % f)
def gather_candidates(self, context): if self.__use_previous_result(context): return self.__prev_candidates omnifunc = get_buffer_config(self.vim, context, 'b:deoplete_omni_functions', 'g:deoplete#omni#functions', 'g:deoplete#omni#_functions') if omnifunc == '': omnifunc = self.vim.eval('&l:omnifunc') try: self.debug(omnifunc) candidates = self.vim.call( omnifunc, 0, context['complete_str']) except: error(self.vim, 'Error occurred calling omnifunction: ' + omnifunc) candidates = [] self.__prev_linenr = self.vim.funcs.line('.') self.__prev_pos = context['complete_position'] self.__prev_input = context['input'] self.__prev_candidates = candidates return candidates
def find_binary_path(self, cmd): def is_exec(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK) fpath, fname = os.path.split(cmd) if fpath: if is_exec(cmd): return cmd else: for path in os.environ["PATH"].split(os.pathsep): path = path.strip('"') binary = os.path.join(path, cmd) if is_exec(binary): return binary return error(self.vim, cmd + ' binary not found')
def _itersource(self, context): filetypes = context['filetypes'] ignore_sources = set(self._ignore_sources) for ft in filetypes: ignore_sources.update( get_buffer_config(context, ft, 'deoplete_ignore_sources', 'deoplete#ignore_sources', {})) for source_name, source in self._sources.items(): if source.filetypes is None or source_name in ignore_sources: continue if context['sources'] and source_name not in context['sources']: continue if source.filetypes and not any(x in filetypes for x in source.filetypes): continue if not source.is_initialized and hasattr(source, 'on_init'): self.debug('on_init Source: %s', source.name) try: source.on_init(context) except Exception as exc: if isinstance(exc, SourceInitError): error(self._vim, 'Error when loading source {}: {}. ' 'Ignoring.'.format(source_name, exc)) else: error_tb(self._vim, 'Error when loading source {}: {}. ' 'Ignoring.'.format(source_name, exc)) self._ignore_sources.append(source_name) continue else: source.is_initialized = True yield source_name, source