Пример #1
0
    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 []
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
 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
Пример #5
0
 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
Пример #6
0
 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
Пример #7
0
    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")
Пример #8
0
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
Пример #9
0
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
Пример #10
0
    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")
Пример #11
0
    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 []
Пример #12
0
    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 []
Пример #13
0
 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