aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/layout.py
diff options
context:
space:
mode:
authormonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
committermonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
commit06e5c21a835c0e923506c4ff27929f34e00761c2 (patch)
tree75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/layout.py
parent03f024c4412e3aa613bb543cf1660176320ba8f4 (diff)
downloadydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz
fix ya.make
Diffstat (limited to 'contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/layout.py')
-rw-r--r--contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/layout.py411
1 files changed, 0 insertions, 411 deletions
diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/layout.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/layout.py
deleted file mode 100644
index 62a3184ee2..0000000000
--- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/layout/layout.py
+++ /dev/null
@@ -1,411 +0,0 @@
-"""
-Wrapper for the layout.
-"""
-from typing import Dict, Generator, Iterable, List, Optional, Union
-
-from prompt_toolkit.buffer import Buffer
-
-from .containers import (
- AnyContainer,
- ConditionalContainer,
- Container,
- Window,
- to_container,
-)
-from .controls import BufferControl, SearchBufferControl, UIControl
-
-__all__ = [
- "Layout",
- "InvalidLayoutError",
- "walk",
-]
-
-FocusableElement = Union[str, Buffer, UIControl, AnyContainer]
-
-
-class Layout:
- """
- The layout for a prompt_toolkit
- :class:`~prompt_toolkit.application.Application`.
- This also keeps track of which user control is focused.
-
- :param container: The "root" container for the layout.
- :param focused_element: element to be focused initially. (Can be anything
- the `focus` function accepts.)
- """
-
- def __init__(
- self,
- container: AnyContainer,
- focused_element: Optional[FocusableElement] = None,
- ) -> None:
-
- self.container = to_container(container)
- self._stack: List[Window] = []
-
- # Map search BufferControl back to the original BufferControl.
- # This is used to keep track of when exactly we are searching, and for
- # applying the search.
- # When a link exists in this dictionary, that means the search is
- # currently active.
- # Map: search_buffer_control -> original buffer control.
- self.search_links: Dict[SearchBufferControl, BufferControl] = {}
-
- # Mapping that maps the children in the layout to their parent.
- # This relationship is calculated dynamically, each time when the UI
- # is rendered. (UI elements have only references to their children.)
- self._child_to_parent: Dict[Container, Container] = {}
-
- if focused_element is None:
- try:
- self._stack.append(next(self.find_all_windows()))
- except StopIteration as e:
- raise InvalidLayoutError(
- "Invalid layout. The layout does not contain any Window object."
- ) from e
- else:
- self.focus(focused_element)
-
- # List of visible windows.
- self.visible_windows: List[Window] = [] # List of `Window` objects.
-
- def __repr__(self) -> str:
- return f"Layout({self.container!r}, current_window={self.current_window!r})"
-
- def find_all_windows(self) -> Generator[Window, None, None]:
- """
- Find all the :class:`.UIControl` objects in this layout.
- """
- for item in self.walk():
- if isinstance(item, Window):
- yield item
-
- def find_all_controls(self) -> Iterable[UIControl]:
- for container in self.find_all_windows():
- yield container.content
-
- def focus(self, value: FocusableElement) -> None:
- """
- Focus the given UI element.
-
- `value` can be either:
-
- - a :class:`.UIControl`
- - a :class:`.Buffer` instance or the name of a :class:`.Buffer`
- - a :class:`.Window`
- - Any container object. In this case we will focus the :class:`.Window`
- from this container that was focused most recent, or the very first
- focusable :class:`.Window` of the container.
- """
- # BufferControl by buffer name.
- if isinstance(value, str):
- for control in self.find_all_controls():
- if isinstance(control, BufferControl) and control.buffer.name == value:
- self.focus(control)
- return
- raise ValueError(f"Couldn't find Buffer in the current layout: {value!r}.")
-
- # BufferControl by buffer object.
- elif isinstance(value, Buffer):
- for control in self.find_all_controls():
- if isinstance(control, BufferControl) and control.buffer == value:
- self.focus(control)
- return
- raise ValueError(f"Couldn't find Buffer in the current layout: {value!r}.")
-
- # Focus UIControl.
- elif isinstance(value, UIControl):
- if value not in self.find_all_controls():
- raise ValueError(
- "Invalid value. Container does not appear in the layout."
- )
- if not value.is_focusable():
- raise ValueError("Invalid value. UIControl is not focusable.")
-
- self.current_control = value
-
- # Otherwise, expecting any Container object.
- else:
- value = to_container(value)
-
- if isinstance(value, Window):
- # This is a `Window`: focus that.
- if value not in self.find_all_windows():
- raise ValueError(
- "Invalid value. Window does not appear in the layout: %r"
- % (value,)
- )
-
- self.current_window = value
- else:
- # Focus a window in this container.
- # If we have many windows as part of this container, and some
- # of them have been focused before, take the last focused
- # item. (This is very useful when the UI is composed of more
- # complex sub components.)
- windows = []
- for c in walk(value, skip_hidden=True):
- if isinstance(c, Window) and c.content.is_focusable():
- windows.append(c)
-
- # Take the first one that was focused before.
- for w in reversed(self._stack):
- if w in windows:
- self.current_window = w
- return
-
- # None was focused before: take the very first focusable window.
- if windows:
- self.current_window = windows[0]
- return
-
- raise ValueError(
- f"Invalid value. Container cannot be focused: {value!r}"
- )
-
- def has_focus(self, value: FocusableElement) -> bool:
- """
- Check whether the given control has the focus.
- :param value: :class:`.UIControl` or :class:`.Window` instance.
- """
- if isinstance(value, str):
- if self.current_buffer is None:
- return False
- return self.current_buffer.name == value
- if isinstance(value, Buffer):
- return self.current_buffer == value
- if isinstance(value, UIControl):
- return self.current_control == value
- else:
- value = to_container(value)
- if isinstance(value, Window):
- return self.current_window == value
- else:
- # Check whether this "container" is focused. This is true if
- # one of the elements inside is focused.
- for element in walk(value):
- if element == self.current_window:
- return True
- return False
-
- @property
- def current_control(self) -> UIControl:
- """
- Get the :class:`.UIControl` to currently has the focus.
- """
- return self._stack[-1].content
-
- @current_control.setter
- def current_control(self, control: UIControl) -> None:
- """
- Set the :class:`.UIControl` to receive the focus.
- """
- for window in self.find_all_windows():
- if window.content == control:
- self.current_window = window
- return
-
- raise ValueError("Control not found in the user interface.")
-
- @property
- def current_window(self) -> Window:
- "Return the :class:`.Window` object that is currently focused."
- return self._stack[-1]
-
- @current_window.setter
- def current_window(self, value: Window) -> None:
- "Set the :class:`.Window` object to be currently focused."
- self._stack.append(value)
-
- @property
- def is_searching(self) -> bool:
- "True if we are searching right now."
- return self.current_control in self.search_links
-
- @property
- def search_target_buffer_control(self) -> Optional[BufferControl]:
- """
- Return the :class:`.BufferControl` in which we are searching or `None`.
- """
- # Not every `UIControl` is a `BufferControl`. This only applies to
- # `BufferControl`.
- control = self.current_control
-
- if isinstance(control, SearchBufferControl):
- return self.search_links.get(control)
- else:
- return None
-
- def get_focusable_windows(self) -> Iterable[Window]:
- """
- Return all the :class:`.Window` objects which are focusable (in the
- 'modal' area).
- """
- for w in self.walk_through_modal_area():
- if isinstance(w, Window) and w.content.is_focusable():
- yield w
-
- def get_visible_focusable_windows(self) -> List[Window]:
- """
- Return a list of :class:`.Window` objects that are focusable.
- """
- # focusable windows are windows that are visible, but also part of the
- # modal container. Make sure to keep the ordering.
- visible_windows = self.visible_windows
- return [w for w in self.get_focusable_windows() if w in visible_windows]
-
- @property
- def current_buffer(self) -> Optional[Buffer]:
- """
- The currently focused :class:`~.Buffer` or `None`.
- """
- ui_control = self.current_control
- if isinstance(ui_control, BufferControl):
- return ui_control.buffer
- return None
-
- def get_buffer_by_name(self, buffer_name: str) -> Optional[Buffer]:
- """
- Look in the layout for a buffer with the given name.
- Return `None` when nothing was found.
- """
- for w in self.walk():
- if isinstance(w, Window) and isinstance(w.content, BufferControl):
- if w.content.buffer.name == buffer_name:
- return w.content.buffer
- return None
-
- @property
- def buffer_has_focus(self) -> bool:
- """
- Return `True` if the currently focused control is a
- :class:`.BufferControl`. (For instance, used to determine whether the
- default key bindings should be active or not.)
- """
- ui_control = self.current_control
- return isinstance(ui_control, BufferControl)
-
- @property
- def previous_control(self) -> UIControl:
- """
- Get the :class:`.UIControl` to previously had the focus.
- """
- try:
- return self._stack[-2].content
- except IndexError:
- return self._stack[-1].content
-
- def focus_last(self) -> None:
- """
- Give the focus to the last focused control.
- """
- if len(self._stack) > 1:
- self._stack = self._stack[:-1]
-
- def focus_next(self) -> None:
- """
- Focus the next visible/focusable Window.
- """
- windows = self.get_visible_focusable_windows()
-
- if len(windows) > 0:
- try:
- index = windows.index(self.current_window)
- except ValueError:
- index = 0
- else:
- index = (index + 1) % len(windows)
-
- self.focus(windows[index])
-
- def focus_previous(self) -> None:
- """
- Focus the previous visible/focusable Window.
- """
- windows = self.get_visible_focusable_windows()
-
- if len(windows) > 0:
- try:
- index = windows.index(self.current_window)
- except ValueError:
- index = 0
- else:
- index = (index - 1) % len(windows)
-
- self.focus(windows[index])
-
- def walk(self) -> Iterable[Container]:
- """
- Walk through all the layout nodes (and their children) and yield them.
- """
- yield from walk(self.container)
-
- def walk_through_modal_area(self) -> Iterable[Container]:
- """
- Walk through all the containers which are in the current 'modal' part
- of the layout.
- """
- # Go up in the tree, and find the root. (it will be a part of the
- # layout, if the focus is in a modal part.)
- root: Container = self.current_window
- while not root.is_modal() and root in self._child_to_parent:
- root = self._child_to_parent[root]
-
- yield from walk(root)
-
- def update_parents_relations(self) -> None:
- """
- Update child->parent relationships mapping.
- """
- parents = {}
-
- def walk(e: Container) -> None:
- for c in e.get_children():
- parents[c] = e
- walk(c)
-
- walk(self.container)
-
- self._child_to_parent = parents
-
- def reset(self) -> None:
- # Remove all search links when the UI starts.
- # (Important, for instance when control-c is been pressed while
- # searching. The prompt cancels, but next `run()` call the search
- # links are still there.)
- self.search_links.clear()
-
- self.container.reset()
-
- def get_parent(self, container: Container) -> Optional[Container]:
- """
- Return the parent container for the given container, or ``None``, if it
- wasn't found.
- """
- try:
- return self._child_to_parent[container]
- except KeyError:
- return None
-
-
-class InvalidLayoutError(Exception):
- pass
-
-
-def walk(container: Container, skip_hidden: bool = False) -> Iterable[Container]:
- """
- Walk through layout, starting at this container.
- """
- # When `skip_hidden` is set, don't go into disabled ConditionalContainer containers.
- if (
- skip_hidden
- and isinstance(container, ConditionalContainer)
- and not container.filter()
- ):
- return
-
- yield container
-
- for c in container.get_children():
- # yield from walk(c)
- yield from walk(c, skip_hidden=skip_hidden)