Anonymous avatar Anonymous committed eb0d53c

Moved ide related packages to ropeide

Comments (0)

Files changed (23)

rope/ide/codeassist.py

 import keyword
 import re
+import sys
 
 import rope.base.codeanalyze
 from rope.base import pyobjects, pynames, taskhandle, builtins
 from rope.base.codeanalyze import (StatementRangeFinder, ArrayLinesAdapter,
                                    WordRangeFinder, ScopeNameFinder,
                                    SourceLinesAdapter, BadIdentifierError)
-from rope.ide import pydoc
-from rope.refactor import occurrences
+from rope.refactor import occurrences, functionutils
 
 
 def code_assist(project, source_code, offset, resource=None, templates={}):
     if element is None:
         return None
     pyobject = element.get_object()
-    return pydoc.get_doc(pyobject)
+    return PyDocExtractor().get_doc(pyobject)
 
 
 def get_definition_location(project, source_code, offset, resource=None):
     if resource and resource.exists() and source_code == resource.read():
         return pycore.resource_to_pyobject(resource)
     return pycore.get_string_module(source_code, resource=resource)
+
+
+class PyDocExtractor(object):
+
+    def get_doc(self, pyobject):
+        if isinstance(pyobject, pyobjects.AbstractFunction):
+            return self._get_function_docstring(pyobject)
+        elif isinstance(pyobject, pyobjects.AbstractClass):
+            return self._get_class_docstring(pyobject)
+        elif isinstance(pyobject, pyobjects.AbstractModule):
+            return self._trim_docstring(pyobject.get_doc())
+        return None
+
+    def _get_class_docstring(self, pyclass):
+        contents = self._trim_docstring(pyclass.get_doc(), 2)
+        supers = [super.get_name() for super in pyclass.get_superclasses()]
+        doc = 'class %s(%s):\n\n' % (pyclass.get_name(), ', '.join(supers)) + contents
+
+        if '__init__' in pyclass.get_attributes():
+            init = pyclass.get_attribute('__init__').get_object()
+            if isinstance(init, pyobjects.AbstractFunction):
+                doc += '\n\n' + self._get_single_function_docstring(init)
+        return doc
+
+    def _get_function_docstring(self, pyfunction):
+        functions = [pyfunction]
+        if self._is_method(pyfunction):
+            functions.extend(self._get_super_methods(pyfunction.parent,
+                                                     pyfunction.get_name()))
+        return '\n\n'.join([self._get_single_function_docstring(function)
+                            for function in functions])
+
+    def _is_method(self, pyfunction):
+        return isinstance(pyfunction, pyobjects.PyFunction) and \
+               isinstance(pyfunction.parent, pyobjects.PyClass)
+
+    def _get_single_function_docstring(self, pyfunction):
+        signature = self._get_function_signature(pyfunction)
+        if self._is_method(pyfunction):
+            signature = pyfunction.parent.get_name() + '.' + signature
+            self._get_super_methods(pyfunction.parent, pyfunction.get_name())
+        return signature + ':\n\n' + self._trim_docstring(pyfunction.get_doc(),
+                                                         indents=2)
+
+    def _get_super_methods(self, pyclass, name):
+        result = []
+        for super_class in pyclass.get_superclasses():
+            if name in super_class.get_attributes():
+                function = super_class.get_attribute(name).get_object()
+                if isinstance(function, pyobjects.AbstractFunction):
+                    result.append(function)
+            result.extend(self._get_super_methods(super_class, name))
+        return result
+
+    def _get_function_signature(self, pyfunction):
+        if isinstance(pyfunction, pyobjects.PyFunction):
+            info = functionutils.DefinitionInfo.read(pyfunction)
+            return info.to_string()
+        else:
+            return '%s(%s)' % (pyfunction.get_name(),
+                               ', '.join(pyfunction.get_param_names()))
+
+    def _trim_docstring(self, docstring, indents=0):
+        """The sample code from :PEP:`257`"""
+        if not docstring:
+            return ''
+        # Convert tabs to spaces (following normal Python rules)
+        # and split into a list of lines:
+        lines = docstring.expandtabs().splitlines()
+        # Determine minimum indentation (first line doesn't count):
+        indent = sys.maxint
+        for line in lines[1:]:
+            stripped = line.lstrip()
+            if stripped:
+                indent = min(indent, len(line) - len(stripped))
+        # Remove indentation (first line is special):
+        trimmed = [lines[0].strip()]
+        if indent < sys.maxint:
+            for line in lines[1:]:
+                trimmed.append(line[indent:].rstrip())
+        # Strip off trailing and leading blank lines:
+        while trimmed and not trimmed[-1]:
+            trimmed.pop()
+        while trimmed and not trimmed[0]:
+            trimmed.pop(0)
+        # Return a single string:
+        return '\n'.join((' ' * indents + line for line in trimmed))

rope/ide/formatter.py

-# NOTE: This actually does not format anything.  It merely removes
-#   extra blank lines and trailing white-spaces.  Now that
-#   `rope.refactor.patchedast` has been added I think this can be
-#   implemented.
-
-
-class Formatter(object):
-
-    def format(self, source_code):
-        source_code = self._remove_extra_spaces(source_code)
-        source_code = self._remove_extra_lines(source_code)
-        source_code = self._correct_end_of_file_lines(source_code)
-        return source_code
-
-    def _remove_extra_spaces(self, source_code):
-        result = []
-        for line in source_code.splitlines():
-            result.append(line.rstrip())
-        if source_code.endswith('\n'):
-            result.append('')
-        return '\n'.join(result)
-
-    def _remove_extra_lines(self, source_code):
-        result = []
-        blank_lines = 0
-        for line in source_code.splitlines(True):
-            if line.strip() == '':
-                blank_lines += 1
-                if blank_lines <= 2:
-                    result.append(line)
-            else:
-                blank_lines = 0
-                result.append(line)
-        return ''.join(result)
-
-    def _correct_end_of_file_lines(self, source_code):
-        result = source_code.splitlines()
-        while result and result[-1].strip() == '':
-            del result[-1]
-        if not result:
-            result.append('')
-        result.append('')
-        return '\n'.join(result)

rope/ide/movements.py

-import re
-
-from rope.base import codeanalyze
-
-
-class Statements(object):
-
-    def __init__(self, source):
-        self.source = source
-        self.lines = codeanalyze.SourceLinesAdapter(source)
-        self.logical_lines = codeanalyze.LogicalLineFinder(self.lines)
-
-    def next(self, offset):
-        if offset == len(self.source):
-            return offset
-        lineno = self.lines.get_line_number(offset)
-        if offset == self.lines.get_line_end(lineno):
-            lineno = self._next_nonblank(lineno, 1)
-        start, end = self.logical_lines.get_logical_line_in(lineno)
-        end_offset = self.lines.get_line_end(end)
-        return end_offset
-
-    def prev(self, offset):
-        if offset == 0:
-            return offset
-        lineno = self.lines.get_line_number(offset)
-        if self.lines.get_line_start(lineno) <= offset:
-            diff = self.source[self.lines.get_line_start(lineno):offset]
-            if not diff.strip():
-                lineno = self._next_nonblank(lineno, -1)
-        start, end = self.logical_lines.get_logical_line_in(lineno)
-        start_offset = self.lines.get_line_start(start)
-        return _next_char(self.source, start_offset)
-
-    def _next_nonblank(self, lineno, direction=1):
-        lineno += direction
-        while lineno > 1 and lineno < self.lines.length():
-            line = self.lines.get_line(lineno).strip()
-            if line == '' or line.startswith('#'):
-                lineno += direction
-            else:
-                break
-        return lineno
-
-
-class Scopes(object):
-
-    def __init__(self, source):
-        self.source = source
-        self.pattern = re.compile(r'^[ \t]*(def|class)\s', re.M)
-        self.matches = None
-
-    def next(self, offset):
-        match = self.pattern.search(self.source, offset)
-        if match is not None:
-            if self.source[offset:match.start()].strip(' \t\r\n') == '':
-                match = self.pattern.search(self.source, match.end())
-        if match is not None:
-            offset = match.start()
-        else:
-            offset = len(self.source)
-        return self._prev_char(offset - 1)
-
-    def _prev_char(self, offset):
-        while 0 < offset and self.source[offset] in ' \t\r\n':
-            offset -= 1
-        return offset + 1
-
-    def prev(self, offset):
-        if self.matches is None:
-            self.matches = list(self.pattern.finditer(self.source))
-        prev_match = None
-        for match in self.matches:
-            if match.start() <= offset:
-                prev_match = match
-            else:
-                break
-        if prev_match is not None:
-            start = prev_match.start()
-            if self.source[start] == '\n':
-                start += 1
-            if self.source[start:offset].strip() == '':
-                return self.prev(prev_match.start() - 1)
-            return _next_char(self.source, start)
-        return 0
-
-
-def _next_char(source, offset):
-    while offset < len(source) and \
-          source[offset] in ' \t':
-        offset += 1
-    return offset

rope/ide/notes.py

-import re
-
-from rope.base import ast, codeanalyze
-from rope.refactor import patchedast, similarfinder
-
-
-class Codetags(object):
-
-    def __init__(self):
-        self.pattern = re.compile('# ([A-Z!\\?]{2,10}):')
-
-    def tags(self, source):
-        result = []
-        for lineno, line in enumerate(source.splitlines(False)):
-            match = self.pattern.search(line)
-            if match:
-                result.append((lineno + 1, line[match.start() + 2:]))
-        return result
-
-
-class Errors(object):
-
-    def errors(self, source):
-        try:
-            ast.parse(source)
-        except SyntaxError, e:
-            return [(e.lineno, e.msg)]
-        except SyntaxWarning:
-            pass
-        return []
-
-
-class Warnings(object):
-
-    def warnings(self, source):
-        result = []
-        try:
-            node = ast.parse(source)
-        except SyntaxError:
-            return []
-        except SyntaxWarning, e:
-            result.append((e.lineno, e.msg))
-        visitor = _WarningsVisitor()
-        ast.walk(node, visitor)
-        result.extend(visitor.warnings)
-        result.extend(self._find_self_assignments(node, source))
-        result.sort(cmp=lambda o1, o2: cmp(o1[0], o2[0]))
-        return result
-
-    def _find_self_assignments(self, node, source):
-        result = []
-        finder = similarfinder.SimilarFinder(source, node)
-        lines = codeanalyze.SourceLinesAdapter(source)
-        for self_assignment in finder.get_matches('${?a} = ${?a}'):
-            region = patchedast.node_region(self_assignment.get_ast('?a'))
-            message = 'Assigning <%s> to itself' % source[region[0]:region[1]]
-            lineno = lines.get_line_number(self_assignment.get_region()[0])
-            result.append((lineno, message))
-        return result
-
-
-class _WarningsVisitor(object):
-
-    def __init__(self):
-        self.definitions = set()
-        self.warnings = []
-
-    def _FunctionDef(self, node):
-        self._new_definition(node.name, node.lineno)
-        self._new_scope(node)
-
-    def _ClassDef(self, node):
-        self._new_definition(node.name, node.lineno)
-        self._new_scope(node)
-
-    def _Name(self, node):
-        if isinstance(node.ctx, ast.Store):
-            self._new_name(node.id, node.lineno)
-
-    def _new_name(self, name, lineno):
-        if name in self.definitions:
-            self.warnings.append(
-                (lineno, 'Rebinding defined name <%s>' % name))
-
-    def _new_definition(self, name, lineno):
-        self._new_name(name, lineno)
-        self.definitions.add(name)
-
-    def _new_scope(self, node):
-        visitor = _WarningsVisitor()
-        for child in ast.get_child_nodes(node):
-            ast.walk(child, visitor)
-        self.warnings.extend(visitor.warnings)

rope/ide/outline.py

-from rope.base import ast
-
-
-class PythonASTOutlineNode(object):
-
-    def __init__(self, ast_node):
-        self.name = ast_node.name
-        self.node = ast_node
-        self.children = None
-
-    def get_name(self):
-        return self.name
-
-    def get_line_number(self):
-        return self.node.lineno
-
-    def get_children(self):
-        if self.children is None:
-            self.children = _get_ast_children(self.node)
-        return self.children
-
-    def __cmp__(self, obj):
-        return cmp(self.get_line_number(), obj.get_line_number())
-
-
-class _ASTDefinedVisitor(object):
-
-    def __init__(self):
-        self.result = []
-
-    def _FunctionDef(self, node):
-        self.result.append(PythonASTOutlineNode(node))
-
-    def _ClassDef(self, node):
-        self.result.append(PythonASTOutlineNode(node))
-
-
-def _get_ast_children(node):
-    visitor = _ASTDefinedVisitor()
-    for child in ast.get_child_nodes(node):
-        ast.walk(child, visitor)
-    return visitor.result
-
-
-class PythonOutline(object):
-
-    def __init__(self, project):
-        self.project = project
-
-    def get_root_nodes(self, source_code):
-        if isinstance(source_code, unicode):
-            source_code = source_code.encode('utf-8')
-        ast_node = ast.parse(source_code)
-        return _get_ast_children(ast_node)

rope/ide/pydoc.py

-import sys
-
-from rope.base import pyobjects
-from rope.refactor import functionutils
-
-
-def get_doc(pyobject):
-    return PyDocExtractor().get_doc(pyobject)
-
-
-class PyDocExtractor(object):
-
-    def get_doc(self, pyobject):
-        if isinstance(pyobject, pyobjects.AbstractFunction):
-            return self._get_function_docstring(pyobject)
-        elif isinstance(pyobject, pyobjects.AbstractClass):
-            return self._get_class_docstring(pyobject)
-        elif isinstance(pyobject, pyobjects.AbstractModule):
-            return self._trim_docstring(pyobject.get_doc())
-        return None
-
-    def _get_class_docstring(self, pyclass):
-        contents = self._trim_docstring(pyclass.get_doc(), 2)
-        supers = [super.get_name() for super in pyclass.get_superclasses()]
-        doc = 'class %s(%s):\n\n' % (pyclass.get_name(), ', '.join(supers)) + contents
-
-        if '__init__' in pyclass.get_attributes():
-            init = pyclass.get_attribute('__init__').get_object()
-            if isinstance(init, pyobjects.AbstractFunction):
-                doc += '\n\n' + self._get_single_function_docstring(init)
-        return doc
-
-    def _get_function_docstring(self, pyfunction):
-        functions = [pyfunction]
-        if self._is_method(pyfunction):
-            functions.extend(self._get_super_methods(pyfunction.parent,
-                                                     pyfunction.get_name()))
-        return '\n\n'.join([self._get_single_function_docstring(function)
-                            for function in functions])
-
-    def _is_method(self, pyfunction):
-        return isinstance(pyfunction, pyobjects.PyFunction) and \
-               isinstance(pyfunction.parent, pyobjects.PyClass)
-
-    def _get_single_function_docstring(self, pyfunction):
-        signature = self._get_function_signature(pyfunction)
-        if self._is_method(pyfunction):
-            signature = pyfunction.parent.get_name() + '.' + signature
-            self._get_super_methods(pyfunction.parent, pyfunction.get_name())
-        return signature + ':\n\n' + self._trim_docstring(pyfunction.get_doc(),
-                                                         indents=2)
-
-    def _get_super_methods(self, pyclass, name):
-        result = []
-        for super_class in pyclass.get_superclasses():
-            if name in super_class.get_attributes():
-                function = super_class.get_attribute(name).get_object()
-                if isinstance(function, pyobjects.AbstractFunction):
-                    result.append(function)
-            result.extend(self._get_super_methods(super_class, name))
-        return result
-
-    def _get_function_signature(self, pyfunction):
-        if isinstance(pyfunction, pyobjects.PyFunction):
-            info = functionutils.DefinitionInfo.read(pyfunction)
-            return info.to_string()
-        else:
-            return '%s(%s)' % (pyfunction.get_name(),
-                               ', '.join(pyfunction.get_param_names()))
-
-    def _trim_docstring(self, docstring, indents=0):
-        """The sample code from :PEP:`257`"""
-        if not docstring:
-            return ''
-        # Convert tabs to spaces (following normal Python rules)
-        # and split into a list of lines:
-        lines = docstring.expandtabs().splitlines()
-        # Determine minimum indentation (first line doesn't count):
-        indent = sys.maxint
-        for line in lines[1:]:
-            stripped = line.lstrip()
-            if stripped:
-                indent = min(indent, len(line) - len(stripped))
-        # Remove indentation (first line is special):
-        trimmed = [lines[0].strip()]
-        if indent < sys.maxint:
-            for line in lines[1:]:
-                trimmed.append(line[indent:].rstrip())
-        # Strip off trailing and leading blank lines:
-        while trimmed and not trimmed[-1]:
-            trimmed.pop()
-        while trimmed and not trimmed[0]:
-            trimmed.pop(0)
-        # Return a single string:
-        return '\n'.join((' ' * indents + line for line in trimmed))

rope/ide/sort.py

-from rope.base import change
-
-
-class SortScopes(object):
-
-    def __init__(self, project, resource, offset):
-        self.pycore = project.pycore
-        self.resource = resource
-        self.pymodule = self.pycore.resource_to_pyobject(resource)
-        self.scope = self.pymodule.get_scope().\
-                     get_inner_scope_for_offset(offset)
-        if self.scope.parent is not None and not self.scope.get_scopes():
-            self.scope = self.scope.parent
-
-    def get_changes(self, sorter=None):
-        if sorter is None:
-            sorter = AlphaSorter()
-        changes = change.ChangeSet('Sorting scopes (%s) in <%s>' %
-                                   (sorter, self._get_scope_name()))
-        scopes = self._get_scopes()
-        stmts = self._get_statements(scopes)
-        if not scopes:
-            return changes
-        blanks = scopes[0].blanks
-        scopes[-1].blanks = blanks
-        start = scopes[0].start
-        end = scopes[-1].end
-
-        scopes.sort(cmp=sorter)
-        pieces = self._mix_scopes_and_stmts(scopes, stmts)
-
-        pieces[-1].blanks = 0
-        result = []
-        result.append(self._get_text(1, start - 1))
-        for piece in pieces:
-            extracted = self._get_text(piece.start, piece.end)
-            result.append(extracted + '\n' * piece.blanks)
-        result.append(self._get_text(end + 1))
-        source = ''.join(result)
-        if source != self.resource.read():
-            changes.add_change(change.ChangeContents(self.resource, source))
-        return changes
-
-    def _get_scope_name(self):
-        if self.scope.get_kind() == 'Module':
-            return self.scope.pyobject.resource.path + ' file'
-        return self.scope.pyobject.get_name() + ' scope'
-
-    def _mix_scopes_and_stmts(self, scopes, stmts):
-        result = []
-        for scope in reversed(scopes):
-            while stmts and scope.start < stmts[-1].start:
-                result.append(stmts.pop())
-            result.append(scope)
-        for stmt in stmts:
-            result.append(stmt)
-        result.reverse()
-        return result
-
-    def _get_scopes(self):
-        subs = self.scope.get_scopes()
-        if not subs:
-            return []
-        result = []
-        for scope in subs:
-            start = scope.get_start()
-            end = scope.get_end()
-            blanks = self._count_blanks(end + 1)
-            result.append(_Scope(scope, start, end, blanks))
-        result[-1].blanks = 0
-        return result
-
-    def _get_statements(self, scopes):
-        if not scopes:
-            return []
-        start = scopes[0].end + 1 + scopes[0].blanks
-        result = []
-        for scope in scopes[1:]:
-            end = scope.start - 1
-            if self._get_text(start, end).strip() != '':
-                blanks = self._count_blanks_reversed(end)
-                result.append(_Statements(start, end - blanks, blanks))
-            start = scope.end + 1 + scope.blanks
-        return result
-
-    def _count_blanks(self, start):
-        lines = self.pymodule.lines
-        blanks = 0
-        for lineno in range(start, lines.length() + 1):
-            line = lines.get_line(lineno)
-            if not line.strip():
-                blanks += 1
-            else:
-                break
-        return blanks
-
-    def _count_blanks_reversed(self, start):
-        lines = self.pymodule.lines
-        blanks = 0
-        for lineno in range(start, 0, -1):
-            line = lines.get_line(lineno)
-            if not line.strip():
-                blanks += 1
-            else:
-                break
-        return blanks
-
-    def _get_text(self, start_line, end_line=None):
-        lines = self.pymodule.lines
-        source = self.pymodule.source_code
-        if end_line is None:
-            end_line = lines.length()
-        if start_line > end_line:
-            return ''
-        start = lines.get_line_start(start_line)
-        end = min(lines.get_line_end(end_line) + 1, len(source))
-        return source[start:end]
-
-
-def get_sorter(kind, reverse=False):
-    """Return a sorter that can be passed to `SortScopes.get_changes()`
-
-    Kind can be:
-
-    * 'alpha': for sorting alphabetically
-    * 'kind': classes first
-    * 'underlined': underlined first
-    * 'special': special methods first
-    * 'pydocs': with-pydocs first
-
-    """
-    try:
-        return eval(kind.title() + 'Sorter')(reverse=reverse)
-    except NameError:
-        raise RuntimeError('No such sort kind')
-
-
-class _Scope(object):
-
-    def __init__(self, scope, start, end, blanks):
-        self.start = start
-        self.end = end
-        self.blanks = blanks
-        self.name = scope.pyobject.get_name()
-        self.kind = scope.get_kind()
-        self.has_pydoc = scope.pyobject.get_doc() is not None
-
-
-class _Statements(object):
-
-    def __init__(self, start, end, blanks):
-        self.start = start
-        self.end = end
-        self.blanks = blanks
-
-
-class _Sorter(object):
-
-    def __init__(self, reverse=False):
-        self.coef = 1
-        if reverse:
-            self.coef = -1
-
-    def __str__(self):
-        reverse = ''
-        if self.coef == -1:
-            reverse = 'reversed '
-        return '%sbased on %s' % (reverse, self.kind)
-
-    kind = ''
-
-
-class AlphaSorter(_Sorter):
-
-    def __call__(self, scope1, scope2):
-        return self.coef * cmp(scope1.name.lower() + scope1.name,
-                               scope2.name.lower() + scope1.name)
-
-    kind = 'name'
-
-
-class KindSorter(_Sorter):
-
-    def __call__(self, scope1, scope2):
-        return self.coef * cmp(scope1.kind, scope2.kind)
-
-    kind = 'kind'
-
-
-class UnderlinedSorter(_Sorter):
-
-    def __call__(self, scope1, scope2):
-        return self.coef * -cmp(self._is_underlined(scope1.name),
-                                self._is_underlined(scope2.name))
-
-    def _is_underlined(self, name):
-        return name.startswith('_') and not name.endswith('_')
-
-    kind = 'being underlined'
-
-
-class SpecialSorter(_Sorter):
-
-    def __call__(self, scope1, scope2):
-        return self.coef * -cmp(self._is_special(scope1.name),
-                                self._is_special(scope2.name))
-
-    def _is_special(self, name):
-        return name.startswith('__') and name.endswith('__')
-
-    kind = 'being special method'
-
-
-class PydocSorter(_Sorter):
-
-    def __call__(self, scope1, scope2):
-        return self.coef * -cmp(scope1.has_pydoc, scope2.has_pydoc)
-
-    kind = 'having pydoc'

rope/ide/spellchecker.py

-import subprocess
-import os
-from rope.base import exceptions
-
-
-class SpellChecker(object):
-    """An interface to Aspell/Ispell programs"""
-
-    def __init__(self, text, aspell=None, save_dict=True):
-        self.text = text
-        if aspell is None:
-            self.aspell = Aspell()
-        else:
-            self.aspell = aspell
-        self.aspell.read_line()
-        self.aspell.write_line('!')
-        self.line_offset = 0
-        self.line_ignored = set()
-        self.do_quit = False
-        self.save_dict = save_dict
-
-    def check(self):
-        lines = self.text.splitlines()
-        for line in lines:
-            if self.do_quit:
-                break
-            for typo in self._check_line(line):
-                yield typo
-            self.line_offset += len(line) + 1
-            self.line_ignored.clear()
-        # PORT: Removed finally clause for python 2.4
-        if self.save_dict:
-            self.aspell.write_line('#')
-        self.aspell.close()
-
-    def _check_line(self, line):
-        self.aspell.write_line('^%s' % line)
-        while True:
-            if self.do_quit:
-                break
-            result = self.aspell.read_line()
-            if result.strip() == '':
-                break
-            words = result.split()
-            typo = None
-            if result.startswith('&'):
-                suggestions = []
-                for word in words[4:]:
-                    suggestions.append(word.rstrip(','))
-                offset = int(words[3][:-1]) - 1 + self.line_offset
-                typo = self._get_typo(words[1], offset, suggestions)
-            if result.startswith('#'):
-                offset = int(words[2]) - 1 + self.line_offset
-                typo = self._get_typo(words[1], offset)
-            if typo is not None:
-                yield typo
-
-    def _get_typo(self, word, offset, suggestions=[]):
-        if word not in self.line_ignored:
-            return Typo(word, offset, suggestions)
-
-    def accept_word(self, word):
-        self.aspell.write_line('@%s' % word)
-        self.line_ignored.add(word)
-
-    def insert_dictionary(self, word):
-        self.aspell.write_line('*%s' % word)
-        self.line_ignored.add(word)
-
-    def save_dictionary(self):
-        self.aspell.write_line('#')
-
-    def quit(self):
-        self.do_quit = True
-
-
-class Typo(object):
-
-    def __init__(self, original, offset, suggestions=[]):
-        self.original = original
-        self.offset = offset
-        self.suggestions = suggestions
-
-
-class Aspell(object):
-
-    def __init__(self):
-        self.process = subprocess.Popen(
-            [self._find_executable(), '-a'], stdin=subprocess.PIPE,
-            stdout=subprocess.PIPE, close_fds=True)
-
-    def _find_executable(self):
-        candidates = ['/usr/bin/aspell', '/usr/local/bin/aspell',
-                      '/usr/bin/ispell', '/usr/local/bin/ispell']
-        for candidate in candidates:
-            if os.path.exists(candidate):
-                return candidate
-        raise exceptions.RopeError('Cannot find Aspell/Ispell')
-
-    def write_line(self, line):
-        self.process.stdin.write(line + '\n')
-        self.process.stdin.flush()
-
-    def read_line(self):
-        return self.process.stdout.readline()
-
-    def close(self):
-        self.process.stdin.close()

ropeide/editactions.py

 from ropeide import uihelpers, fill
 from ropeide.extension import SimpleAction
 from ropeide.menubar import MenuAddress
-from rope.ide import movements
+import ropeide.movements
 
 
 def set_mark(context):
 
 class PrevNextElement(object):
 
-    def __init__(self, next=True, element=movements.Statements):
+    def __init__(self, next=True, element=ropeide.movements.Statements):
         self.next = next
         self.element_type = element
         self.elements = None
 actions.append(SimpleAction('prev_statement', PrevNextElement(False), 'M-a',
                             others.child('Prev Statement'), ['python']))
 actions.append(
-    SimpleAction('next_scope', PrevNextElement(element=movements.Scopes), 'C-M-e',
+    SimpleAction('next_scope', PrevNextElement(element=ropeide.movements.Scopes), 'C-M-e',
                  others.child('Next Scope'), ['python']))
 actions.append(
-    SimpleAction('prev_scope', PrevNextElement(False, movements.Scopes), 'M-C-a',
+    SimpleAction('prev_scope', PrevNextElement(False, ropeide.movements.Scopes), 'M-C-a',
                  others.child('Prev Scope'), ['python']))
 
 

ropeide/formatter.py

+# NOTE: This actually does not format anything.  It merely removes
+#   extra blank lines and trailing white-spaces.  Now that
+#   `rope.refactor.patchedast` has been added I think this can be
+#   implemented.
+
+
+class Formatter(object):
+
+    def format(self, source_code):
+        source_code = self._remove_extra_spaces(source_code)
+        source_code = self._remove_extra_lines(source_code)
+        source_code = self._correct_end_of_file_lines(source_code)
+        return source_code
+
+    def _remove_extra_spaces(self, source_code):
+        result = []
+        for line in source_code.splitlines():
+            result.append(line.rstrip())
+        if source_code.endswith('\n'):
+            result.append('')
+        return '\n'.join(result)
+
+    def _remove_extra_lines(self, source_code):
+        result = []
+        blank_lines = 0
+        for line in source_code.splitlines(True):
+            if line.strip() == '':
+                blank_lines += 1
+                if blank_lines <= 2:
+                    result.append(line)
+            else:
+                blank_lines = 0
+                result.append(line)
+        return ''.join(result)
+
+    def _correct_end_of_file_lines(self, source_code):
+        result = source_code.splitlines()
+        while result and result[-1].strip() == '':
+            del result[-1]
+        if not result:
+            result.append('')
+        result.append('')
+        return '\n'.join(result)

ropeide/movements.py

+import re
+
+from rope.base import codeanalyze
+
+
+class Statements(object):
+
+    def __init__(self, source):
+        self.source = source
+        self.lines = codeanalyze.SourceLinesAdapter(source)
+        self.logical_lines = codeanalyze.LogicalLineFinder(self.lines)
+
+    def next(self, offset):
+        if offset == len(self.source):
+            return offset
+        lineno = self.lines.get_line_number(offset)
+        if offset == self.lines.get_line_end(lineno):
+            lineno = self._next_nonblank(lineno, 1)
+        start, end = self.logical_lines.get_logical_line_in(lineno)
+        end_offset = self.lines.get_line_end(end)
+        return end_offset
+
+    def prev(self, offset):
+        if offset == 0:
+            return offset
+        lineno = self.lines.get_line_number(offset)
+        if self.lines.get_line_start(lineno) <= offset:
+            diff = self.source[self.lines.get_line_start(lineno):offset]
+            if not diff.strip():
+                lineno = self._next_nonblank(lineno, -1)
+        start, end = self.logical_lines.get_logical_line_in(lineno)
+        start_offset = self.lines.get_line_start(start)
+        return _next_char(self.source, start_offset)
+
+    def _next_nonblank(self, lineno, direction=1):
+        lineno += direction
+        while lineno > 1 and lineno < self.lines.length():
+            line = self.lines.get_line(lineno).strip()
+            if line == '' or line.startswith('#'):
+                lineno += direction
+            else:
+                break
+        return lineno
+
+
+class Scopes(object):
+
+    def __init__(self, source):
+        self.source = source
+        self.pattern = re.compile(r'^[ \t]*(def|class)\s', re.M)
+        self.matches = None
+
+    def next(self, offset):
+        match = self.pattern.search(self.source, offset)
+        if match is not None:
+            if self.source[offset:match.start()].strip(' \t\r\n') == '':
+                match = self.pattern.search(self.source, match.end())
+        if match is not None:
+            offset = match.start()
+        else:
+            offset = len(self.source)
+        return self._prev_char(offset - 1)
+
+    def _prev_char(self, offset):
+        while 0 < offset and self.source[offset] in ' \t\r\n':
+            offset -= 1
+        return offset + 1
+
+    def prev(self, offset):
+        if self.matches is None:
+            self.matches = list(self.pattern.finditer(self.source))
+        prev_match = None
+        for match in self.matches:
+            if match.start() <= offset:
+                prev_match = match
+            else:
+                break
+        if prev_match is not None:
+            start = prev_match.start()
+            if self.source[start] == '\n':
+                start += 1
+            if self.source[start:offset].strip() == '':
+                return self.prev(prev_match.start() - 1)
+            return _next_char(self.source, start)
+        return 0
+
+
+def _next_char(source, offset):
+    while offset < len(source) and \
+          source[offset] in ' \t':
+        offset += 1
+    return offset
+import re
+
+from rope.base import ast, codeanalyze
+from rope.refactor import patchedast, similarfinder
+
+
+class Codetags(object):
+
+    def __init__(self):
+        self.pattern = re.compile('# ([A-Z!\\?]{2,10}):')
+
+    def tags(self, source):
+        result = []
+        for lineno, line in enumerate(source.splitlines(False)):
+            match = self.pattern.search(line)
+            if match:
+                result.append((lineno + 1, line[match.start() + 2:]))
+        return result
+
+
+class Errors(object):
+
+    def errors(self, source):
+        try:
+            ast.parse(source)
+        except SyntaxError, e:
+            return [(e.lineno, e.msg)]
+        except SyntaxWarning:
+            pass
+        return []
+
+
+class Warnings(object):
+
+    def warnings(self, source):
+        result = []
+        try:
+            node = ast.parse(source)
+        except SyntaxError:
+            return []
+        except SyntaxWarning, e:
+            result.append((e.lineno, e.msg))
+        visitor = _WarningsVisitor()
+        ast.walk(node, visitor)
+        result.extend(visitor.warnings)
+        result.extend(self._find_self_assignments(node, source))
+        result.sort(cmp=lambda o1, o2: cmp(o1[0], o2[0]))
+        return result
+
+    def _find_self_assignments(self, node, source):
+        result = []
+        finder = similarfinder.SimilarFinder(source, node)
+        lines = codeanalyze.SourceLinesAdapter(source)
+        for self_assignment in finder.get_matches('${?a} = ${?a}'):
+            region = patchedast.node_region(self_assignment.get_ast('?a'))
+            message = 'Assigning <%s> to itself' % source[region[0]:region[1]]
+            lineno = lines.get_line_number(self_assignment.get_region()[0])
+            result.append((lineno, message))
+        return result
+
+
+class _WarningsVisitor(object):
+
+    def __init__(self):
+        self.definitions = set()
+        self.warnings = []
+
+    def _FunctionDef(self, node):
+        self._new_definition(node.name, node.lineno)
+        self._new_scope(node)
+
+    def _ClassDef(self, node):
+        self._new_definition(node.name, node.lineno)
+        self._new_scope(node)
+
+    def _Name(self, node):
+        if isinstance(node.ctx, ast.Store):
+            self._new_name(node.id, node.lineno)
+
+    def _new_name(self, name, lineno):
+        if name in self.definitions:
+            self.warnings.append(
+                (lineno, 'Rebinding defined name <%s>' % name))
+
+    def _new_definition(self, name, lineno):
+        self._new_name(name, lineno)
+        self.definitions.add(name)
+
+    def _new_scope(self, node):
+        visitor = _WarningsVisitor()
+        for child in ast.get_child_nodes(node):
+            ast.walk(child, visitor)
+        self.warnings.extend(visitor.warnings)

ropeide/outline.py

+from rope.base import ast
+
+
+class PythonASTOutlineNode(object):
+
+    def __init__(self, ast_node):
+        self.name = ast_node.name
+        self.node = ast_node
+        self.children = None
+
+    def get_name(self):
+        return self.name
+
+    def get_line_number(self):
+        return self.node.lineno
+
+    def get_children(self):
+        if self.children is None:
+            self.children = _get_ast_children(self.node)
+        return self.children
+
+    def __cmp__(self, obj):
+        return cmp(self.get_line_number(), obj.get_line_number())
+
+
+class _ASTDefinedVisitor(object):
+
+    def __init__(self):
+        self.result = []
+
+    def _FunctionDef(self, node):
+        self.result.append(PythonASTOutlineNode(node))
+
+    def _ClassDef(self, node):
+        self.result.append(PythonASTOutlineNode(node))
+
+
+def _get_ast_children(node):
+    visitor = _ASTDefinedVisitor()
+    for child in ast.get_child_nodes(node):
+        ast.walk(child, visitor)
+    return visitor.result
+
+
+class PythonOutline(object):
+
+    def __init__(self, project):
+        self.project = project
+
+    def get_root_nodes(self, source_code):
+        if isinstance(source_code, unicode):
+            source_code = source_code.encode('utf-8')
+        ast_node = ast.parse(source_code)
+        return _get_ast_children(ast_node)
+from rope.base import change
+
+
+class SortScopes(object):
+
+    def __init__(self, project, resource, offset):
+        self.pycore = project.pycore
+        self.resource = resource
+        self.pymodule = self.pycore.resource_to_pyobject(resource)
+        self.scope = self.pymodule.get_scope().\
+                     get_inner_scope_for_offset(offset)
+        if self.scope.parent is not None and not self.scope.get_scopes():
+            self.scope = self.scope.parent
+
+    def get_changes(self, sorter=None):
+        if sorter is None:
+            sorter = AlphaSorter()
+        changes = change.ChangeSet('Sorting scopes (%s) in <%s>' %
+                                   (sorter, self._get_scope_name()))
+        scopes = self._get_scopes()
+        stmts = self._get_statements(scopes)
+        if not scopes:
+            return changes
+        blanks = scopes[0].blanks
+        scopes[-1].blanks = blanks
+        start = scopes[0].start
+        end = scopes[-1].end
+
+        scopes.sort(cmp=sorter)
+        pieces = self._mix_scopes_and_stmts(scopes, stmts)
+
+        pieces[-1].blanks = 0
+        result = []
+        result.append(self._get_text(1, start - 1))
+        for piece in pieces:
+            extracted = self._get_text(piece.start, piece.end)
+            result.append(extracted + '\n' * piece.blanks)
+        result.append(self._get_text(end + 1))
+        source = ''.join(result)
+        if source != self.resource.read():
+            changes.add_change(change.ChangeContents(self.resource, source))
+        return changes
+
+    def _get_scope_name(self):
+        if self.scope.get_kind() == 'Module':
+            return self.scope.pyobject.resource.path + ' file'
+        return self.scope.pyobject.get_name() + ' scope'
+
+    def _mix_scopes_and_stmts(self, scopes, stmts):
+        result = []
+        for scope in reversed(scopes):
+            while stmts and scope.start < stmts[-1].start:
+                result.append(stmts.pop())
+            result.append(scope)
+        for stmt in stmts:
+            result.append(stmt)
+        result.reverse()
+        return result
+
+    def _get_scopes(self):
+        subs = self.scope.get_scopes()
+        if not subs:
+            return []
+        result = []
+        for scope in subs:
+            start = scope.get_start()
+            end = scope.get_end()
+            blanks = self._count_blanks(end + 1)
+            result.append(_Scope(scope, start, end, blanks))
+        result[-1].blanks = 0
+        return result
+
+    def _get_statements(self, scopes):
+        if not scopes:
+            return []
+        start = scopes[0].end + 1 + scopes[0].blanks
+        result = []
+        for scope in scopes[1:]:
+            end = scope.start - 1
+            if self._get_text(start, end).strip() != '':
+                blanks = self._count_blanks_reversed(end)
+                result.append(_Statements(start, end - blanks, blanks))
+            start = scope.end + 1 + scope.blanks
+        return result
+
+    def _count_blanks(self, start):
+        lines = self.pymodule.lines
+        blanks = 0
+        for lineno in range(start, lines.length() + 1):
+            line = lines.get_line(lineno)
+            if not line.strip():
+                blanks += 1
+            else:
+                break
+        return blanks
+
+    def _count_blanks_reversed(self, start):
+        lines = self.pymodule.lines
+        blanks = 0
+        for lineno in range(start, 0, -1):
+            line = lines.get_line(lineno)
+            if not line.strip():
+                blanks += 1
+            else:
+                break
+        return blanks
+
+    def _get_text(self, start_line, end_line=None):
+        lines = self.pymodule.lines
+        source = self.pymodule.source_code
+        if end_line is None:
+            end_line = lines.length()
+        if start_line > end_line:
+            return ''
+        start = lines.get_line_start(start_line)
+        end = min(lines.get_line_end(end_line) + 1, len(source))
+        return source[start:end]
+
+
+def get_sorter(kind, reverse=False):
+    """Return a sorter that can be passed to `SortScopes.get_changes()`
+
+    Kind can be:
+
+    * 'alpha': for sorting alphabetically
+    * 'kind': classes first
+    * 'underlined': underlined first
+    * 'special': special methods first
+    * 'pydocs': with-pydocs first
+
+    """
+    try:
+        return eval(kind.title() + 'Sorter')(reverse=reverse)
+    except NameError:
+        raise RuntimeError('No such sort kind')
+
+
+class _Scope(object):
+
+    def __init__(self, scope, start, end, blanks):
+        self.start = start
+        self.end = end
+        self.blanks = blanks
+        self.name = scope.pyobject.get_name()
+        self.kind = scope.get_kind()
+        self.has_pydoc = scope.pyobject.get_doc() is not None
+
+
+class _Statements(object):
+
+    def __init__(self, start, end, blanks):
+        self.start = start
+        self.end = end
+        self.blanks = blanks
+
+
+class _Sorter(object):
+
+    def __init__(self, reverse=False):
+        self.coef = 1
+        if reverse:
+            self.coef = -1
+
+    def __str__(self):
+        reverse = ''
+        if self.coef == -1:
+            reverse = 'reversed '
+        return '%sbased on %s' % (reverse, self.kind)
+
+    kind = ''
+
+
+class AlphaSorter(_Sorter):
+
+    def __call__(self, scope1, scope2):
+        return self.coef * cmp(scope1.name.lower() + scope1.name,
+                               scope2.name.lower() + scope1.name)
+
+    kind = 'name'
+
+
+class KindSorter(_Sorter):
+
+    def __call__(self, scope1, scope2):
+        return self.coef * cmp(scope1.kind, scope2.kind)
+
+    kind = 'kind'
+
+
+class UnderlinedSorter(_Sorter):
+
+    def __call__(self, scope1, scope2):
+        return self.coef * -cmp(self._is_underlined(scope1.name),
+                                self._is_underlined(scope2.name))
+
+    def _is_underlined(self, name):
+        return name.startswith('_') and not name.endswith('_')
+
+    kind = 'being underlined'
+
+
+class SpecialSorter(_Sorter):
+
+    def __call__(self, scope1, scope2):
+        return self.coef * -cmp(self._is_special(scope1.name),
+                                self._is_special(scope2.name))
+
+    def _is_special(self, name):
+        return name.startswith('__') and name.endswith('__')
+
+    kind = 'being special method'
+
+
+class PydocSorter(_Sorter):
+
+    def __call__(self, scope1, scope2):
+        return self.coef * -cmp(scope1.has_pydoc, scope2.has_pydoc)
+
+    kind = 'having pydoc'

ropeide/sourceactions.py

 import ropeide.core
 import ropeide.testview
 from rope.base import codeanalyze
-from rope.ide import formatter, notes, generate, sort, outline
+from rope.ide import generate
 from ropeide import spelldialog, registers
 from ropeide.actionhelpers import ConfirmEditorsAreSaved, StoppableTaskRunner
 from ropeide.extension import SimpleAction
 from ropeide.menubar import MenuAddress
 from ropeide.uihelpers import (TreeView, TreeViewHandle, EnhancedList,
                                EnhancedListHandle)
+import ropeide.formatter
+import ropeide.notes
+import ropeide.outline
+import ropeide.sort
 class _OutlineViewHandle(TreeViewHandle):
 
     def __init__(self, editor, toplevel):
     toplevel.title('Quick Outline')
     tree_view = TreeView(toplevel, _OutlineViewHandle(editor, toplevel),
                          title='Quick Outline')
-    for node in (outline.PythonOutline(context.project).\
+    for node in (ropeide.outline.PythonOutline(context.project).\
                  get_root_nodes(editor.get_text())):
         tree_view.add_entry(node)
     toplevel.grab_set()
 
 def do_format_code(context):
     editor = context.editor
-    result = formatter.Formatter().format(editor.get_text())
+    result = ropeide.formatter.Formatter().format(editor.get_text())
     if result != editor.get_text():
         editor.set_text(result, reset_editor=False)
 
     enhanced_list.list.focus_set()
 
 def show_codetags(context):
-    tags = notes.Codetags().tags(context.resource.read())
+    tags = ropeide.notes.Codetags().tags(context.resource.read())
     _show_annotations(context, 'Codetag', tags)
 
 def show_errors(context):
-    tags = notes.Errors().errors(context.resource.read())
+    tags = ropeide.notes.Errors().errors(context.resource.read())
     _show_annotations(context, 'Error', tags)
 
 def show_warnings(context):
-    tags = notes.Warnings().warnings(context.resource.read())
+    tags = ropeide.notes.Warnings().warnings(context.resource.read())
     _show_annotations(context, 'Warning', tags)
 
 def show_all(context):
-    result = notes.Codetags().tags(context.resource.read())
-    result.extend(notes.Warnings().warnings(context.resource.read()))
-    result.extend(notes.Errors().errors(context.resource.read()))
+    result = ropeide.notes.Codetags().tags(context.resource.read())
+    result.extend(ropeide.notes.Warnings().warnings(context.resource.read()))
+    result.extend(ropeide.notes.Errors().errors(context.resource.read()))
     result.sort()
     _show_annotations(context, 'Annotation', result)
 
                  'p': 'pydoc', 's': 'special', 'u': 'underlined'}
 
 def sort_scopes(context, kind):
-    sorter = sort.get_sorter(_sort_mapping[kind.lower()],
+    sorter = ropeide.sort.get_sorter(_sort_mapping[kind.lower()],
                              reverse=context.prefix)
-    sort_scopes = sort.SortScopes(context.project,
+    sort_scopes = ropeide.sort.SortScopes(context.project,
                                   context.resource, context.offset)
     context.project.do(sort_scopes.get_changes(sorter=sorter))
     
 def _generate_sort_actions(menu):
     for name in _sort_mapping.values():
         c = name[0].lower()
-        sorter = sort.get_sorter(name)
+        sorter = ropeide.sort.get_sorter(name)
         action_name = 'sort_by_' + name
         menu_name = str(sorter)
         yield SimpleAction(

ropeide/spellchecker.py

+import subprocess
+import os
+from rope.base import exceptions
+
+
+class SpellChecker(object):
+    """An interface to Aspell/Ispell programs"""
+
+    def __init__(self, text, aspell=None, save_dict=True):
+        self.text = text
+        if aspell is None:
+            self.aspell = Aspell()
+        else:
+            self.aspell = aspell
+        self.aspell.read_line()
+        self.aspell.write_line('!')
+        self.line_offset = 0
+        self.line_ignored = set()
+        self.do_quit = False
+        self.save_dict = save_dict
+
+    def check(self):
+        lines = self.text.splitlines()
+        for line in lines:
+            if self.do_quit:
+                break
+            for typo in self._check_line(line):
+                yield typo
+            self.line_offset += len(line) + 1
+            self.line_ignored.clear()
+        # PORT: Removed finally clause for python 2.4
+        if self.save_dict:
+            self.aspell.write_line('#')
+        self.aspell.close()
+
+    def _check_line(self, line):
+        self.aspell.write_line('^%s' % line)
+        while True:
+            if self.do_quit:
+                break
+            result = self.aspell.read_line()
+            if result.strip() == '':
+                break
+            words = result.split()
+            typo = None
+            if result.startswith('&'):
+                suggestions = []
+                for word in words[4:]:
+                    suggestions.append(word.rstrip(','))
+                offset = int(words[3][:-1]) - 1 + self.line_offset
+                typo = self._get_typo(words[1], offset, suggestions)
+            if result.startswith('#'):
+                offset = int(words[2]) - 1 + self.line_offset
+                typo = self._get_typo(words[1], offset)
+            if typo is not None:
+                yield typo
+
+    def _get_typo(self, word, offset, suggestions=[]):
+        if word not in self.line_ignored:
+            return Typo(word, offset, suggestions)
+
+    def accept_word(self, word):
+        self.aspell.write_line('@%s' % word)
+        self.line_ignored.add(word)
+
+    def insert_dictionary(self, word):
+        self.aspell.write_line('*%s' % word)
+        self.line_ignored.add(word)
+
+    def save_dictionary(self):
+        self.aspell.write_line('#')
+
+    def quit(self):
+        self.do_quit = True
+
+
+class Typo(object):
+
+    def __init__(self, original, offset, suggestions=[]):
+        self.original = original
+        self.offset = offset
+        self.suggestions = suggestions
+
+
+class Aspell(object):
+
+    def __init__(self):
+        self.process = subprocess.Popen(
+            [self._find_executable(), '-a'], stdin=subprocess.PIPE,
+            stdout=subprocess.PIPE, close_fds=True)
+
+    def _find_executable(self):
+        candidates = ['/usr/bin/aspell', '/usr/local/bin/aspell',
+                      '/usr/bin/ispell', '/usr/local/bin/ispell']
+        for candidate in candidates:
+            if os.path.exists(candidate):
+                return candidate
+        raise exceptions.RopeError('Cannot find Aspell/Ispell')
+
+    def write_line(self, line):
+        self.process.stdin.write(line + '\n')
+        self.process.stdin.flush()
+
+    def read_line(self):
+        return self.process.stdout.readline()
+
+    def close(self):
+        self.process.stdin.close()

ropeide/spelldialog.py

 import threading
 import Tkinter
 
-from rope.ide.spellchecker import SpellChecker
+from ropeide.spellchecker import SpellChecker
 
 
 class _SpellCheckingDialog(object):

ropetest/ide/formattertest.py

 import unittest
 
-from rope.ide.formatter import Formatter
+from ropeide.formatter import Formatter
 
 
 class FormatterTest(unittest.TestCase):

ropetest/ide/movementstest.py

 import unittest
-from rope.ide import movements
+import ropeide.movements
 
 
 class StatementsTest(unittest.TestCase):
         super(StatementsTest, self).tearDown()
 
     def test_trivial_case(self):
-        statements = movements.Statements('')
+        statements = ropeide.movements.Statements('')
         self.assertEquals(0, statements.next(0))
 
     def test_real_statements(self):
         code = 'a = 1\n'
-        statements = movements.Statements(code)
+        statements = ropeide.movements.Statements(code)
         self.assertEquals(code.index('\n'), statements.next(0))
 
     def test_next_statement(self):
         code = 'a = 1\nb = 1\n'
-        statements = movements.Statements(code)
+        statements = ropeide.movements.Statements(code)
         self.assertEquals(code.rindex('\n'),
                           statements.next(code.index('\n')))
 
     def test_trivial_prev(self):
-        statements = movements.Statements('')
+        statements = ropeide.movements.Statements('')
         self.assertEquals(0, statements.prev(0))
 
     def test_prev_statement_at_the_start(self):
         code = 'a = 1\n'
-        statements = movements.Statements(code)
+        statements = ropeide.movements.Statements(code)
         self.assertEquals(0, statements.prev(0))
 
     def test_prev_statement_at_the_start(self):
         code = 'a = 1\n'
-        statements = movements.Statements(code)
+        statements = ropeide.movements.Statements(code)
         self.assertEquals(0, statements.prev(code.index('1')))
 
     def test_prev_statement(self):
         code = 'a = 1\nb = 1\n'
-        statements = movements.Statements(code)
+        statements = ropeide.movements.Statements(code)
         self.assertEquals(0, statements.prev(code.index('b')))
         self.assertEquals(code.index('b'), statements.prev(code.rindex('1')))
 
     def test_prev_statement_with_blank_lines(self):
         code = 'a = 1\n\nb = 1\n'
-        statements = movements.Statements(code)
+        statements = ropeide.movements.Statements(code)
         self.assertEquals(0, statements.prev(code.index('b')))
         self.assertEquals(code.index('b'), statements.prev(code.rindex('1')))
 
     def test_prev_statement_with_indented_lines(self):
         code = 'def f():\n    a = 1\n'
-        statements = movements.Statements(code)
+        statements = ropeide.movements.Statements(code)
         self.assertEquals(code.index('a'), statements.prev(len(code)))
 
     def test_prev_statement_and_comments(self):
         code = 'a = 1\n# ccc\nb = 1\n'
-        statements = movements.Statements(code)
+        statements = ropeide.movements.Statements(code)
         self.assertEquals(0, statements.prev(code.index('b')))
 
 
 
     def test_trivial_case(self):
         code = ''
-        scopes = movements.Scopes(code)
+        scopes = ropeide.movements.Scopes(code)
         self.assertEquals(0, scopes.next(0))
 
     def test_next_on_functions(self):
         code = 'def f():\n    pass\n'
-        scopes = movements.Scopes(code)
+        scopes = ropeide.movements.Scopes(code)
         self.assertEquals(len(code) - 1, scopes.next(0))
 
     def test_next_on_functions(self):
         code = 'def f():\n    pass\n\ndef g():\n    pass\n'
-        scopes = movements.Scopes(code)
+        scopes = ropeide.movements.Scopes(code)
         self.assertEquals(code.index('\n\n'), scopes.next(0))
         self.assertEquals(code.index('\n\n'), scopes.next(1))
         self.assertEquals(len(code) - 1, scopes.next(code.index('g')))
 
     def test_trivial_prev(self):
         code = ''
-        scopes = movements.Scopes(code)
+        scopes = ropeide.movements.Scopes(code)
         self.assertEquals(0, scopes.prev(0))
 
     def test_prev_on_functions(self):
         code = 'def f():\n    pass\n'
-        scopes = movements.Scopes(code)
+        scopes = ropeide.movements.Scopes(code)
         self.assertEquals(0, scopes.prev(10))
         self.assertEquals(0, scopes.prev(len(code)))
 
     def test_prev_on_functions(self):
         code = 'def f():\n    pass\n\ndef g():\n    pass\n'
-        scopes = movements.Scopes(code)
+        scopes = ropeide.movements.Scopes(code)
         self.assertEquals(0, scopes.prev(code.index('()')))
         self.assertEquals(code.index('def g'), scopes.prev(len(code)))
 
     def test_prev_on_indented_functions(self):
         code = 'class A(object):\n    def f():\n        pass\n\n\n' \
                '    def g():\n        pass\n'
-        scopes = movements.Scopes(code)
+        scopes = ropeide.movements.Scopes(code)
         self.assertEquals(code.index('def f'),
                           scopes.prev(code.index('def g')))
 

ropetest/ide/notestest.py

 import unittest
-
-from rope.ide import notes
 from ropetest import testutils
+import ropeide.notes
 
 
 class AnnotationsTest(unittest.TestCase):
     def setUp(self):
         super(AnnotationsTest, self).setUp()
         self.project = testutils.sample_project()
-        self.tags = notes.Codetags()
+        self.tags = ropeide.notes.Codetags()
 
     def tearDown(self):
         testutils.remove_project(self.project)
              self.tags.tags('# XXX: todo\n\n# FIXME: fix me\n'))
 
     def test_errors_empty_input(self):
-        errors = notes.Errors()
+        errors = ropeide.notes.Errors()
         self.assertEquals([], errors.errors(''))
 
     def test_errors_trival_error(self):
-        errors = notes.Errors()
+        errors = ropeide.notes.Errors()
         self.assertEquals([(1, 'invalid syntax')],
                           errors.errors('error input\n'))
 
     def test_warnings_empty_input(self):
-        warnings = notes.Warnings()
+        warnings = ropeide.notes.Warnings()
         self.assertEquals([], warnings.warnings(''))
 
     def test_warnings_redefining_functions_in_global_scope(self):
-        warnings = notes.Warnings()
+        warnings = ropeide.notes.Warnings()
         self.assertEquals([(3, 'Rebinding defined name <f>')],
                           warnings.warnings('def f():\n    pass\nf = 1\n'))
 
     def test_warnings_redefining_classes_in_global_scope(self):
-        warnings = notes.Warnings()
+        warnings = ropeide.notes.Warnings()
         self.assertEquals([(3, 'Rebinding defined name <C>')],
                           warnings.warnings('class C(object):\n    pass\nC = 1\n'))
 
     def test_warnings_redefining_nested_scopes(self):
-        warnings = notes.Warnings()
+        warnings = ropeide.notes.Warnings()
         self.assertEquals(
             [(4, 'Rebinding defined name <g>')], warnings.warnings(
             'def f():\n    def g():\n        pass\n    g = 1\n'))
 
     def test_warnings_not_redefining_in_nested_scopes(self):
-        warnings = notes.Warnings()
+        warnings = ropeide.notes.Warnings()
         self.assertEquals([], warnings.warnings(
                           'def f():\n    def g():\n        pass\ng = 1\n'))
 
     def test_warnings_redefining_functions_by_functions(self):
-        warnings = notes.Warnings()
+        warnings = ropeide.notes.Warnings()
         self.assertEquals([(3, 'Rebinding defined name <f>')],
                           warnings.warnings('def f():\n    pass\n'
                                             'def f():\n    pass\n'))
 
     def test_self_assignment_warnings(self):
-        warnings = notes.Warnings()
+        warnings = ropeide.notes.Warnings()
         self.assertEquals([(2, 'Assigning <a> to itself')],
                           warnings.warnings('a = 1\na = a\n'))
 
     def test_self_assignment_warnings(self):
-        warnings = notes.Warnings()
+        warnings = ropeide.notes.Warnings()
         self.assertEquals([(2, 'Assigning <a.b> to itself')],
                           warnings.warnings('a = None\na.b = a.b\n'))
 

ropetest/ide/outlinetest.py

 import unittest
 
-from rope.ide.outline import PythonOutline
+from ropeide.outline import PythonOutline
 from ropetest import testutils
 
 

ropetest/ide/sorttest.py

 import unittest
-
-from rope.ide import sort
 from ropetest import testutils
+import ropeide.sort
 
 
 class SortScopesTest(unittest.TestCase):
         super(SortScopesTest, self).tearDown()
 
     def _do_sort(self, offset, sorter=None):
-        sort_scopes = sort.SortScopes(self.project, self.mod, offset)
+        sort_scopes = ropeide.sort.SortScopes(self.project, self.mod, offset)
         self.project.do(sort_scopes.get_changes(sorter))
 
     def test_trivial_case(self):
 
     def test_classes_first(self):
         self.mod.write('\ndef a():\n    pass\n\nclass b():\n    pass\n')
-        self._do_sort(0, sort.KindSorter())
+        self._do_sort(0, ropeide.sort.KindSorter())
         self.assertEquals('\nclass b():\n    pass\n\ndef a():\n    pass\n',
                           self.mod.read())
 
     def test_functions_first(self):
         self.mod.write('\ndef a():\n    pass\n\nclass b():\n    pass\n')
-        self._do_sort(0, sort.KindSorter(reverse=True))
+        self._do_sort(0, ropeide.sort.KindSorter(reverse=True))
         self.assertEquals('\ndef a():\n    pass\n\nclass b():\n    pass\n',
                           self.mod.read())
 
     def test_underlined_last(self):
         self.mod.write('\ndef _a():\n    pass\n\ndef a():\n    pass\n')
-        self._do_sort(0, sort.UnderlinedSorter(reverse=True))
+        self._do_sort(0, ropeide.sort.UnderlinedSorter(reverse=True))
         self.assertEquals('\ndef a():\n    pass\n\ndef _a():\n    pass\n',
                           self.mod.read())
 
     def test_special_last(self):
         self.mod.write('\ndef __a__():\n    pass\n\ndef a():\n    pass\n')
-        self._do_sort(0, sort.SpecialSorter(reverse=True))
+        self._do_sort(0, ropeide.sort.SpecialSorter(reverse=True))
         self.assertEquals('\ndef a():\n    pass\n\ndef __a__():\n    pass\n',
                           self.mod.read())
 
     def test_classes_first(self):
         self.mod.write('\ndef a():\n    pass\n\nclass b():\n    """pydoc"""\n')
-        self._do_sort(0, sort.PydocSorter())
+        self._do_sort(0, ropeide.sort.PydocSorter())
         self.assertEquals('\nclass b():\n    """pydoc"""\n\ndef a():\n    pass\n',
                           self.mod.read())
 

ropetest/ide/spellcheckertest.py

 import unittest
 
-from rope.ide.spellchecker import SpellChecker
+from ropeide.spellchecker import SpellChecker
 from ropetest import testutils
 from StringIO import StringIO
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.