diff options
25 files changed, 81 insertions, 2489 deletions
@@ -4,13 +4,31 @@ Python Prompt Toolkit |Build Status| |PyPI| ``prompt_toolkit`` is a Library for building powerful interactive command lines -in Python. It ships with a nice interactive Python shell (called ``ptpython``) -built on top of the library. +in Python. -``prompt_toolkit`` could be a replacement for ``readline``, but it can be much +Looking for ptpython, the Python REPL? +************************************** + +Are you looking for the interactive Python Shell? We moved the ``ptpython`` +source code in a separate repository This way we are sure not to pollute the +``prompt_toolkit`` library with any ``ptpython`` specific stuff and +``ptpython`` can be developed independently. You will now have to install it +through:: + + pip install ptpython + +`Go to ptpython... <http://github.com/jonathanslenders/ptpython/>`_ + +.. image :: docs/images/ptpython.png + +prompt-toolkit features +*********************** + +``prompt_toolkit`` could be a replacement for `GNU readline +<http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html>`_, but it can be much more than that. -Features: +Some features: - Pure Python. - Syntax highlighting of the input while typing. (For instance, with a Pygments lexer.) @@ -18,17 +36,19 @@ Features: - Advanced code completion. - Both Emacs and Vi key bindings. (Similar to readline.) - Reverse and forward incremental search. -- Both Python 3 and Python 2.7 support. +- Runs on all Python versions from 2.6 up to 3.4. - Works well with Unicode double width characters. (Chinese input.) - Selecting text for copy/paste. (Both Emacs and Vi style.) +- Multiple input buffers. - No global state. +- Lightweight, the only dependencies are Pygments, six and wcwidth. - Code written with love. - Runs on Linux, OS X, OpenBSD and Windows systems. - Feel free to create tickets for bugs and feature requests, and create pull requests if you have nice patches that you would like to share with others. + About Windows support ********************* @@ -38,11 +58,8 @@ different event loop (``WaitForMultipleObjects`` instead of ``select``), and another input and output system. (Win32 APIs instead of pseudo-terminals and VT100.) -.. image :: docs/images/ptpython-windows.png - - That should work fine, however the library is currently much more tested on -Linux and Mac os X systems. So, if you find any bugs in the Windows +Linux and Mac OS X systems. So, if you find any bugs in the Windows implementation, or you have an idea how to make the experience better, please create a Github issue. @@ -59,129 +76,57 @@ Installation pip install prompt-toolkit -The Python repl +Getting started --------------- -Run ``ptpython`` to get an interactive Python prompt with syntax highlighting, -code completion, etc... - -.. image :: docs/images/ptpython-screenshot.png - -If you prefer to have Vi key bindings (which currently are more completely -implemented than the Emacs bindings), run ``ptpython --vi``. - -If you want to embed the REPL inside your application at one point, do: +The most simple example of the library would look like this: .. code:: python - from prompt_toolkit.contrib.repl import embed - embed(globals(), locals(), vi_mode=False, history_filename=None) - -Autocompletion -************** - -``Tab`` and ``shift+tab`` complete the input. (Thanks to the `Jedi -<http://jedi.jedidjah.ch/en/latest/>`_ autocompletion library.) -In Vi-mode, you can also use ``Ctrl+N`` and ``Ctrl+P``. - -.. image :: docs/images/ptpython-complete-menu.png - - -Multiline editing -***************** - -Usually, multi-line editing mode will automatically turn on when you press enter -after a colon, however you can always turn it on by pressing ``F7``. - -To execute the input in multi-line mode, you can either press ``Alt+Enter``, or -``Esc`` followed by ``Enter``. (If you want the first to work in the OS X -terminal, you have to check the "Use option as meta key" checkbox in your -terminal settings. For iTerm2, you have to check "Left option acts as +Esc" in -the options.) + from prompt_toolkit.contrib.shortcuts import get_input -Other features -*************** - -Running system commands: Press ``Meta-!`` in Emacs mode or just ``!`` in Vi -navigation mode to see the "Shell command" prompt. There you can enter system -commands without leaving the REPL. - -Selecting text: Press ``Control+Space`` in Emacs mode on ``V`` (major V) in Vi -navigation mode. - -You love IPython? -***************** - -Run ``ptipython`` (prompt_toolkit - IPython), to get a nice interactive shell -with all the power that IPython has to offer, like magic functions and shell -integration. Make sure that IPython has been installed. (``pip install -ipython``) - -.. image :: docs/images/ipython-integration.png - -You are using Django? -********************* - -`django-extensions <https://github.com/django-extensions/django-extensions>`_ -has a ``shell_plus`` management command. When ``prompt_toolkit`` has been -installed, it will by default use ``ptpython`` or ``ptipython``. - - -Using as a library ------------------- - -This is a library which allows you to build highly customizable input prompts. -Every step (key bindings, layout, etc..) can be customized. - -Note that this is work in progress. Many things work, but code is still -refactored a lot and APIs can change (they will become even better), so be -prepared to handle these changes. - -Certainly look in the ``examples`` directory to see what is possible. - -A very simple example: - -.. code:: python - - from prompt_toolkit import CommandLineInterface, AbortAction - from prompt_toolkit import Exit + if __name__ == '__main__': + answer = get_input('Give me some input: ') + print('You said: %s' % answer) - def main(): - cli = CommandLineInterface() +For more complex examples, have a look in the examples directory. All examples +are choosen to demonstrate only one thing. Also, don't be afraid to look at the +source code. The implementation of the ``get_input`` function could be a good +start. - try: - while True: - code_obj = cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION) - print('You said: ' + code_obj.text) - except Exit: # Quit on Ctrl-D keypress - return +Projects using prompt-toolkit +------------------------------ - if __name__ == '__main__': - main() +- `ptpython <http://github.com/jonathanslenders/ptpython/>`_: Python REPL +- `ptpdb <http://github.com/jonathanslenders/ptpdb/>`_: Python debugger (pdb replacement) +- `pgcli <http://pgcli.com/>`_: Postgres Shell +(Want you own project to be listed here? Please create a GitHub issue.) -FAQ ---- -Q - The ``Ctrl-S`` forward search doesn't work and freezes my terminal. -A - Try to run ``stty -ixon`` in your terminal to disable flow control. +Philosophy +--------- -Q - The ``Meta``-key doesn't work. -A - For some terminals you have to enable the Alt-key to act as meta key, but you - can also type ``Escape`` before any key instead. +The source code of ``prompt_toolkit`` should be readable, concise and +efficient. We prefer short functions focussing each on one task and for which +the input and output types are clearly specified. We mostly prefer composition +over inheritance, because inheritance can result in too much functionality in +the same object. We prefer immutable objects where possible (objects don't +change after initialisation). Reusability is important. We absolutely refrain +from having a changing global state, it should be possible to have multiple +independent instances of the same code in the same process. The architecture +should be layered: the lower levels operate on primitive operations and data +structures giving -- when correctly combined -- all the possible flexibility; +while at the higher level, there should be a simpler API, ready-to-use and +sufficient for most use cases. Thinking about algorithms and efficiency is +important, but avoid premature optimization. Special thanks to ----------------- - `Pygments <http://pygments.org/>`_: Syntax highlighter. -- `Jedi <http://jedi.jedidjah.ch/en/latest/>`_: Autocompletion library. -- `Docopt <http://docopt.org/>`_: Command-line interface description language. - `wcwidth <https://github.com/jquast/wcwidth>`_: Determine columns needed for a wide characters. .. |Build Status| image:: https://api.travis-ci.org/jonathanslenders/python-prompt-toolkit.svg?branch=master diff --git a/docs/images/ipython-integration.png b/docs/images/ipython-integration.png Binary files differdeleted file mode 100644 index a14a1968..00000000 --- a/docs/images/ipython-integration.png +++ /dev/null diff --git a/docs/images/ptpython-complete-menu.png b/docs/images/ptpython-complete-menu.png Binary files differdeleted file mode 100644 index 2bdb18d2..00000000 --- a/docs/images/ptpython-complete-menu.png +++ /dev/null diff --git a/docs/images/ptpython-windows.png b/docs/images/ptpython-windows.png Binary files differdeleted file mode 100644 index 396f41e9..00000000 --- a/docs/images/ptpython-windows.png +++ /dev/null diff --git a/docs/images/ptpython.png b/docs/images/ptpython.png Binary files differnew file mode 100644 index 00000000..c20e2fa2 --- /dev/null +++ b/docs/images/ptpython.png diff --git a/examples/pdb-example.py b/examples/pdb-example.py deleted file mode 100755 index 854b827a..00000000 --- a/examples/pdb-example.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python -""" -Example of how to call the prompt-toolkit version of the Python debugger (pdb). -""" -from prompt_toolkit.contrib.pdb import set_trace - - -def fibo(n): - """ - Calculate fibonaci number. - """ - if n == 10: - set_trace() - - if n == 0: - return 0 - elif n == 1: - return 1 - else: - return fibo(n-1) + fibo(n-2) - - -if __name__ == '__main__': - fibo(20) diff --git a/examples/python-embed.py b/examples/python-embed.py deleted file mode 100755 index aedad145..00000000 --- a/examples/python-embed.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python -""" -""" -from __future__ import unicode_literals - -from prompt_toolkit.contrib.repl import embed - - -def main(): - embed(globals(), locals(), vi_mode=False) - - -if __name__ == '__main__': - main() diff --git a/examples/python-input.py b/examples/python-input.py deleted file mode 100755 index 7162c106..00000000 --- a/examples/python-input.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python -""" -""" -from __future__ import unicode_literals - -from prompt_toolkit.contrib.python_input import PythonCommandLineInterface - - -def main(): - cli = PythonCommandLineInterface() - - code_obj = cli.read_input() - print('You said: ' + code_obj.text) - - -if __name__ == '__main__': - main() diff --git a/prompt_toolkit/contrib/entry_points/__init__.py b/prompt_toolkit/contrib/entry_points/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/prompt_toolkit/contrib/entry_points/__init__.py +++ /dev/null diff --git a/prompt_toolkit/contrib/entry_points/ptipython.py b/prompt_toolkit/contrib/entry_points/ptipython.py deleted file mode 100644 index 01a0df9e..00000000 --- a/prompt_toolkit/contrib/entry_points/ptipython.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python -""" -ptipython: IPython interactive shell with the `prompt_toolkit` front-end. -Usage: - ptpython [ --vi ] [ --history=<filename> ] - [ --autocompletion=<type> ] [ --always-multiline ] - [--] [ <file> <arg>... ] - ptpython -h | --help - -Options: - --vi : Use Vi keybindings instead of Emacs bindings. - --history=<filename> : Path to history file. -""" -import docopt -import os -import six -import sys - - -def run(): - a = docopt.docopt(__doc__) - - vi_mode = bool(a['--vi']) - - # If IPython is not available, show message and exit here with error status - # code. - try: - import IPython - except ImportError: - print('IPython not found. Please install IPython (pip install ipython).') - sys.exit(1) - else: - from prompt_toolkit.contrib.ipython import embed - - # Log history - if a['--history']: - history_filename = os.path.expanduser(a['--history']) - else: - history_filename = os.path.expanduser('~/.ptpython_history') - - # Add the current directory to `sys.path`. - sys.path.append('.') - - # When a file has been given, run that, otherwise start the shell. - if a['<file>']: - sys.argv = [a['<file>']] + a['<arg>'] - six.exec_(compile(open(a['<file>'], "rb").read(), a['<file>'], 'exec')) - else: - # Create an empty namespace for this interactive shell. (If we don't do - # that, all the variables from this function will become available in - # the IPython shell.) - user_ns = {} - - # Run interactive shell. - embed(vi_mode=vi_mode, history_filename=history_filename, user_ns=user_ns) - - -if __name__ == '__main__': - run() diff --git a/prompt_toolkit/contrib/entry_points/ptpython.py b/prompt_toolkit/contrib/entry_points/ptpython.py deleted file mode 100644 index 314afce4..00000000 --- a/prompt_toolkit/contrib/entry_points/ptpython.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -""" -ptpython: Interactive Python shell. -Usage: - ptpython [ --vi ] [ --history=<filename> ] [ --no-colors ] - [ --autocompletion=<type> ] [ --always-multiline ] - [ --interactive=<filename> ] [--] [ <file> <arg>... ] - ptpython -h | --help - -Options: - --vi : Use Vi keybindings instead of Emacs bindings. - --history=<filename> : Path to history file. - --interactive=<filename> : Start interactive shell after executing this file. - -Other environment variables: -PYTHONSTARTUP: file executed on interactive startup (no default) -""" -import docopt -import os -import six -import sys - -from prompt_toolkit.contrib.repl import embed - - -def run(): - a = docopt.docopt(__doc__) - - vi_mode = bool(a['--vi']) - no_colors = bool(a['--no-colors']) - - # Create globals/locals dict. - globals_, locals_ = {}, {} - - # Log history - if a['--history']: - history_filename = os.path.expanduser(a['--history']) - else: - history_filename = os.path.expanduser('~/.ptpython_history') - - # Startup path - startup_paths = [] - if 'PYTHONSTARTUP' in os.environ: - startup_paths.append(os.environ['PYTHONSTARTUP']) - - # --interactive - if a['--interactive']: - startup_paths.append(a['--interactive']) - - # Add the current directory to `sys.path`. - sys.path.append('.') - - # When a file has been given, run that, otherwise start the shell. - if a['<file>']: - sys.argv = [a['<file>']] + a['<arg>'] - six.exec_(compile(open(a['<file>'], "rb").read(), a['<file>'], 'exec')) - else: - # Run interactive shell. - embed(globals_, locals_, vi_mode=vi_mode, history_filename=history_filename, - no_colors=no_colors, startup_paths=startup_paths) - -if __name__ == '__main__': - run() diff --git a/prompt_toolkit/contrib/ipython.py b/prompt_toolkit/contrib/ipython.py index f9ec678c..c9a9dccf 100644 --- a/prompt_toolkit/contrib/ipython.py +++ b/prompt_toolkit/contrib/ipython.py @@ -1,163 +1,20 @@ """ - -Adaptor for using the input system of `prompt_toolkit` with the IPython -backend. - -This gives a powerful interactive shell that has a nice user interface, but -also the power of for instance all the %-magic functions that IPython has to -offer. - +DEPRECATED. """ from __future__ import unicode_literals -from prompt_toolkit import AbortAction -from prompt_toolkit.completion import Completion -from prompt_toolkit.contrib.python_input import PythonCommandLineInterface, PythonValidator, PythonCompleter -from prompt_toolkit import Exit -from prompt_toolkit.document import Document -from prompt_toolkit.layout.controls import TokenListControl - -from IPython.terminal.embed import InteractiveShellEmbed as _InteractiveShellEmbed -from IPython.terminal.ipapp import load_default_config -from IPython import utils as ipy_utils -from IPython.core.inputsplitter import IPythonInputSplitter - -from pygments.lexers import PythonLexer, BashLexer, TextLexer -from pygments.token import Token - - -class IPythonPrompt(TokenListControl): - """ - Prompt showing something like "In [1]:". - """ - def __init__(self, prompt_manager): - def get_tokens(cli): - text = prompt_manager.render('in', color=False, just=False) - return [(Token.Layout.Prompt, text)] - - super(IPythonPrompt, self).__init__(get_tokens) - - -class IPythonValidator(PythonValidator): - def __init__(self, *args, **kwargs): - super(IPythonValidator, self).__init__(*args, **kwargs) - self.isp = IPythonInputSplitter() - - def validate(self, document): - document = Document(text=self.isp.transform_cell(document.text)) - super(IPythonValidator, self).validate(document) - - -class IPythonCompleter(PythonCompleter): - def __init__(self, get_globals, get_locals, magics_manager): - super(IPythonCompleter, self).__init__(get_globals, get_locals) - self._magics_manager = magics_manager - - def get_completions(self, document, complete_event): - text = document.text_before_cursor.lstrip() - - # Don't complete in shell mode. - if text.startswith('!'): - return - - if text.startswith('%'): - # Complete magic functions. - for m in self._magics_manager.magics['line']: - if m.startswith(text[1:]): - yield Completion('%%%s' % m, -len(text)) - else: - # Complete as normal Python code. - for c in super(IPythonCompleter, self).get_completions(document, complete_event): - yield c - -# TODO: Use alternate lexers in layout, if we have a ! prefix or ? suffix. -# @property -# def lexer(self): -# if self.text.lstrip().startswith('!'): -# return BashLexer -# elif self.text.rstrip().endswith('?'): -# return TextLexer -# else: -# return PythonLexer +__all__ = ('PythonRepl', 'embed') -class IPythonCommandLineInterface(PythonCommandLineInterface): +def embed(*a, **kw): """ - Override our `PythonCommandLineInterface` to add IPython specific stuff. - """ - def __init__(self, ipython_shell, *a, **kw): - kw['_completer'] = IPythonCompleter(kw['get_globals'], kw['get_globals'], ipython_shell.magics_manager) - kw['_validator'] = IPythonValidator() - kw['_python_prompt_control'] = IPythonPrompt(ipython_shell.prompt_manager) - - super(IPythonCommandLineInterface, self).__init__(*a, **kw) - self.ipython_shell = ipython_shell - - -class InteractiveShellEmbed(_InteractiveShellEmbed): - """ - Override the `InteractiveShellEmbed` from IPython, to replace the front-end - with our input shell. - """ - def __init__(self, *a, **kw): - vi_mode = kw.pop('vi_mode', False) - history_filename = kw.pop('history_filename', None) - - super(InteractiveShellEmbed, self).__init__(*a, **kw) - - def get_globals(): - return self.user_ns - - self._cli = IPythonCommandLineInterface( - self, get_globals=get_globals, vi_mode=vi_mode, - history_filename=history_filename) - - def raw_input(self, prompt=''): - print('') - try: - string = self._cli.cli.read_input(on_exit=AbortAction.RAISE_EXCEPTION).text - - # In case of multiline input, make sure to append a newline to the input, - # otherwise, IPython will ask again for more input in some cases. - if '\n' in string: - return string + '\n\n' - else: - return string - except Exit: - self.ask_exit() - return '' - - -def initialize_extensions(shell, extensions): - """ - Partial copy of `InteractiveShellApp.init_extensions` from IPython. + DEPRECATED. Only for backwards compatibility. + Please call ptpython.ipython.embed directly! """ try: - iter(extensions) - except TypeError: - pass # no extensions found - else: - for ext in extensions: - try: - shell.extension_manager.load_extension(ext) - except: - ipy_utils.warn.warn( - "Error in loading extension: %s" % ext + - "\nCheck your config files in %s" % ipy_utils.path.get_ipython_dir()) - shell.showtraceback() - - -def embed(**kwargs): - """ - Copied from `IPython/terminal/embed.py`, but using our `InteractiveShellEmbed` instead. - """ - config = kwargs.get('config') - header = kwargs.pop('header', u'') - compile_flags = kwargs.pop('compile_flags', None) - if config is None: - config = load_default_config() - config.InteractiveShellEmbed = config.TerminalInteractiveShell - kwargs['config'] = config - shell = InteractiveShellEmbed.instance(**kwargs) - initialize_extensions(shell, config['InteractiveShellApp']['extensions']) - shell(header=header, stack_depth=2, compile_flags=compile_flags) + import ptpython.ipython import embed + embed(*a, **kw) + except ImportError as e: + print('prompt_toolkit was installed, but could not find ptpython.') + print('Please run: "pip install ptpython"') + raise e diff --git a/prompt_toolkit/contrib/pdb/__init__.py b/prompt_toolkit/contrib/pdb/__init__.py deleted file mode 100644 index 376dd215..00000000 --- a/prompt_toolkit/contrib/pdb/__init__.py +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/env python -""" -Python debugger prompt. -Enhanced version of Pdb, using a prompt-toolkit front-end. - -Usage:: - - from prompt_toolkit.contrib.pdb import set_trace - set_trace() -""" -from __future__ import unicode_literals, absolute_import -from pygments.lexers import PythonLexer - -from prompt_toolkit import AbortAction, Exit -from prompt_toolkit.buffer import Buffer -from prompt_toolkit.contrib.python_input import PythonCompleter, PythonValidator, document_is_multiline_python, PythonCLISettings, load_python_bindings, PythonCommandLineInterface -from prompt_toolkit.contrib.regular_languages.completion import GrammarCompleter -from prompt_toolkit.contrib.regular_languages.validation import GrammarValidator -from prompt_toolkit.document import Document -from prompt_toolkit.filters import IsDone -from prompt_toolkit.history import FileHistory -from prompt_toolkit.key_binding.manager import KeyBindingManager -from prompt_toolkit.layout import HSplit, Window -from prompt_toolkit.layout.controls import BufferControl -from prompt_toolkit.completion import Completer -from prompt_toolkit.validation import Validator - -from .commands import commands_with_help, shortcuts -from .completers import PythonFileCompleter, PythonFunctionCompleter, BreakPointListCompleter, AliasCompleter, PdbCommandsCompleter -from .grammar import create_pdb_grammar -#from .key_bindings import load_custom_pdb_key_bindings -from .layout import PdbLeftMargin -from .toolbars import PdbShortcutsToolbar, FileLocationToolbar - -import linecache -import os -import pdb -import sys -import weakref - - -__all__ = ( - 'PtPdb', - 'set_trace', -) - - -class DynamicCompleter(Completer): - """ - Proxy to a real completer which we can change at runtime. - """ - def __init__(self, get_completer_func): - self.get_completer_func = get_completer_func - - def get_completions(self, document, complete_event): - for c in self.get_completer_func().get_completions(document, complete_event): - yield c - - -class DynamicValidator(Validator): - """ - Proxy to a real validator which we can change at runtime. - """ - def __init__(self, get_validator_func): - self.get_validator_func = get_validator_func - - def validate(self, document): - return self.get_validator_func().validate(document) - - -class PtPdb(pdb.Pdb): - def __init__(self): - pdb.Pdb.__init__(self) - - # Cache for the grammar. - self._grammar_cache = None # (current_pdb_commands, grammar) tuple. - - self._cli_history = FileHistory(os.path.expanduser('~/.ptpdb_history')) - - self.python_cli_settings = PythonCLISettings() - - self.completer = None - self.validator = None - - # def is_multiline(document): - # if (self.python_cli_settings.paste_mode or - # self.python_cli_settings.currently_multiline): - # return True - - # match = g.match_prefix(document.text) - # if match: - # for v in match.variables().getall('python_code'): - # if document_is_multiline_python(Document(v)): - # return True - # return False - - self.cli = PythonCommandLineInterface( - get_locals=lambda: self.curframe.f_locals, - get_globals=lambda: self.curframe.f_globals, - _completer=DynamicCompleter(lambda: self.completer), - _validator=DynamicValidator(lambda: self.validator), - _python_prompt_control=PdbLeftMargin(self.python_cli_settings, - self._get_current_pdb_commands()), - _extra_buffers={'source_code': Buffer()}, - _extra_sidebars=[ - HSplit([ - FileLocationToolbar(weakref.ref(self)), - Window( - BufferControl( - buffer_name='source_code', - lexer=PythonLexer, - ), - filter=~IsDone(), - ), - PdbShortcutsToolbar(weakref.ref(self)), - ]), - ], - ) - # XXX: TODO: add CompletionHint() after the input!! - # XXX: TODO: Add PDB key bindings again. - -# # The key bindings manager. We reuse it between Pdb calls, in order to -# # remember vi/emacs state, etc..) -# self.key_bindings_manager = self._create_key_bindings_manager(self.python_cli_settings) -# -# def _create_key_bindings_manager(self, settings): -# key_bindings_manager = KeyBindingManager() -# load_custom_pdb_key_bindings(key_bindings_manager.registry) # XXX: implement -# load_python_bindings(key_bindings_manager, settings, None, None) # XXX: pass create tab functions -# -# return key_bindings_manager - - def cmdloop(self, intro=None): - """ - Copy/Paste of pdb.Pdb.cmdloop. But using our own CommandLineInterface - for reading input instead. - """ - self.preloop() - - if intro is not None: - self.intro = intro - if self.intro: - self.stdout.write(str(self.intro)+"\n") - stop = None - while not stop: - if self.cmdqueue: - line = self.cmdqueue.pop(0) - else: - if self.use_rawinput: - line = self._get_input() - - line = self.precmd(line) - stop = self.onecmd(line) - stop = self.postcmd(stop, line) - self.postloop() - - def _get_current_pdb_commands(self): - return ( - list(commands_with_help.keys()) + - list(shortcuts.keys()) + - list(self.aliases.keys())) - - def _create_grammar(self): - """ - Return the compiled grammar for this PDB shell. - - The grammar of PDB depends on the available list of PDB commands (which - depends on the currently defined aliases.) Therefor we generate a new - grammar when it changes, but cache it otherwise. (It's still expensive - to compile.) - """ - pdb_commands = self._get_current_pdb_commands() - - if self._grammar_cache is None or self._grammar_cache[0] != pdb_commands: - self._grammar_cache = [ - pdb_commands, - create_pdb_grammar(pdb_commands)] - - return self._grammar_cache[1] - - def _get_input(self): - """ - Read PDB input. Return input text. - """ - # Reset multiline/paste mode every time. - self.python_cli_settings.paste_mode = False - self.python_cli_settings.currently_multiline = False - - # Make sure not to start in Vi navigation mode. -# self.key_bindings_manager.reset() - - # Set source code document. - self.cli.cli.buffers['source_code'].document = Document(self._get_source_code()) - - # Set up a new completer and validator for the new grammar. - g = self._create_grammar() - - self.completer = GrammarCompleter(g, completers={ - 'enabled_breakpoint': BreakPointListCompleter(only_enabled=True), - 'disabled_breakpoint': BreakPointListCompleter(only_disabled=True), - 'alias_name': AliasCompleter(self), - 'python_code': PythonCompleter(lambda: self.curframe.f_globals, lambda: self.curframe.f_locals), - 'breakpoint': BreakPointListCompleter(), - 'pdb_command': PdbCommandsCompleter(self), - 'python_file': PythonFi |