Repository: spyder-ide/spyder

Issue:
Code completion: insert automatically parentheses for functions/methods
_From [jorisvan...@gmail.com](https://code.google.com/u/101707288318167035253/) on 2011-06-03T08:49:09Z_

What steps will reproduce the problem?
1. For example if you type in the editor 'plt.', a list of possibilities will show.
2. When I choose one, for expample 'show', in the editor 'plt.show' shows up.

What is the expected output? What do you see instead? Would it be possible that not 'plt.show' appears, but at once 'plt.show()' (and with the cursor between the brackets), so you don't have to type the brackets yourself?
Because after show, brackets are always needed. What version of the product are you using? On what operating system? Spyder 2.0.11, Ubuntu 11.04

_Original issue: http://code.google.com/p/spyderlib/issues/detail?id=680_



Discussion:
_From [pierre.raybaut](https://code.google.com/u/pierre.raybaut/) on 2011-06-03T07:16:18Z_

I think it can be done quite easily. I'll take a look at it.

**Summary:** Code completion: insert automatically parentheses for functions/methods  
  **Status:** Accepted  
  **Labels:** -Type-Defect Type-Enhancement Milestone-Release2.1 Cat-Editor  

_From [pierre.raybaut](https://code.google.com/u/pierre.raybaut/) on 2011-10-16T05:47:56Z_

**Labels:** -Milestone-Release2.1 Milestone-Release2.2  

_From [pierre.raybaut](https://code.google.com/u/pierre.raybaut/) on 2012-03-18T13:48:27Z_

**Labels:** -Milestone-Release2.2 Milestone-v2.2  

_From [pierre.raybaut](https://code.google.com/u/pierre.raybaut/) on 2012-03-18T13:55:49Z_

**Labels:** -Milestone-v2.2 MS-v2.2  

_From [pierre.raybaut](https://code.google.com/u/pierre.raybaut/) on 2012-03-18T14:14:39Z_

**Labels:** -Type-Enhancement Type-Enh  

_From [jed.lud...@gmail.com](https://code.google.com/u/114333776555678317161/) on 2013-04-29T14:39:30Z_

**Labels:** -MS-v2.2 MS-v2.3  

_From [pierre.raybaut](https://code.google.com/u/pierre.raybaut/) on 2013-05-11T06:00:20Z_

**Labels:** -MS-v2.3 MS-v2.4  

Is this closer to your area of expertize in spyder @blink1073 ?

This would be cool to have!

Agreed.


Resolving patch:
diff --git a/spyderlib/widgets/sourcecode/base.py b/spyderlib/widgets/sourcecode/base.py
--- a/spyderlib/widgets/sourcecode/base.py
+++ b/spyderlib/widgets/sourcecode/base.py
@@ -67,6 +67,9 @@ def show_list(self, completion_list, automatic=True):
         completion_list = [c[0] for c in completion_list]
         if len(completion_list) == 1 and not automatic:
             self.textedit.insert_completion(completion_list[0])
+            if self.textedit.close_parentheses_enabled:
+                if types[0] in ['class', 'function', 'method']:
+                    self.textedit.handle_close_parentheses('')
             return
 
         self.completion_list = completion_list
@@ -79,6 +82,7 @@ def show_list(self, completion_list, automatic=True):
                      'class': 'class',
                      'module': 'module'}
 
+        self.type_list = types
         if any(types):
             for (c, t) in zip(completion_list, types):
                 icon = icons_map.get(t, 'no_match')
@@ -155,6 +159,11 @@ def keyPressEvent(self, event):
         if (key in (Qt.Key_Return, Qt.Key_Enter) and self.enter_select) \
            or key == Qt.Key_Tab:
             self.item_selected()
+            if self.type_list[self.currentRow()] not in ['class', 'function',
+                                                         'method']:
+                return
+            if self.textedit.close_parentheses_enabled:
+                self.textedit.handle_close_parentheses('')
         elif key in (Qt.Key_Return, Qt.Key_Enter,
                      Qt.Key_Left, Qt.Key_Right) or text in ('.', ':'):
             self.hide()
diff --git a/spyderlib/widgets/sourcecode/codeeditor.py b/spyderlib/widgets/sourcecode/codeeditor.py
--- a/spyderlib/widgets/sourcecode/codeeditor.py
+++ b/spyderlib/widgets/sourcecode/codeeditor.py
@@ -2572,20 +2572,8 @@ def keyPressEvent(self, event):
             self.stdkey_end(shift, ctrl)
         elif text == '(' and not self.has_selected_text():
             self.hide_completion_widget()
-            position = self.get_position('cursor')
-            s_trailing_text = self.get_text('cursor', 'eol').strip()
-            if self.close_parentheses_enabled and \
-              (len(s_trailing_text) == 0 or \
-              s_trailing_text[0] in (',', ')', ']', '}')):
-                self.insert_text('()')
-                cursor = self.textCursor()
-                cursor.movePosition(QTextCursor.PreviousCharacter)
-                self.setTextCursor(cursor)
-            else:
-                self.insert_text(text)
-            if self.is_python_like() and self.get_text('sol', 'cursor') and \
-              self.calltips:
-                self.sig_show_object_info.emit(position)
+            if self.close_parentheses_enabled:
+                self.handle_close_parentheses(text)
         elif text in ('[', '{') and not self.has_selected_text() \
           and self.close_parentheses_enabled:
             s_trailing_text = self.get_text('cursor', 'eol').strip()
@@ -2654,6 +2642,22 @@ def keyPressEvent(self, event):
             if self.is_completion_widget_visible() and text:
                 self.completion_text += text
 
+    def handle_close_parentheses(self, text):
+        if not self.close_parentheses_enabled:
+            return
+        position = self.get_position('cursor')
+        rest = self.get_text('cursor', 'eol').rstrip()
+        if not rest or rest[0] in (',', ')', ']', '}'):
+            self.insert_text('()')
+            cursor = self.textCursor()
+            cursor.movePosition(QTextCursor.PreviousCharacter)
+            self.setTextCursor(cursor)
+        else:
+            self.insert_text(text)
+        if self.is_python_like() and self.get_text('sol', 'cursor') and \
+                self.calltips:
+            self.sig_show_object_info.emit(position)
+
     def mouseMoveEvent(self, event):
         """Underline words when pressing <CONTROL>"""
         if self.has_selected_text():


Test patch: