Skip to content

Commit 28cd9c8

Browse files
- (4 commits)
1 parent 024aac5 commit 28cd9c8

File tree

6 files changed

+71
-33
lines changed

6 files changed

+71
-33
lines changed

CHANGELOG

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,34 @@ Changes:
2020
are two different keys that can be handled independently. This is a big
2121
backward-incompatibility, because the `Enter` key is `ControlM`, not
2222
`ControlJ`. So, now that we stopped translating \r into \n, it could be that
23-
custom key bindings for `Enter` don't work anymore. Make sure to use
24-
`Keys.Enter` instead of `Keys.ControlJ` in the key bindings for handling the
25-
`Enter` key.
23+
custom key bindings for `Enter` don't work anymore. Make sure to bind
24+
`Keys.Enter` instead of `Keys.ControlJ` for handling the `Enter` key.
2625

2726
- The `CommandLineInterface` and the `Application` classes are merged. First,
2827
`CommandLineInterface` contained all the I/O objects (like the input, output
2928
and event loop), while the `Application` contained everything else. There was
3029
no practical reason to keep this separation. (`CommandLineInterface` was
3130
mostly a proxy to `Application`.)
3231

33-
A consequence is that all almost code which received a
32+
A consequence is that all almost code which used to received a
3433
`CommandLineInterface`, will now receive an `Application`. Usually, where we
3534
had an attribute `cli`, we'll now have an attribute `app`.
3635

3736
* `CLIFilter` will now take an `Application`, so it was renamed to `AppFilter`.
3837
* `to_cli_filter` was renamed to `to_app_filter`.
3938

39+
(For backwards-compatibility, we have aliases to the old names, whenever
40+
possible.)
41+
4042
- The `buffers` dictionary (`CommandLineInterface.buffers`) does not exist
4143
anymore. Further, `buffers` was a `BufferMapping` that keeps track of which
4244
buffer has the focus. This significantly reduces the freedom for creating
4345
complex applications. We wanted to move toward a layout that can be defined
44-
as a collection of and relation between user widgets. A user widget does not
45-
need to have a `Buffer` underneath and any widget should be focussable.
46+
as a (hierarchical) collection of user widgets. A user widget does not need
47+
to have a `Buffer` underneath and any widget should be focusable.
4648

47-
* `layout.focus.Focus` was introduced and `Application.focussed_control` was
48-
added.
49+
* `layout.Layout` was introduced to contain the root layout widget and keep
50+
track of the focus.
4951

5052
- The key bindings were refactored. It became much more flexible to combine
5153
sets of key bindings.
@@ -63,6 +65,15 @@ Changes:
6365
* `KeyBindingManager` has been removed completely.
6466
* `input_processor` was renamed to `key_processor`.
6567

68+
Further:
69+
70+
* The `Key` class does not exist anymore. Every key is a string and it's
71+
considered fine to use string literals in the key bindings. This is more
72+
readible, but we still have run-time validation. The `Keys` enum still
73+
exist (for backwards-compatibility, but also to have an overview of which
74+
keys are supported.)
75+
* 'enter' and 'tab' are key aliases for 'c-m' and 'c-i'.
76+
6677
- User controls can define key bindings, which are active when the user control
6778
is focussed.
6879

@@ -76,7 +87,7 @@ Changes:
7687
(TOP/CENTER/BOTTOM/JUSTIFY) or (LEFT/CENTER/RIGHT/JUSTIFY).
7788
* `Float` now takes `allow_cover_cursor` and `attach_to_window` arguments.
7889
* `Window` got an `Align` argument. This can be used for the alignment of the
79-
content. `TokenListControl` does not have an allignment argument anymore.
90+
content. `TokenListControl` does not have an alignment argument anymore.
8091
* `Window` got a `token` and `get_token` argument. This is used to fill the
8192
window's background using the given `Token`. That way, a window can for
8293
instance be given a background color.
@@ -90,17 +101,31 @@ Changes:
90101

91102
* `BufferControl` now takes a `input_processor` as argument. (Singular
92103
instead of plural). If you want to combine multiple, they have to be merged
93-
together using `merge_input_processors`.
104+
together using `merge_input_processors`. (Similar to `merge_key_bindings`.)
94105

95106
* The `InputProcessor` class has been refactored. The `apply_transformation`
96-
method should now accept a `TransformationInput` object.
107+
method should now takes a `TransformationInput` object as input.
97108

98109
* The text `(reverse-i-search)` is now displayed through a processor. (See
99110
the `shortcuts` module for an example of the usage.)
100111

112+
- `widgets` and `dialogs` modules:
113+
114+
* A small collection of widgets was added. These are more complex collections
115+
of user controls that are ready to embed in a layout. A `shortcuts.dialogs`
116+
module was added with shortcuts for displaying input, confirmation and
117+
message dialogs.
118+
119+
* Every class that exposes a ``__pt_container__`` method (which is supposed
120+
to return a ``Container`` instance) is considered a widget. The
121+
``to_container`` shortcut will call this method in situations where a
122+
``Container`` object is expected. This avoids inheritance from other
123+
``Container`` types, but also having to unpack the container object from
124+
the widget, in case we would have used composition.
125+
101126
- Changes related to `shortcuts.prompt`:
102127

103-
* There is now a class `Prompt` that which has a method `prompt`. Both the
128+
* There is now a class `Prompt` which also has a method `prompt`. Both the
104129
class and the method take about the same arguments. This can be used to
105130
create a session. Every `prompt` call of the same instance will reuse all
106131
the arguments given to the class itself. This can be used for instance to
@@ -111,6 +136,7 @@ Changes:
111136

112137
* The `prompt` function now takes an `extra_key_bindings` argument instead of
113138
`key_bindings_registry`. This should only contain the additional bindings.
139+
(The default bindings are always included.)
114140

115141
- Changes to the event loops:
116142

@@ -123,9 +149,9 @@ Changes:
123149
event loop until the `Future` is set and returns that result.
124150

125151
* The asyncio adaptors (like the asyncio event loop integration) now require
126-
Python 3.5.
152+
Python 3.5. (We use the async/await syntax internally.)
127153

128-
* The `Input` and `Output` classes has some changes. (Not really important.)
154+
* The `Input` and `Output` classes have some changes. (Not really important.)
129155

130156
- Changes to the `filters` module:
131157

@@ -153,14 +179,9 @@ Changes:
153179

154180
* `to_container` and `to_window` utilities were added.
155181

156-
* Added a small collection of widgets. These are more complex collections of
157-
user controls that are ready to embed in a layout.
158-
159182
****
160183
- `run_sub_applications` returns a future instead of taking a callback.
161184

162-
- Key() object does not exist anymore. Keys are all strings.
163-
164185

165186

166187
- Deprecated

prompt_toolkit/application.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -457,17 +457,19 @@ def read_from_input():
457457

458458
def auto_flush_input():
459459
# Flush input after timeout.
460+
# (Used for flushing the enter key.)
460461
time.sleep(self.input_timeout)
461462
loop.call_from_executor(flush_input)
462463

463464
def flush_input():
464-
# Get keys, and feed to key processor.
465-
keys = self.input.flush_keys()
466-
self.key_processor.feed_multiple(keys)
467-
self.key_processor.process_keys()
468-
469-
if self.input.closed:
470-
f.set_exception(EOFError)
465+
if not self.is_done:
466+
# Get keys, and feed to key processor.
467+
keys = self.input.flush_keys()
468+
self.key_processor.feed_multiple(keys)
469+
self.key_processor.process_keys()
470+
471+
if self.input.closed:
472+
f.set_exception(EOFError)
471473

472474
# Set event loop handlers.
473475
previous_input, previous_cb = loop.set_input(self.input, read_from_input)

prompt_toolkit/layout/containers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1038,9 +1038,9 @@ class Window(Container):
10381038
if `cursorcolumn` is True.
10391039
:param align: alignment of content.
10401040
:param token: If given, apply this token to all of the cells in this window.
1041-
:param char: Character to be used for filling the background.
10421041
:param get_token: Callable that takes an `Application` and returns the token
10431042
to be applied to all the cells in this window.
1043+
:param char: Character to be used for filling the background.
10441044
:param transparent: When `False`, first erase everything underneath. (This
10451045
is mainly useful if this Window is displayed inside a `Float`.)
10461046
(when `char` or `get_char` is geven, it will never be transparant

prompt_toolkit/layout/widgets/base.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def __init__(self, text='', multiline=True, password=False,
8585
focussable=True, wrap_lines=True,
8686
width=None, height=None,
8787
dont_extend_height=False, dont_extend_width=False,
88-
scrollbar=False, token=Token, loop=None):
88+
scrollbar=False, token=Token, loop=None, _label=False):
8989
assert isinstance(text, six.text_type)
9090
assert loop is None or isinstance(loop, EventLoop)
9191

@@ -117,13 +117,17 @@ def __init__(self, text='', multiline=True, password=False,
117117
height = D.exact(1)
118118
margins = []
119119

120+
if not _label:
121+
# (In case of a Label, we don't want to apply the TextArea token.)
122+
token = Token.TextArea | token
123+
120124
self.window = Window(
121125
height=height,
122126
width=width,
123127
dont_extend_height=dont_extend_height,
124128
dont_extend_width=dont_extend_width,
125129
content=self.control,
126-
token=Token.TextArea|token,
130+
token=token,
127131
wrap_lines=wrap_lines,
128132
right_margins=margins)
129133

@@ -158,18 +162,26 @@ def __init__(self, text, token=Token, width=None, loop=None,
158162
longest_line = max(get_cwidth(line) for line in text.splitlines())
159163
width = D(preferred=longest_line)
160164

161-
162165
self.text_area = TextArea(
163166
text=text,
164167
width=width,
165168
token=Token.Label | token,
166169
focussable=False,
167170
dont_extend_height=dont_extend_height,
168171
dont_extend_width=dont_extend_width,
169-
loop=loop)
172+
loop=loop,
173+
_label=True)
170174

171175
loop = loop or get_event_loop()
172176

177+
@property
178+
def text(self):
179+
return self.text_area.buffer.text
180+
181+
@text.setter
182+
def text(self, value):
183+
self.text_area.buffer.text = value
184+
173185
def __pt_container__(self):
174186
return self.text_area
175187

@@ -534,7 +546,7 @@ def percentage(self):
534546
def percentage(self, value):
535547
assert isinstance(value, int)
536548
self._percentage = value
537-
self.label.buffer.text = '{}%'.format(value)
549+
self.label.text = '{}%'.format(value)
538550

539551
def __pt_container__(self):
540552
return self.container

prompt_toolkit/shortcuts/prompt.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ def __init__(
253253
assert extra_key_bindings is None or isinstance(extra_key_bindings, KeyBindingsBase)
254254

255255
# Defaults.
256+
self._close_loop = loop is None
256257
loop = loop or create_event_loop()
257258

258259
output = output or create_output(true_color)
@@ -687,7 +688,8 @@ def _get_title(self):
687688
return self.get_title()
688689

689690
def close(self):
690-
return#self.loop.close()
691+
if self._close_loop:
692+
self.loop.close()
691693

692694

693695
def prompt(*a, **kw):

tests/test_cli.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def _feed_cli_with_input(
5353

5454
finally:
5555
inp.close()
56+
p.close()
5657

5758

5859
def test_simple_text_input():

0 commit comments

Comments
 (0)