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_info(self, info): """Get a formatted calltip and docstring from Rope""" if self.project is None: return default_info_response() filename = info['filename'] source_code = info['source_code'] offset = info['position'] # Set python path into rope project self.project.prefs.set('python_path', info['sys_path']) if filename is not None: 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_info(self, info): """Get a formatted calltip and docstring from Rope""" if self.project is None: return default_info_response() filename = info['filename'] source_code = info['source_code'] offset = info['position'] # Set python path into rope project self.project.prefs.set('python_path', info['sys_path']) if filename is not None: 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'] # Set python path into rope project self.project.prefs.set('python_path', info['sys_path']) # 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 filename is not None: 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): """ 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 r'^c?import.*\W{0}{1}', r'from.*\W{0}\W.*c?import ', r'from .* c?import.*\W{0}{1}', r'class\s*{0}{1}', r'c?p?def[^=]*\W{0}{1}', r'cdef.*\[.*\].*\W{0}{1}', # enaml keyword definitions r'enamldef.*\W{0}{1}', r'attr.*\W{0}{1}', r'event.*\W{0}{1}', r'id\s*:.*\W{0}{1}' ] matches = get_matches(patterns, source, token, start_line) if not matches: patterns = [ r'.*\Wself.{0}{1}[^=!<>]*=[^=]', r'.*\W{0}{1}[^=!<>]*=[^=]', r'self.{0}{1}[^=!<>]*=[^=]', r'{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 r'^c?import.*\W{0}{1}', r'from.*\W{0}\W.*c?import ', r'from .* c?import.*\W{0}{1}', r'class\s*{0}{1}', r'c?p?def[^=]*\W{0}{1}', r'cdef.*\[.*\].*\W{0}{1}', # enaml keyword definitions r'enamldef.*\W{0}{1}', r'attr.*\W{0}{1}', r'event.*\W{0}{1}', r'id\s*:.*\W{0}{1}'] matches = get_matches(patterns, source, token, start_line) if not matches: patterns = [r'.*\Wself.{0}{1}[^=!<>]*=[^=]', r'.*\W{0}{1}[^=!<>]*=[^=]', r'self.{0}{1}[^=!<>]*=[^=]', r'{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_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'] # Set python path into rope project self.project.prefs.set('python_path', info['sys_path']) # 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 filename is not None: 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(self, info): """Find a definition location using Rope""" if self.project is None: return filename = info['filename'] source_code = info['source_code'] offset = info['position'] # Set python path into rope project self.project.prefs.set('python_path', info['sys_path']) if filename is not None: 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 if filename and lineno: return filename, lineno except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_definition_location")
def get_definition(self, info): """Find a definition location using Rope""" if self.project is None: return filename = info['filename'] source_code = info['source_code'] offset = info['position'] # Set python path into rope project self.project.prefs.set('python_path', info['sys_path']) if filename is not None: 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 if filename and lineno: return filename, lineno except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_definition_location")