Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable python repl autocomplete and still allow new line tabs

I currently have the following in ~/.pythonrc to enable auto completion in the python repl:

# Autocompletion
import rlcompleter, readline
readline.parse_and_bind('tab:complete')

However, when I tab from the start of a new line (for instance, on the inner part of a for loop), I get a list of suggestions instead of a tab.

Ideally, I would want to get suggestions only following a non-whitespace character.

Is this straightforward to implement in a ~/.pythonrc?

like image 844
ZenBalance Avatar asked Aug 21 '14 20:08

ZenBalance


People also ask

How do I turn on autocomplete in Python?

Shift+Enter: run cell, select below. Shift+Tab: signature autocompletion.

How do I enable autocomplete in Python idle?

Python IDLE has basic code completion functionality. It can only autocomplete the names of functions and classes. To use autocompletion in the editor, just press the tab key after a sequence of text. The call tip will display as a popup note, reminding you how to append to a list.

Does Python have tab completion feature?

Tab Completion and History Editing. Completion of variable and module names is automatically enabled at interpreter startup so that the Tab key invokes the completion function; it looks at Python statement names, the current local variables, and the available module names.

How do I get idle suggestions in Python?

As it says in the settings of IDLE, you can trigger the autocomplete with "Control + Space", e.g. after a "QtGui.". Then a menu opens where you can arrow-scroll through the entries.


1 Answers

You should just use IPython. It has both tab completion and auto-indenting of for loops or function definitions. For example:

# Ipython prompt
In [1]: def stuff(x):
   ...:     |
#           ^ cursor automatically moves to this position

To install it, you can use pip:

pip install ipython

If you don't have pip installed, you can follow the instructions on this page. On python >= 3.4, pip is installed by default.

If you're on windows, this page contains installers for ipython (and many other python libraries that may be difficult to install).


However, if for any reason you can't install ipython, Brandon Invergo had created a python start-up script that adds several features to the python interpreter, among which is auto indentation. He has released it under GPL v3 and published the source here.

I've copied the code that handles the auto-indentation below. I had to add indent = '' at line 11 to make it work on my python 3.4 interpreter.

import readline

def rl_autoindent():
    """Auto-indent upon typing a new line according to the contents of the
    previous line.  This function will be used as Readline's
    pre-input-hook.

    """
    hist_len = readline.get_current_history_length()
    last_input = readline.get_history_item(hist_len)
    indent = ''
    try:
        last_indent_index = last_input.rindex("    ")
    except:
        last_indent = 0
    else:
        last_indent = int(last_indent_index / 4) + 1
    if len(last_input.strip()) > 1:
        if last_input.count("(") > last_input.count(")"):
            indent = ''.join(["    " for n in range(last_indent + 2)])
        elif last_input.count(")") > last_input.count("("):
            indent = ''.join(["    " for n in range(last_indent - 1)])
        elif last_input.count("[") > last_input.count("]"):
            indent = ''.join(["    " for n in range(last_indent + 2)])
        elif last_input.count("]") > last_input.count("["):
            indent = ''.join(["    " for n in range(last_indent - 1)])
        elif last_input.count("{") > last_input.count("}"):
            indent = ''.join(["    " for n in range(last_indent + 2)])
        elif last_input.count("}") > last_input.count("{"):
            indent = ''.join(["    " for n in range(last_indent - 1)])
        elif last_input[-1] == ":":
            indent = ''.join(["    " for n in range(last_indent + 1)])
        else:
            indent = ''.join(["    " for n in range(last_indent)])
    readline.insert_text(indent)

readline.set_pre_input_hook(rl_autoindent)
like image 124
parchment Avatar answered Nov 03 '22 05:11

parchment