automatic indentation for readline shell

This commit is contained in:
Anthony Scopatz 2015-08-02 20:52:07 -05:00
parent 06b892e70a
commit 8772d5832a

View file

@ -80,6 +80,14 @@ def rl_completion_suppress_append(val=1):
RL_COMPLETION_SUPPRESS_APPEND.value = val
def _insert_text_func(s, readline):
"""Creates a function to insert text via readline."""
def inserter():
readline.insert_text(s)
readline.redisplay()
return inserter
class ReadlineShell(BaseShell, Cmd):
"""The readline based xonsh shell."""
@ -89,6 +97,7 @@ class ReadlineShell(BaseShell, Cmd):
stdout=stdout,
**kwargs)
setup_readline()
self._current_indent = ''
def __del__(self):
teardown_readline()
@ -107,6 +116,32 @@ class ReadlineShell(BaseShell, Cmd):
# tab complete on first index too
completenames = completedefault
def postcmd(self, stop, line):
"""Called just before execution of line. For readline, this handles the
automatic indentation of code blocks.
"""
try:
import readline
except ImportError:
return stop
if self.need_more_lines:
if len(line.strip()) == 0:
readline.set_pre_input_hook(None)
self._current_indent = ''
elif line.rstrip()[-1] == ':':
ind = line[:len(line) - len(line.lstrip())]
ind += builtins.__xonsh_env__.get('INDENT', '')
readline.set_pre_input_hook(_insert_text_func(ind, readline))
self._current_indent = ind
else:
ind = line[:len(line) - len(line.lstrip())]
if ind != self._current_indent:
readline.set_pre_input_hook(_insert_text_func(ind, readline))
self._current_indent = ind
else:
readline.set_pre_input_hook(None)
return stop
def cmdloop(self, intro=None):
while not builtins.__xonsh_exit__:
try: