You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			240 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			240 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Python
		
	
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("")
 |