summaryrefslogtreecommitdiffstats
path: root/src/prompt_toolkit/shortcuts/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/prompt_toolkit/shortcuts/utils.py')
-rw-r--r--src/prompt_toolkit/shortcuts/utils.py239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/prompt_toolkit/shortcuts/utils.py b/src/prompt_toolkit/shortcuts/utils.py
new file mode 100644
index 0000000..abf4fd2
--- /dev/null
+++ b/src/prompt_toolkit/shortcuts/utils.py
@@ -0,0 +1,239 @@
+from __future__ import annotations
+
+from asyncio.events import AbstractEventLoop
+from typing import TYPE_CHECKING, Any, TextIO
+
+from prompt_toolkit.application import Application
+from prompt_toolkit.application.current import get_app_or_none, get_app_session
+from prompt_toolkit.application.run_in_terminal import run_in_terminal
+from prompt_toolkit.formatted_text import (
+ FormattedText,
+ StyleAndTextTuples,
+ to_formatted_text,
+)
+from prompt_toolkit.input import DummyInput
+from prompt_toolkit.layout import Layout
+from prompt_toolkit.output import ColorDepth, Output
+from prompt_toolkit.output.defaults import create_output
+from prompt_toolkit.renderer import (
+ print_formatted_text as renderer_print_formatted_text,
+)
+from prompt_toolkit.styles import (
+ BaseStyle,
+ StyleTransformation,
+ default_pygments_style,
+ default_ui_style,
+ merge_styles,
+)
+
+if TYPE_CHECKING:
+ from prompt_toolkit.layout.containers import AnyContainer
+
+__all__ = [
+ "print_formatted_text",
+ "print_container",
+ "clear",
+ "set_title",
+ "clear_title",
+]
+
+
+def print_formatted_text(
+ *values: Any,
+ sep: str = " ",
+ end: str = "\n",
+ file: TextIO | None = None,
+ flush: bool = False,
+ style: BaseStyle | None = None,
+ output: Output | None = None,
+ color_depth: ColorDepth | None = None,
+ style_transformation: StyleTransformation | None = None,
+ include_default_pygments_style: bool = True,
+) -> None:
+ """
+ ::
+
+ print_formatted_text(*values, sep=' ', end='\\n', file=None, flush=False, style=None, output=None)
+
+ Print text to stdout. This is supposed to be compatible with Python's print
+ function, but supports printing of formatted text. You can pass a
+ :class:`~prompt_toolkit.formatted_text.FormattedText`,
+ :class:`~prompt_toolkit.formatted_text.HTML` or
+ :class:`~prompt_toolkit.formatted_text.ANSI` object to print formatted
+ text.
+
+ * Print HTML as follows::
+
+ print_formatted_text(HTML('<i>Some italic text</i> <ansired>This is red!</ansired>'))
+
+ style = Style.from_dict({
+ 'hello': '#ff0066',
+ 'world': '#884444 italic',
+ })
+ print_formatted_text(HTML('<hello>Hello</hello> <world>world</world>!'), style=style)
+
+ * Print a list of (style_str, text) tuples in the given style to the
+ output. E.g.::
+
+ style = Style.from_dict({
+ 'hello': '#ff0066',
+ 'world': '#884444 italic',
+ })
+ fragments = FormattedText([
+ ('class:hello', 'Hello'),
+ ('class:world', 'World'),
+ ])
+ print_formatted_text(fragments, style=style)
+
+ If you want to print a list of Pygments tokens, wrap it in
+ :class:`~prompt_toolkit.formatted_text.PygmentsTokens` to do the
+ conversion.
+
+ If a prompt_toolkit `Application` is currently running, this will always
+ print above the application or prompt (similar to `patch_stdout`). So,
+ `print_formatted_text` will erase the current application, print the text,
+ and render the application again.
+
+ :param values: Any kind of printable object, or formatted string.
+ :param sep: String inserted between values, default a space.
+ :param end: String appended after the last value, default a newline.
+ :param style: :class:`.Style` instance for the color scheme.
+ :param include_default_pygments_style: `bool`. Include the default Pygments
+ style when set to `True` (the default).
+ """
+ assert not (output and file)
+
+ # Create Output object.
+ if output is None:
+ if file:
+ output = create_output(stdout=file)
+ else:
+ output = get_app_session().output
+
+ assert isinstance(output, Output)
+
+ # Get color depth.
+ color_depth = color_depth or output.get_default_color_depth()
+
+ # Merges values.
+ def to_text(val: Any) -> StyleAndTextTuples:
+ # Normal lists which are not instances of `FormattedText` are
+ # considered plain text.
+ if isinstance(val, list) and not isinstance(val, FormattedText):
+ return to_formatted_text(f"{val}")
+ return to_formatted_text(val, auto_convert=True)
+
+ fragments = []
+ for i, value in enumerate(values):
+ fragments.extend(to_text(value))
+
+ if sep and i != len(values) - 1:
+ fragments.extend(to_text(sep))
+
+ fragments.extend(to_text(end))
+
+ # Print output.
+ def render() -> None:
+ assert isinstance(output, Output)
+
+ renderer_print_formatted_text(
+ output,
+ fragments,
+ _create_merged_style(
+ style, include_default_pygments_style=include_default_pygments_style
+ ),
+ color_depth=color_depth,
+ style_transformation=style_transformation,
+ )
+
+ # Flush the output stream.
+ if flush:
+ output.flush()
+
+ # If an application is running, print above the app. This does not require
+ # `patch_stdout`.
+ loop: AbstractEventLoop | None = None
+
+ app = get_app_or_none()
+ if app is not None:
+ loop = app.loop
+
+ if loop is not None:
+ loop.call_soon_threadsafe(lambda: run_in_terminal(render))
+ else:
+ render()
+
+
+def print_container(
+ container: AnyContainer,
+ file: TextIO | None = None,
+ style: BaseStyle | None = None,
+ include_default_pygments_style: bool = True,
+) -> None:
+ """
+ Print any layout to the output in a non-interactive way.
+
+ Example usage::
+
+ from prompt_toolkit.widgets import Frame, TextArea
+ print_container(
+ Frame(TextArea(text='Hello world!')))
+ """
+ if file:
+ output = create_output(stdout=file)
+ else:
+ output = get_app_session().output
+
+ app: Application[None] = Application(
+ layout=Layout(container=container),
+ output=output,
+ # `DummyInput` will cause the application to terminate immediately.
+ input=DummyInput(),
+ style=_create_merged_style(
+ style, include_default_pygments_style=include_default_pygments_style
+ ),
+ )
+ try:
+ app.run(in_thread=True)
+ except EOFError:
+ pass
+
+
+def _create_merged_style(
+ style: BaseStyle | None, include_default_pygments_style: bool
+) -> BaseStyle:
+ """
+ Merge user defined style with built-in style.
+ """
+ styles = [default_ui_style()]
+ if include_default_pygments_style:
+ styles.append(default_pygments_style())
+ if style:
+ styles.append(style)
+
+ return merge_styles(styles)
+
+
+def clear() -> None:
+ """
+ Clear the screen.
+ """
+ output = get_app_session().output
+ output.erase_screen()
+ output.cursor_goto(0, 0)
+ output.flush()
+
+
+def set_title(text: str) -> None:
+ """
+ Set the terminal title.
+ """
+ output = get_app_session().output
+ output.set_title(text)
+
+
+def clear_title() -> None:
+ """
+ Erase the current title.
+ """
+ set_title("")