Merge pull request #2166 from xonsh/rtnjdei

Return of the Jedi
This commit is contained in:
Gil Forsyth 2017-02-21 15:50:42 -05:00 committed by GitHub
commit fba07c5cd0
7 changed files with 85 additions and 7 deletions

View file

@ -41,6 +41,7 @@ the xonsh shell
"WHAT...is your favorite shell?",
"Conches for the xonsh god!",
"Python-powered, cross-platform, Unix-gazing shell",
"Tab completion in Alderaan places",
"Exploiting the workers and hanging on to outdated imperialist dogma since 2015."
];
document.write(taglines[Math.floor(Math.random() * taglines.length)]);

14
news/jedi.rst Normal file
View file

@ -0,0 +1,14 @@
**Added:**
* New ``jedi`` xontrib enables jedi-based tab completions when it is loaded.
This supercedes xonsh's default Python-mode completer.
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -270,6 +270,7 @@ class BaseShell(object):
self.mlprompt = None
self._styler = DefaultNotGiven
self.prompt_formatter = PromptFormatter()
self.accumulated_inputs = ''
@property
def styler(self):
@ -336,6 +337,7 @@ class BaseShell(object):
finally:
ts1 = ts1 or time.time()
self._append_history(inp=src, ts=[ts0, ts1], tee_out=tee.getvalue())
self.accumulated_inputs += src
tee.close()
self._fix_cwd()
if builtins.__xonsh_exit__: # pylint: disable=no-member

View file

@ -1,3 +1,4 @@
import inspect
import builtins
import collections
@ -75,19 +76,29 @@ def _register_completer(args, stdin=None):
"For help, run: completer help add")
else:
name = args[0]
func = args[1]
func_name = args[1]
if name in builtins.__xonsh_completers__:
err = ("The name %s is already a registered "
"completer function.") % name
else:
if func in builtins.__xonsh_ctx__:
if not callable(builtins.__xonsh_ctx__[func]):
err = "%s is not callable" % func
if func_name in builtins.__xonsh_ctx__:
func = builtins.__xonsh_ctx__[func_name]
if not callable(func):
err = "%s is not callable" % func_name
else:
err = "No such function: %s" % func
print(inspect.stack(context=0))
for frame_info in inspect.stack(context=0):
frame = frame_info[0]
if func_name in frame.f_locals:
func = frame.f_locals[func_name]
break
elif func_name in frame.f_globals:
func = frame.f_globals[func_name]
break
else:
err = "No such function: %s" % func_name
if err is None:
position = "start" if len(args) == 2 else args[2]
func = builtins.__xonsh_ctx__[func]
_add_one_completer(name, func, position)
else:
return None, err + '\n', 1

View file

@ -95,7 +95,7 @@ def complete_python_mode(prefix, line, start, end, ctx):
if not (prefix.startswith('@(') or prefix.startswith('${')):
return set()
prefix_start = prefix[:2]
python_matches = complete_python(prefix[2:], line, start+2, end, ctx)
python_matches = complete_python(prefix[2:], line, start-2, end-2, ctx)
if isinstance(python_matches, cabc.Sequence):
python_matches = python_matches[0]
return set(prefix_start + i for i in python_matches)

View file

@ -64,6 +64,11 @@
"url": "https://github.com/xsteadfastx/xonsh-docker-tabcomplete",
"description": ["Adds tabcomplete functionality to docker inside of xonsh."]
},
{"name": "jedi",
"package": "xonsh",
"url": "http://xon.sh",
"description": ["Jedi tab completion hooks for xonsh."]
},
{"name": "mpl",
"package": "xonsh",
"url": "http://xon.sh",

45
xontrib/jedi.xsh Normal file
View file

@ -0,0 +1,45 @@
"""Jedi-based completer for Python-mode."""
import builtins
import importlib
from xonsh.lazyasd import lazyobject, lazybool
__all__ = ()
@lazybool
def HAS_JEDI():
"""``True`` if `jedi` is available, else ``False``."""
spec = importlib.util.find_spec('jedi')
return (spec is not None)
@lazyobject
def jedi():
if HAS_JEDI:
import jedi as m
else:
m = None
return m
def complete_jedi(prefix, line, start, end, ctx):
"""Jedi-based completer for Python-mode."""
if not HAS_JEDI:
return set()
src = builtins.__xonsh_shell__.shell.accumulated_inputs + line
script = jedi.api.Interpreter(src, [ctx], column=end)
if builtins.__xonsh_env__.get('CASE_SENSITIVE_COMPLETIONS'):
rtn = {x.name_with_symbols for x in script.completions()
if x.name_with_symbols.startswith(prefix)}
else:
rtn = {x.name_with_symbols for x in script.completions()}
return rtn
# register the completer
builtins.__xonsh_ctx__['complete_jedi'] = complete_jedi
completer add jedi complete_jedi end
completer remove python_mode
del builtins.__xonsh_ctx__['complete_jedi']