You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.6 KiB
80 lines
2.6 KiB
r"""
|
|
Store input key strokes if we did read more than was required.
|
|
|
|
The input classes `Vt100Input` and `Win32Input` read the input text in chunks
|
|
of a few kilobytes. This means that if we read input from stdin, it could be
|
|
that we read a couple of lines (with newlines in between) at once.
|
|
|
|
This creates a problem: potentially, we read too much from stdin. Sometimes
|
|
people paste several lines at once because they paste input in a REPL and
|
|
expect each input() call to process one line. Or they rely on type ahead
|
|
because the application can't keep up with the processing.
|
|
|
|
However, we need to read input in bigger chunks. We need this mostly to support
|
|
pasting of larger chunks of text. We don't want everything to become
|
|
unresponsive because we:
|
|
- read one character;
|
|
- parse one character;
|
|
- call the key binding, which does a string operation with one character;
|
|
- and render the user interface.
|
|
Doing text operations on single characters is very inefficient in Python, so we
|
|
prefer to work on bigger chunks of text. This is why we have to read the input
|
|
in bigger chunks.
|
|
|
|
Further, line buffering is also not an option, because it doesn't work well in
|
|
the architecture. We use lower level Posix APIs, that work better with the
|
|
event loop and so on. In fact, there is also nothing that defines that only \n
|
|
can accept the input, you could create a key binding for any key to accept the
|
|
input.
|
|
|
|
To support type ahead, this module will store all the key strokes that were
|
|
read too early, so that they can be feed into to the next `prompt()` call or to
|
|
the next prompt_toolkit `Application`.
|
|
"""
|
|
from __future__ import unicode_literals
|
|
from collections import defaultdict
|
|
from .base import Input
|
|
|
|
__all__ = [
|
|
'store_typeahead',
|
|
'get_typeahead',
|
|
'clear_typeahead',
|
|
]
|
|
|
|
_buffer = defaultdict(list) # input hash -> list of key presses.
|
|
|
|
|
|
def store_typeahead(input_obj, key_presses):
|
|
"""
|
|
Insert typeahead key presses for the given input.
|
|
"""
|
|
assert isinstance(input_obj, Input)
|
|
assert isinstance(key_presses, list)
|
|
|
|
global _buffer
|
|
key = input_obj.typeahead_hash()
|
|
_buffer[key].extend(key_presses)
|
|
|
|
|
|
def get_typeahead(input_obj):
|
|
"""
|
|
Retrieve typeahead and reset the buffer for this input.
|
|
"""
|
|
assert isinstance(input_obj, Input)
|
|
global _buffer
|
|
|
|
key = input_obj.typeahead_hash()
|
|
result = _buffer[key]
|
|
_buffer[key] = []
|
|
return result
|
|
|
|
|
|
def clear_typeahead(input_obj):
|
|
"""
|
|
Clear typeahead buffer.
|
|
"""
|
|
assert isinstance(input_obj, Input)
|
|
global _buffer
|
|
key = input_obj.typeahead_hash()
|
|
_buffer[key] = []
|