Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/prompt_toolkit/filters/app.py: 45%
173 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
1"""
2Filters that accept a `Application` as argument.
3"""
4from __future__ import annotations
6from typing import TYPE_CHECKING, cast
8from prompt_toolkit.application.current import get_app
9from prompt_toolkit.cache import memoized
10from prompt_toolkit.enums import EditingMode
12from .base import Condition
14if TYPE_CHECKING:
15 from prompt_toolkit.layout.layout import FocusableElement
18__all__ = [
19 "has_arg",
20 "has_completions",
21 "completion_is_selected",
22 "has_focus",
23 "buffer_has_focus",
24 "has_selection",
25 "has_suggestion",
26 "has_validation_error",
27 "is_done",
28 "is_read_only",
29 "is_multiline",
30 "renderer_height_is_known",
31 "in_editing_mode",
32 "in_paste_mode",
33 "vi_mode",
34 "vi_navigation_mode",
35 "vi_insert_mode",
36 "vi_insert_multiple_mode",
37 "vi_replace_mode",
38 "vi_selection_mode",
39 "vi_waiting_for_text_object_mode",
40 "vi_digraph_mode",
41 "vi_recording_macro",
42 "emacs_mode",
43 "emacs_insert_mode",
44 "emacs_selection_mode",
45 "shift_selection_mode",
46 "is_searching",
47 "control_is_searchable",
48 "vi_search_direction_reversed",
49]
52# NOTE: `has_focus` below should *not* be `memoized`. It can reference any user
53# control. For instance, if we would continuously create new
54# `PromptSession` instances, then previous instances won't be released,
55# because this memoize (which caches results in the global scope) will
56# still refer to each instance.
57def has_focus(value: FocusableElement) -> Condition:
58 """
59 Enable when this buffer has the focus.
60 """
61 from prompt_toolkit.buffer import Buffer
62 from prompt_toolkit.layout import walk
63 from prompt_toolkit.layout.containers import Container, Window, to_container
64 from prompt_toolkit.layout.controls import UIControl
66 if isinstance(value, str):
68 def test() -> bool:
69 return get_app().current_buffer.name == value
71 elif isinstance(value, Buffer):
73 def test() -> bool:
74 return get_app().current_buffer == value
76 elif isinstance(value, UIControl):
78 def test() -> bool:
79 return get_app().layout.current_control == value
81 else:
82 value = to_container(value)
84 if isinstance(value, Window):
86 def test() -> bool:
87 return get_app().layout.current_window == value
89 else:
91 def test() -> bool:
92 # Consider focused when any window inside this container is
93 # focused.
94 current_window = get_app().layout.current_window
96 for c in walk(cast(Container, value)):
97 if isinstance(c, Window) and c == current_window:
98 return True
99 return False
101 @Condition
102 def has_focus_filter() -> bool:
103 return test()
105 return has_focus_filter
108@Condition
109def buffer_has_focus() -> bool:
110 """
111 Enabled when the currently focused control is a `BufferControl`.
112 """
113 return get_app().layout.buffer_has_focus
116@Condition
117def has_selection() -> bool:
118 """
119 Enable when the current buffer has a selection.
120 """
121 return bool(get_app().current_buffer.selection_state)
124@Condition
125def has_suggestion() -> bool:
126 """
127 Enable when the current buffer has a suggestion.
128 """
129 buffer = get_app().current_buffer
130 return buffer.suggestion is not None and buffer.suggestion.text != ""
133@Condition
134def has_completions() -> bool:
135 """
136 Enable when the current buffer has completions.
137 """
138 state = get_app().current_buffer.complete_state
139 return state is not None and len(state.completions) > 0
142@Condition
143def completion_is_selected() -> bool:
144 """
145 True when the user selected a completion.
146 """
147 complete_state = get_app().current_buffer.complete_state
148 return complete_state is not None and complete_state.current_completion is not None
151@Condition
152def is_read_only() -> bool:
153 """
154 True when the current buffer is read only.
155 """
156 return get_app().current_buffer.read_only()
159@Condition
160def is_multiline() -> bool:
161 """
162 True when the current buffer has been marked as multiline.
163 """
164 return get_app().current_buffer.multiline()
167@Condition
168def has_validation_error() -> bool:
169 "Current buffer has validation error."
170 return get_app().current_buffer.validation_error is not None
173@Condition
174def has_arg() -> bool:
175 "Enable when the input processor has an 'arg'."
176 return get_app().key_processor.arg is not None
179@Condition
180def is_done() -> bool:
181 """
182 True when the CLI is returning, aborting or exiting.
183 """
184 return get_app().is_done
187@Condition
188def renderer_height_is_known() -> bool:
189 """
190 Only True when the renderer knows it's real height.
192 (On VT100 terminals, we have to wait for a CPR response, before we can be
193 sure of the available height between the cursor position and the bottom of
194 the terminal. And usually it's nicer to wait with drawing bottom toolbars
195 until we receive the height, in order to avoid flickering -- first drawing
196 somewhere in the middle, and then again at the bottom.)
197 """
198 return get_app().renderer.height_is_known
201@memoized()
202def in_editing_mode(editing_mode: EditingMode) -> Condition:
203 """
204 Check whether a given editing mode is active. (Vi or Emacs.)
205 """
207 @Condition
208 def in_editing_mode_filter() -> bool:
209 return get_app().editing_mode == editing_mode
211 return in_editing_mode_filter
214@Condition
215def in_paste_mode() -> bool:
216 return get_app().paste_mode()
219@Condition
220def vi_mode() -> bool:
221 return get_app().editing_mode == EditingMode.VI
224@Condition
225def vi_navigation_mode() -> bool:
226 """
227 Active when the set for Vi navigation key bindings are active.
228 """
229 from prompt_toolkit.key_binding.vi_state import InputMode
231 app = get_app()
233 if (
234 app.editing_mode != EditingMode.VI
235 or app.vi_state.operator_func
236 or app.vi_state.waiting_for_digraph
237 or app.current_buffer.selection_state
238 ):
239 return False
241 return (
242 app.vi_state.input_mode == InputMode.NAVIGATION
243 or app.vi_state.temporary_navigation_mode
244 or app.current_buffer.read_only()
245 )
248@Condition
249def vi_insert_mode() -> bool:
250 from prompt_toolkit.key_binding.vi_state import InputMode
252 app = get_app()
254 if (
255 app.editing_mode != EditingMode.VI
256 or app.vi_state.operator_func
257 or app.vi_state.waiting_for_digraph
258 or app.current_buffer.selection_state
259 or app.vi_state.temporary_navigation_mode
260 or app.current_buffer.read_only()
261 ):
262 return False
264 return app.vi_state.input_mode == InputMode.INSERT
267@Condition
268def vi_insert_multiple_mode() -> bool:
269 from prompt_toolkit.key_binding.vi_state import InputMode
271 app = get_app()
273 if (
274 app.editing_mode != EditingMode.VI
275 or app.vi_state.operator_func
276 or app.vi_state.waiting_for_digraph
277 or app.current_buffer.selection_state
278 or app.vi_state.temporary_navigation_mode
279 or app.current_buffer.read_only()
280 ):
281 return False
283 return app.vi_state.input_mode == InputMode.INSERT_MULTIPLE
286@Condition
287def vi_replace_mode() -> bool:
288 from prompt_toolkit.key_binding.vi_state import InputMode
290 app = get_app()
292 if (
293 app.editing_mode != EditingMode.VI
294 or app.vi_state.operator_func
295 or app.vi_state.waiting_for_digraph
296 or app.current_buffer.selection_state
297 or app.vi_state.temporary_navigation_mode
298 or app.current_buffer.read_only()
299 ):
300 return False
302 return app.vi_state.input_mode == InputMode.REPLACE
305@Condition
306def vi_replace_single_mode() -> bool:
307 from prompt_toolkit.key_binding.vi_state import InputMode
309 app = get_app()
311 if (
312 app.editing_mode != EditingMode.VI
313 or app.vi_state.operator_func
314 or app.vi_state.waiting_for_digraph
315 or app.current_buffer.selection_state
316 or app.vi_state.temporary_navigation_mode
317 or app.current_buffer.read_only()
318 ):
319 return False
321 return app.vi_state.input_mode == InputMode.REPLACE_SINGLE
324@Condition
325def vi_selection_mode() -> bool:
326 app = get_app()
327 if app.editing_mode != EditingMode.VI:
328 return False
330 return bool(app.current_buffer.selection_state)
333@Condition
334def vi_waiting_for_text_object_mode() -> bool:
335 app = get_app()
336 if app.editing_mode != EditingMode.VI:
337 return False
339 return app.vi_state.operator_func is not None
342@Condition
343def vi_digraph_mode() -> bool:
344 app = get_app()
345 if app.editing_mode != EditingMode.VI:
346 return False
348 return app.vi_state.waiting_for_digraph
351@Condition
352def vi_recording_macro() -> bool:
353 "When recording a Vi macro."
354 app = get_app()
355 if app.editing_mode != EditingMode.VI:
356 return False
358 return app.vi_state.recording_register is not None
361@Condition
362def emacs_mode() -> bool:
363 "When the Emacs bindings are active."
364 return get_app().editing_mode == EditingMode.EMACS
367@Condition
368def emacs_insert_mode() -> bool:
369 app = get_app()
370 if (
371 app.editing_mode != EditingMode.EMACS
372 or app.current_buffer.selection_state
373 or app.current_buffer.read_only()
374 ):
375 return False
376 return True
379@Condition
380def emacs_selection_mode() -> bool:
381 app = get_app()
382 return bool(
383 app.editing_mode == EditingMode.EMACS and app.current_buffer.selection_state
384 )
387@Condition
388def shift_selection_mode() -> bool:
389 app = get_app()
390 return bool(
391 app.current_buffer.selection_state
392 and app.current_buffer.selection_state.shift_mode
393 )
396@Condition
397def is_searching() -> bool:
398 "When we are searching."
399 app = get_app()
400 return app.layout.is_searching
403@Condition
404def control_is_searchable() -> bool:
405 "When the current UIControl is searchable."
406 from prompt_toolkit.layout.controls import BufferControl
408 control = get_app().layout.current_control
410 return (
411 isinstance(control, BufferControl) and control.search_buffer_control is not None
412 )
415@Condition
416def vi_search_direction_reversed() -> bool:
417 "When the '/' and '?' key bindings for Vi-style searching have been reversed."
418 return get_app().reverse_vi_search_direction()