Anonymous avatar Anonymous committed b4ef691

Ignoring string and comment content while correcting indentation

Comments (0)

Files changed (6)

 * Auto-completing function parameter names when calling @ 2
 
 
+* Optimizing StatementRangeFinder @ 1
+  Add CachedLines and not starting from the start of the lines
+
+
+* Hold the list of project classes and import them automatically
+  in codeassist
+
+
 * Control blocks and auto-completion @ 1
   Completions for for-loop, except, lambda and with variables
 

docs/workingon.txt

-*** Ignoring string contents while indenting @ 1 ***
+*** Ignoring string and comment contents while indenting @ 1 ***
 
 - Add codeanalyze module
 - Adding LineEditor to the Editor class
+- Ignoring string contents
+- Ignoring comment contents
 
-! StatementRangeFinder reports all elements with indentation from current
-  statment
-* Add CachedLines
-* Ignoring comment contents
-* Ignoring string contents
-? Add StatementRangeFinderTest to runtests
-* Hold the list of project classes and import them automatically
-  in codeassist
 
 
 --- Before 0.2 Release ---
-* Next/prev word should consider underline and capitals as spaces; make it configurable
+* Next/prev word should stop at underlines and capitals; make it configurable
 * GUI testing redux; make a ropefunctest direction; ? rename ropetest to ropeunittest
 * Better editor changing dialog; use uihelpers module
 * More builtin templates
 * Highlighting enhancement
+* Profiling to find the bottlenecks
 
 
 

rope/codeanalyze.py

 
 
     def analyze(self):
-        last_statement = 0
+        last_statement = 1
         for current_line_number in range(1, self.lineno + 1):
             if not self.explicit_continuation and self.open_parens == 0 and self.in_string == '':
                 last_statement = current_line_number
     def _get_correct_indentation(self, lineno):
         if lineno == 1:
             return 0
-        new_indent = self._get_base_indentation_old(lineno)
+        new_indent = self._get_base_indentation(lineno)
 
         prev_lineno = self._get_last_non_empty_line(lineno)
         prev_line = self.line_editor.get_line(prev_lineno)
         if prev_lineno == lineno or prev_line.strip() == '':
             new_indent = 0
-        else:
-            new_indent += self._get_indentation_changes_caused_by_prev_line(prev_line)
         current_line = self.line_editor.get_line(lineno)
-        new_indent += self._get_indentation_changes_caused_by_current_line(current_line)
+        new_indent += self._get_indentation_changes_caused_by_current_stmt(current_line)
         return new_indent
 
-    def _get_base_indentation_old(self, lineno):
-        current_line = self.line_editor.get_line(lineno)
-        current_lineno = self._get_last_non_empty_line(lineno)
-
-        openings = 0
-        while True:
-            current_line = self.line_editor.get_line(current_lineno)
-            current = len(current_line) - 1
-            while current >= 0:
-                if current_line[current] in '([{':
-                    openings += 1
-                if current_line[current] in ')]}':
-                    openings -= 1
-                if openings > 0:
-                    return current + 1
-                current -= 1
-            if openings == 0:
-                break
-            if current_lineno == 1:
-                break
-            current_lineno -= 1
-
-        if current_line.rstrip().endswith('\\'):
-            real_lineno = self._get_starting_backslash_line(current_lineno)
-            if (real_lineno == current_lineno):
-                try:
-                    return current_line.index(' = ') + 3
-                except ValueError:
-                    match = re.search('\\b ', current_line)
-                    if match:
-                        return match.start() + 1
-                    else:
-                        return len(current_line) + 1
-        else:
-            second_prev_lineno = current_lineno - 1
-            if second_prev_lineno >= 1 and \
-               self.line_editor.get_line(second_prev_lineno).rstrip().endswith('\\'):
-                real_lineno = self._get_starting_backslash_line(second_prev_lineno)
-                return self._count_line_indents(real_lineno)
-        return self._count_line_indents(current_lineno)
-
-    def _get_base_indentation_old(self, lineno):
-        range_finder = StatementRangeFinder(self.line_editor, lineno - 1)
+    def _get_base_indentation(self, lineno):
+        range_finder = StatementRangeFinder(self.line_editor, self._get_last_non_empty_line(lineno))
         range_finder.analyze()
         start = range_finder.get_statement_start()
         if not range_finder.is_line_continued():
-            return self._count_line_indents(self._get_last_non_empty_line(start + 1))
+            changes = self._get_indentation_changes_caused_by_prev_stmt((start,
+                                                                         self._get_last_non_empty_line(lineno)))
+            return self._count_line_indents(start) + changes
 
         if range_finder.last_open_parens():
             return range_finder.last_open_parens()[1] + 1
                 else:
                     return len(start_line) + 1
         else:
-            return self._count_line_indents(self._get_last_non_empty_line(lineno)) 
+            return self._count_line_indents(self._get_last_non_empty_line(lineno))
 
 
-    def _is_line_continued(self, line_contents):
-        if line_contents.endswith('\\'):
-            return True
-        current = len(line_contents) - 1
-        openings = 0
-        while current >= 0:
-            if line_contents[current] in list('([{'):
-                openings += 1
-            if line_contents[current] in list(')]}'):
-                openings -= 1
-            if openings > 0:
-                return True
-            current -= 1
-        return False
-
-
-    def _get_indentation_changes_caused_by_prev_line(self, prev_line):
+    def _get_indentation_changes_caused_by_prev_stmt(self, stmt_range):
+        first_line = self.line_editor.get_line(stmt_range[0])
+        last_line = self.line_editor.get_line(stmt_range[1])
         new_indent = 0
-        if prev_line.rstrip().endswith(':'):
+        if last_line.rstrip().endswith(':'):
             new_indent += 4
-        if prev_line.strip() == 'pass':
+        if last_line.strip() == 'pass':
             new_indent -= 4
-        if (prev_line.lstrip().startswith('return ') or
-            prev_line.lstrip().startswith('raise ')) and not self._is_line_continued(prev_line):
+        if first_line.lstrip().startswith('return ') or \
+           first_line.lstrip().startswith('raise '):
             new_indent -= 4
-        if prev_line.strip() == 'break':
+        if first_line.strip() == 'break':
             new_indent -= 4
-        if prev_line.strip() == 'continue':
+        if first_line.strip() == 'continue':
             new_indent -= 4
         return new_indent
 
-    def _get_indentation_changes_caused_by_current_line(self, current_line):
+    def _get_indentation_changes_caused_by_current_stmt(self, current_line):
         new_indent = 0
         if current_line.strip() == 'else:':
             new_indent -= 4

ropetest/indentertest.py

         self.indenter.correct_indentation(2)
         self.assertEquals('print "("\na = 10', self.editor.get_text())
 
-    # TODO: handle this case
-    def xxx_test_deindenting_after_implicit_continuation_after_return(self):
+    def test_ignoring_parens_in_comments(self):
+        self.editor.set_text('# hello ( \na = 10')
+        self.indenter.correct_indentation(2)
+        self.assertEquals('# hello ( \na = 10', self.editor.get_text())
+
+    def test_deindenting_after_implicit_continuation_after_return(self):
         self.editor.set_text('def f():\n    return (2,\n            3)\na = 10')
         self.indenter.correct_indentation(4)
         self.assertEquals('def f():\n    return (2,\n            3)\na = 10',
                           self.editor.get_text())
 
 
+    # TODO: handle this case
+    def xxx_test_ignoring_back_slash_in_comments(self):
+        self.editor.set_text('# hello \\\na = 10')
+        self.indenter.correct_indentation(2)
+        self.assertEquals('# hello \\\na = 10', self.editor.get_text())
+
+
 if __name__ == '__main__':
     unittest.main()
 
 import ropetest.indentertest
 import ropetest.codeassisttest
 import ropetest.statusbartest
+import ropetest.codeanalyzetest
 
 
 if __name__ == '__main__':
     result.addTests(unittest.makeSuite(ropetest.indentertest.PythonCodeIndenterTest))
     result.addTests(ropetest.codeassisttest.suite())
     result.addTests(unittest.makeSuite(ropetest.statusbartest.StatusBarTest))
+    result.addTests(unittest.makeSuite(ropetest.codeanalyzetest.StatementRangeFinderTest))
     runner = unittest.TextTestRunner()
     runner.run(result)
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.