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