Skip to content

Commit adb6bf5

Browse files
Several improvements for TextArea.
New attributes: auto_suggest, complete_wile_typing, history, get_line_prefix. Several attributes became writable: lexer, completer, complete_while_typing, accept_handler, read_only, wrap_lines.
1 parent 451266e commit adb6bf5

File tree

1 file changed

+87
-33
lines changed

1 file changed

+87
-33
lines changed

prompt_toolkit/widgets/base.py

Lines changed: 87 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
import six
1818

1919
from prompt_toolkit.application.current import get_app
20+
from prompt_toolkit.auto_suggest import DynamicAutoSuggest
2021
from prompt_toolkit.buffer import Buffer
22+
from prompt_toolkit.completion import DynamicCompleter
2123
from prompt_toolkit.document import Document
22-
from prompt_toolkit.filters import to_filter, Condition
24+
from prompt_toolkit.filters import to_filter, Condition, is_true, has_focus, is_done
2325
from prompt_toolkit.formatted_text import to_formatted_text, Template, is_formatted_text
2426
from prompt_toolkit.formatted_text.utils import fragment_list_to_text
2527
from prompt_toolkit.key_binding.key_bindings import KeyBindings
@@ -28,7 +30,8 @@
2830
from prompt_toolkit.layout.dimension import Dimension as D
2931
from prompt_toolkit.layout.dimension import is_dimension, to_dimension
3032
from prompt_toolkit.layout.margins import ScrollbarMargin, NumberedMargin
31-
from prompt_toolkit.layout.processors import PasswordProcessor, ConditionalProcessor, BeforeInput
33+
from prompt_toolkit.layout.processors import PasswordProcessor, ConditionalProcessor, BeforeInput, AppendAutoSuggestion
34+
from prompt_toolkit.lexers import DynamicLexer
3235
from prompt_toolkit.mouse_events import MouseEventType
3336
from prompt_toolkit.utils import get_cwidth
3437
from prompt_toolkit.keys import Keys
@@ -66,46 +69,66 @@ class TextArea(object):
6669
"""
6770
A simple input field.
6871
69-
This contains a ``prompt_toolkit`` :class:`~prompt_toolkit.buffer.Buffer`
70-
object that hold the text data structure for the edited buffer, the
71-
:class:`~prompt_toolkit.layout.BufferControl`, which applies a
72-
:class:`~prompt_toolkit.lexers.Lexer` to the text and turns it into a
73-
:class:`~prompt_toolkit.layout.UIControl`, and finally, this
74-
:class:`~prompt_toolkit.layout.UIControl` is wrapped in a
75-
:class:`~prompt_toolkit.layout.Window` object (just like any
76-
:class:`~prompt_toolkit.layout.UIControl`), which is responsible for the
77-
scrolling.
78-
79-
This widget does have some options, but it does not intend to cover every
80-
single use case. For more configurations options, you can always build a
81-
text area manually, using a :class:`~prompt_toolkit.buffer.Buffer`,
72+
This is a higher level abstraction on top of several other classes with
73+
sane defaults.
74+
75+
This widget does have the most common options, but it does not intend to
76+
cover every single use case. For more configurations options, you can
77+
always build a text area manually, using a
78+
:class:`~prompt_toolkit.buffer.Buffer`,
8279
:class:`~prompt_toolkit.layout.BufferControl` and
8380
:class:`~prompt_toolkit.layout.Window`.
8481
82+
Buffer attributes:
83+
8584
:param text: The initial text.
8685
:param multiline: If True, allow multiline input.
87-
:param lexer: :class:`~prompt_toolkit.lexers.Lexer` instance for syntax highlighting.
88-
:param completer: :class:`~prompt_toolkit.completion.Completer` instance for auto completion.
86+
:param completer: :class:`~prompt_toolkit.completion.Completer` instance
87+
for auto completion.
88+
:param complete_while_typing: Boolean.
89+
:param accept_handler: Called when `Enter` is pressed (This should be a
90+
callable that takes a buffer as input).
91+
:param history: :class:`~prompt_toolkit.history.History` instance.
92+
:param auto_suggest: :class:`~prompt_toolkit.auto_suggest.AutoSuggest`
93+
instance for input suggestions.
94+
95+
BufferControl attributes:
96+
97+
:param password: When `True`, display using asterisks.
8998
:param focusable: When `True`, allow this widget to receive the focus.
9099
:param focus_on_click: When `True`, focus after mouse click.
100+
101+
Window attributes:
102+
103+
:param lexer: :class:`~prompt_toolkit.lexers.Lexer` instance for syntax
104+
highlighting.
91105
:param wrap_lines: When `True`, don't scroll horizontally, but wrap lines.
92106
:param width: Window width. (:class:`~prompt_toolkit.layout.Dimension` object.)
93107
:param height: Window height. (:class:`~prompt_toolkit.layout.Dimension` object.)
94-
:param password: When `True`, display using asterisks.
95-
:param accept_handler: Called when `Enter` is pressed.
96108
:param scrollbar: When `True`, display a scroll bar.
97-
:param search_field: An optional `SearchToolbar` object.
98109
:param style: A style string.
99-
:param dont_extend_height:
100-
:param dont_extend_width:
110+
:param dont_extend_width: When `True`, don't take up more width then the
111+
preferred width reported by the control.
112+
:param dont_extend_height: When `True`, don't take up more width then the
113+
preferred height reported by the control.
114+
:param get_line_prefix: None or a callable that returns formatted text to
115+
be inserted before a line. It takes a line number (int) and a
116+
wrap_count and returns formatted text. This can be used for
117+
implementation of line continuations, things like Vim "breakindent" and
118+
so on.
119+
120+
Other attributes:
121+
122+
:param search_field: An optional `SearchToolbar` object.
101123
"""
102124
def __init__(self, text='', multiline=True, password=False,
103-
lexer=None, completer=None, accept_handler=None,
125+
lexer=None, auto_suggest=None, completer=None,
126+
complete_while_typing=True, accept_handler=None, history=None,
104127
focusable=True, focus_on_click=False, wrap_lines=True,
105128
read_only=False, width=None, height=None,
106129
dont_extend_height=False, dont_extend_width=False,
107-
line_numbers=False, scrollbar=False, style='',
108-
search_field=None, preview_search=True, prompt=''):
130+
line_numbers=False, get_line_prefix=None, scrollbar=False,
131+
style='', search_field=None, preview_search=True, prompt=''):
109132
assert isinstance(text, six.text_type)
110133
assert search_field is None or isinstance(search_field, SearchToolbar)
111134

@@ -114,18 +137,32 @@ def __init__(self, text='', multiline=True, password=False,
114137
elif isinstance(search_field, SearchToolbar):
115138
search_control = search_field.control
116139

140+
# Writeable attributes.
141+
self.completer = completer
142+
self.complete_while_typing = complete_while_typing
143+
self.lexer = lexer
144+
self.auto_suggest = auto_suggest
145+
self.read_only = read_only
146+
self.wrap_lines = wrap_lines
147+
117148
self.buffer = Buffer(
118149
document=Document(text, 0),
119150
multiline=multiline,
120-
read_only=read_only,
121-
completer=completer,
122-
complete_while_typing=True,
123-
accept_handler=(lambda buff: accept_handler(buff)) if accept_handler else None)
151+
read_only=Condition(lambda: is_true(self.read_only)),
152+
completer=DynamicCompleter(lambda: self.completer),
153+
complete_while_typing=Condition(
154+
lambda: is_true(self.complete_while_typing)),
155+
auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
156+
accept_handler=accept_handler,
157+
history=history)
124158

125159
self.control = BufferControl(
126160
buffer=self.buffer,
127-
lexer=lexer,
161+
lexer=DynamicLexer(lambda: self.lexer),
128162
input_processors=[
163+
ConditionalProcessor(
164+
AppendAutoSuggestion(),
165+
has_focus(self.buffer) & ~is_done),
129166
ConditionalProcessor(
130167
processor=PasswordProcessor(),
131168
filter=to_filter(password)
@@ -147,7 +184,6 @@ def __init__(self, text='', multiline=True, password=False,
147184
else:
148185
left_margins = []
149186
else:
150-
wrap_lines = False # Never wrap for single line input.
151187
height = D.exact(1)
152188
left_margins = []
153189
right_margins = []
@@ -161,12 +197,16 @@ def __init__(self, text='', multiline=True, password=False,
161197
dont_extend_width=dont_extend_width,
162198
content=self.control,
163199
style=style,
164-
wrap_lines=wrap_lines,
200+
wrap_lines=Condition(lambda: is_true(self.wrap_lines)),
165201
left_margins=left_margins,
166-
right_margins=right_margins)
202+
right_margins=right_margins,
203+
get_line_prefix=get_line_prefix)
167204

168205
@property
169206
def text(self):
207+
"""
208+
The `Buffer` text.
209+
"""
170210
return self.buffer.text
171211

172212
@text.setter
@@ -175,12 +215,26 @@ def text(self, value):
175215

176216
@property
177217
def document(self):
218+
"""
219+
The `Buffer` document (text + cursor position).
220+
"""
178221
return self.buffer.document
179222

180223
@document.setter
181224
def document(self, value):
182225
self.buffer.document = value
183226

227+
@property
228+
def accept_handler(self):
229+
"""
230+
The accept handler. Called when the user accepts the input.
231+
"""
232+
return self.buffer.accept_handler
233+
234+
@accept_handler.setter
235+
def accept_handler(self, value):
236+
self.buffer.accept_handler = value
237+
184238
def __pt_container__(self):
185239
return self.window
186240

0 commit comments

Comments
 (0)