| | 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) |
| |
|
| | |
| | if output is None: |
| | if file: |
| | output = create_output(stdout=file) |
| | else: |
| | output = get_app_session().output |
| |
|
| | assert isinstance(output, Output) |
| |
|
| | |
| | color_depth = color_depth or output.get_default_color_depth() |
| |
|
| | |
| | def to_text(val: Any) -> StyleAndTextTuples: |
| | |
| | |
| | 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)) |
| |
|
| | |
| | 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, |
| | ) |
| |
|
| | |
| | if flush: |
| | output.flush() |
| |
|
| | |
| | |
| | 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, |
| | |
| | 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("") |
| |
|