Anonymous avatar Anonymous committed f8e5139

Better scope endpoint selection

Comments (0)

Files changed (5)

+- Auto-completion should ignore current statement : May 23, 2006
+
+
 - Proposing function parameters in functions : May 22, 2006
 
 
 * Auto-complete from-import imported objects @ 3
 
 
-* Auto-completion should ignore current statement @ 2
-  What if the statement in current line is spread in more than one line.
-
-
 --- Remaining Stories ---
 ? Change program goals and description; principles.html
   ? Go toward refactoring and ... library rather than an IDE

docs/workingon.txt

-*** Auto-completion should ignore current statement @ 2 ***
+--- Auto-completion should ignore current statement @ 2 ---
   What if the statement in current line is spread in more than one line.
 
 - More tests for explicit and implicit continuations
 ? Transform big unextractible methods into method objects
 - Not proposing variables defined after current line in the same scope
 - Ignoring """ or ''' string content
+- scopes_count does not work because there might be loops and other blocks
 
 
-! scopes_count does not work because there might be loops and other blocks
 ? Add rope.scopes module
 ? Completions for for-loop, except, lambda, with variables
 ? Remote pair programming support

rope/codeassist.py

             current_offset -= 1;
         return current_offset + 1
 
-    def _comment_current_statement(self, source_code, offset):
-        lines = source_code.split('\n')
-        current_pos = 0
-        lineno = 0
-        while current_pos + len(lines[lineno]) < offset:
-            current_pos += len(lines[lineno]) + 1
-            lineno += 1
+    def _comment_current_statement(self, lines, lineno):
         range_finder = _CurrentStatementRangeFinder(lines, lineno)
         start, end = range_finder.get_range()
         last_indents = range_finder.get_line_indents(start)
         for line in range(start + 1, end + 1):
             lines[line] = '#' # + lines[line]
         lines.append('\n')
-        return '\n'.join(lines)
-
 
     def _get_matching_builtins(self, starting):
         result = {}
                 result[kw] = CompletionProposal(kw, 'keyword')
         return result
 
-    def _get_all_completions(self, global_scope, lineno, indents):
+    def _get_line_indents(self, lines, line_number):
+        indents = 0
+        for char in lines[line_number]:
+            if char == ' ':
+                indents += 1
+            else:
+                break
+        return indents
+
+
+    def _get_all_completions(self, global_scope, lines, lineno):
         result = {}
         current_scope = global_scope
-        nested_scope_count = 0
-        while current_scope is not None and nested_scope_count <= indents:
+        current_indents = self._get_line_indents(lines, lineno)
+        while current_scope is not None and \
+              self._get_line_indents(lines, current_scope.lineno) <= current_indents:
             result.update(current_scope.var_dict)
             new_scope = None
             for scope in current_scope.children:
                 else:
                     break
             current_scope = new_scope
-            nested_scope_count += 1
         return result
-    
+
     def _get_line_number(self, source_code, offset):
         return source_code[:offset].count('\n') + 1
 
             return []
         starting_offset = self._find_starting_offset(source_code, offset)
         starting = source_code[starting_offset:offset]
-        commented_source_code = self._comment_current_statement(source_code, offset)
+        lines = source_code.split('\n')
+        current_pos = 0
+        lineno = 0
+        while current_pos + len(lines[lineno]) < offset:
+            current_pos += len(lines[lineno]) + 1
+            lineno += 1
+        self._comment_current_statement(lines, lineno)
+        commented_source_code = '\n'.join(lines)
         try:
             code_ast = compiler.parse(commented_source_code)
         except SyntaxError, e:
             raise RopeSyntaxError(e)
         visitor = _GlobalScopeVisitor(starting)
         compiler.walk(code_ast, visitor)
-        result = self._get_all_completions(visitor.scope,
-                                           self._get_line_number(source_code, offset),
-                                           self._count_line_indents(source_code, offset))
+        result = self._get_all_completions(visitor.scope, lines, lineno)
         if len(starting) > 0:
             result.update(self._get_matching_builtins(starting))
             result.update(self._get_matching_keywords(starting))

ropetest/codeassisttest.py

         result = self.assist.complete_code(code, len(code))
         self.assert_proposal_not_in_result('func_var', 'local_variable', result)
 
+    def test_scope_better_endpoint_selection(self):
+        code = "if True:\n    def f():\n        my_var = 10\n    my_"
+        result = self.assist.complete_code(code, len(code))
+        self.assert_proposal_not_in_result('my_var', 'local_variable', result)
+
     def test_imports_inside_function(self):
         code = "def f():\n    import sys\n    sy"
         result = self.assist.complete_code(code, len(code))
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.