some updates to new model

This commit is contained in:
Anthony Scopatz 2018-06-17 13:39:12 -04:00
parent 478cdb1080
commit e144aa9f02
5 changed files with 50 additions and 178 deletions

View file

@ -304,8 +304,8 @@ def main():
url='https://github.com/xonsh/xonsh',
platforms='Cross Platform',
classifiers=['Programming Language :: Python :: 3'],
packages=['xonsh', 'xonsh.ply.ply', 'xonsh.ptk', 'xonsh.parsers',
'xonsh.xoreutils', 'xontrib',
packages=['xonsh', 'xonsh.ply.ply', 'xonsh.ptk', 'xonsh.ptk2',
'xonsh.parsers', 'xonsh.xoreutils', 'xontrib',
'xonsh.completers', 'xonsh.history', 'xonsh.prompt'],
package_dir={'xonsh': 'xonsh', 'xontrib': 'xontrib'},
package_data={'xonsh': ['*.json', '*.githash'], 'xontrib': ['*.xsh']},
@ -330,7 +330,7 @@ def main():
}
skw['cmdclass']['develop'] = xdevelop
skw['extras_require'] = {
'ptk': ['prompt-toolkit<2.0.0'],
'ptk': ['prompt-toolkit'],
'pygments': ['pygments'],
'win': ['win_unicode_console'],
'mac': ['gnureadline'],

View file

@ -146,6 +146,15 @@ def ptk_version_is_supported():
return ptk_version_info()[:2] >= minimum_required_ptk_version
@functools.lru_cache(1)
def ptk_shell_type():
"""Returns the prompt_toolkit shell type based on the installed version."""
if ptk_version_info()[:2] < (2, 0):
return 'prompt_toolkit1'
else:
return 'prompt_toolkit2'
@functools.lru_cache(1)
def best_shell_type():
if ON_WINDOWS or has_prompt_toolkit():

View file

@ -12,10 +12,10 @@ except ImportError:
from xonsh.platform import ptk_version_info
from xonsh.base_shell import BaseShell
from xonsh.tools import print_exception, carriage_return
from xonsh.ptk.completer import PromptToolkitCompleter, PromptToolkit2Completer
from xonsh.ptk.history import PromptToolkitHistory
from xonsh.ptk.key_bindings import load_xonsh_bindings
from xonsh.ptk.shortcuts import get_prompter
from xonsh.ptk2.completer import PromptToolkitCompleter, PromptToolkit2Completer
from xonsh.ptk2.history import PromptToolkitHistory
from xonsh.ptk2.key_bindings import load_xonsh_bindings
from xonsh.ptk2.shortcuts import get_prompter
from xonsh.events import events
from xonsh.shell import transform_command
from xonsh.platform import HAS_PYGMENTS, ON_WINDOWS
@ -23,18 +23,12 @@ from xonsh.style_tools import partial_color_tokenize, _TokenType, DEFAULT_STYLE_
from xonsh.lazyimps import pygments, pyghooks, winutils
if ptk_version_info()[:2] < (2, 0):
from prompt_toolkit.key_binding.manager import KeyBindingManager
from prompt_toolkit.shortcuts import print_tokens as ptk_print
from prompt_toolkit.styles import style_from_dict
from prompt_toolkit.styles import PygmentsStyle as style_from_pygments
else: # ptk 2.0
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.shortcuts import print_formatted_text as ptk_print
from prompt_toolkit.shortcuts import CompleteStyle
from prompt_toolkit.formatted_text import PygmentsTokens
from prompt_toolkit.styles.pygments import Style, pygments_token_to_classname
from prompt_toolkit.styles.pygments import style_from_pygments_cls as style_from_pygments
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.shortcuts import print_formatted_text as ptk_print
from prompt_toolkit.shortcuts import CompleteStyle
from prompt_toolkit.formatted_text import PygmentsTokens
from prompt_toolkit.styles.pygments import Style, pygments_token_to_classname
from prompt_toolkit.styles.pygments import style_from_pygments_cls as style_from_pygments
Token = _TokenType()
@ -47,8 +41,8 @@ Fired after prompt toolkit has been initialized
""")
class PromptToolkitShell(BaseShell):
"""The xonsh shell."""
class PromptToolkit2Shell(BaseShell):
"""The xonsh shell for prompt_toolkit v2."""
def __init__(self, **kwargs):
super().__init__(**kwargs)
@ -58,14 +52,9 @@ class PromptToolkitShell(BaseShell):
self.prompter = get_prompter()
self.history = PromptToolkitHistory()
self.pt_completer = PromptToolkitCompleter(self.completer, self.ctx, self)
key_bindings_manager_args = {
'enable_auto_suggest_bindings': True,
'enable_search': True,
'enable_abort_and_exit_bindings': True,
}
self.key_bindings_manager = KeyBindingManager(**key_bindings_manager_args)
load_xonsh_bindings(self.key_bindings_manager)
# This assumes that PromptToolkitShell is a singleton
self.key_bindings = KeyBindings()
load_xonsh_bindings(self.key_bindings)
# This assumes that PromptToolkit2Shell is a singleton
events.on_ptk_create.fire(
prompter=self.prompter,
history=self.history,
@ -331,26 +320,6 @@ class PromptToolkitShell(BaseShell):
class PromptToolkitShell2(PromptToolkitShell):
"""The xonsh shell for ptk 2.0.
"""
def __init__(self, **kwargs):
super(PromptToolkitShell, self).__init__(**kwargs)
if ON_WINDOWS:
winutils.enable_virtual_terminal_processing()
self._first_prompt = True
self.prompter = get_prompter()
self.history = PromptToolkitHistory()
self.pt_completer = PromptToolkit2Completer(
self.completer, self.ctx, self)
self.key_bindings = KeyBindings()
load_xonsh_bindings(self.key_bindings)
# This assumes that PromptToolkitShell is a singleton
events.on_ptk_create.fire(
prompter=self.prompter,
history=self.history,
completer=self.pt_completer,
bindings=self.key_bindings,
)
def singleline(self, store_in_history=True, auto_suggest=None,
enable_history_search=True, multiline=True, **kwargs):

View file

@ -1,4 +1,4 @@
"""A prompt-toolkit inspired shortcut collection."""
"""A prompt-toolkit v2 inspired shortcut collection."""
import builtins
import textwrap
@ -8,126 +8,10 @@ from prompt_toolkit.utils import DummyContext
from xonsh.platform import ptk_version_info
import xonsh.tools as xt
if ptk_version_info()[:2] < (2, 0):
from prompt_toolkit.interface import CommandLineInterface
from prompt_toolkit.shortcuts import (
create_prompt_application, create_eventloop, create_asyncio_eventloop,
create_output)
else:
from prompt_toolkit.shortcuts import Prompt
from prompt_toolkit.shortcuts import Prompt
class Prompter(object):
def __init__(self, cli=None, *args, **kwargs):
"""Implements a prompt that statefully holds a command-line
interface. When used as a context manager, it will return itself
on entry and reset itself on exit.
Parameters
----------
cli : CommandLineInterface or None, optional
If this is not a CommandLineInterface object, such an object
will be created when the prompt() method is called.
"""
self.cli = cli
self.major_minor = ptk_version_info()[:2]
def __enter__(self):
self.reset()
return self
def __exit__(self, exc_type, exc_value, traceback):
pass
def prompt(self, message='', **kwargs):
"""Get input from the user and return it.
This is a wrapper around a lot of prompt_toolkit functionality and
can be a replacement for raw_input. (or GNU readline.) If you want
to keep your history across several calls, create one
`~prompt_toolkit.history.History instance and pass it every
time. This function accepts many keyword arguments. Except for the
following. they are a proxy to the arguments of
create_prompt_application().
Parameters
----------
patch_stdout : file-like, optional
Replace ``sys.stdout`` by a proxy that ensures that print
statements from other threads won't destroy the prompt. (They
will be printed above the prompt instead.)
return_asyncio_coroutine : bool, optional
When True, return a asyncio coroutine. (Python >3.3)
Notes
-----
This method was forked from the mainline prompt-toolkit repo.
Copyright (c) 2014, Jonathan Slenders, All rights reserved.
"""
patch_stdout = kwargs.pop('patch_stdout', False)
return_asyncio_coroutine = kwargs.pop('return_asyncio_coroutine', False)
if return_asyncio_coroutine:
eventloop = create_asyncio_eventloop()
else:
eventloop = kwargs.pop('eventloop', None) or create_eventloop()
# Create CommandLineInterface.
if self.cli is None:
if builtins.__xonsh_env__.get('VI_MODE'):
editing_mode = EditingMode.VI
else:
editing_mode = EditingMode.EMACS
kwargs['editing_mode'] = editing_mode
cli = CommandLineInterface(
application=create_prompt_application(message, **kwargs),
eventloop=eventloop,
output=create_output())
self.cli = cli
else:
cli = self.cli
# Replace stdout.
patch_context = cli.patch_stdout_context() if patch_stdout else DummyContext()
# Read input and return it.
if return_asyncio_coroutine:
# Create an asyncio coroutine and call it.
exec_context = {'patch_context': patch_context, 'cli': cli}
exec(textwrap.dedent('''
import asyncio
@asyncio.coroutine
def prompt_coro():
with patch_context:
document = yield from cli.run_async(reset_current_buffer=False)
if document:
return document.text
'''), exec_context)
return exec_context['prompt_coro']()
else:
# Note: We pass `reset_current_buffer=False`, because that way
# it's easy to give DEFAULT_BUFFER a default value, without it
# getting erased. We don't have to reset anyway, because this is
# the first and only time that this CommandLineInterface will run.
try:
with patch_context:
document = cli.run(reset_current_buffer=False)
if document:
return document.text
except Exception:
xt.print_exception()
# return something to prevent xonsh crash when any
# exceptions raise
return ''
finally:
eventloop.close()
def reset(self):
"""Resets the prompt and cli to a pristine state on this object."""
self.cli = None
class Prompter2(object):
"""Prompter for ptk 2.0
"""
def __init__(self, cli=None, *args, **kwargs):
@ -175,10 +59,3 @@ class Prompter2(object):
"""Resets the prompt and cli to a pristine state on this object."""
# XXX Is this necessary any more?
# self.prompt = None
def get_prompter():
if ptk_version_info()[:2] < (2, 0):
return Prompter()
else:
return Prompter2()

View file

@ -8,7 +8,7 @@ import builtins
import warnings
from xonsh.platform import (best_shell_type, has_prompt_toolkit,
ptk_version_is_supported)
ptk_version_is_supported, ptk_shell_type)
from xonsh.tools import XonshError, print_exception
from xonsh.events import events
import xonsh.history.main as xhm
@ -93,6 +93,18 @@ class Shell(object):
readline version of shell should be used.
"""
shell_type_aliases = {
'b': 'best',
'ptk': 'prompt_toolkit',
'ptk1': 'prompt_toolkit1',
'ptk2': 'prompt_toolkit2',
'prompt-toolkit': 'prompt_toolkit',
'prompt-toolkit1': 'prompt_toolkit1',
'prompt-toolkit2': 'prompt_toolkit2',
'rand': 'random',
'rl': 'readline',
}
def __init__(self, execer, ctx=None, shell_type=None, **kwargs):
"""
Parameters
@ -105,7 +117,7 @@ class Shell(object):
this no additional context is computed and this is used
directly.
shell_type : str, optional
The shell type to start, such as 'readline', 'prompt_toolkit',
The shell type to start, such as 'readline', 'prompt_toolkit1',
or 'random'.
"""
self.execer = execer
@ -123,6 +135,7 @@ class Shell(object):
# This bricks interactive xonsh
# Can happen from the use of .xinitrc, .xsession, etc
shell_type = 'best'
shell_type = self.shell_type_aliases.get(shell_type, shell_type)
if shell_type == 'best' or shell_type is None:
shell_type = best_shell_type()
elif shell_type == 'random':
@ -137,12 +150,16 @@ class Shell(object):
'supported. Please update prompt-toolkit. Using '
'readline instead.')
shell_type = 'readline'
else:
shell_type = ptk_shell_type()
self.shell_type = env['SHELL_TYPE'] = shell_type
# actually make the shell
if shell_type == 'none':
from xonsh.base_shell import BaseShell as shell_class
elif shell_type == 'prompt_toolkit':
from xonsh.ptk.shell import get_ptk_shell as shell_class
elif shell_type == 'prompt_toolkit2':
from xonsh.ptk2.shell import PromptToolkit2Shell as shell_class
elif shell_type == 'prompt_toolkit1':
from xonsh.ptk.shell import PromptToolkitShell as shell_class
elif shell_type == 'readline':
from xonsh.readline_shell import ReadlineShell as shell_class
else: