[Python-modules-commits] [prompt-toolkit] 01/03: Imported Upstream version 1.0.14
Scott Kitterman
kitterman at moszumanska.debian.org
Sun Jun 18 05:13:15 UTC 2017
This is an automated email from the git hooks/post-receive script.
kitterman pushed a commit to branch debian/master
in repository prompt-toolkit.
commit 66aeecfd464da12ce888a3119046027519e59f1e
Author: Scott Kitterman <scott at kitterman.com>
Date: Sun Jun 18 01:02:32 2017 -0400
Imported Upstream version 1.0.14
---
CHANGELOG | 71 ++++
PKG-INFO | 4 +-
README.rst | 2 +
examples/autocompletion-like-readline.py | 10 +-
examples/autocorrection.py | 11 +-
examples/custom-key-binding.py | 17 +-
examples/custom-vi-operator-and-text-object.py | 64 ++++
examples/full-screen-layout.py | 17 +-
.../get-password-with-toggle-display-shortcut.py | 8 +-
examples/operate-and-get-next.py | 19 +
examples/patch-stdout.py | 4 +-
examples/switch-between-vi-emacs.py | 11 +-
prompt_toolkit.egg-info/PKG-INFO | 4 +-
prompt_toolkit.egg-info/SOURCES.txt | 5 +-
prompt_toolkit/__init__.py | 2 +-
prompt_toolkit/application.py | 29 +-
prompt_toolkit/buffer.py | 53 ++-
prompt_toolkit/clipboard/base.py | 5 +
prompt_toolkit/clipboard/in_memory.py | 28 +-
prompt_toolkit/document.py | 22 +-
prompt_toolkit/eventloop/asyncio_posix.py | 4 +-
prompt_toolkit/interface.py | 42 ++-
prompt_toolkit/key_binding/bindings/basic.py | 68 ++--
prompt_toolkit/key_binding/bindings/emacs.py | 86 ++---
.../key_binding/bindings/named_commands.py | 196 ++++++++++-
prompt_toolkit/key_binding/bindings/utils.py | 25 --
prompt_toolkit/key_binding/bindings/vi.py | 383 ++++++++++++---------
prompt_toolkit/key_binding/defaults.py | 119 +++++++
prompt_toolkit/key_binding/input_processor.py | 44 ++-
prompt_toolkit/key_binding/manager.py | 109 ++----
prompt_toolkit/key_binding/registry.py | 192 ++++++++++-
prompt_toolkit/layout/containers.py | 2 +
prompt_toolkit/layout/lexers.py | 11 +
prompt_toolkit/layout/margins.py | 5 +-
prompt_toolkit/selection.py | 7 +
prompt_toolkit/shortcuts.py | 26 +-
prompt_toolkit/styles/from_pygments.py | 6 +
prompt_toolkit/terminal/vt100_input.py | 11 +
prompt_toolkit/terminal/vt100_output.py | 20 +-
prompt_toolkit/terminal/win32_output.py | 26 +-
setup.cfg | 3 +-
tests/test_cli.py | 116 ++++++-
tests/test_key_binding.py | 42 +++
tests/test_print_tokens.py | 50 +++
tests/test_shortcuts.py | 9 +-
45 files changed, 1494 insertions(+), 494 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index a584447..1666226 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,77 @@
CHANGELOG
=========
+1.0.14: 2017-03-26
+------------------
+
+Fixes:
+- Handle arguments in the $EDITOR and $VISUAL env variable.
+- Added missing explicit loops for Futures in asyncio_posix eventloop.
+- Fallback to default terminal size if reported as 0.
+- Don't save undo state when receiving CPRResponse.
+- Set VMIN terminal flag to 1 when entering raw mode.
+ (Fixes a bug on Solaris.)
+- Fix `previous_key_sequences`.
+
+
+1.0.13: 2017-02-02
+------------------
+
+Fixes:
+- The 1.0.11 and 1.0.12 builds went wrong. (1.0.11 contained an additional
+ empty directory `prompt_toolkit/input/` which did hide the
+ `prompt_toolkit/input.py` file, and 1.0.12 contained an additional
+ broken `widgets.py` test file.)
+
+
+1.0.11: 2017-02-02
+------------------
+
+Fixes:
+- Only handle 'edit-and-execute-command' in Vi navigation mode.
+ (This affects every tool that uses `enable_open_in_editor=True`.)
+
+
+1.0.10: 2017-01-30
+------------------
+
+Fixes:
+- Fixed the `NoConsoleScreenBuffer` error that appeared on some 64bit Python
+ versions.
+- Fix mixup in the mapping from ANSI color names for vt100 output.
+
+New features:
+- Added a `reverse_vi_search_direction` option.
+- Handle Ctrl-Left/Right in rxvt.
+- Implemented difference between `backward-kill-word` and `unix-word-rubout`.
+- Implementation of the Emacs kill-ring (yank-pop command).
+- Take a 'file' argument in 'print_tokens'.
+- Implemented the `operate-and-get-next` command, bound to C-O in Emacs mode.
+- Added multiple named commands:
+ * Added `insert-comment` command, bound to M-#.
+ * Added `vi-editing-mode` and `emacs-editing-mode` commands.
+ * Added `prefix-meta` command.
+ * Added `edit-and-execute` command.
+ * Added `complete`/`menu_complete`/`menu-complete-backward` commands.
+ * Added `quoted-insert` command.
+- Take $VISUAL into account.
+- Display a quoted inserted using the `^` character, just like Vi does.
+- Implemented keyboard macros. (Like Readline.)
+- Extracted the Vi `create_operator_decorator` and
+ `create_text_object_decorator` functions. (This makes it easier to implement
+ custom Vi bindings.)
+- Pass `raw=True` to the `stdout_context` in `prompt_toolkit.shortcuts`.
+- Added `Buffer.validation_state`. (Don't call the validator again if the input
+ didn't change.)
+
+Changes:
+- Refactoring of the key bindings.
+ * All the load functions now create a new `Registry` object.
+ * Added `MergedRegistry` and `ConditionalRegistry`.
+ * Added `prompt_toolkit.key_binding.defaults` for loading the default key
+ bindings.
+
+
1.0.9: 2016-11-07
-----------------
diff --git a/PKG-INFO b/PKG-INFO
index 7173e68..6aeb2d2 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: prompt_toolkit
-Version: 1.0.9
+Version: 1.0.14
Summary: Library for building powerful interactive command lines in Python
Home-page: https://github.com/jonathanslenders/python-prompt-toolkit
Author: Jonathan Slenders
@@ -135,6 +135,8 @@ Description: Python Prompt Toolkit
- `haxor-news <https://github.com/donnemartin/haxor-news>`_: A Hacker News CLI.
- `gitsome <https://github.com/donnemartin/gitsome>`_: A Git/Shell Autocompleter with GitHub Integration.
- `http-prompt <https://github.com/eliangcs/http-prompt>`_: An interactive command-line HTTP client.
+ - `coconut <http://coconut-lang.org/>`_: Functional programming in Python.
+ - `Ergonomica <https://ergonomica.github.io/>`_: A Bash alternative written in Python.
Full screen applications:
diff --git a/README.rst b/README.rst
index 80a6e07..ba7c983 100644
--- a/README.rst
+++ b/README.rst
@@ -127,6 +127,8 @@ Shells:
- `haxor-news <https://github.com/donnemartin/haxor-news>`_: A Hacker News CLI.
- `gitsome <https://github.com/donnemartin/gitsome>`_: A Git/Shell Autocompleter with GitHub Integration.
- `http-prompt <https://github.com/eliangcs/http-prompt>`_: An interactive command-line HTTP client.
+- `coconut <http://coconut-lang.org/>`_: Functional programming in Python.
+- `Ergonomica <https://ergonomica.github.io/>`_: A Bash alternative written in Python.
Full screen applications:
diff --git a/examples/autocompletion-like-readline.py b/examples/autocompletion-like-readline.py
index e262558..68316a4 100755
--- a/examples/autocompletion-like-readline.py
+++ b/examples/autocompletion-like-readline.py
@@ -8,7 +8,7 @@ from __future__ import unicode_literals
from prompt_toolkit import prompt
from prompt_toolkit.contrib.completers import WordCompleter
from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
-from prompt_toolkit.key_binding.manager import KeyBindingManager
+from prompt_toolkit.key_binding.defaults import load_key_bindings
from prompt_toolkit.keys import Keys
@@ -20,14 +20,16 @@ animal_completer = WordCompleter([
'turtle',
], ignore_case=True)
+
# Create key bindings registry with a custom binding for the Tab key that
# displays completions like GNU readline.
-key_bindings_manager = KeyBindingManager.for_prompt()
-key_bindings_manager.registry.add_binding(Keys.ControlI)(display_completions_like_readline)
+registry = load_key_bindings()
+registry.add_binding(Keys.ControlI)(display_completions_like_readline)
+
def main():
text = prompt('Give some animals: ', completer=animal_completer,
- key_bindings_registry=key_bindings_manager.registry,
+ key_bindings_registry=registry,
# Important: for this to work: `complete_while_typing` needs
# to be False.
diff --git a/examples/autocorrection.py b/examples/autocorrection.py
index 42b0151..8819eb2 100755
--- a/examples/autocorrection.py
+++ b/examples/autocorrection.py
@@ -5,7 +5,7 @@ Example of implementing auto correction while typing.
The word "impotr" will be corrected when the user types a space afterwards.
"""
from __future__ import unicode_literals
-from prompt_toolkit.key_binding.manager import KeyBindingManager
+from prompt_toolkit.key_binding.defaults import load_key_bindings_for_prompt
from prompt_toolkit import prompt
# Database of words to be replaced by typing.
@@ -16,12 +16,11 @@ corrections = {
def main():
- # We start with a `KeyBindingManager` instance, because this will already
- # nicely load all the default key bindings.
- key_bindings_manager = KeyBindingManager()
+ # We start with a `Registry` that contains the default key bindings.
+ registry = load_key_bindings_for_prompt()
# We add a custom key binding to space.
- @key_bindings_manager.registry.add_binding(' ')
+ @registry.add_binding(' ')
def _(event):
"""
When space is pressed, we check the word before the cursor, and
@@ -38,7 +37,7 @@ def main():
b.insert_text(' ')
# Read input.
- text = prompt('Say something: ', key_bindings_registry=key_bindings_manager.registry)
+ text = prompt('Say something: ', key_bindings_registry=registry)
print('You said: %s' % text)
diff --git a/examples/custom-key-binding.py b/examples/custom-key-binding.py
index 5da6aaf..3ddf6de 100755
--- a/examples/custom-key-binding.py
+++ b/examples/custom-key-binding.py
@@ -4,24 +4,23 @@ Example of adding a custom key binding to a prompt.
"""
from __future__ import unicode_literals
from prompt_toolkit import prompt
-from prompt_toolkit.key_binding.manager import KeyBindingManager
+from prompt_toolkit.key_binding.defaults import load_key_bindings_for_prompt
from prompt_toolkit.keys import Keys
def main():
- # We start with a `KeyBindingManager` instance, because this will already
- # nicely load all the default key bindings.
- key_bindings_manager = KeyBindingManager.for_prompt()
+ # We start with a `Registry` of default key bindings.
+ registry = load_key_bindings_for_prompt()
# Add our own key binding to the registry of the key bindings manager.
- @key_bindings_manager.registry.add_binding(Keys.F4)
+ @registry.add_binding(Keys.F4)
def _(event):
"""
When F4 has been pressed. Insert "hello world" as text.
"""
event.cli.current_buffer.insert_text('hello world')
- @key_bindings_manager.registry.add_binding('x', 'y')
+ @registry.add_binding('x', 'y')
def _(event):
"""
(Useless, but for demoing.)
@@ -34,12 +33,12 @@ def main():
"""
event.cli.current_buffer.insert_text('z')
- @key_bindings_manager.registry.add_binding('a', 'b', 'c')
+ @registry.add_binding('a', 'b', 'c')
def _(event):
" Typing 'abc' should insert 'd'. "
event.cli.current_buffer.insert_text('d')
- @key_bindings_manager.registry.add_binding(Keys.ControlT)
+ @registry.add_binding(Keys.ControlT)
def _(event):
"""
Print 'hello world' in the terminal when ControlT is pressed.
@@ -55,7 +54,7 @@ def main():
# Read input.
print('Press F4 to insert "hello world", type "xy" to insert "z":')
- text = prompt('> ', key_bindings_registry=key_bindings_manager.registry)
+ text = prompt('> ', key_bindings_registry=registry)
print('You said: %s' % text)
diff --git a/examples/custom-vi-operator-and-text-object.py b/examples/custom-vi-operator-and-text-object.py
new file mode 100755
index 0000000..a43f4b4
--- /dev/null
+++ b/examples/custom-vi-operator-and-text-object.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+"""
+Example of adding a custom Vi operator and text object.
+(Note that this API is not guaranteed to remain stable.)
+"""
+from __future__ import unicode_literals
+from prompt_toolkit import prompt
+from prompt_toolkit.key_binding.defaults import load_key_bindings_for_prompt
+from prompt_toolkit.key_binding.bindings.vi import create_operator_decorator, create_text_object_decorator, TextObject
+from prompt_toolkit.enums import EditingMode
+
+
+def main():
+ # We start with a `Registry` of default key bindings.
+ registry = load_key_bindings_for_prompt()
+
+ # Create the decorators to be used for registering text objects and
+ # operators in this registry.
+ operator = create_operator_decorator(registry)
+ text_object = create_text_object_decorator(registry)
+
+ # Create a custom operator.
+
+ @operator('R')
+ def _(event, text_object):
+ " Custom operator that reverses text. "
+ buff = event.current_buffer
+
+ # Get relative start/end coordinates.
+ start, end = text_object.operator_range(buff.document)
+ start += buff.cursor_position
+ end += buff.cursor_position
+
+ text = buff.text[start:end]
+ text = ''.join(reversed(text))
+
+ event.cli.current_buffer.text = buff.text[:start] + text + buff.text[end:]
+
+ # Create a text object.
+
+ @text_object('A')
+ def _(event):
+ " A custom text object that involves everything. "
+ # Note that a `TextObject` has coordinatens, relative to the cursor position.
+ buff = event.current_buffer
+ return TextObject(
+ -buff.document.cursor_position, # The start.
+ len(buff.text) - buff.document.cursor_position) # The end.
+
+ # Read input.
+ print('There is a custom text object "A" that applies to everything')
+ print('and a custom operator "r" that reverses the text object.\n')
+
+ print('Things that are possible:')
+ print('- Riw - reverse inner word.')
+ print('- yA - yank everything.')
+ print('- RA - reverse everything.')
+
+ text = prompt('> ', default='hello world', key_bindings_registry=registry, editing_mode=EditingMode.VI)
+ print('You said: %s' % text)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/examples/full-screen-layout.py b/examples/full-screen-layout.py
index f9e6ea1..d581d88 100755
--- a/examples/full-screen-layout.py
+++ b/examples/full-screen-layout.py
@@ -11,7 +11,7 @@ from prompt_toolkit.application import Application
from prompt_toolkit.buffer import Buffer
from prompt_toolkit.enums import DEFAULT_BUFFER
from prompt_toolkit.interface import CommandLineInterface
-from prompt_toolkit.key_binding.manager import KeyBindingManager
+from prompt_toolkit.key_binding.defaults import load_key_bindings
from prompt_toolkit.keys import Keys
from prompt_toolkit.layout.containers import VSplit, HSplit, Window
from prompt_toolkit.layout.controls import BufferControl, FillControl, TokenListControl
@@ -89,12 +89,11 @@ layout = HSplit([
# As a demonstration, we will add just a ControlQ key binding to exit the
# application. Key bindings are registered in a
-# `prompt_toolkit.key_bindings.registry.Registry` instance. However instead of
-# starting with an empty `Registry` instance, usually you'd use a
-# `KeyBindingmanager`, because it prefills the registry with all of the key
-# bindings that are required for basic text editing.
+# `prompt_toolkit.key_bindings.registry.Registry` instance. We use the
+# `load_default_key_bindings` utility function to create a registry that
+# already contains the default key bindings.
-manager = KeyBindingManager() # Start with the `KeyBindingManager`.
+registry = load_key_bindings()
# Now add the Ctrl-Q binding. We have to pass `eager=True` here. The reason is
# that there is another key *sequence* that starts with Ctrl-Q as well. Yes, a
@@ -113,8 +112,8 @@ manager = KeyBindingManager() # Start with the `KeyBindingManager`.
# `eager=True` to all key bindings, but do it when it conflicts with another
# existing key binding, and you definitely want to override that behaviour.
- at manager.registry.add_binding(Keys.ControlC, eager=True)
- at manager.registry.add_binding(Keys.ControlQ, eager=True)
+ at registry.add_binding(Keys.ControlC, eager=True)
+ at registry.add_binding(Keys.ControlQ, eager=True)
def _(event):
"""
Pressing Ctrl-Q or Ctrl-C will exit the user interface.
@@ -160,7 +159,7 @@ buffers[DEFAULT_BUFFER].on_text_changed += default_buffer_changed
application = Application(
layout=layout,
buffers=buffers,
- key_bindings_registry=manager.registry,
+ key_bindings_registry=registry,
# Let's add mouse support!
mouse_support=True,
diff --git a/examples/get-password-with-toggle-display-shortcut.py b/examples/get-password-with-toggle-display-shortcut.py
index ae6daf8..403543d 100755
--- a/examples/get-password-with-toggle-display-shortcut.py
+++ b/examples/get-password-with-toggle-display-shortcut.py
@@ -5,16 +5,16 @@ With the addition of a ControlT shortcut to hide/show the input.
"""
from __future__ import unicode_literals
from prompt_toolkit import prompt
-from prompt_toolkit.key_binding.manager import KeyBindingManager
+from prompt_toolkit.key_binding.defaults import load_key_bindings_for_prompt
from prompt_toolkit.keys import Keys
from prompt_toolkit.filters import Condition
def main():
hidden = [True] # Nonlocal
- key_bindings_manager = KeyBindingManager()
+ registry = load_key_bindings_for_prompt()
- @key_bindings_manager.registry.add_binding(Keys.ControlT)
+ @registry.add_binding(Keys.ControlT)
def _(event):
' When ControlT has been pressed, toggle visibility. '
hidden[0] = not hidden[0]
@@ -23,7 +23,7 @@ def main():
print('Type Control-T to toggle password visible.')
password = prompt('Password: ',
is_password=Condition(lambda cli: hidden[0]),
- key_bindings_registry=key_bindings_manager.registry)
+ key_bindings_registry=registry)
print('You said: %s' % password)
diff --git a/examples/operate-and-get-next.py b/examples/operate-and-get-next.py
new file mode 100755
index 0000000..4386819
--- /dev/null
+++ b/examples/operate-and-get-next.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+"""
+Demo of "operate-and-get-next".
+
+(Actually, this creates one prompt application, and keeps running the same app
+over and over again. -- For now, this is the only way to get this working.)
+"""
+from __future__ import unicode_literals
+from prompt_toolkit.shortcuts import create_prompt_application, run_application
+
+
+def main():
+ app = create_prompt_application('prompt> ')
+ while True:
+ run_application(app)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/examples/patch-stdout.py b/examples/patch-stdout.py
index 23eb3ff..6dc38f0 100755
--- a/examples/patch-stdout.py
+++ b/examples/patch-stdout.py
@@ -22,7 +22,9 @@ def main():
i += 1
print('i=%i' % i)
time.sleep(1)
- threading.Thread(target=thread).start()
+ t = threading.Thread(target=thread)
+ t.daemon = True
+ t.start()
# Now read the input. The print statements of the other thread
# should not disturb anything.
diff --git a/examples/switch-between-vi-emacs.py b/examples/switch-between-vi-emacs.py
index 8ba11ac..0e21636 100755
--- a/examples/switch-between-vi-emacs.py
+++ b/examples/switch-between-vi-emacs.py
@@ -5,18 +5,17 @@ Example that displays how to switch between Emacs and Vi input mode.
"""
from prompt_toolkit import prompt
from prompt_toolkit.enums import EditingMode
-from prompt_toolkit.key_binding.manager import KeyBindingManager
+from prompt_toolkit.key_binding.defaults import load_key_bindings_for_prompt
from prompt_toolkit.keys import Keys
from prompt_toolkit.styles import style_from_dict
from prompt_toolkit.token import Token
def run():
- # Create a set of key bindings that have Vi mode enabled if the
- # ``vi_mode_enabled`` is True..
- manager = KeyBindingManager.for_prompt()
+ # Create a `Registry` that contains the default key bindings.
+ registry = load_key_bindings_for_prompt()
# Add an additional key binding for toggling this flag.
- @manager.registry.add_binding(Keys.F4)
+ @registry.add_binding(Keys.F4)
def _(event):
" Toggle between Emacs and Vi mode. "
if event.cli.editing_mode == EditingMode.VI:
@@ -36,7 +35,7 @@ def run():
(Token.Toolbar, ' [F4] %s ' % text)
]
- prompt('> ', key_bindings_registry=manager.registry,
+ prompt('> ', key_bindings_registry=registry,
get_bottom_toolbar_tokens=get_bottom_toolbar_tokens,
style=style)
diff --git a/prompt_toolkit.egg-info/PKG-INFO b/prompt_toolkit.egg-info/PKG-INFO
index 718a00c..c5685cc 100644
--- a/prompt_toolkit.egg-info/PKG-INFO
+++ b/prompt_toolkit.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: prompt-toolkit
-Version: 1.0.9
+Version: 1.0.14
Summary: Library for building powerful interactive command lines in Python
Home-page: https://github.com/jonathanslenders/python-prompt-toolkit
Author: Jonathan Slenders
@@ -135,6 +135,8 @@ Description: Python Prompt Toolkit
- `haxor-news <https://github.com/donnemartin/haxor-news>`_: A Hacker News CLI.
- `gitsome <https://github.com/donnemartin/gitsome>`_: A Git/Shell Autocompleter with GitHub Integration.
- `http-prompt <https://github.com/eliangcs/http-prompt>`_: An interactive command-line HTTP client.
+ - `coconut <http://coconut-lang.org/>`_: Functional programming in Python.
+ - `Ergonomica <https://ergonomica.github.io/>`_: A Bash alternative written in Python.
Full screen applications:
diff --git a/prompt_toolkit.egg-info/SOURCES.txt b/prompt_toolkit.egg-info/SOURCES.txt
index 1298a22..0f82ade 100644
--- a/prompt_toolkit.egg-info/SOURCES.txt
+++ b/prompt_toolkit.egg-info/SOURCES.txt
@@ -16,6 +16,7 @@ examples/clock-input.py
examples/colored-prompt.py
examples/confirmation-prompt.py
examples/custom-key-binding.py
+examples/custom-vi-operator-and-text-object.py
examples/finalterm-shell-integration.py
examples/full-screen-layout.py
examples/get-input-vi-mode.py
@@ -33,6 +34,7 @@ examples/multi-column-autocompletion-with-meta.py
examples/multi-column-autocompletion.py
examples/multiline-prompt.py
examples/no-wrapping.py
+examples/operate-and-get-next.py
examples/patch-stdout.py
examples/persistent-history.py
examples/print-tokens.py
@@ -114,6 +116,7 @@ prompt_toolkit/filters/cli.py
prompt_toolkit/filters/types.py
prompt_toolkit/filters/utils.py
prompt_toolkit/key_binding/__init__.py
+prompt_toolkit/key_binding/defaults.py
prompt_toolkit/key_binding/digraphs.py
prompt_toolkit/key_binding/input_processor.py
prompt_toolkit/key_binding/manager.py
@@ -125,7 +128,6 @@ prompt_toolkit/key_binding/bindings/completion.py
prompt_toolkit/key_binding/bindings/emacs.py
prompt_toolkit/key_binding/bindings/named_commands.py
prompt_toolkit/key_binding/bindings/scroll.py
-prompt_toolkit/key_binding/bindings/utils.py
prompt_toolkit/key_binding/bindings/vi.py
prompt_toolkit/layout/__init__.py
prompt_toolkit/layout/containers.py
@@ -160,6 +162,7 @@ tests/test_filter.py
tests/test_inputstream.py
tests/test_key_binding.py
tests/test_layout.py
+tests/test_print_tokens.py
tests/test_regular_languages.py
tests/test_shortcuts.py
tests/test_style.py
diff --git a/prompt_toolkit/__init__.py b/prompt_toolkit/__init__.py
index a8d0203..eb80a15 100644
--- a/prompt_toolkit/__init__.py
+++ b/prompt_toolkit/__init__.py
@@ -19,4 +19,4 @@ from .shortcuts import prompt, prompt_async
# Don't forget to update in `docs/conf.py`!
-__version__ = '1.0.9'
+__version__ = '1.0.14'
diff --git a/prompt_toolkit/application.py b/prompt_toolkit/application.py
index e2489e3..272d8bb 100644
--- a/prompt_toolkit/application.py
+++ b/prompt_toolkit/application.py
@@ -8,7 +8,8 @@ from .filters import CLIFilter, to_cli_filter
from .key_binding.bindings.basic import load_basic_bindings
from .key_binding.bindings.emacs import load_emacs_bindings
from .key_binding.bindings.vi import load_vi_bindings
-from .key_binding.registry import Registry
+from .key_binding.registry import BaseRegistry
+from .key_binding.defaults import load_key_bindings
from .layout import Window
from .layout.containers import Container
from .layout.controls import BufferControl
@@ -49,14 +50,17 @@ class Application(object):
:param buffer: A :class:`~prompt_toolkit.buffer.Buffer` instance for the default buffer.
:param initial_focussed_buffer: Name of the buffer that is focussed during start-up.
:param key_bindings_registry:
- :class:`~prompt_toolkit.key_binding.registry.Registry` instance for the
- key bindings.
+ :class:`~prompt_toolkit.key_binding.registry.BaseRegistry` instance for
+ the key bindings.
:param clipboard: :class:`~prompt_toolkit.clipboard.base.Clipboard` to use.
:param on_abort: What to do when Control-C is pressed.
:param on_exit: What to do when Control-D is pressed.
:param use_alternate_screen: When True, run the application on the alternate screen buffer.
:param get_title: Callable that returns the current title to be displayed in the terminal.
:param erase_when_done: (bool) Clear the application output when it finishes.
+ :param reverse_vi_search_direction: Normally, in Vi mode, a '/' searches
+ forward and a '?' searches backward. In readline mode, this is usually
+ reversed.
Filters:
@@ -90,6 +94,7 @@ class Application(object):
paste_mode=False, ignore_case=False, editing_mode=EditingMode.EMACS,
erase_when_done=False,
+ reverse_vi_search_direction=False,
on_input_timeout=None, on_start=None, on_stop=None,
on_reset=None, on_initialize=None, on_buffer_changed=None,
@@ -98,11 +103,12 @@ class Application(object):
paste_mode = to_cli_filter(paste_mode)
ignore_case = to_cli_filter(ignore_case)
mouse_support = to_cli_filter(mouse_support)
+ reverse_vi_search_direction = to_cli_filter(reverse_vi_search_direction)
assert layout is None or isinstance(layout, Container)
assert buffer is None or isinstance(buffer, Buffer)
assert buffers is None or isinstance(buffers, (dict, BufferMapping))
- assert key_bindings_registry is None or isinstance(key_bindings_registry, Registry)
+ assert key_bindings_registry is None or isinstance(key_bindings_registry, BaseRegistry)
assert clipboard is None or isinstance(clipboard, Clipboard)
assert on_abort in AbortAction._all
assert on_exit in AbortAction._all
@@ -145,10 +151,7 @@ class Application(object):
self.style = style or DEFAULT_STYLE
if key_bindings_registry is None:
- key_bindings_registry = Registry()
- load_basic_bindings(key_bindings_registry)
- load_emacs_bindings(key_bindings_registry)
- load_vi_bindings(key_bindings_registry)
+ key_bindings_registry = load_key_bindings()
if get_title is None:
get_title = lambda: None
@@ -165,6 +168,7 @@ class Application(object):
self.ignore_case = ignore_case
self.editing_mode = editing_mode
self.erase_when_done = erase_when_done
+ self.reverse_vi_search_direction = reverse_vi_search_direction
def dummy_handler(cli):
" Dummy event handler. "
@@ -177,3 +181,12 @@ class Application(object):
self.on_buffer_changed = on_buffer_changed or dummy_handler
self.on_render = on_render or dummy_handler
self.on_invalidate = on_invalidate or dummy_handler
+
+ # List of 'extra' functions to execute before a CommandLineInterface.run.
+ # Note: It's important to keep this here, and not in the
+ # CommandLineInterface itself. shortcuts.run_application creates
+ # a new Application instance everytime. (Which is correct, it
+ # could be that we want to detach from one IO backend and attach
+ # the UI on a different backend.) But important is to keep as
+ # much state as possible between runs.
+ self.pre_run_callables = []
diff --git a/prompt_toolkit/buffer.py b/prompt_toolkit/buffer.py
index fc25db8..92bab8f 100644
--- a/prompt_toolkit/buffer.py
+++ b/prompt_toolkit/buffer.py
@@ -12,7 +12,7 @@ from .enums import IncrementalSearchDirection
from .filters import to_simple_filter
from .history import History, InMemoryHistory
from .search_state import SearchState
-from .selection import SelectionType, SelectionState
+from .selection import SelectionType, SelectionState, PasteMode
from .utils import Event
from .cache import FastDictCache
from .validation import ValidationError
@@ -21,6 +21,7 @@ from six.moves import range
import os
import re
+import shlex
import six
import subprocess
import tempfile
@@ -86,13 +87,27 @@ class AcceptAction(object):
def _return_document_handler(cli, buffer):
+ # Set return value.
cli.set_return_value(buffer.document)
+ # Make sure that if we run this UI again, that we reset this buffer, next
+ # time.
+ def reset_this_buffer():
+ buffer.reset()
+ cli.pre_run_callables.append(reset_this_buffer)
+
AcceptAction.RETURN_DOCUMENT = AcceptAction(_return_document_handler)
AcceptAction.IGNORE = AcceptAction(handler=None)
+class ValidationState(object):
+ " The validation state of a buffer. This is set after the validation. "
+ VALID = 'VALID'
+ INVALID = 'INVALID'
+ UNKNOWN = 'UNKNOWN'
+
+
class CompletionState(object):
"""
Immutable class that contains a completion state.
@@ -270,6 +285,7 @@ class Buffer(object):
# `ValidationError` instance. (Will be set when the input is wrong.)
self.validation_error = None
+ self.validation_state = ValidationState.UNKNOWN
# State of the selection.
self.selection_state = None
@@ -288,6 +304,10 @@ class Buffer(object):
# State of Emacs yank-nth-arg completion.
self.yank_nth_arg_state = None # for yank-nth-arg.
+ # Remember the document that we had *right before* the last paste
+ # operation. This is used for rotating through the kill ring.
+ self.document_before_paste = None
+
# Current suggestion.
self.suggestion = None
@@ -393,8 +413,10 @@ class Buffer(object):
def _text_changed(self):
# Remove any validation errors and complete state.
self.validation_error = None
+ self.validation_state = ValidationState.UNKNOWN
self.complete_state = None
self.yank_nth_arg_state = None
+ self.document_before_paste = None
self.selection_state = None
self.suggestion = None
self.preferred_column = None
@@ -405,8 +427,10 @@ class Buffer(object):
def _cursor_position_changed(self):
# Remove any validation errors and complete state.
self.validation_error = None
+ self.validation_state = ValidationState.UNKNOWN
self.complete_state = None
self.yank_nth_arg_state = None
+ self.document_before_paste = None
# Unset preferred_column. (Will be set after the cursor movement, if
# required.)
@@ -962,12 +986,19 @@ class Buffer(object):
"""
return self.copy_selection(_cut=True)
- def paste_clipboard_data(self, data, before=False, count=1):
+ def paste_clipboard_data(self, data, paste_mode=PasteMode.EMACS, count=1):
"""
Insert the data from the clipboard.
"""
assert isinstance(data, ClipboardData)
- self.document = self.document.paste_clipboard_data(data, before=before, count=count)
+ assert paste_mode in (PasteMode.VI_BEFORE, PasteMode.VI_AFTER, PasteMode.EMACS)
+
+ original_document = self.document
+ self.document = self.document.paste_clipboard_data(data, paste_mode=paste_mode, count=count)
+
+ # Remember original document. This assignment should come at the end,
+ # because assigning to 'document' will erase it.
+ self.document_before_paste = original_document
def newline(self, copy_margin=True):
"""
@@ -1062,7 +1093,10 @@ class Buffer(object):
"""
Returns `True` if valid.
"""
- self.validation_error = None
+ # Don't call the validator again, if it was already called for the
+ # current input.
+ if self.validation_state != ValidationState.UNKNOWN:
+ return self.validation_state == ValidationState.VALID
# Validate first. If not valid, set validation exception.
if self.validator:
@@ -1073,9 +1107,12 @@ class Buffer(object):
cursor_position = e.cursor_position
self.cursor_position = min(max(0, cursor_position), len(self.text))
+ self.validation_state = ValidationState.INVALID
self.validation_error = e
return False
+ self.validation_state = ValidationState.VALID
+ self.validation_error = None
return True
def append_to_history(self):
@@ -1260,11 +1297,13 @@ class Buffer(object):
Return True when we received a zero return code.
"""
- # If the 'EDITOR' environment variable has been set, use that one.
+ # If the 'VISUAL' or 'EDITOR' environment variable has been set, use that.
# Otherwise, fall back to the first available editor that we can find.
+ visual = os.environ.get('VISUAL')
editor = os.environ.get('EDITOR')
editors = [
+ visual,
editor,
# Order of preference.
@@ -1278,7 +1317,9 @@ class Buffer(object):
for e in editors:
if e:
try:
- returncode = subprocess.call([e, filename])
+ # Use 'shlex.split()', because $VISUAL can contain spaces
+ # and quotes.
+ returncode = subprocess.call(shlex.split(e) + [filename])
return returncode == 0
except OSError:
diff --git a/prompt_toolkit/clipboard/base.py b/prompt_toolkit/clipboard/base.py
index cd5adea..803c0b0 100644
--- a/prompt_toolkit/clipboard/base.py
+++ b/prompt_toolkit/clipboard/base.py
@@ -50,6 +50,11 @@ class Clipboard(with_metaclass(ABCMeta, object)):
assert isinstance(text, six.string_types)
self.set_data(ClipboardData(text))
+ def rotate(self):
+ """
+ For Emacs mode, rotate the kill ring.
+ """
+
@abstractmethod
def get_data(self):
"""
diff --git a/prompt_toolkit/clipboard/in_memory.py b/prompt_toolkit/clipboard/in_memory.py
index e7cd0ef..081666a 100644
--- a/prompt_toolkit/clipboard/in_memory.py
+++ b/prompt_toolkit/clipboard/in_memory.py
@@ -1,5 +1,7 @@
from .base import Clipboard, ClipboardData
+from collections import deque
+
__all__ = (
'InMemoryClipboard',
)
@@ -9,14 +11,32 @@ class InMemoryClipboard(Clipboard):
"""
Default clipboard implementation.
Just keep the data in memory.
+
+ This implements a kill-ring, for Emacs mode.
"""
- def __init__(self, data=None):
+ def __init__(self, data=None, max_size=60):
assert data is None or isinstance(data, ClipboardData)
- self._data = data
+ assert max_size >= 1
+
+ self.max_size = max_size
+ self._ring = deque()
+ if data is not None:
+ self.set_data(data)
def set_data(self, data):
assert isinstance(data, ClipboardData)
- self._data = data
+ self._ring.appendleft(data)
+
+ while len(self._ring) > self.max_size:
+ self._ring.pop()
def get_data(self):
- return self._data or ClipboardData()
+ if self._ring:
+ return self._ring[0]
+ else:
+ return ClipboardData()
+
+ def rotate(self):
+ if self._ring:
+ # Add the very first item at the end.
+ self._ring.append(self._ring.popleft())
diff --git a/prompt_toolkit/document.py b/prompt_toolkit/document.py
index 470ba27..25d817d 100644
--- a/prompt_toolkit/document.py
+++ b/prompt_toolkit/document.py
@@ -10,7 +10,7 @@ import string
import weakref
from six.moves import range, map
-from .selection import SelectionType, SelectionState
+from .selection import SelectionType, SelectionState, PasteMode
from .clipboard import ClipboardData
__all__ = ('Document',)
@@ -874,24 +874,30 @@ class Document(object):
else:
return self, ClipboardData('')
- def paste_clipboard_data(self, data, before=False, count=1):
+ def paste_clipboard_data(self, data, paste_mode=PasteMode.EMACS, count=1):
"""
Return a new :class:`.Document` instance which contains the result if
we would paste this data at the current cursor position.
- :param before: Paste before the cursor position. (For line/character mode.)
+ :param paste_mode: Where to paste. (Before/after/emacs.)
:param count: When >1, Paste multiple times.
"""
assert isinstance(data, ClipboardData)
+ assert paste_mode in (PasteMode.VI_BEFORE, PasteMode.VI_AFTER, PasteMode.EMACS)
+
+ before = (paste_mode == PasteMode.VI_BEFORE)
+ after = (paste_mode == PasteMode.VI_AFTER)
if data.type == SelectionType.CHARACTERS:
- if before:
- new_text = self.text_before_cursor + data.text * count + self.text_after_cursor
- new_cursor_position = self.cursor_position + len(data.text) * count - 1
- else:
+ if after:
new_text = (self.text[:self.cursor_position + 1] + data.text * count +
self.text[self.cursor_position + 1:])
- new_cursor_position = self.cursor_position + len(data.text) * count
+ else:
+ new_text = self.text_before_cursor + data.text * count + self.text_after_cursor
+
+ new_cursor_position = self.cursor_position + len(data.text) * count
+ if before:
+ new_cursor_position -= 1
elif data.type == SelectionType.LINES:
l = self.cursor_position_row
diff --git a/prompt_toolkit/eventloop/asyncio_posix.py b/prompt_toolkit/eventloop/asyncio_posix.py
index 72dff0d..426ed96 100644
--- a/prompt_toolkit/eventloop/asyncio_posix.py
+++ b/prompt_toolkit/eventloop/asyncio_posix.py
@@ -22,7 +22,7 @@ class PosixAsyncioEventLoop(EventLoop):
self.loop = loop or asyncio.get_event_loop()
self.closed = False
- self._stopped_f = asyncio.Future()
+ self._stopped_f = asyncio.Future(loop=self.loop)
@asyncio.coroutine
def run_as_coroutine(self, stdin, callbacks):
@@ -41,7 +41,7 @@ class PosixAsyncioEventLoop(EventLoop):
try:
# Create a new Future every time.
- self._stopped_f = asyncio.Future()
+ self._stopped_f = asyncio.Future(loop=self.loop)
# Handle input timouts
def timeout_handler():
diff --git a/prompt_toolkit/interface.py b/prompt_toolkit/interface.py
index 458c85d..898ac0e 100644
--- a/prompt_toolkit/interface.py
+++ b/prompt_toolkit/interface.py
@@ -87,6 +87,9 @@ class CommandLineInterface(object):
#: EditingMode.VI or EditingMode.EMACS
self.editing_mode = application.editing_mode
... 2619 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/prompt-toolkit.git
More information about the Python-modules-commits
mailing list