def get_completions(self, info): """Get a list of (completion, type) tuples using Rope""" if self.project is None: return [] filename = info.filename source_code = info.source_code offset = info.position if PY2: filename = filename.encode('utf-8') else: #TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters pass try: resource = rope.base.libutils.path_to_resource(self.project, filename) except Exception as _error: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "path_to_resource: %r" % filename) resource = None try: if DEBUG_EDITOR: t0 = time.time() proposals = rope.contrib.codeassist.code_assist(self.project, source_code, offset, resource, maxfixes=3) proposals = rope.contrib.codeassist.sorted_proposals(proposals) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "code_assist/sorted_proposals", t0) return [(proposal.name, proposal.type) for proposal in proposals] except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_completion_list") return []
def get_jedi_object(self, func_name, info, use_filename=True): """Call a desired function on a Jedi Script and return the result""" if not jedi: return if DEBUG_EDITOR: t0 = time.time() # override IPython qt_loaders ImportDenier behavior metas = sys.meta_path for meta in metas: if (meta.__class__.__name__ == 'ImportDenier' and hasattr(meta, 'forbid')): sys.meta_path.remove(meta) if use_filename: filename = info.filename else: filename = None try: script = jedi.Script(info.source_code, info.line_num, info.column, filename) func = getattr(script, func_name) val = func() except Exception as e: val = None debug_print('Jedi error (%s)' % func_name) debug_print(str(e)) if DEBUG_EDITOR: log_last_error(LOG_FILENAME, str(e)) if DEBUG_EDITOR: log_dt(LOG_FILENAME, func_name, t0) if not val and filename: return self.get_jedi_object(func_name, info, False) else: return val
def get_definition_location(self, source_code, offset, filename): """Find a definition location using Rope""" if self.project is None: raise ValueError if PY2: filename = filename.encode('utf-8') else: #TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters pass try: resource = rope.base.libutils.path_to_resource( self.project, filename) except Exception as _error: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "path_to_resource: %r" % filename) resource = None try: if DEBUG_EDITOR: t0 = time.time() resource, lineno = rope.contrib.codeassist.get_definition_location( self.project, source_code, offset, resource, maxfixes=3) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "get_definition_location", t0) if resource is not None: filename = resource.real_path else: raise ValueError return filename, lineno except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_definition_location") raise ValueError
def get_definition_location(self, source_code, offset, filename): """Find a definition location using Rope""" if self.project is None: raise ValueError if PY2: filename = filename.encode('utf-8') else: #TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters pass try: resource = rope.base.libutils.path_to_resource(self.project, filename) except Exception as _error: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "path_to_resource: %r" % filename) resource = None try: if DEBUG_EDITOR: t0 = time.time() resource, lineno = rope.contrib.codeassist.get_definition_location( self.project, source_code, offset, resource, maxfixes=3) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "get_definition_location", t0) if resource is not None: filename = resource.real_path else: raise ValueError return filename, lineno except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_definition_location") raise ValueError
def get_definition_with_regex(source, token, start_line=-1, use_assignment=False): """ Find the definition of an object within a source closest to a given line """ if not token: return None if DEBUG_EDITOR: t0 = time.time() patterns = [ # python / cython keyword definitions '^c?import.*\W{0}{1}', 'from.*\W{0}\W.*c?import ', 'from .* c?import.*\W{0}{1}', 'class\s*{0}{1}', 'c?p?def[^=]*\W{0}{1}', 'cdef.*\[.*\].*\W{0}{1}', # enaml keyword definitions 'enamldef.*\W{0}{1}', 'attr.*\W{0}{1}', 'event.*\W{0}{1}', 'id\s*:.*\W{0}{1}'] if use_assignment: patterns += ['.*\Wself.{0}{1}[^=!<>]*=[^=]', '.*\W{0}{1}[^=!<>]*=[^=]', 'self.{0}{1}[^=!<>]*=[^=]', '{0}{1}[^=!<>]*=[^=]'] patterns = [pattern.format(token, r'[^0-9a-zA-Z.[]') for pattern in patterns] pattern = re.compile('|^'.join(patterns)) # add the trailing space to allow some regexes to match eol = sourcecode.get_eol_chars(source) or '\n' lines = source.split(eol) lines = [line.strip() + ' ' for line in lines] if start_line == -1: start_line = len(lines) matches = [] for (index, line) in enumerate(lines): if re.match(pattern, line): matches.append(index + 1) # find the one closest to the start line (prefer before the start line) if matches: min_dist = len(lines) best_ind = 0 for match in matches: dist = abs(start_line - match) if match <= start_line or not best_ind: if dist < min_dist: min_dist = dist best_ind = match if matches: if DEBUG_EDITOR: log_dt(LOG_FILENAME, 'regex definition match', t0) return best_ind else: if DEBUG_EDITOR: log_dt(LOG_FILENAME, 'regex definition failed match', t0) return None
def get_info(self, info): """Get a formatted calltip and docstring from Rope""" if self.project is None: return filename = info.filename source_code = info.source_code offset = info.position if PY2: filename = filename.encode('utf-8') else: #TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters pass try: resource = rope.base.libutils.path_to_resource( self.project, filename) except Exception as _error: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "path_to_resource: %r" % filename) resource = None try: if DEBUG_EDITOR: t0 = time.time() cts = rope.contrib.codeassist.get_calltip(self.project, source_code, offset, resource, ignore_unknown=False, remove_self=True, maxfixes=3) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "get_calltip", t0) if cts is not None: while '..' in cts: cts = cts.replace('..', '.') if '(.)' in cts: cts = cts.replace('(.)', '(...)') try: doc_text = rope.contrib.codeassist.get_doc(self.project, source_code, offset, resource, maxfixes=3) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "get_doc", t0) except Exception as _error: doc_text = '' if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_doc") return self.handle_info(cts, doc_text, source_code, offset) except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_calltip_text")
def get_definition_with_regex(source, token, start_line=-1): """ Find the definition of an object within a source closest to a given line """ if not token: return None if DEBUG_EDITOR: t0 = time.time() patterns = [ # python / cython keyword definitions '^c?import.*\W{0}{1}', 'from.*\W{0}\W.*c?import ', 'from .* c?import.*\W{0}{1}', 'class\s*{0}{1}', 'c?p?def[^=]*\W{0}{1}', 'cdef.*\[.*\].*\W{0}{1}', # enaml keyword definitions 'enamldef.*\W{0}{1}', 'attr.*\W{0}{1}', 'event.*\W{0}{1}', 'id\s*:.*\W{0}{1}' ] matches = get_matches(patterns, source, token, start_line) if not matches: patterns = [ '.*\Wself.{0}{1}[^=!<>]*=[^=]', '.*\W{0}{1}[^=!<>]*=[^=]', 'self.{0}{1}[^=!<>]*=[^=]', '{0}{1}[^=!<>]*=[^=]' ] matches = get_matches(patterns, source, token, start_line) # find the one closest to the start line (prefer before the start line) if matches: min_dist = len(source.splitlines()) best_ind = 0 for match in matches: dist = abs(start_line - match) if match <= start_line or not best_ind: if dist < min_dist: min_dist = dist best_ind = match if matches: if DEBUG_EDITOR: log_dt(LOG_FILENAME, 'regex definition match', t0) return best_ind else: if DEBUG_EDITOR: log_dt(LOG_FILENAME, 'regex definition failed match', t0) return None
def get_definition_with_regex(source, token, start_line=-1): """ Find the definition of an object within a source closest to a given line """ if not token: return None if DEBUG_EDITOR: t0 = time.time() patterns = [ # python / cython keyword definitions '^c?import.*\W{0}{1}', 'from.*\W{0}\W.*c?import ', 'from .* c?import.*\W{0}{1}', 'class\s*{0}{1}', 'c?p?def[^=]*\W{0}{1}', 'cdef.*\[.*\].*\W{0}{1}', # enaml keyword definitions 'enamldef.*\W{0}{1}', 'attr.*\W{0}{1}', 'event.*\W{0}{1}', 'id\s*:.*\W{0}{1}'] matches = get_matches(patterns, source, token, start_line) if not matches: patterns = ['.*\Wself.{0}{1}[^=!<>]*=[^=]', '.*\W{0}{1}[^=!<>]*=[^=]', 'self.{0}{1}[^=!<>]*=[^=]', '{0}{1}[^=!<>]*=[^=]'] matches = get_matches(patterns, source, token, start_line) # find the one closest to the start line (prefer before the start line) if matches: min_dist = len(source.splitlines()) best_ind = 0 for match in matches: dist = abs(start_line - match) if match <= start_line or not best_ind: if dist < min_dist: min_dist = dist best_ind = match if matches: if DEBUG_EDITOR: log_dt(LOG_FILENAME, 'regex definition match', t0) return best_ind else: if DEBUG_EDITOR: log_dt(LOG_FILENAME, 'regex definition failed match', t0) return None
def get_info(self, info): """Get a formatted calltip and docstring from Rope""" if self.project is None: return filename = info.filename source_code = info.source_code offset = info.position if PY2: filename = filename.encode('utf-8') else: #TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters pass try: resource = rope.base.libutils.path_to_resource(self.project, filename) except Exception as _error: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "path_to_resource: %r" % filename) resource = None try: if DEBUG_EDITOR: t0 = time.time() cts = rope.contrib.codeassist.get_calltip( self.project, source_code, offset, resource, ignore_unknown=False, remove_self=True, maxfixes=3) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "get_calltip", t0) if cts is not None: while '..' in cts: cts = cts.replace('..', '.') if '(.)' in cts: cts = cts.replace('(.)', '(...)') try: doc_text = rope.contrib.codeassist.get_doc(self.project, source_code, offset, resource, maxfixes=3) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "get_doc", t0) except Exception as _error: doc_text = '' if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_doc") return self.handle_info(cts, doc_text, source_code, offset) except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_calltip_text")
def get_completions(self, info): """Get a list of (completion, type) tuples using Rope""" if self.project is None: return [] filename = info['filename'] source_code = info['source_code'] offset = info['position'] # Prevent Rope from returning import completions because # it can't handle them. Only Jedi can do it! lines = sourcecode.split_source(source_code[:offset]) last_line = lines[-1].lstrip() if (last_line.startswith('import ') or last_line.startswith('from ')) \ and not ';' in last_line: return [] if PY2: filename = filename.encode('utf-8') else: #TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters pass try: resource = rope.base.libutils.path_to_resource( self.project, filename) except Exception as _error: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "path_to_resource: %r" % filename) resource = None try: if DEBUG_EDITOR: t0 = time.time() proposals = rope.contrib.codeassist.code_assist(self.project, source_code, offset, resource, maxfixes=3) proposals = rope.contrib.codeassist.sorted_proposals(proposals) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "code_assist/sorted_proposals", t0) return [(proposal.name, proposal.type) for proposal in proposals] except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_completion_list") return []
def get_completions(self, info): """Get a list of (completion, type) tuples using Rope""" if self.project is None: return [] filename = info['filename'] source_code = info['source_code'] offset = info['position'] # Prevent Rope from returning import completions because # it can't handle them. Only Jedi can do it! lines = sourcecode.split_source(source_code[:offset]) last_line = lines[-1].lstrip() if (last_line.startswith('import ') or last_line.startswith('from ')) \ and not ';' in last_line: return [] if PY2: filename = filename.encode('utf-8') else: #TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters pass try: resource = rope.base.libutils.path_to_resource(self.project, filename) except Exception as _error: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "path_to_resource: %r" % filename) resource = None try: if DEBUG_EDITOR: t0 = time.time() proposals = rope.contrib.codeassist.code_assist(self.project, source_code, offset, resource, maxfixes=3) proposals = rope.contrib.codeassist.sorted_proposals(proposals) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "code_assist/sorted_proposals", t0) return [(proposal.name, proposal.type) for proposal in proposals] except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_completion_list") return []
def get_definition_with_regex(source, token, start_line=-1, use_assignment=False): """ Find the definition of an object within a source closest to a given line """ if not token: return None if DEBUG_EDITOR: t0 = time.time() patterns = [ # python / cython keyword definitions '^c?import.*\W{0}{1}', 'from.*\W{0}\W.*c?import ', 'from .* c?import.*\W{0}{1}', 'class\s*{0}{1}', 'c?p?def[^=]*\W{0}{1}', 'cdef.*\[.*\].*\W{0}{1}', # enaml keyword definitions 'enamldef.*\W{0}{1}', 'attr.*\W{0}{1}', 'event.*\W{0}{1}', 'id\s*:.*\W{0}{1}' ] if use_assignment: patterns += [ '.*\Wself.{0}{1}[^=!<>]*=[^=]', '.*\W{0}{1}[^=!<>]*=[^=]', 'self.{0}{1}[^=!<>]*=[^=]', '{0}{1}[^=!<>]*=[^=]' ] patterns = [ pattern.format(token, r'[^0-9a-zA-Z.[]') for pattern in patterns ] pattern = re.compile('|^'.join(patterns)) # add the trailing space to allow some regexes to match eol = sourcecode.get_eol_chars(source) or '\n' lines = source.split(eol) lines = [line.strip() + ' ' for line in lines] if start_line == -1: start_line = len(lines) matches = [] for (index, line) in enumerate(lines): if re.match(pattern, line): matches.append(index + 1) # find the one closest to the start line (prefer before the start line) if matches: min_dist = len(lines) best_ind = 0 for match in matches: dist = abs(start_line - match) if match <= start_line or not best_ind: if dist < min_dist: min_dist = dist best_ind = match if matches: if DEBUG_EDITOR: log_dt(LOG_FILENAME, 'regex definition match', t0) return best_ind else: if DEBUG_EDITOR: log_dt(LOG_FILENAME, 'regex definition failed match', t0) return None