summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Slenders <jonathan@slenders.be>2015-01-24 20:50:04 +0100
committerJonathan Slenders <jonathan@slenders.be>2015-01-25 11:55:50 +0100
commita622f51d038951611082b4405ffd4f937bfb86e7 (patch)
tree79c842332beda43b9abd8bd0fc80cdaf6696a5f7
parent10ee9326443b9c121f7ae84682c63bbe1b4a0c58 (diff)
Moving ptpython code out of the prompt-toolkit repository.
We have a separate ptpython repository now.
-rw-r--r--README.rst171
-rw-r--r--docs/images/ipython-integration.pngbin43234 -> 0 bytes
-rw-r--r--docs/images/ptpython-complete-menu.pngbin21056 -> 0 bytes
-rw-r--r--docs/images/ptpython-windows.pngbin14096 -> 0 bytes
-rw-r--r--docs/images/ptpython.pngbin0 -> 27156 bytes
-rwxr-xr-xexamples/pdb-example.py24
-rwxr-xr-xexamples/python-embed.py14
-rwxr-xr-xexamples/python-input.py17
-rw-r--r--prompt_toolkit/contrib/entry_points/__init__.py0
-rw-r--r--prompt_toolkit/contrib/entry_points/ptipython.py59
-rw-r--r--prompt_toolkit/contrib/entry_points/ptpython.py63
-rw-r--r--prompt_toolkit/contrib/ipython.py165
-rw-r--r--prompt_toolkit/contrib/pdb/__init__.py254
-rw-r--r--prompt_toolkit/contrib/pdb/commands.py69
-rw-r--r--prompt_toolkit/contrib/pdb/completers.py109
-rw-r--r--prompt_toolkit/contrib/pdb/completion_hints.py34
-rw-r--r--prompt_toolkit/contrib/pdb/grammar.py56
-rw-r--r--prompt_toolkit/contrib/pdb/key_bindings.py27
-rw-r--r--prompt_toolkit/contrib/pdb/layout.py32
-rw-r--r--prompt_toolkit/contrib/pdb/style.py22
-rw-r--r--prompt_toolkit/contrib/pdb/toolbars.py50
-rw-r--r--prompt_toolkit/contrib/python_input.py1187
-rw-r--r--prompt_toolkit/contrib/repl.py203
-rw-r--r--prompt_toolkit/contrib/shortcuts.py2
-rw-r--r--setup.py12
25 files changed, 81 insertions, 2489 deletions
diff --git a/README.rst b/README.rst
index c7b44f90..9b90d53d 100644
--- a/README.rst
+++ b/README.rst
@@ -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
deleted file mode 100644
index a14a1968..00000000
--- a/docs/images/ipython-integration.png
+++ /dev/null
Binary files differ
diff --git a/docs/images/ptpython-complete-menu.png b/docs/images/ptpython-complete-menu.png
deleted file mode 100644
index 2bdb18d2..00000000
--- a/docs/images/ptpython-complete-menu.png
+++ /dev/null
Binary files differ
diff --git a/docs/images/ptpython-windows.png b/docs/images/ptpython-windows.png
deleted file mode 100644
index 396f41e9..00000000
--- a/docs/images/ptpython-windows.png
+++ /dev/null
Binary files differ
diff --git a/docs/images/ptpython.png b/docs/images/ptpython.png
new file mode 100644
index 00000000..c20e2fa2
--- /dev/null
+++ b/docs/images/ptpython.png
Binary files differ
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
-