# Technical Documentation: prompt-toolkit/python-prompt-toolkit

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/prompt-toolkit/python-prompt-toolkit)

### Overview (`examples/tutorial/README.md`)

See http://python-prompt-toolkit.readthedocs.io/en/stable/pages/tutorials/repl.html

---

### Index (`docs/index.rst`)

Python Prompt Toolkit 3.0
=========================

`prompt_toolkit` is a library for building powerful interactive command line
and terminal applications in Python.


It can be a very advanced pure Python replacement for `GNU readline
<https://tiswww.case.edu/php/chet/readline/rltop.html>`_, but it can also be
used for building full screen applications.

.. image:: images/ptpython-2.png

Some features:

- Syntax highlighting of the input while typing. (For instance, with a Pygments lexer.)
- Multi-line input editing.
- Advanced code completion.
- Selecting text for copy/paste. (Both Emacs and Vi style.)
- Mouse support for cursor positioning and scrolling.
- Auto suggestions. (Like `fish shell <http://fishshell.com/>`_.)
- No global state.

Like readline:

- Both Emacs and Vi key bindings.
- Reverse and forward incremental search.
- Works well with Unicode double width characters. (Chinese input.)

Works everywhere:

- Pure Python. Runs on all Python versions starting at Python 3.6.
  (Python 2.6 - 3.x is supported in prompt_toolkit 2.0; not 3.0).
- Runs on Linux, OS X, OpenBSD and Windows systems.
- Lightweight, the only dependencies are Pygments and wcwidth.
- No assumptions about I/O are made. Every prompt_toolkit application should
  also run in a telnet/ssh server or an `asyncio
  <https://docs.python.org/3/library/asyncio.html>`_ process.

Have a look at :ref:`the gallery <gallery>` to get an idea of what is possible.

Getting started
---------------

Go to :ref:`getting started <getting_started>` and build your first prompt.
Issues are tracked `on the Github project
<https://github.com/prompt-toolkit/python-prompt-toolkit>`_.


Thanks to:
----------

A special thanks to `all the contributors
<https://github.com/prompt-toolkit/python-prompt-toolkit/graphs/contributors>`_
for making prompt_toolkit possible.

Also, a special thanks to the `Pygments <http://pygments.org/>`_ and `wcwidth
<https://github.com/jquast/wcwidth>`_ libraries.


Table of contents
-----------------

.. toctree::
   :maxdepth: 2

   pages/gallery
   pages/getting_started
   pages/upgrading/index
   pages/printing_text
   pages/asking_for_input
   pages/asking_for_a_choice
   pages/dialogs
   pages/progress_bars
   pages/full_screen_apps
   pages/tutorials/index
   pages/advanced_topics/index
   pages/reference
   pages/related_projects


Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

Prompt_toolkit was created by `Jonathan Slenders
<http://github.com/prompt-toolkit/>`_.

---

### Requirements (`docs/requirements.txt`)

Sphinx>=8,<9
wcwidth<1
pyperclip<2
sphinx_copybutton>=0.5.2,<1.0.0
sphinx-nefertiti>=0.8.8

---

### Pages Asking For A Choice (`docs/pages/asking_for_a_choice.rst`)

.. _asking_for_a_choice:

Asking for a choice
===================

Similar to how the :func:`~prompt_toolkit.shortcuts.prompt` function allows for
text input, prompt_toolkit has a
:func:`~prompt_toolkit.shortcuts.choice` function to ask for a choice
from a list of options:

.. code:: python

    from prompt_toolkit.shortcuts import choice

    result = choice(
        message="Please choose a dish:",
        options=[
            ("pizza", "Pizza with mushrooms"),
            ("salad", "Salad with tomatoes"),
            ("sushi", "Sushi"),
        ],
        default="salad",
    )
    print(f"You have chosen: {result}")

.. image:: ../images/choice-input.png


Coloring the options
--------------------

It is possible to customize the colors and styles. The ``message`` parameter
takes any :ref:`formatted text <formatted_text>`, and the labels (2nd argument
from the options) can be :ref:`formatted text <formatted_text>` as well.
Further, we can pass a :class:`~prompt_toolkit.styles.Style` instance using the
:meth:`~prompt_toolkit.styles.Style.from_dict` function:

.. code:: python

    from prompt_toolkit.formatted_text import HTML
    from prompt_toolkit.shortcuts import choice
    from prompt_toolkit.styles import Style

    style = Style.from_dict(
        {
            "input-selection": "fg:#ff0000",
            "number": "fg:#884444 bold",
            "selected-option": "underline",
        }
    )

    result = choice(
        message=HTML("<u>Please select a dish</u>:"),
        options=[
            ("pizza", "Pizza with mushrooms"),
            (
                "salad",
                HTML("<ansigreen>Salad</ansigreen> with <ansired>tomatoes</ansired>"),
            ),
            ("sushi", "Sushi"),
        ],
        style=style,
    )
    print(f"You have chosen: {result}")

.. image:: ../images/colored-choice.png


Adding a frame
--------------

The :func:`~prompt_toolkit.shortcuts.choice` function takes a
``show_frame`` argument. When ``True``, the input is displayed within a frame.
It is also possible to pass a :ref:`filter <filters>`, like ``~is_done``, so
that the frame is only displayed when asking for input, but hidden once the
input is accepted.

.. code:: python

    from prompt_toolkit.shortcuts import choice
    from prompt_toolkit.filters import is_done
    from prompt_toolkit.styles import Style

    style = Style.from_dict(
        {
            "frame.border": "#884444",
            "selected-option": "bold",
        }
    )
    result = choice(
        message="Please select a dish:",
        options=[
            ("pizza", "Pizza with mushrooms"),
            ("salad", "Salad with tomatoes"),
            ("sushi", "Sushi"),
        ],
        style=style,
        show_frame=~is_done,
    )
    print(f"You have chosen: {result}")

.. image:: ../images/choice-with-frame.png


Adding a bottom toolbar
-----------------------

Adding a bottom toolbar can be done by passing a ``bottom_toolbar`` argument to
:func:`~prompt_toolkit.shortcuts.choice`. This argument can be plain text,
:ref:`formatted text <formatted_text>` or a callable that returns plain or
formatted text.


.. code:: python

    from prompt_toolkit.filters import is_done
    from prompt_toolkit.formatted_text import HTML
    from prompt_toolkit.shortcuts import choice
    from prompt_toolkit.styles import Style

    style = Style.from_dict(
        {
            "frame.border": "#ff4444",
            "selected-option": "bold",
            # ('noreverse' because the default toolbar style uses 'reverse')
            "bottom-toolbar": "#ffffff bg:#333333 noreverse",
        }
    )

    result = choice(
        message=HTML("<u>Please select a dish</u>:"),
        options=[
            ("pizza", "Pizza with mushrooms"),
            ("salad", "Salad with tomatoes"),
            ("sushi", "Sushi"),
        ],
        style=style,
        bottom_toolbar=HTML(
            " Press <b>[Up]</b>/<b>[Down]</b> to select, <b>[Enter]</b> to accept."
        ),
        show_frame=~is_done,
    )
    print(f"You have chosen: {result}")

.. image:: ../images/choice-with-frame-and-bottom-toolbar.png

---

### Pages Asking For Input (`docs/pages/asking_for_input.rst`)

.. _asking_for_input:

Asking for input (prompts)
==========================

This page is about building prompts. Pieces of code that we can embed in a
program for asking the user for input. Even if you want to use `prompt_toolkit`
for building full screen terminal applications, it is probably still a good
idea to read this first, before heading to the :ref:`building full screen
applications <full_screen_applications>` page.

In this page, we will cover autocompletion, syntax highlighting, key bindings,
and so on.


Hello world
-----------

The following snippet is the most simple example, it uses the
:func:`~prompt_toolkit.shortcuts.prompt` function to ask the user for input
and returns the text. Just like ``(raw_)input``.

.. code:: python

    from prompt_toolkit import prompt

    text = prompt("Give me some input: ")
    print(f"You said: {text}")

.. image:: ../images/hello-world-prompt.png

What we get here is a simple prompt that supports the Emacs key bindings like
readline, but further nothing special. However,
:func:`~prompt_toolkit.shortcuts.prompt` has a lot of configuration options.
In the following sections, we will discover all these parameters.


The `PromptSession` object
--------------------------

Instead of calling the :func:`~prompt_toolkit.shortcuts.prompt` function, it's
also possible to create a :class:`~prompt_toolkit.shortcuts.PromptSession`
instance followed by calling its
:meth:`~prompt_toolkit.shortcuts.PromptSession.prompt` method for every input
call. This creates a kind of an input session.

.. code:: python

    from prompt_toolkit import PromptSession

    # Create prompt object.
    session = PromptSession()

    # Do multiple input calls.
    text1 = session.prompt()
    text2 = session.prompt()

This has mainly two advantages:

- The input history will be kept between consecutive
  :meth:`~prompt_toolkit.shortcuts.PromptSession.prompt` calls.

- The :func:`~prompt_toolkit.shortcuts.PromptSession` instance and its
  :meth:`~prompt_toolkit.shortcuts.PromptSession.prompt` method take about the
  same arguments, like all the options described below (highlighting,
  completion, etc...). So if you want to ask for multiple inputs, but each
  input call needs about the same arguments, they can be passed to the
  :func:`~prompt_toolkit.shortcuts.PromptSession` instance as well, and they
  can be overridden by passing values to the
  :meth:`~prompt_toolkit.shortcuts.PromptSession.prompt` method.


Syntax highlighting
-------------------

Adding syntax highlighting is as simple as adding a lexer. All of the `Pygments
<http://pygments.org/>`_ lexers can be used after wrapping them in a
:class:`~prompt_toolkit.lexers.PygmentsLexer`. It is also possible to create a
custom lexer by implementing the :class:`~prompt_toolkit.lexers.Lexer` abstract
base class.

.. code:: python

    from pygments.lexers.html import HtmlLexer
    from prompt_toolkit.shortcuts import prompt
    from prompt_toolkit.lexers import PygmentsLexer

    text = prompt("Enter HTML: ", lexer=PygmentsLexer(HtmlLexer))
    print(f"You said: {text}")

.. image:: ../images/html-input.png

The default Pygments colorscheme is included as part of the default style in
prompt_toolkit. If you want to use another Pygments style along with the lexer,
you can do the following:

.. code:: python

    from pygments.lexers.html import HtmlLexer
    from pygments.styles import get_style_by_name
    from prompt_toolkit.shortcuts import prompt
    from prompt_toolkit.lexers import PygmentsLexer
    from prompt_toolkit.styles.pygments import style_from_pygments_cls

    style = style_from_pygments_cls(get_style_by_name("monokai"))
    text = prompt(
        "Enter HTML: ",
        lexer=PygmentsLexer(HtmlLexer),
        style=style,
        include_default_pygments_style=False
    )
    print(f"You said: {text}")

We pass ``include_default_pygments_style=False``, because otherwise, both
styles will be merged, possibly giving slightly different colors in the outcome
for cases where where our custom Pygments style doesn't specify a color.

.. _colors:

Colors
------

The colors for syntax highlighting are defined by a
:class:`~prompt_toolkit.styles.Style` instance. By default, a neutral
built-in style is used, but any style instance can be passed to the
:func:`~prompt_toolkit.shortcuts.prompt` function. A simple way to create a
style, is by using the :meth:`~prompt_toolkit.styles.Style.from_dict`
function:

.. code:: python

    from pygments.lexers.html import HtmlLexer
    from prompt_toolkit.shortcuts import prompt
    from prompt_toolkit.styles import Style
    from prompt_toolkit.lexers import PygmentsLexer

    our_style = Style.from_dict({
        "pygments.comment": "#888888 bold",
        "pygments.keyword": "#ff88ff bold",
    })

    text = prompt(
        "Enter HTML: ",
        lexer=PygmentsLexer(HtmlLexer),
        style=our_style
    )


The style dictionary is very similar to the Pygments ``styles`` dictionary,
with a few differences:

- The `roman`, `sans`, `mono` and `border` options are ignored.
- The style has a few additions: ``blink``, ``noblink``, ``reverse`` and ``noreverse``.
- Colors can be in the ``#ff0000`` format, but they can be one of the built-in
  ANSI color names as well. In that case, they map directly to the 16 color
  palette of the terminal.

:ref:`Read more about styling <styling>`.


Using a Pygments style
^^^^^^^^^^^^^^^^^^^^^^

All Pygments style classes can be used as well, when they are wrapped through
:func:`~prompt_toolkit.styles.style_from_pygments_cls`.

Suppose we'd like to use a Pygments style, for instance
``pygments.styles.tango.TangoStyle``, that is possible like this:

.. code:: python

    from prompt_toolkit.shortcuts import prompt
    from prompt_toolkit.styles import style_from_pygments_cls
    from prompt_toolkit.lexers import PygmentsLexer
    from pygments.styles.tango import TangoStyle
    from pygments.lexers.html import HtmlLexer

    tango_style = style_from_pygments_cls(TangoStyle)

    text = prompt(
        "Enter HTML: ",
        lexer=PygmentsLexer(HtmlLexer),
        style=tango_style
    )

Creating a custom style could be done like this:

.. code:: python

    from prompt_toolkit.shortcuts import prompt
    from prompt_toolkit.styles import Style, style_from_pygments_cls, merge_styles
    from prompt_toolkit.lexers import PygmentsLexer

    from pygments.styles.tango import TangoStyle
    from pygments.lexers.html import HtmlLexer

    our_style = merge_styles([
        style_from_pygments_cls(TangoStyle),
        Style.from_dict({
            "pygments.comment": "#888888 bold",
            "pygments.keyword": "#ff88ff bold",
        })
    ])

    text = prompt(
        "Enter HTML: ",
        lexer=PygmentsLexer(HtmlLexer),
        style=our_style
    )


Coloring the prompt itself
^^^^^^^^^^^^^^^^^^^^^^^^^^

It is possible to add some colors to the prompt itself. For this, we need to
build some :ref:`formatted text <formatted_text>`. One way of doing this is by
creating a list of style/text tuples. In the following example, we use class
names to refer to the style.

.. code:: python

    from prompt_toolkit.shortcuts import prompt
    from prompt_toolkit.styles import Style

    style = Style.from_dict({
        # User input (default text).
        "":          "#ff0066",

        # Prompt.
        "username": "#884444",
        "at":       "#00aa00",
        "colon":    "#0000aa",
        "pound":    "#00aa00",
        "host":     "#00ffff bg:#444400",
        "path":     "ansicyan underline",
    })

    message = [
        ("class:username", "john"),
        ("class:at",       "@"),
        ("class:host",     "localhost"),
        ("class:colon",    ":"),
        ("class:path",     "/user/john"),
        ("class:pound",    "# "),
    ]

    text = prompt(message, style=style)

.. image:: ../images/colored-prompt.png

The `message` can be any kind of formatted text, as discussed :ref:`here
<formatted_text>`. It can also be a callable that returns some formatted text.

By default, colors are taken from the 256 color palette. If you want to have
24bit true color, this is possible by adding the
``color_depth=ColorDepth.TRUE_COLOR`` option to the
:func:`~prompt_toolkit.shortcuts.prompt.prompt` function.

.. code:: python

    from prompt_toolkit.output import ColorDepth

    text = prompt(message, style=style, color_depth=ColorDepth.TRUE_COLOR)


Autocompletion
--------------

Autocompletion can be added by passing a ``completer`` parameter. This should
be an instance of the :class:`~prompt_toolkit.completion.Completer` abstract
base class. :class:`~prompt_toolkit.completion.WordCompleter` is an example of
a completer that implements that interface.

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.completion import WordCompleter

    html_completer = WordCompleter(["<html>", "<body>", "<head>", "<title>"])
    text = prompt("Enter HTML: ", completer=html_completer)
    print(f"You said: {text}")

:class:`~prompt_toolkit.completion.WordCompleter` is a simple completer that
completes the last word before the cursor with any of the given words.

.. image:: ../images/html-completion.png

.. note::

    Note that in prompt_toolkit 2.0, the auto completion became synchronous. This
    means that if it takes a long time to compute the completions, that this
    will block the event loop and the input processing.

    For heavy completion algorithms, it is recommended to wrap the completer in
    a :class:`~prompt_toolkit.completion.ThreadedCompleter` in order to run it
    in a background thread.


Nested completion
^^^^^^^^^^^^^^^^^

Sometimes you have a command line interface where the completion depends on the
previous words from the input. Examples are the CLIs from routers and switches.
A simple :class:`~prompt_toolkit.completion.WordCompleter` is not enough in
that case. We want to to be able to define completions at multiple hierarchical
levels. :class:`~prompt_toolkit.completion.NestedCompleter` solves this issue:

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.completion import NestedCompleter

    completer = NestedCompleter.from_nested_dict({
        "show": {
            "version": None,
            "clock": None,
            "ip": {
                "interface": {"brief"}
            }
        },
        "exit": None,
    })

    text = prompt("# ", completer=completer)
    print(f"You said: {text}")

Whenever there is a ``None`` value in the dictionary, it means that there is no
further nested completion at that point. When all values of a dictionary would
be ``None``, it can also be replaced with a set.


A custom completer
^^^^^^^^^^^^^^^^^^

For more complex examples, it makes sense to create a custom completer. For
instance:

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.completion import Completer, Completion

    class MyCustomCompleter(Completer):
        def get_completions(self, document, complete_event):
            yield Completion("completion", start_position=0)

    text = prompt("> ", completer=MyCustomCompleter())

A :class:`~prompt_toolkit.completion.Completer` class has to implement a
generator named :meth:`~prompt_toolkit.completion.Completer.get_completions`
that takes a :class:`~prompt_toolkit.document.Document` and yields the current
:class:`~prompt_toolkit.completion.Completion` instances. Each completion
contains a portion of text, and a position.

The position is used for fixing text before the cursor. Pressing the tab key
could for instance turn parts of the input from lowercase to uppercase. This
makes sense for a case insensitive completer. Or in case of a fuzzy completion,
it could fix typos. When ``start_position`` is something negative, this amount
of characters will be deleted and replaced.


Styling individual completions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Each completion can provide a custom style, which is used when it is rendered
in the completion menu or toolbar. This is possible by passing a style to each
:class:`~prompt_toolkit.completion.Completion` instance.

.. code:: python

    from prompt_toolkit.completion import Completer, Completion

    class MyCustomCompleter(Completer):
        def get_completions(self, document, complete_event):
            # Display this completion, black on yellow.
            yield Completion(
                "completion1",
                start_position=0,
                style="bg:ansiyellow fg:ansiblack"
            )

            # Underline completion.
            yield Completion(
                "completion2",
                start_position=0,
                style="underline"
            )

            # Specify class name, which will be looked up in the style sheet.
            yield Completion(
                "completion3",
                start_position=0,
                style="class:special-completion"
            )

The "colorful-prompts.py" example uses completion styling:

.. image:: ../images/colorful-completions.png

Finally, it is possible to pass :ref:`formatted text <formatted_text>` for the
``display`` attribute of a :class:`~prompt_toolkit.completion.Completion`. This
provides all the freedom you need to display the text in any possible way. It
can also be combined with the ``style`` attribute. For instance:

.. code:: python


    from prompt_toolkit.completion import Completer, Completion
    from prompt_toolkit.formatted_text import HTML

    class MyCustomCompleter(Completer):
        def get_completions(self, document, complete_event):
            yield Completion(
                "completion1",
                start_position=0,
                display=HTML("<b>completion</b><ansired>1</ansired>"),
                style="bg:ansiyellow"
            )


Fuzzy completion
^^^^^^^^^^^^^^^^

If one possible completions is "django_migrations", a fuzzy completer would
allow you to get this by typing "djm" only, a subset of characters for this
string.

Prompt_toolkit ships with a :class:`~prompt_toolkit.completion.FuzzyCompleter`
and :class:`~prompt_toolkit.completion.FuzzyWordCompleter` class. These provide
the means for doing this kind of "fuzzy completion". The first one can take any
completer instance and wrap it so that it becomes a fuzzy completer. The second
one behaves like a :class:`~prompt_toolkit.completion.WordCompleter` wrapped
into a :class:`~prompt_toolkit.completion.FuzzyCompleter`.


Complete while typing
^^^^^^^^^^^^^^^^^^^^^

Autcompletions can be generated automatically while typing or when the user
presses the tab key. This can be configured with the ``complete_while_typing``
option:

.. code:: python

    text = prompt(
        "Enter HTML: ",
        completer=my_completer,
        complete_while_typing=True
    )

Notice that this setting is incompatible with the ``enable_history_search``
option. The reason for this is that the up and down key bindings would conflict
otherwise. So, make sure to disable history search for this.


Asynchronous completion
^^^^^^^^^^^^^^^^^^^^^^^

When generating the completions takes a lot of time, it's better to do this in
a background thread. This is possible by wrapping the completer in a
:class:`~prompt_toolkit.completion.ThreadedCompleter`, but also by passing the
`complete_in_thread=True` argument.


.. code:: python

    text = prompt("> ", completer=MyCustomCompleter(), complete_in_thread=True)


Input validation
----------------

A prompt can have a validator attached. This is some code that will check
whether the given input is acceptable and it will only return it if that's the
case. Otherwise it will show an error message and move the cursor to a given
position.

A validator should implements the :class:`~prompt_toolkit.validation.Validator`
abstract base class. This requires only one method, named ``validate`` that
takes a :class:`~prompt_toolkit.document.Document` as input and raises
:class:`~prompt_toolkit.validation.ValidationError` when the validation fails.

.. code:: python

    from prompt_toolkit.validation import Validator, ValidationError
    from prompt_toolkit import prompt

    class NumberValidator(Validator):
        def validate(self, document):
            text = document.text

            if text and not text.isdigit():
                i = 0

                # Get index of first non numeric character.
                # We want to move the cursor here.
                for i, c in enumerate(text):
                    if not c.isdigit():
                        break

                raise ValidationError(
                    message="This input contains non-numeric characters",
                    cursor_position=i
                )

    number = int(prompt("Give a number: ", validator=NumberValidator()))
    print(f"You said: {number}")

.. image:: ../images/number-validator.png

By default, the input is validated in real-time while the user is typing, but
prompt_toolkit can also validate after the user presses the enter key:

.. code:: python

    prompt(
        "Give a number: ",
        validator=NumberValidator(),
        validate_while_typing=False
    )

If the input validation contains some heavy CPU intensive code, but you don't
want to block the event loop, then it's recommended to wrap the validator class
in a :class:`~prompt_toolkit.validation.ThreadedValidator`.

Validator from a callable
^^^^^^^^^^^^^^^^^^^^^^^^^

Instead of implementing the :class:`~prompt_toolkit.validation.Validator`
abstract base class, it is also possible to start from a simple function and
use the :meth:`~prompt_toolkit.validation.Validator.from_callable` classmethod.
This is easier and sufficient for probably 90% of the validators. It looks as
follows:

.. code:: python

    from prompt_toolkit.validation import Validator
    from prompt_toolkit import prompt

    def is_number(text):
        return text.isdigit()

    validator = Validator.from_callable(
        is_number,
        error_message="This input contains non-numeric characters",
        move_cursor_to_end=True
    )

    number = int(prompt("Give a number: ", validator=validator))
    print(f"You said: {number}")

We define a function that takes a string, and tells whether it's valid input or
not by returning a boolean.
:meth:`~prompt_toolkit.validation.Validator.from_callable` turns that into a
:class:`~prompt_toolkit.validation.Validator` instance. Notice that setting the
cursor position is not possible this way.


History
-------

A :class:`~prompt_toolkit.history.History` object keeps track of all the
previously entered strings, so that the up-arrow can reveal previously entered
items.

The recommended way is to use a
:class:`~prompt_toolkit.shortcuts.PromptSession`, which uses an
:class:`~prompt_toolkit.history.InMemoryHistory` for the entire session by
default. The following example has a history out of the box:

.. code:: python

   from prompt_toolkit import PromptSession

   session = PromptSession()

   while True:
       session.prompt()

To persist a history to disk, use a :class:`~prompt_toolkit.history.FileHistory`
instead of the default
:class:`~prompt_toolkit.history.InMemoryHistory`. This history object can be
passed either to a :class:`~prompt_toolkit.shortcuts.PromptSession` or to the
:meth:`~prompt_toolkit.shortcuts.prompt` function. For instance:

.. code:: python

   from prompt_toolkit import PromptSession
   from prompt_toolkit.history import FileHistory

   session = PromptSession(history=FileHistory("~/.myhistory"))

   while True:
       session.prompt()


Auto suggestion
---------------

Auto suggestion is a way to propose some input completions to the user like the
`fish shell <http://fishshell.com/>`_.

Usually, the input is compared to the history and when there is another entry
starting with the given text, the completion will be shown as gray text behind
the current input. Pressing the right arrow :kbd:`→` or :kbd:`c-e` will insert
this suggestion, :kbd:`alt-f` will insert the first word of the suggestion.

.. note::

    When suggestions are based on the history, don't forget to share one
    :class:`~prompt_toolkit.history.History` object between consecutive
    :func:`~prompt_toolkit.shortcuts.prompt` calls. Using a
    :class:`~prompt_toolkit.shortcuts.PromptSession` does this for you.

Example:

.. code:: python

    from prompt_toolkit import PromptSession
    from prompt_toolkit.history import InMemoryHistory
    from prompt_toolkit.auto_suggest import AutoSuggestFromHistory

    session = PromptSession()

    while True:
        text = session.prompt("> ", auto_suggest=AutoSuggestFromHistory())
        print(f"You said: {text}")

.. image:: ../images/auto-suggestion.png

A suggestion does not have to come from the history. Any implementation of the
:class:`~prompt_toolkit.auto_suggest.AutoSuggest` abstract base class can be
passed as an argument.


Adding a bottom toolbar
-----------------------

Adding a bottom toolbar is as easy as passing a ``bottom_toolbar`` argument to
:func:`~prompt_toolkit.shortcuts.prompt`. This argument be either plain text,
:ref:`formatted text <formatted_text>` or a callable that returns plain or
formatted text.

When a function is given, it will be called every time the prompt is rendered,
so the bottom toolbar can be used to display dynamic information.

The toolbar is always erased when the prompt returns.
Here we have an example of a callable that returns an
:class:`~prompt_toolkit.formatted_text.HTML` object. By default, the toolbar
has the **reversed style**, which is why we are setting the background instead
of the foreground.

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.formatted_text import HTML

    def bottom_toolbar():
        return HTML('This is a <b><style bg="ansired">Toolbar</style></b>!')

    text = prompt("> ", bottom_toolbar=bottom_toolbar)
    print(f"You said: {text}")

.. image:: ../images/bottom-toolbar.png

Similar, we could use a list of style/text tuples.

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.styles import Style

    def bottom_toolbar():
        return [("class:bottom-toolbar", " This is a toolbar. ")]

    style = Style.from_dict({
        "bottom-toolbar": "#ffffff bg:#333333",
    })

    text = prompt("> ", bottom_toolbar=bottom_toolbar, style=style)
    print(f"You said: {text}")

The default class name is ``bottom-toolbar`` and that will also be used to fill
the background of the toolbar.


Adding a right prompt
---------------------

The :func:`~prompt_toolkit.shortcuts.prompt` function has out of the box
support for right prompts as well. People familiar to ZSH could recognize this
as the `RPROMPT` option.

So, similar to adding a bottom toolbar, we can pass an ``rprompt`` argument.
This can be either plain text, :ref:`formatted text <formatted_text>` or a
callable which returns either.

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.styles import Style

    example_style = Style.from_dict({
        "rprompt": "bg:#ff0066 #ffffff",
    })

    def get_rprompt():
        return "<rprompt>"

    answer = prompt("> ", rprompt=get_rprompt, style=example_style)

.. image:: ../images/rprompt.png

The ``get_rprompt`` function can return any kind of formatted text such as
:class:`~prompt_toolkit.formatted_text.HTML`. it is also possible to pass text
directly to the ``rprompt`` argument of the
:func:`~prompt_toolkit.shortcuts.prompt` function. It does not have to be a
callable.


Vi input mode
-------------

Prompt-toolkit supports both Emacs and Vi key bindings, similar to Readline.
The :func:`~prompt_toolkit.shortcuts.prompt` function will use Emacs bindings by
default. This is done because on most operating systems, also the Bash shell
uses Emacs bindings by default, and that is more intuitive. If however, Vi
binding are required, just pass ``vi_mode=True``.

.. code:: python

    from prompt_toolkit import prompt

    prompt("> ", vi_mode=True)


Adding custom key bindings
--------------------------

By default, every prompt already has a set of key bindings which implements the
usual Vi or Emacs behavior. We can extend this by passing another
:class:`~prompt_toolkit.key_binding.KeyBindings` instance to the
``key_bindings`` argument of the :func:`~prompt_toolkit.shortcuts.prompt`
function or the :class:`~prompt_toolkit.shortcuts.PromptSession` class.

An example of a prompt that prints ``'hello world'`` when :kbd:`Control-T` is
pressed.

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.application import run_in_terminal
    from prompt_toolkit.key_binding import KeyBindings

    bindings = KeyBindings()

    @bindings.add("c-t")
    def _(event):
        " Say "hello" when `c-t` is pressed. "
        def print_hello():
            print("hello world")
        run_in_terminal(print_hello)

    @bindings.add("c-x")
    def _(event):
        " Exit when `c-x` is pressed. "
        event.app.exit()

    text = prompt("> ", key_bindings=bindings)
    print(f"You said: {text}")


Note that we use
:meth:`~prompt_toolkit.application.run_in_terminal` for the first key binding.
This ensures that the output of the print-statement and the prompt don't mix
up. If the key bindings doesn't print anything, then it can be handled directly
without nesting functions.


Enable key bindings according to a condition
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Often, some key bindings can be enabled or disabled according to a certain
condition. For instance, the Emacs and Vi bindings will never be active at the
same time, but it is possible to switch between Emacs and Vi bindings at run
time.

In order to enable a key binding according to a certain condition, we have to
pass it a :class:`~prompt_toolkit.filters.Filter`, usually a
:class:`~prompt_toolkit.filters.Condition` instance. (:ref:`Read more about
filters <filters>`.)

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.filters import Condition
    from prompt_toolkit.key_binding import KeyBindings

    bindings = KeyBindings()

    @Condition
    def is_active():
        " Only activate key binding on the second half of each minute. "
        return datetime.datetime.now().second > 30

    @bindings.add("c-t", filter=is_active)
    def _(event):
        # ...
        pass

    prompt("> ", key_bindings=bindings)


Dynamically switch between Emacs and Vi mode
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The :class:`~prompt_toolkit.application.Application` has an ``editing_mode``
attribute. We can change the key bindings by changing this attribute from
``EditingMode.VI`` to ``EditingMode.EMACS``.

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.application.current import get_app
    from prompt_toolkit.enums import EditingMode
    from prompt_toolkit.key_binding import KeyBindings

    def run():
        # Create a set of key bindings.
        bindings = KeyBindings()

        # Add an additional key binding for toggling this flag.
        @bindings.add("f4")
        def _(event):
            " Toggle between Emacs and Vi mode. "
            app = event.app

            if app.editing_mode == EditingMode.VI:
                app.editing_mode = EditingMode.EMACS
            else:
                app.editing_mode = EditingMode.VI

        # Add a toolbar at the bottom to display the current input mode.
        def bottom_toolbar():
            " Display the current input mode. "
            text = "Vi" if get_app().editing_mode == EditingMode.VI else "Emacs"
            return [
                ("class:toolbar", " [F4] %s " % text)
            ]

        prompt("> ", key_bindings=bindings, bottom_toolbar=bottom_toolbar)

    run()

:ref:`Read more about key bindings ...<key_bindings>`

Using control-space for completion
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

An popular short cut that people sometimes use it to use control-space for
opening the autocompletion menu instead of the tab key. This can be done with
the following key binding.

.. code:: python

    kb = KeyBindings()

    @kb.add("c-space")
    def _(event):
        " Initialize autocompletion, or select the next completion. "
        buff = event.app.current_buffer
        if buff.complete_state:
            buff.complete_next()
        else:
            buff.start_completion(select_first=False)


Other prompt options
--------------------

Multiline input
^^^^^^^^^^^^^^^

Reading multiline input is as easy as passing the ``multiline=True`` parameter.

.. code:: python

    from prompt_toolkit import prompt

    prompt("> ", multiline=True)

A side effect of this is that the enter key will now insert a newline instead
of accepting and returning the input. The user will now have to press
:kbd:`Meta+Enter` in order to accept the input. (Or :kbd:`Escape` followed by
:kbd:`Enter`.)

It is possible to specify a continuation prompt. This works by passing a
``prompt_continuation`` callable to :func:`~prompt_toolkit.shortcuts.prompt`.
This function is supposed to return :ref:`formatted text <formatted_text>`, or
a list of ``(style, text)`` tuples. The width of the returned text should not
exceed the given width. (The width of the prompt margin is defined by the
prompt.)

.. code:: python

    from prompt_toolkit import prompt

    def prompt_continuation(width, line_number, is_soft_wrap):
        return "." * width
        # Or: return [("", "." * width)]

    prompt(
        "multiline input> ",
        multiline=True,
        prompt_continuation=prompt_continuation
    )

.. image:: ../images/multiline-input.png


Passing a default
^^^^^^^^^^^^^^^^^

A default value can be given:

.. code:: python

    from prompt_toolkit import prompt
    import getpass

    prompt("What is your name: ", default=f"{getpass.getuser()}")


Mouse support
^^^^^^^^^^^^^

There is limited mouse support for positioning the cursor, for scrolling (in
case of large multiline inputs) and for clicking in the autocompletion menu.

Enabling can be done by passing the ``mouse_support=True`` option.

.. code:: python

    from prompt_toolkit import prompt

    prompt("What is your name: ", mouse_support=True)


Line wrapping
^^^^^^^^^^^^^

Line wrapping is enabled by default. This is what most people are used to and
this is what GNU Readline does. When it is disabled, the input string will
scroll horizontally.

.. code:: python

    from prompt_toolkit import prompt

    prompt("What is your name: ", wrap_lines=False)


Password input
^^^^^^^^^^^^^^

When the ``is_password=True`` flag has been given, the input is replaced by
asterisks (``*`` characters).

.. code:: python

    from prompt_toolkit import prompt

    prompt("Enter password: ", is_password=True)


Cursor shapes
-------------

Many terminals support displaying different types of cursor shapes. The most
common are block, beam or underscore. Either blinking or not. It is possible to
decide which cursor to display while asking for input, or in case of Vi input
mode, have a modal prompt for which its cursor shape changes according to the
input mode.

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.cursor_shapes import CursorShape, ModalCursorShapeConfig

    # Several possible values for the `cursor_shape_config` parameter:
    prompt(">", cursor=CursorShape.BLOCK)
    prompt(">", cursor=CursorShape.UNDERLINE)
    prompt(">", cursor=CursorShape.BEAM)
    prompt(">", cursor=CursorShape.BLINKING_BLOCK)
    prompt(">", cursor=CursorShape.BLINKING_UNDERLINE)
    prompt(">", cursor=CursorShape.BLINKING_BEAM)
    prompt(">", cursor=ModalCursorShapeConfig())


Adding a frame
--------------

A frame can be displayed around the input by passing ``show_frame=True`` as a
parameter. The color of the frame can be chosen by styling the ``frame.border``
element:

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.styles import Style

    style = Style.from_dict(
        {
            "frame.border": "#884444",
        }
    )

    answer = prompt("Say something > ", style=style, show_frame=True)
    print(f"You said: {answer}")

.. image:: ../images/prompt-with-frame.png

It is also possible to pass a :ref:`filter <filters>`, for instance
``show_frame=~is_done``, so that the frame is only displayed when asking for
input, but hidden once the input is accepted.

.. code:: python

    from prompt_toolkit import prompt
    from prompt_toolkit.filters import is_done

    answer = prompt("Say something > ", show_frame=~is_done)
    print(f"You said: {answer}")


Prompt in an `asyncio` application
----------------------------------

.. note::

    New in prompt_toolkit 3.0. (In prompt_toolkit 2.0 this was possible using a
    work-around).

For `asyncio <https://docs.python.org/3/library/asyncio.html>`_ applications,
it's very important to never block the eventloop. However,
:func:`~prompt_toolkit.shortcuts.prompt` is blocking, and calling this would
freeze the whole application. Asyncio actually won't even allow us to run that
function within a coroutine.

The answer is to call
:meth:`~prompt_toolkit.shortcuts.PromptSession.prompt_async` instead of
:meth:`~prompt_toolkit.shortcuts.PromptSession.prompt`. The async variation
returns a coroutines and is awaitable.

.. code:: python

    from prompt_toolkit import PromptSession
    from prompt_toolkit.patch_stdout import patch_stdout

    async def my_coroutine():
        session = PromptSession()
        while True:
            with patch_stdout():
                result = await session.prompt_async("Say something: ")
            print(f"You said: {result}")

The :func:`~prompt_toolkit.patch_stdout.patch_stdout` context manager is
optional, but it's recommended, because other coroutines could print to stdout.
This ensures that other output won't destroy the prompt.


Reading keys from stdin, one key at a time, but without a prompt
----------------------------------------------------------------

Suppose that you want to use prompt_toolkit to read the keys from stdin, one
key at a time, but not render a prompt to the output, that is also possible:

.. code:: python

    import asyncio

    from prompt_toolkit.input import create_input
    from prompt_toolkit.keys import Keys


    async def main() -> None:
        done = asyncio.Event()
        input = create_input()

        def keys_ready():
            for key_press in input.read_keys():
                print(key_press)

                if key_press.key == Keys.ControlC:
                    done.set()

        with input.raw_mode():
            with input.attach(keys_ready):
                await done.wait()


    if __name__ == "__main__":
        asyncio.run(main())

The above snippet will print the `KeyPress` object whenever a key is pressed.
This is also cross platform, and should work on Windows.

---

### Pages Dialogs (`docs/pages/dialogs.rst`)

.. _dialogs:

Dialogs
=======

Prompt_toolkit ships with a high level API for displaying dialogs, similar to
the Whiptail program, but in pure Python.


Message box
-----------

Use the :func:`~prompt_toolkit.shortcuts.message_dialog` function to display a
simple message box. For instance:

.. code:: python

    from prompt_toolkit.shortcuts import message_dialog

    message_dialog(
        title='Example dialog window',
        text='Do you want to continue?\nPress ENTER to quit.').run()

.. image:: ../images/dialogs/messagebox.png


Input box
---------

The :func:`~prompt_toolkit.shortcuts.input_dialog` function can display an
input box. It will return the user input as a string.

.. code:: python

    from prompt_toolkit.shortcuts import input_dialog

    text = input_dialog(
        title='Input dialog example',
        text='Please type your name:').run()

.. image:: ../images/dialogs/inputbox.png


The ``password=True`` option can be passed to the
:func:`~prompt_toolkit.shortcuts.input_dialog` function to turn this into a
password input box.


Yes/No confirmation dialog
--------------------------

The :func:`~prompt_toolkit.shortcuts.yes_no_dialog` function displays a yes/no
confirmation dialog. It will return a boolean according to the selection.

.. code:: python

    from prompt_toolkit.shortcuts import yes_no_dialog

    result = yes_no_dialog(
        title='Yes/No dialog example',
        text='Do you want to confirm?').run()

.. image:: ../images/dialogs/confirm.png


Button dialog
-------------

The :func:`~prompt_toolkit.shortcuts.button_dialog` function displays a dialog
with choices offered as buttons. Buttons are indicated as a list of tuples,
each providing the label (first) and return value if clicked (second).

.. code:: python

    from prompt_toolkit.shortcuts import button_dialog

    result = button_dialog(
        title='Button dialog example',
        text='Do you want to confirm?',
        buttons=[
            ('Yes', True),
            ('No', False),
            ('Maybe...', None)
        ],
    ).run()

.. image:: ../images/dialogs/button.png


Radio list dialog
-----------------

The :func:`~prompt_toolkit.shortcuts.radiolist_dialog` function displays a dialog
with choices offered as a radio list. The values are provided as a list of tuples,
each providing the return value (first element) and the displayed value (second element).

.. code:: python

    from prompt_toolkit.shortcuts import radiolist_dialog

    result = radiolist_dialog(
        title="RadioList dialog",
        text="Which breakfast would you like ?",
        values=[
            ("breakfast1", "Eggs and beacon"),
            ("breakfast2", "French breakfast"),
            ("breakfast3", "Equestrian breakfast")
        ]
    ).run()


Checkbox list dialog
--------------------

The :func:`~prompt_toolkit.shortcuts.checkboxlist_dialog` has the same usage and purpose than the Radiolist dialog, but allows several values to be selected and therefore returned.

.. code:: python

    from prompt_toolkit.shortcuts import checkboxlist_dialog

    results_array = checkboxlist_dialog(
        title="CheckboxList dialog",
        text="What would you like in your breakfast ?",
        values=[
            ("eggs", "Eggs"),
            ("bacon", "Bacon"),
            ("croissants", "20 Croissants"),
            ("daily", "The breakfast of the day")
        ]
    ).run()


Styling of dialogs
------------------

A custom :class:`~prompt_toolkit.styles.Style` instance can be passed to all
dialogs to override the default style. Also, text can be styled by passing an
:class:`~prompt_toolkit.formatted_text.HTML` object.


.. code:: python

    from prompt_toolkit.formatted_text import HTML
    from prompt_toolkit.shortcuts import message_dialog
    from prompt_toolkit.styles import Style

    example_style = Style.from_dict({
        'dialog':             'bg:#88ff88',
        'dialog frame.label': 'bg:#ffffff #000000',
        'dialog.body':        'bg:#000000 #00ff00',
        'dialog shadow':      'bg:#00aa00',
    })

    message_dialog(
        title=HTML('<style bg="blue" fg="white">Styled</style> '
                   '<style fg="ansired">dialog</style> window'),
        text='Do you want to continue?\nPress ENTER to quit.',
        style=example_style).run()

.. image:: ../images/dialogs/styled.png

Styling reference sheet
-----------------------

In reality, the shortcut commands presented above build a full-screen frame by using a list of components. The two tables below allow you to get the classnames available for each shortcut, therefore you will be able to provide a custom style for every element that is displayed, using the method provided above.

.. note:: All the shortcuts use the ``Dialog`` component, therefore it isn't specified explicitly below.

+--------------------------+-------------------------+
| Shortcut                 | Components used         |
+==========================+=========================+
| ``yes_no_dialog``        | - ``Label``             |
|                          | - ``Button`` (x2)       |
+--------------------------+-------------------------+
| ``button_dialog``        | - ``Label``             |
|                          | - ``Button``            |
+--------------------------+-------------------------+
| ``input_dialog``         | - ``TextArea``          |
|                          | - ``Button`` (x2)       |
+--------------------------+-------------------------+
| ``message_dialog``       | - ``Label``             |
|                          | - ``Button``            |
+--------------------------+-------------------------+
| ``radiolist_dialog``     | - ``Label``             |
|                          | - ``RadioList``         |
|                          | - ``Button`` (x2)       |
+--------------------------+-------------------------+
| ``checkboxlist_dialog``  | - ``Label``             |
|                          | - ``CheckboxList``      |
|                          | - ``Button`` (x2)       |
+--------------------------+-------------------------+
| ``progress_dialog``      | - ``Label``             |
|                          | - ``TextArea`` (locked) |
|                          | - ``ProgressBar``       |
+--------------------------+-------------------------+

+----------------+-----------------------------+
| Components     | Available classnames        |
+================+=============================+
| Dialog         | - ``dialog``                |
|                | - ``dialog.body``           |
+----------------+-----------------------------+
| TextArea       | - ``text-area``             |
|                | - ``text-area.prompt``      |
+----------------+-----------------------------+
| Label          | - ``label``                 |
+----------------+-----------------------------+
| Button         | - ``button``                |
|                | - ``button.focused``        |
|                | - ``button.arrow``          |
|                | - ``button.text``           |
+----------------+-----------------------------+
| Frame          | - ``frame``                 |
|                | - ``frame.border``          |
|                | - ``frame.label``           |
+----------------+-----------------------------+
| Shadow         | - ``shadow``                |
+----------------+-----------------------------+
| RadioList      | - ``radio-list``            |
|                | - ``radio``                 |
|                | - ``radio-checked``         |
|                | - ``radio-selected``        |
+----------------+-----------------------------+
| CheckboxList   | - ``checkbox-list``         |
|                | - ``checkbox``              |
|                | - ``checkbox-checked``      |
|                | - ``checkbox-selected``     |
+----------------+-----------------------------+
| VerticalLine   | - ``line``                  |
|                | - ``vertical-line``         |
+----------------+-----------------------------+
| HorizontalLine | - ``line``                  |
|                | - ``horizontal-line``       |
+----------------+-----------------------------+
| ProgressBar    | - ``progress-bar``          |
|                | - ``progress-bar.used``     |
+----------------+-----------------------------+

Example
_______

Let's customize the example of the ``checkboxlist_dialog``.

It uses 2 ``Button``, a ``CheckboxList`` and a ``Label``, packed inside a ``Dialog``.
Therefore we can customize each of these elements separately, using for instance:

.. code:: python

    from prompt_toolkit.shortcuts import checkboxlist_dialog
    from prompt_toolkit.styles import Style

    results = checkboxlist_dialog(
        title="CheckboxList dialog",
        text="What would you like in your breakfast ?",
        values=[
            ("eggs", "Eggs"),
            ("bacon", "Bacon"),
            ("croissants", "20 Croissants"),
            ("daily", "The breakfast of the day")
        ],
        style=Style.from_dict({
            'dialog': 'bg:#cdbbb3',
            'button': 'bg:#bf99a4',
            'checkbox': '#e8612c',
            'dialog.body': 'bg:#a9cfd0',
            'dialog shadow': 'bg:#c98982',
            'frame.label': '#fcaca3',
            'dialog.body label': '#fd8bb6',
        })
    ).run()

---

### Pages Full Screen Apps (`docs/pages/full_screen_apps.rst`)

.. _full_screen_applications:

Building full screen applications
=================================

`prompt_toolkit` can be used to create complex full screen terminal
applications. Typically, an application consists of a layout (to describe the
graphical part) and a set of key bindings.

The sections below describe the components required for full screen
applications (or custom, non full screen applications), and how to assemble
them together.

Before going through this page, it could be helpful to go through :ref:`asking
for input <asking_for_input>` (prompts) first. Many things that apply to an
input prompt, like styling, key bindings and so on, also apply to full screen
applications.

.. note::

    Also remember that the ``examples`` directory of the prompt_toolkit
    repository contains plenty of examples. Each example is supposed to explain
    one idea. So, this as well should help you get started.

    Don't hesitate to open a GitHub issue if you feel that a certain example is
    missing.


A simple application
--------------------

Every prompt_toolkit application is an instance of an
:class:`~prompt_toolkit.application.Application` object. The simplest full
screen example would look like this:

.. code:: python

    from prompt_toolkit import Application

    app = Application(full_screen=True)
    app.run()

This will display a dummy application that says "No layout specified. Press
ENTER to quit.".

.. note::

        If we wouldn't set the ``full_screen`` option, the application would
        not run in the alternate screen buffer, and only consume the least
        amount of space required for the layout.

An application consists of several components. The most important are:

- I/O objects: the input and output device.
- The layout: this defines the graphical structure of the application. For
  instance, a text box on the left side, and a button on the right side.
  You can also think of the layout as a collection of 'widgets'.
- A style: this defines what colors and underline/bold/italic styles are used
  everywhere.
- A set of key bindings.

We will discuss all of these in more detail below.


I/O objects
-----------

Every :class:`~prompt_toolkit.application.Application` instance requires an I/O
object for input and output:

- An :class:`~prompt_toolkit.input.Input` instance, which is an abstraction
  of the input stream (stdin).
- An :class:`~prompt_toolkit.output.Output` instance, which is an
  abstraction of the output stream, and is called by the renderer.

Both are optional and normally not needed to pass explicitly. Usually, the
default works fine.

There is a third I/O object which is also required by the application, but not
passed inside. This is the event loop, an
:class:`~prompt_toolkit.eventloop` instance. This is basically a
while-true loop that waits for user input, and when it receives something (like
a key press), it will send that to the the appropriate handler, like for
instance, a key binding.

When :func:`~prompt_toolkit.application.Application.run()` is called, the event
loop will run until the application is done. An application will quit when
:func:`~prompt_toolkit.application.Application.exit()` is called.


The layout
----------

A layered layout architecture
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

There are several ways to create a prompt_toolkit layout, depending on how
customizable you want things to be. In fact, there are several layers of
abstraction.

- The most low-level way of creating a layout is by combining
  :class:`~prompt_toolkit.layout.Container` and
  :class:`~prompt_toolkit.layout.UIControl` objects.

  Examples of :class:`~prompt_toolkit.layout.Container` objects are
  :class:`~prompt_toolkit.layout.VSplit` (vertical split),
  :class:`~prompt_toolkit.layout.HSplit` (horizontal split) and
  :class:`~prompt_toolkit.layout.FloatContainer`. These containers arrange the
  layout and can split it in multiple regions. Each container can recursively
  contain multiple other containers. They can be combined in any way to define
  the "shape" of the layout.

  The :class:`~prompt_toolkit.layout.Window` object is a special kind of
  container that can contain a :class:`~prompt_toolkit.layout.UIControl`
  object. The :class:`~prompt_toolkit.layout.UIControl` object is responsible
  for the generation of the actual content. The
  :class:`~prompt_toolkit.layout.Window` object acts as an adaptor between the
  :class:`~prompt_toolkit.layout.UIControl` and other containers, but it's also
  responsible for the scrolling and line wrapping of the content.

  Examples of :class:`~prompt_toolkit.layout.UIControl` objects are
  :class:`~prompt_toolkit.layout.BufferControl` for showing the content of an
  editable/scrollable buffer, and
  :class:`~prompt_toolkit.layout.FormattedTextControl` for displaying
  (:ref:`formatted <formatted_text>`) text.

  Normally, it is never needed to create new
  :class:`~prompt_toolkit.layout.UIControl` or
  :class:`~prompt_toolkit.layout.Container` classes, but instead you would
  create the layout by composing instances of the existing built-ins.

- A higher level abstraction of building a layout is by using "widgets". A
  widget is a reusable layout component that can contain multiple containers
  and controls. Widgets have a ``__pt_container__`` function, which returns
  the root container for this widget. Prompt_toolkit contains a couple of
  widgets like :class:`~prompt_toolkit.widgets.TextArea`,
  :class:`~prompt_toolkit.widgets.Button`,
  :class:`~prompt_toolkit.widgets.Frame`,
  :class:`~prompt_toolkit.widgets.VerticalLine` and so on.

- The highest level abstractions can be found in the ``shortcuts`` module.
  There we don't have to think about the layout, controls and containers at
  all. This is the simplest way to use prompt_toolkit, but is only meant for
  specific use cases, like a prompt or a simple dialog window.

Containers and controls
^^^^^^^^^^^^^^^^^^^^^^^

The biggest difference between containers and controls is that containers
arrange the layout by splitting the screen in many regions, while controls are
responsible for generating the actual content.

.. note::

   Under the hood, the difference is:

   - containers use *absolute coordinates*, and paint on a
     :class:`~prompt_toolkit.layout.screen.Screen` instance.
   - user controls create a :class:`~prompt_toolkit.layout.controls.UIContent`
     instance. This is a collection of lines that represent the actual
     content. A :class:`~prompt_toolkit.layout.controls.UIControl` is not aware
     of the screen.

+---------------------------------------------+------------------------------------------------------+
| Abstract base class                         | Examples                                             |
+=============================================+======================================================+
| :class:`~prompt_toolkit.layout.Container`   | :class:`~prompt_toolkit.layout.HSplit`               |
|                                             | :class:`~prompt_toolkit.layout.VSplit`               |
|                                             | :class:`~prompt_toolkit.layout.FloatContainer`       |
|                                             | :class:`~prompt_toolkit.layout.Window`               |
|                                             | :class:`~prompt_toolkit.layout.ScrollablePane`       |
+---------------------------------------------+------------------------------------------------------+
| :class:`~prompt_toolkit.layout.UIControl`   | :class:`~prompt_toolkit.layout.BufferControl`        |
|                                             | :class:`~prompt_toolkit.layout.FormattedTextControl` |
+---------------------------------------------+------------------------------------------------------+

The :class:`~prompt_toolkit.layout.Window` class itself is
particular: it is a :class:`~prompt_toolkit.layout.Container` that
can contain a :class:`~prompt_toolkit.layout.UIControl`. Thus, it's the adaptor
between the two. The :class:`~prompt_toolkit.layout.Window` class also takes
care of scrolling the content and wrapping the lines if needed.

Finally, there is the :class:`~prompt_toolkit.layout.Layout` class which wraps
the whole layout. This is responsible for keeping track of which window has the
focus.

Here is an example of a layout that displays the content of the default buffer
on the left, and displays ``"Hello world"`` on the right. In between it shows a
vertical line:

.. code:: python

    from prompt_toolkit import Application
    from prompt_toolkit.buffer import Buffer
    from prompt_toolkit.layout.containers import VSplit, Window
    from prompt_toolkit.layout.controls import BufferControl, FormattedTextControl
    from prompt_toolkit.layout.layout import Layout

    buffer1 = Buffer()  # Editable buffer.

    root_container = VSplit([
        # One window that holds the BufferControl with the default buffer on
        # the left.
        Window(content=BufferControl(buffer=buffer1)),

        # A vertical line in the middle. We explicitly specify the width, to
        # make sure that the layout engine will not try to divide the whole
        # width by three for all these windows. The window will simply fill its
        # content by repeating this character.
        Window(width=1, char='|'),

        # Display the text 'Hello world' on the right.
        Window(content=FormattedTextControl(text='Hello world')),
    ])

    layout = Layout(root_container)

    app = Application(layout=layout, full_screen=True)
    app.run() # You won't be able to Exit this app

Notice that if you execute this right now, there is no way to quit this
application yet. This is something we explain in the next section below.

More complex layouts can be achieved by nesting multiple
:class:`~prompt_toolkit.layout.VSplit`,
:class:`~prompt_toolkit.layout.HSplit` and
:class:`~prompt_toolkit.layout.FloatContainer` objects.

If you want to make some part of the layout only visible when a certain
condition is satisfied, use a
:class:`~prompt_toolkit.layout.ConditionalContainer`.

Finally, there is :class:`~prompt_toolkit.layout.ScrollablePane`, a container
class that can be used to create long forms or nested layouts that are
scrollable as a whole.


Focusing windows
^^^^^^^^^^^^^^^^^

Focusing something can be done by calling the
:meth:`~prompt_toolkit.layout.Layout.focus` method. This method is very
flexible and accepts a :class:`~prompt_toolkit.layout.Window`, a
:class:`~prompt_toolkit.buffer.Buffer`, a
:class:`~prompt_toolkit.layout.controls.UIControl` and more.

In the following example, we use :func:`~prompt_toolkit.application.get_app`
for getting the active application.

.. code:: python

    from prompt_toolkit.application import get_app

    # This window was created earlier.
    w = Window()

    # ...

    # Now focus it.
    get_app().layout.focus(w)

Changing the focus is something which is typically done in a key binding, so
read on to see how to define key bindings.

Key bindings
------------

In order to react to user actions, we need to create a
:class:`~prompt_toolkit.key_binding.KeyBindings` object and pass
that to our :class:`~prompt_toolkit.application.Application`.

There are two kinds of key bindings:

- Global key bindings, which are always active.
- Key bindings that belong to a certain
  :class:`~prompt_toolkit.layout.controls.UIControl` and are only active when
  this control is focused. Both
  :class:`~prompt_toolkit.layout.BufferControl`
  :class:`~prompt_toolkit.layout.FormattedTextControl` take a ``key_bindings``
  argument.


Global key bindings
^^^^^^^^^^^^^^^^^^^

Key bindings can be passed to the application as follows:

.. code:: python

    from prompt_toolkit import Application
    from prompt_toolkit.key_binding import KeyBindings

    kb = KeyBindings()
    app = Application(key_bindings=kb)
    app.run()

To register a new keyboard shortcut, we can use the
:meth:`~prompt_toolkit.key_binding.KeyBindings.add` method as a decorator of
the key handler:

.. code:: python

    from prompt_toolkit import Application
    from prompt_toolkit.key_binding import KeyBindings

    kb = KeyBindings()

    @kb.add('c-q')
    def exit_(event):
        """
        Pressing Ctrl-Q will exit the user interface.

        Setting a return value means: quit the event loop that drives the user
        interface and return this value from the `Application.run()` call.
        """
        event.app.exit()

    app = Application(key_bindings=kb, full_screen=True)
    app.run()

The callback function is named ``exit_`` for clarity, but it could have been
named ``_`` (underscore) as well, because we won't refer to this name.

:ref:`Read more about key bindings ...<key_bindings>`


Modal containers
^^^^^^^^^^^^^^^^

The following container objects take a ``modal`` argument
:class:`~prompt_toolkit.layout.VSplit`,
:class:`~prompt_toolkit.layout.HSplit`, and
:class:`~prompt_toolkit.layout.FloatContainer`.

Setting ``modal=True`` makes what is called a **modal** container. Normally, a
child container would inherit its parent key bindings. This does not apply to
**modal** containers.

Consider a **modal** container (e.g. :class:`~prompt_toolkit.layout.VSplit`)
is child of another container, its parent. Any key bindings from the parent
are not taken into account if the **modal** container (child) has the focus.

This is useful in a complex layout, where many controls have their own key
bindings, but you only want to enable the key bindings for a certain region of
the layout.

The global key bindings are always active.


More about the Window class
---------------------------

As said earlier, a :class:`~prompt_toolkit.layout.Window` is a
:class:`~prompt_toolkit.layout.Container` that wraps a
:class:`~prompt_toolkit.layout.UIControl`, like a
:class:`~prompt_toolkit.layout.BufferControl` or
:class:`~prompt_toolkit.layout.FormattedTextControl`.

.. note::

    Basically, windows are the leaves in the tree structure that represent the UI.

A :class:`~prompt_toolkit.layout.Window` provides a "view" on the
:class:`~prompt_toolkit.layout.UIControl`, which provides lines of content. The
window is in the first place responsible for the line wrapping and scrolling of
the content, but there are much more options.

- Adding left or right margins. These are used for displaying scroll bars or
  line numbers.
- There are the `cursorline` and `cursorcolumn` options. These allow
  highlighting the line or column of the cursor position.
- Alignment of the content. The content can be left aligned, right aligned or
  centered.
- Finally, the background can be filled with a default character.


More about buffers and `BufferControl`
--------------------------------------



Input processors
^^^^^^^^^^^^^^^^

A :class:`~prompt_toolkit.layout.processors.Processor` is used to postprocess
the content of a :class:`~prompt_toolkit.layout.BufferControl` before it's
displayed. It can for instance highlight matching brackets or change the
visualization of tabs and so on.

A :class:`~prompt_toolkit.layout.processors.Processor` operates on individual
lines. Basically, it takes a (formatted) line and produces a new (formatted)
line.

Some built-in processors:

+----------------------------------------------------------------------------+-----------------------------------------------------------+
| Processor                                                                  | Usage:                                                    |
+============================================================================+===========================================================+
| :class:`~prompt_toolkit.layout.processors.HighlightSearchProcessor`        | Highlight the current search results.                     |
+----------------------------------------------------------------------------+-----------------------------------------------------------+
| :class:`~prompt_toolkit.layout.processors.HighlightSelectionProcessor`     | Highlight the selection.                                  |
+----------------------------------------------------------------------------+-----------------------------------------------------------+
| :class:`~prompt_toolkit.layout.processors.PasswordProcessor`               | Display input as asterisks. (``*`` characters).           |
+----------------------------------------------------------------------------+-----------------------------------------------------------+
| :class:`~prompt_toolkit.layout.processors.BracketsMismatchProcessor`       | Highlight open/close mismatches for brackets.             |
+----------------------------------------------------------------------------+-----------------------------------------------------------+
| :class:`~prompt_toolkit.layout.processors.BeforeInput`                     | Insert some text before.                                  |
+----------------------------------------------------------------------------+-----------------------------------------------------------+
| :class:`~prompt_toolkit.layout.processors.AfterInput`                      | Insert some text after.                                   |
+----------------------------------------------------------------------------+-----------------------------------------------------------+
| :class:`~prompt_toolkit.layout.processors.AppendAutoSuggestion`            | Append auto suggestion text.                              |
+----------------------------------------------------------------------------+-----------------------------------------------------------+
| :class:`~prompt_toolkit.layout.processors.ShowLeadingWhiteSpaceProcessor`  | Visualize leading whitespace.                             |
+----------------------------------------------------------------------------+-----------------------------------------------------------+
| :class:`~prompt_toolkit.layout.processors.ShowTrailingWhiteSpaceProcessor` | Visualize trailing whitespace.                            |
+----------------------------------------------------------------------------+-----------------------------------------------------------+
| :class:`~prompt_toolkit.layout.processors.TabsProcessor`                   | Visualize tabs as `n` spaces, or some symbols.            |
+----------------------------------------------------------------------------+-----------------------------------------------------------+

A :class:`~prompt_toolkit.layout.BufferControl` takes only one processor as
input, but it is possible to "merge" multiple processors into one with the
:func:`~prompt_toolkit.layout.processors.merge_processors` function.

---

### Pages Gallery (`docs/pages/gallery.rst`)

.. _gallery:

Gallery
=======

Showcase, demonstrating the possibilities of prompt_toolkit.

Ptpython, a Python REPL
^^^^^^^^^^^^^^^^^^^^^^^

The prompt:

.. image:: ../images/ptpython.png

The configuration menu of ptpython.

.. image:: ../images/ptpython-menu.png

The history page with its help. (This is a full-screen layout.)

.. image:: ../images/ptpython-history-help.png

Pyvim, a Vim clone
^^^^^^^^^^^^^^^^^^

.. image:: ../images/pyvim.png


Pymux, a terminal multiplexer (like tmux) in Python
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. image:: ../images/pymux.png

---

### Pages Getting Started (`docs/pages/getting_started.rst`)

.. _getting_started:

Getting started
===============

Installation
------------

::

    pip install prompt_toolkit

For Conda, do:

::

    conda install -c https://conda.anaconda.org/conda-forge prompt_toolkit


Several use cases: prompts versus full screen terminal applications
--------------------------------------------------------------------

`prompt_toolkit` was in the first place meant to be a replacement for readline.
However, when it became more mature, we realized that all the components for
full screen applications are there and `prompt_toolkit` is very capable of
handling many use situations. `Pyvim
<http://github.com/prompt-toolkit/pyvim>`_ and `pymux
<http://github.com/prompt-toolkit/pymux>`_ are examples of full screen
applications.

.. image:: ../images/pyvim.png

Basically, at the core, `prompt_toolkit` has a layout engine, that supports
horizontal and vertical splits as well as floats, where each "window" can
display a user control. The API for user controls is simple yet powerful.

When `prompt_toolkit` is used as a readline replacement, (to simply read some
input from the user), it uses a rather simple built-in layout. One that
displays the default input buffer and the prompt, a float for the
autocompletions and a toolbar for input validation which is hidden by default.

For full screen applications, usually we build a custom layout ourselves.

Further, there is a very flexible key binding system that can be programmed for
all the needs of full screen applications.


A simple prompt
---------------

The following snippet is the most simple example, it uses the
:func:`~prompt_toolkit.shortcuts.prompt` function to asks the user for input
and returns the text. Just like ``(raw_)input``.

.. code:: python

    from prompt_toolkit import prompt

    text = prompt("Give me some input: ")
    print(f"You said: {text}")


Learning `prompt_toolkit`
-------------------------

In order to learn and understand `prompt_toolkit`, it is best to go through the
all sections in the order below. Also don't forget to have a look at all the
`examples
<https://github.com/prompt-toolkit/python-prompt-toolkit/tree/master/examples>`_
in the repository.

- First, :ref:`learn how to print text <printing_text>`. This is important,
  because it covers how to use "formatted text", which is something you'll use
  whenever you want to use colors anywhere.

- Secondly, go through the :ref:`asking for input <asking_for_input>` section.
  This is useful for almost any use case, even for full screen applications.
  It covers autocompletions, syntax highlighting, key bindings, and so on.

- Then, learn about :ref:`dialogs`, which is easy and fun.

- Finally, learn about :ref:`full screen applications
  <full_screen_applications>` and read through :ref:`the advanced topics
  <advanced_topics>`.

---

### Pages Printing Text (`docs/pages/printing_text.rst`)

.. _printing_text:

Printing (and using) formatted text
===================================

Prompt_toolkit ships with a
:func:`~prompt_toolkit.shortcuts.print_formatted_text` function that's meant to
be (as much as possible) compatible with the built-in print function, but on
top of that, also supports colors and formatting.

On Linux systems, this will output VT100 escape sequences, while on Windows it
will use Win32 API calls or VT100 sequences, depending on what is available.

.. note::

        This page is also useful if you'd like to learn how to use formatting
        in other places, like in a prompt or a toolbar. Just like
        :func:`~prompt_toolkit.shortcuts.print_formatted_text` takes any kind
        of "formatted text" as input, prompts and toolbars also accept
        "formatted text".

Printing plain text
-------------------

The print function can be imported as follows:

.. code:: python

    from prompt_toolkit import print_formatted_text

    print_formatted_text('Hello world')

You can replace the built in ``print`` function as follows, if you want to.

.. code:: python

    from prompt_toolkit import print_formatted_text as print

    print('Hello world')

.. note::

    If you're using Python 2, make sure to add ``from __future__ import
    print_function``. Otherwise, it will not be possible to import a function
    named ``print``.

.. _formatted_text:

Formatted text
--------------

There are several ways to display colors:

- By creating an :class:`~prompt_toolkit.formatted_text.HTML` object.
- By creating an :class:`~prompt_toolkit.formatted_text.ANSI` object that
  contains ANSI escape sequences.
- By creating a list of ``(style, text)`` tuples.
- By creating a list of ``(pygments.Token, text)`` tuples, and wrapping it in
  :class:`~prompt_toolkit.formatted_text.PygmentsTokens`.

An instance of any of these four kinds of objects is called "formatted text".
There are various places in prompt toolkit, where we accept not just plain text
(as a string), but also formatted text.

HTML
^^^^

:class:`~prompt_toolkit.formatted_text.HTML` can be used to indicate that a
string contains HTML-like formatting. It recognizes the basic tags for bold,
italic and underline: ``<b>``, ``<i>`` and ``<u>``.

.. code:: python

    from prompt_toolkit import print_formatted_text, HTML

    print_formatted_text(HTML('<b>This is bold</b>'))
    print_formatted_text(HTML('<i>This is italic</i>'))
    print_formatted_text(HTML('<u>This is underlined</u>'))

Further, it's possible to use tags for foreground colors:

.. code:: python

    # Colors from the ANSI palette.
    print_formatted_text(HTML('<ansired>This is red</ansired>'))
    print_formatted_text(HTML('<ansigreen>This is green</ansigreen>'))

    # Named colors (256 color palette, or true color, depending on the output).
    print_formatted_text(HTML('<skyblue>This is sky blue</skyblue>'))
    print_formatted_text(HTML('<seagreen>This is sea green</seagreen>'))
    print_formatted_text(HTML('<violet>This is violet</violet>'))

Both foreground and background colors can also be specified setting the `fg`
and `bg` attributes of any HTML tag:

.. code:: python

    # Colors from the ANSI palette.
    print_formatted_text(HTML('<aaa fg="ansiwhite" bg="ansigreen">White on green</aaa>'))

Underneath, all HTML tags are mapped to classes from a stylesheet, so you can
assign a style for a custom tag.

.. code:: python

    from prompt_toolkit import print_formatted_text, HTML
    from prompt_toolkit.styles import Style

    style = Style.from_dict({
        'aaa': '#ff0066',
        'bbb': '#44ff00 italic',
    })

    print_formatted_text(HTML('<aaa>Hello</aaa> <bbb>world</bbb>!'), style=style)


ANSI
^^^^

Some people like to use the VT100 ANSI escape sequences to generate output.
Natively, this is however only supported on VT100 terminals, but prompt_toolkit
can parse these, and map them to formatted text instances. This means that they
will work on Windows as well. The :class:`~prompt_toolkit.formatted_text.ANSI`
class takes care of that.

.. code:: python

    from prompt_toolkit import print_formatted_text, ANSI

    print_formatted_text(ANSI('\x1b[31mhello \x1b[32mworld'))

Keep in mind that even on a Linux VT100 terminal, the final output produced by
prompt_toolkit, is not necessarily exactly the same. Depending on the color
depth, it is possible that colors are mapped to different colors, and unknown
tags will be removed.


(style, text) tuples
^^^^^^^^^^^^^^^^^^^^

Internally, both :class:`~prompt_toolkit.formatted_text.HTML` and
:class:`~prompt_toolkit.formatted_text.ANSI` objects are mapped to a list of
``(style, text)`` tuples. It is however also possible to create such a list
manually with :class:`~prompt_toolkit.formatted_text.FormattedText` class.
This is a little more verbose, but it's probably the most powerful
way of expressing formatted text.

.. code:: python

    from prompt_toolkit import print_formatted_text
    from prompt_toolkit.formatted_text import FormattedText

    text = FormattedText([
        ('#ff0066', 'Hello'),
        ('', ' '),
        ('#44ff00 italic', 'World'),
    ])

    print_formatted_text(text)

Similar to the :class:`~prompt_toolkit.formatted_text.HTML` example, it is also
possible to use class names, and separate the styling in a style sheet.

.. code:: python

    from prompt_toolkit import print_formatted_text
    from prompt_toolkit.formatted_text import FormattedText
    from prompt_toolkit.styles import Style

    # The text.
    text = FormattedText([
        ('class:aaa', 'Hello'),
        ('', ' '),
        ('class:bbb', 'World'),
    ])

    # The style sheet.
    style = Style.from_dict({
        'aaa': '#ff0066',
        'bbb': '#44ff00 italic',
    })

    print_formatted_text(text, style=style)


Pygments ``(Token, text)`` tuples
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When you have a list of `Pygments <http://pygments.org/>`_ ``(Token, text)``
tuples, then these can be printed by wrapping them in a
:class:`~prompt_toolkit.formatted_text.PygmentsTokens` object.

.. code:: python

    from pygments.token import Token
    from prompt_toolkit import print_formatted_text
    from prompt_toolkit.formatted_text import PygmentsTokens

    text = [
        (Token.Keyword, 'print'),
        (Token.Punctuation, '('),
        (Token.Literal.String.Double, '"'),
        (Token.Literal.String.Double, 'hello'),
        (Token.Literal.String.Double, '"'),
        (Token.Punctuation, ')'),
        (Token.Text, '\n'),
    ]

    print_formatted_text(PygmentsTokens(text))


Similarly, it is also possible to print the output of a Pygments lexer:

.. code:: python

    import pygments
    from pygments.token import Token
    from pygments.lexers.python import PythonLexer

    from prompt_toolkit.formatted_text import PygmentsTokens
    from prompt_toolkit import print_formatted_text

    # Printing the output of a pygments lexer.
    tokens = list(pygments.lex('print("Hello")', lexer=PythonLexer()))
    print_formatted_text(PygmentsTokens(tokens))

Prompt_toolkit ships with a default colorscheme which styles it just like
Pygments would do, but if you'd like to change the colors, keep in mind that
Pygments tokens map to classnames like this:

+-----------------------------------+---------------------------------------------+
| pygments.Token                    | prompt_toolkit classname                    |
+===================================+=============================================+
| - ``Token.Keyword``               | - ``"class:pygments.keyword"``              |
| - ``Token.Punctuation``           | - ``"class:pygments.punctuation"``          |
| - ``Token.Literal.String.Double`` | - ``"class:pygments.literal.string.double"``|
| - ``Token.Text``                  | - ``"class:pygments.text"``                 |
| - ``Token``                       | - ``"class:pygments"``                      |
+-----------------------------------+---------------------------------------------+

A classname like ``pygments.literal.string.double`` is actually decomposed in
the following four classnames: ``pygments``, ``pygments.literal``,
``pygments.literal.string`` and ``pygments.literal.string.double``. The final
style is computed by combining the style for these four classnames. So,
changing the style from these Pygments tokens can be done as follows:

.. code:: python

    from prompt_toolkit.styles import Style

    style = Style.from_dict({
        'pygments.keyword': 'underline',
        'pygments.literal.string': 'bg:#00ff00 #ffffff',
    })
    print_formatted_text(PygmentsTokens(tokens), style=style)


to_formatted_text
^^^^^^^^^^^^^^^^^

A useful function to know about is
:func:`~prompt_toolkit.formatted_text.to_formatted_text`. This ensures that the
given input is valid formatted text. While doing so, an additional style can be
applied as well.

.. code:: python

    from prompt_toolkit.formatted_text import to_formatted_text, HTML
    from prompt_toolkit import print_formatted_text

    html = HTML('<aaa>Hello</aaa> <bbb>world</bbb>!')
    text = to_formatted_text(html, style='class:my_html bg:#00ff00 italic')

    print_formatted_text(text)

---

### Pages Progress Bars (`docs/pages/progress_bars.rst`)

.. _progress_bars:

Progress bars
=============

Prompt_toolkit ships with a high level API for displaying progress bars,
inspired by `tqdm <https://github.com/tqdm/tqdm>`_

.. warning::

    The API for the prompt_toolkit progress bars is still very new and can
    possibly change in the future. It is usable and tested, but keep this in
    mind when upgrading.

Remember that the `examples directory <https://github.com/prompt-toolkit/python-prompt-toolkit/tree/master/examples>`_
of the prompt_toolkit repository ships with many progress bar examples as well.


Simple progress bar
-------------------

Creating a new progress bar can be done by calling the
:class:`~prompt_toolkit.shortcuts.ProgressBar` context manager.

The progress can be displayed for any iterable. This works by wrapping the
iterable (like ``range``) with the
:class:`~prompt_toolkit.shortcuts.ProgressBar` context manager itself. This
way, the progress bar knows when the next item is consumed by the forloop and
when progress happens.

.. code:: python

    from prompt_toolkit.shortcuts import ProgressBar
    import time


    with ProgressBar() as pb:
        for i in pb(range(800)):
            time.sleep(.01)

.. image:: ../images/progress-bars/simple-progress-bar.png

Keep in mind that not all iterables can report their total length. This happens
with a typical generator. In that case, you can still pass the total as follows
in order to make displaying the progress possible:

.. code:: python

    def some_iterable():
        yield ...

    with ProgressBar() as pb:
        for i in pb(some_iterable(), total=1000):
            time.sleep(.01)


Multiple parallel tasks
-----------------------

A prompt_toolkit :class:`~prompt_toolkit.shortcuts.ProgressBar` can display the
progress of multiple tasks running in parallel. Each task can run in a separate
thread and the :class:`~prompt_toolkit.shortcuts.ProgressBar` user interface
runs in its own thread.

Notice that we set the "daemon" flag for both threads that run the tasks. This
is because control-c will stop the progress and quit our application. We don't
want the application to wait for the background threads to finish. Whether you
want this depends on the application.

.. code:: python

    from prompt_toolkit.shortcuts import ProgressBar
    import time
    import threading


    with ProgressBar() as pb:
        # Two parallel tasks.
        def task_1():
            for i in pb(range(100)):
                time.sleep(.05)

        def task_2():
            for i in pb(range(150)):
                time.sleep(.08)

        # Start threads.
        t1 = threading.Thread(target=task_1)
        t2 = threading.Thread(target=task_2)
        t1.daemon = True
        t2.daemon = True
        t1.start()
        t2.start()

        # Wait for the threads to finish. We use a timeout for the join() call,
        # because on Windows, join cannot be interrupted by Control-C or any other
        # signal.
        for t in [t1, t2]:
            while t.is_alive():
                t.join(timeout=.5)

.. image:: ../images/progress-bars/two-tasks.png


Adding a title and label
------------------------

Each progress bar can have one title, and for each task an individual label.
Both the title and the labels can be :ref:`formatted text <formatted_text>`.

.. code:: python

    from prompt_toolkit.shortcuts import ProgressBar
    from prompt_toolkit.formatted_text import HTML
    import time

    title = HTML('Downloading <style bg="yellow" fg="black">4 files...</style>')
    label = HTML('<ansired>some file</ansired>: ')

    with ProgressBar(title=title) as pb:
        for i in pb(range(800), label=label):
            time.sleep(.01)

.. image:: ../images/progress-bars/colored-title-and-label.png


Formatting the progress bar
---------------------------

The visualization of a :class:`~prompt_toolkit.shortcuts.ProgressBar` can be
customized by using a different sequence of formatters. The default formatting
looks something like this:

.. code:: python

    from prompt_toolkit.shortcuts.progress_bar.formatters import *

    default_formatting = [
        Label(),
        Text(' '),
        Percentage(),
        Text(' '),
        Bar(),
        Text(' '),
        Progress(),
        Text(' '),
        Text('eta [', style='class:time-left'),
        TimeLeft(),
        Text(']', style='class:time-left'),
        Text(' '),
    ]

That sequence of
:class:`~prompt_toolkit.shortcuts.progress_bar.formatters.Formatter` can be
passed to the `formatter` argument of
:class:`~prompt_toolkit.shortcuts.ProgressBar`. So, we could change this and
modify the progress bar to look like an apt-get style progress bar:

.. code:: python

    from prompt_toolkit.shortcuts import ProgressBar
    from prompt_toolkit.styles import Style
    from prompt_toolkit.shortcuts.progress_bar import formatters
    import time

    style = Style.from_dict({
        'label': 'bg:#ffff00 #000000',
        'percentage': 'bg:#ffff00 #000000',
        'current': '#448844',
        'bar': '',
    })


    custom_formatters = [
        formatters.Label(),
        formatters.Text(': [', style='class:percentage'),
        formatters.Percentage(),
        formatters.Text(']', style='class:percentage'),
        formatters.Text(' '),
        formatters.Bar(sym_a='#', sym_b='#', sym_c='.'),
        formatters.Text('  '),
    ]

    with ProgressBar(style=style, formatters=custom_formatters) as pb:
        for i in pb(range(1600), label='Installing'):
            time.sleep(.01)

.. image:: ../images/progress-bars/apt-get.png


Adding key bindings and toolbar
-------------------------------

Like other prompt_toolkit applications, we can add custom key bindings, by
passing a :class:`~prompt_toolkit.key_binding.KeyBindings` object:

.. code:: python

    from prompt_toolkit import HTML
    from prompt_toolkit.key_binding import KeyBindings
    from prompt_toolkit.patch_stdout import patch_stdout
    from prompt_toolkit.shortcuts import ProgressBar

    import os
    import time
    import signal

    bottom_toolbar = HTML(' <b>[f]</b> Print "f" <b>[x]</b> Abort.')

    # Create custom key bindings first.
    kb = KeyBindings()
    cancel = [False]

    @kb.add('f')
    def _(event):
        print('You pressed `f`.')

    @kb.add('x')
    def _(event):
        " Send Abort (control-c) signal. "
        cancel[0] = True
        os.kill(os.getpid(), signal.SIGINT)

    # Use `patch_stdout`, to make sure that prints go above the
    # application.
    with patch_stdout():
        with ProgressBar(key_bindings=kb, bottom_toolbar=bottom_toolbar) as pb:
            for i in pb(range(800)):
                time.sleep(.01)

                # Stop when the cancel flag has been set.
                if cancel[0]:
                    break

Notice that we use :func:`~prompt_toolkit.patch_stdout.patch_stdout` to make
printing text possible while the progress bar is displayed. This ensures that
printing happens above the progress bar.

Further, when "x" is pressed, we set a cancel flag, which stops the progress.
It would also be possible to send `SIGINT` to the main thread, but that's not
always considered a clean way of cancelling something.

In the example above, we also display a toolbar at the bottom which shows the
key bindings.

.. image:: ../images/progress-bars/custom-key-bindings.png

:ref:`Read more about key bindings ...<key_bindings>`

---

### Pages Reference (`docs/pages/reference.rst`)

Reference
=========

Application
-----------

.. automodule:: prompt_toolkit.application
    :members: Application, get_app, get_app_or_none, set_app,
        create_app_session, AppSession, get_app_session, DummyApplication,
        in_terminal, run_in_terminal,


Formatted text
--------------

.. automodule:: prompt_toolkit.formatted_text
    :members:


Buffer
------

.. automodule:: prompt_toolkit.buffer
    :members:


Selection
---------

.. automodule:: prompt_toolkit.selection
    :members:


Clipboard
---------

.. automodule:: prompt_toolkit.clipboard
    :members: Clipboard, ClipboardData, DummyClipboard, DynamicClipboard, InMemoryClipboard

.. automodule:: prompt_toolkit.clipboard.pyperclip
    :members:


Auto completion
---------------

.. automodule:: prompt_toolkit.completion
    :members:


Document
--------

.. automodule:: prompt_toolkit.document
    :members:


Enums
-----

.. automodule:: prompt_toolkit.enums
    :members:


History
-------

.. automodule:: prompt_toolkit.history
    :members:


Keys
----

.. automodule:: prompt_toolkit.keys
    :members:


Style
-----

.. automodule:: prompt_toolkit.styles
    :members: Attrs, ANSI_COLOR_NAMES, BaseStyle, DummyStyle, DynamicStyle,
        Style, Priority, merge_styles, style_from_pygments_cls,
        style_from_pygments_dict, pygments_token_to_classname, NAMED_COLORS,
        StyleTransformation, SwapLightAndDarkStyleTransformation,
        AdjustBrightnessStyleTransformation, merge_style_transformations,
        DummyStyleTransformation, ConditionalStyleTransformation,
        DynamicStyleTransformation


Shortcuts
---------

.. automodule:: prompt_toolkit.shortcuts
    :members: prompt, PromptSession, confirm, CompleteStyle,
        create_confirm_session, clear, clear_title, print_formatted_text,
        set_title, ProgressBar, input_dialog, message_dialog, progress_dialog,
        radiolist_dialog, yes_no_dialog, button_dialog, choice

.. automodule:: prompt_toolkit.shortcuts.progress_bar.formatters
    :members:


Validation
----------

.. automodule:: prompt_toolkit.validation
    :members:


Auto suggestion
---------------

.. automodule:: prompt_toolkit.auto_suggest
    :members:


Renderer
--------

.. automodule:: prompt_toolkit.renderer
    :members:

Lexers
------

.. automodule:: prompt_toolkit.lexers
    :members:


Layout
------

.. automodule:: prompt_toolkit.layout

The layout class itself
^^^^^^^^^^^^^^^^^^^^^^^

.. autoclass:: prompt_toolkit.layout.Layout
    :members:

.. autoclass:: prompt_toolkit.layout.InvalidLayoutError
    :members:

.. autoclass:: prompt_toolkit.layout.walk
    :members:

Containers
^^^^^^^^^^

.. autoclass:: prompt_toolkit.layout.Container
    :members:

.. autoclass:: prompt_toolkit.layout.HSplit
    :members:

.. autoclass:: prompt_toolkit.layout.VSplit
    :members:

.. autoclass:: prompt_toolkit.layout.FloatContainer
    :members:

.. autoclass:: prompt_toolkit.layout.Float
    :members:

.. autoclass:: prompt_toolkit.layout.Window
    :members:

.. autoclass:: prompt_toolkit.layout.WindowAlign
    :members:

.. autoclass:: prompt_toolkit.layout.ConditionalContainer
    :members:

.. autoclass:: prompt_toolkit.layout.DynamicContainer
    :members:

.. autoclass:: prompt_toolkit.layout.ScrollablePane
    :members:

.. autoclass:: prompt_toolkit.layout.ScrollOffsets
    :members:

.. autoclass:: prompt_toolkit.layout.ColorColumn
    :members:

.. autoclass:: prompt_toolkit.layout.to_container
    :members:

.. autoclass:: prompt_toolkit.layout.to_window
    :members:

.. autoclass:: prompt_toolkit.layout.is_container
    :members:

.. autoclass:: prompt_toolkit.layout.HorizontalAlign
    :members:

.. autoclass:: prompt_toolkit.layout.VerticalAlign
    :members:

Controls
^^^^^^^^

.. autoclass:: prompt_toolkit.layout.BufferControl
    :members:

.. autoclass:: prompt_toolkit.layout.SearchBufferControl
    :members:

.. autoclass:: prompt_toolkit.layout.DummyControl
    :members:

.. autoclass:: prompt_toolkit.layout.FormattedTextControl
    :members:

.. autoclass:: prompt_toolkit.layout.UIControl
    :members:

.. autoclass:: prompt_toolkit.layout.UIContent
    :members:


Other
^^^^^


Sizing
""""""

.. autoclass:: prompt_toolkit.layout.Dimension
    :members:


Margins
"""""""

.. autoclass:: prompt_toolkit.layout.Margin
    :members:

.. autoclass:: prompt_toolkit.layout.NumberedMargin
    :members:

.. autoclass:: prompt_toolkit.layout.ScrollbarMargin
    :members:

.. autoclass:: prompt_toolkit.layout.ConditionalMargin
    :members:

.. autoclass:: prompt_toolkit.layout.PromptMargin
    :members:


Completion Menus
""""""""""""""""

.. autoclass:: prompt_toolkit.layout.CompletionsMenu
    :members:

.. autoclass:: prompt_toolkit.layout.MultiColumnCompletionsMenu
    :members:


Processors
""""""""""

.. automodule:: prompt_toolkit.layout.processors
    :members:


Utils
"""""

.. automodule:: prompt_toolkit.layout.utils
    :members:


Screen
""""""

.. automodule:: prompt_toolkit.layout.screen
    :members:


Widgets
-------

.. automodule:: prompt_toolkit.widgets
    :members: TextArea, Label, Button, Frame, Shadow, Box, VerticalLine,
        HorizontalLine, RadioList, Checkbox, ProgressBar, CompletionsToolbar,
        FormattedTextToolbar, SearchToolbar, SystemToolbar, ValidationToolbar,
        MenuContainer, MenuItem


Filters
-------

.. automodule:: prompt_toolkit.filters
    :members:

.. autoclass:: prompt_toolkit.filters.Filter
    :members:
    :no-index:

.. autoclass:: prompt_toolkit.filters.Condition
    :members:
    :no-index:

.. automodule:: prompt_toolkit.filters.utils
    :members:

.. automodule:: prompt_toolkit.filters.app
    :members:


Key binding
-----------

.. automodule:: prompt_toolkit.key_binding
    :members: KeyBindingsBase, KeyBindings, ConditionalKeyBindings,
        merge_key_bindings, DynamicKeyBindings

.. automodule:: prompt_toolkit.key_binding.defaults
    :members:

.. automodule:: prompt_toolkit.key_binding.vi_state
    :members:

.. automodule:: prompt_toolkit.key_binding.key_processor
    :members:


Eventloop
---------

.. automodule:: prompt_toolkit.eventloop
    :members: run_in_executor_with_context, call_soon_threadsafe,
        get_traceback_from_context

.. automodule:: prompt_toolkit.eventloop.inputhook
    :members:

.. automodule:: prompt_toolkit.eventloop.utils
    :members:


Input
-----

.. automodule:: prompt_toolkit.input
    :members: Input, DummyInput, create_input, create_pipe_input

.. automodule:: prompt_toolkit.input.vt100
    :members:

.. automodule:: prompt_toolkit.input.vt100_parser
    :members:

.. automodule:: prompt_toolkit.input.ansi_escape_sequences
    :members:

.. automodule:: prompt_toolkit.input.win32
    :members:

Output
------

.. automodule:: prompt_toolkit.output
    :members: Output, DummyOutput, ColorDepth, create_output

.. automodule:: prompt_toolkit.output.vt100
    :members:

.. automodule:: prompt_toolkit.output.win32
    :members:


Data structures
---------------

.. autoclass:: prompt_toolkit.layout.WindowRenderInfo
    :members:

.. autoclass:: prompt_toolkit.data_structures.Point
    :members:

.. autoclass:: prompt_toolkit.data_structures.Size
    :members:

Patch stdout
------------

.. automodule:: prompt_toolkit.patch_stdout
    :members: patch_stdout, StdoutProxy

---

### Pages Related Projects (`docs/pages/related_projects.rst`)

.. _related_projects:

Related projects
================

There are some other Python libraries that provide similar functionality that
are also worth checking out:

- `Urwid <http://urwid.org/>`_
- `Textual <https://textual.textualize.io/>`_
- `Rich <https://rich.readthedocs.io/>`_

---

### Pages Advanced Topics Architecture (`docs/pages/advanced_topics/architecture.rst`)

.. _architecture:


Architecture
============

TODO: this is a little outdated.

::

    +---------------------------------------------------------------+
    |     InputStream                                               |
    |     ===========                                               |
    |          - Parses the input stream coming from a VT100        |
    |            compatible terminal. Translates it into data input |
    |            and control characters. Calls the corresponding    |
    |            handlers of the `InputStreamHandler` instance.     |
    |                                                               |
    |          e.g. Translate '\x1b[6~' into "Keys.PageDown", call  |
    |               the `feed_key` method of `InputProcessor`.      |
    +---------------------------------------------------------------+
               |
               v
    +---------------------------------------------------------------+
    |     InputStreamHandler                                        |
    |     ==================                                        |
    |          - Has a `Registry` of key bindings, it calls the     |
    |            bindings according to the received keys and the    |
    |            input mode.                                        |
    |                                                               |
    |         We have Vi and Emacs bindings.
    +---------------------------------------------------------------+
               |
               v
    +---------------------------------------------------------------+
    |     Key bindings                                              |
    |     ============                                              |
    |          - Every key binding consists of a function that      |
    |            receives an `Event` and usually it operates on     |
    |            the `Buffer` object. (It could insert data or      |
    |            move the cursor for example.)                      |
    +---------------------------------------------------------------+
        |
        | Most of the key bindings operate on a `Buffer` object, but
        | they don't have to. They could also change the visibility
        | of a menu for instance, or change the color scheme.
        |
        v
    +---------------------------------------------------------------+
    |     Buffer                                                    |
    |     ======                                                    |
    |          - Contains a data structure to hold the current      |
    |            input (text and cursor position). This class       |
    |            implements all text manipulations and cursor       |
    |            movements (Like e.g. cursor_forward, insert_char   |
    |            or delete_word.)                                   |
    |                                                               |
    |            +-----------------------------------------------+  |
    |            | Document (text, cursor_position)              |  |
    |            | ================================              |  |
    |            | Accessed as the `document` property of the    |  |
    |            | `Buffer` class. This is a wrapper around the  |  |
    |            | text and cursor position, and contains        |  |
    |            | methods for querying this data , e.g. to give |  |
    |            | the text before the cursor.                   |  |
    |            +-----------------------------------------------+  |
    +---------------------------------------------------------------+
        |
        |  Normally after every key press, the output will be
        |  rendered again. This happens in the event loop of
        |  the `Application` where `Renderer.render` is called.
        v
    +---------------------------------------------------------------+
    |     Layout                                                    |
    |     ======                                                    |
    |          - When the renderer should redraw, the renderer      |
    |            asks the layout what the output should look like.  |
    |          - The layout operates on a `Screen` object that he   |
    |            received from the `Renderer` and will put the      |
    |            toolbars, menus, highlighted content and prompt    |
    |            in place.                                          |
    |                                                               |
    |            +-----------------------------------------------+  |
    |            | Menus, toolbars, prompt                       |  |
    |            | =======================                       |  |
    |            |                                               |  |
    |            +-----------------------------------------------+  |
    +---------------------------------------------------------------+
        |
        v
    +---------------------------------------------------------------+
    |     Renderer                                                  |
    |     ========                                                  |
    |          - Calculates the difference between the last output  |
    |            and the new one and writes it to the terminal      |
    |            output.                                            |
    +---------------------------------------------------------------+

---

### Pages Advanced Topics Asyncio (`docs/pages/advanced_topics/asyncio.rst`)

.. _asyncio:

Running on top of the `asyncio` event loop
==========================================

.. note::

    New in prompt_toolkit 3.0. (In prompt_toolkit 2.0 this was possible using a
    work-around).

Prompt_toolkit 3.0 uses asyncio natively. Calling ``Application.run()`` will
automatically run the asyncio event loop.

If however you want to run a prompt_toolkit ``Application`` within an asyncio
environment, you have to call the ``run_async`` method, like this:

.. code:: python

    from prompt_toolkit.application import Application

    async def main():
        # Define application.
        application = Application(
            ...
        )

        result = await application.run_async()
        print(result)

    asyncio.get_event_loop().run_until_complete(main())

---

### Pages Advanced Topics Filters (`docs/pages/advanced_topics/filters.rst`)

.. _filters:

Filters
=======

Many places in `prompt_toolkit` require a boolean value that can change over
time. For instance:

- to specify whether a part of the layout needs to be visible or not;
- or to decide whether a certain key binding needs to be active or not;
- or the ``wrap_lines`` option of
  :class:`~prompt_toolkit.layout.BufferControl`;
- etcetera.

These booleans are often dynamic and can change at runtime. For instance, the
search toolbar should only be visible when the user is actually searching (when
the search buffer has the focus). The ``wrap_lines`` option could be changed
with a certain key binding. And that key binding could only work when the
default buffer got the focus.

In `prompt_toolkit`, we decided to reduce the amount of state in the whole
framework, and apply a simple kind of reactive programming to describe the flow
of these booleans as expressions. (It's one-way only: if a key binding needs to
know whether it's active or not, it can follow this flow by evaluating an
expression.)

The (abstract) base class is :class:`~prompt_toolkit.filters.Filter`, which
wraps an expression that takes no input and evaluates to a boolean. Getting the
state of a filter is done by simply calling it.


An example
----------

The most obvious way to create such a :class:`~prompt_toolkit.filters.Filter`
instance is by creating a :class:`~prompt_toolkit.filters.Condition` instance
from a function. For instance, the following condition will evaluate to
``True`` when the user is searching:

.. code:: python

    from prompt_toolkit.application.current import get_app
    from prompt_toolkit.filters import Condition

    is_searching = Condition(lambda: get_app().is_searching)

A different way of writing this, is by using the decorator syntax:

.. code:: python

    from prompt_toolkit.application.current import get_app
    from prompt_toolkit.filters import Condition

    @Condition
    def is_searching():
        return get_app().is_searching

This filter can then be used in a key binding, like in the following snippet:

.. code:: python

    from prompt_toolkit.key_binding import KeyBindings

    kb = KeyBindings()

    @kb.add('c-t', filter=is_searching)
    def _(event):
        # Do, something, but only when searching.
        pass

If we want to know the boolean value of this filter, we have to call it like a
function:

.. code:: python

    print(is_searching())


Built-in filters
----------------

There are many built-in filters, ready to use. All of them have a lowercase
name, because they represent the wrapped function underneath, and can be called
as a function.

- :class:`~prompt_toolkit.filters.app.has_arg`
- :class:`~prompt_toolkit.filters.app.has_completions`
- :class:`~prompt_toolkit.filters.app.has_focus`
- :class:`~prompt_toolkit.filters.app.buffer_has_focus`
- :class:`~prompt_toolkit.filters.app.has_selection`
- :class:`~prompt_toolkit.filters.app.has_validation_error`
- :class:`~prompt_toolkit.filters.app.is_aborting`
- :class:`~prompt_toolkit.filters.app.is_done`
- :class:`~prompt_toolkit.filters.app.is_read_only`
- :class:`~prompt_toolkit.filters.app.is_multiline`
- :class:`~prompt_toolkit.filters.app.renderer_height_is_known`
- :class:`~prompt_toolkit.filters.app.in_editing_mode`
- :class:`~prompt_toolkit.filters.app.in_paste_mode`

- :class:`~prompt_toolkit.filters.app.vi_mode`
- :class:`~prompt_toolkit.filters.app.vi_navigation_mode`
- :class:`~prompt_toolkit.filters.app.vi_insert_mode`
- :class:`~prompt_toolkit.filters.app.vi_insert_multiple_mode`
- :class:`~prompt_toolkit.filters.app.vi_replace_mode`
- :class:`~prompt_toolkit.filters.app.vi_selection_mode`
- :class:`~prompt_toolkit.filters.app.vi_waiting_for_text_object_mode`
- :class:`~prompt_toolkit.filters.app.vi_digraph_mode`

- :class:`~prompt_toolkit.filters.app.emacs_mode`
- :class:`~prompt_toolkit.filters.app.emacs_insert_mode`
- :class:`~prompt_toolkit.filters.app.emacs_selection_mode`

- :class:`~prompt_toolkit.filters.app.is_searching`
- :class:`~prompt_toolkit.filters.app.control_is_searchable`
- :class:`~prompt_toolkit.filters.app.vi_search_direction_reversed`


Combining filters
-----------------

Filters can be chained with the ``&`` (AND) and ``|`` (OR) operators and
negated with the ``~`` (negation) operator.

Some examples:

.. code:: python

    from prompt_toolkit.key_binding import KeyBindings
    from prompt_toolkit.filters import has_selection, has_selection

    kb = KeyBindings()

    @kb.add('c-t', filter=~is_searching)
    def _(event):
        " Do something, but not while searching. "
        pass

    @kb.add('c-t', filter=has_search | has_selection)
    def _(event):
        " Do something, but only when searching or when there is a selection. "
        pass


to_filter
---------

Finally, in many situations you want your code to expose an API that is able to
deal with both booleans as well as filters. For instance, when for most users a
boolean works fine because they don't need to change the value over time, while
some advanced users want to be able this value to a certain setting or event
that does changes over time.

In order to handle both use cases, there is a utility called
:func:`~prompt_toolkit.filters.utils.to_filter`.

This is a function that takes
either a boolean or an actual :class:`~prompt_toolkit.filters.Filter`
instance, and always returns a :class:`~prompt_toolkit.filters.Filter`.

.. code:: python

    from prompt_toolkit.filters.utils import to_filter

    # In each of the following three examples, 'f' will be a `Filter`
    # instance.
    f = to_filter(True)
    f = to_filter(False)
    f = to_filter(Condition(lambda: True))
    f = to_filter(has_search | has_selection)

---

### Pages Advanced Topics Index (`docs/pages/advanced_topics/index.rst`)

.. _advanced_topics:

Advanced topics
===============

.. toctree::
    :caption: Contents:
    :maxdepth: 1

    key_bindings
    styling
    filters
    rendering_flow
    asyncio
    unit_testing
    input_hooks
    architecture
    rendering_pipeline

---

### Pages Advanced Topics Input Hooks (`docs/pages/advanced_topics/input_hooks.rst`)

.. _input_hooks:


Input hooks
===========

Input hooks are a tool for inserting an external event loop into the
prompt_toolkit event loop, so that the other loop can run as long as
prompt_toolkit (actually asyncio) is idle. This is used in applications like
`IPython <https://ipython.org/>`_, so that GUI toolkits can display their
windows while we wait at the prompt for user input.

As a consequence, we will "trampoline" back and forth between two event loops.

.. note::

    This will use a :class:`~asyncio.SelectorEventLoop`, not the
    :class:`~asyncio.ProactorEventLoop` (on Windows) due to the way the
    implementation works (contributions are welcome to make that work).


.. code:: python

    from prompt_toolkit.eventloop.inputhook import set_eventloop_with_inputhook

    def inputhook(inputhook_context):
        # At this point, we run the other loop. This loop is supposed to run
        # until either `inputhook_context.fileno` becomes ready for reading or
        # `inputhook_context.input_is_ready()` returns True.

        # A good way is to register this file descriptor in this other event
        # loop with a callback that stops this loop when this FD becomes ready.
        # There is no need to actually read anything from the FD.

        while True:
            ...

    set_eventloop_with_inputhook(inputhook)

    # Any asyncio code at this point will now use this new loop, with input
    # hook installed.

---

### Pages Advanced Topics Key Bindings (`docs/pages/advanced_topics/key_bindings.rst`)

.. _key_bindings:

More about key bindings
=======================

This page contains a few additional notes about key bindings.


Key bindings can be defined as follows by creating a
:class:`~prompt_toolkit.key_binding.KeyBindings` instance:


.. code:: python

    from prompt_toolkit.key_binding import KeyBindings

    bindings = KeyBindings()

    @bindings.add('a')
    def _(event):
        " Do something if 'a' has been pressed. "
        ...


    @bindings.add('c-t')
    def _(event):
        " Do something if Control-T has been pressed. "
        ...

.. note::

    :kbd:`c-q` (control-q) and :kbd:`c-s` (control-s) are often captured by the
    terminal, because they were used traditionally for software flow control.
    When this is enabled, the application will automatically freeze when
    :kbd:`c-s` is pressed, until :kbd:`c-q` is pressed. It won't be possible to
    bind these keys.

    In order to disable this, execute the following command in your shell, or even
    add it to your `.bashrc`.

    .. code::

        stty -ixon

Key bindings can even consist of a sequence of multiple keys. The binding is
only triggered when all the keys in this sequence are pressed.

.. code:: python

    @bindings.add('a', 'b')
    def _(event):
        " Do something if 'a' is pressed and then 'b' is pressed. "
        ...

If the user presses only `a`, then nothing will happen until either a second
key (like `b`) has been pressed or until the timeout expires (see later).


List of special keys
--------------------

Besides literal characters, any of the following keys can be used in a key
binding:

+-------------------+-----------------------------------------+
| Name              + Possible keys                           |
+===================+=========================================+
| Escape            | :kbd:`escape`                           |
| Shift + escape    | :kbd:`s-escape`                         |
+-------------------+-----------------------------------------+
| Arrows            | :kbd:`left`,                            |
|                   | :kbd:`right`,                           |
|                   | :kbd:`up`,                              |
|                   | :kbd:`down`                             |
+-------------------+-----------------------------------------+
| Navigation        | :kbd:`home`,                            |
|                   | :kbd:`end`,                             |
|                   | :kbd:`delete`,                          |
|                   | :kbd:`pageup`,                          |
|                   | :kbd:`pagedown`,                        |
|                   | :kbd:`insert`                           |
+-------------------+-----------------------------------------+
| Control+letter    | :kbd:`c-a`, :kbd:`c-b`, :kbd:`c-c`,     |
|                   | :kbd:`c-d`, :kbd:`c-e`, :kbd:`c-f`,     |
|                   | :kbd:`c-g`, :kbd:`c-h`, :kbd:`c-i`,     |
|                   | :kbd:`c-j`, :kbd:`c-k`, :kbd:`c-l`,     |
|                   |                                         |
|                   | :kbd:`c-m`, :kbd:`c-n`, :kbd:`c-o`,     |
|                   | :kbd:`c-p`, :kbd:`c-q`, :kbd:`c-r`,     |
|                   | :kbd:`c-s`, :kbd:`c-t`, :kbd:`c-u`,     |
|                   | :kbd:`c-v`, :kbd:`c-w`, :kbd:`c-x`,     |
|                   |                                         |
|                   | :kbd:`c-y`, :kbd:`c-z`                  |
+-------------------+-----------------------------------------+
| Control + number  | :kbd:`c-1`, :kbd:`c-2`, :kbd:`c-3`,     |
|                   | :kbd:`c-4`, :kbd:`c-5`, :kbd:`c-6`,     |
|                   | :kbd:`c-7`, :kbd:`c-8`, :kbd:`c-9`,     |
|                   | :kbd:`c-0`                              |
+-------------------+-----------------------------------------+
| Control + arrow   | :kbd:`c-left`,                          |
|                   | :kbd:`c-right`,                         |
|                   | :kbd:`c-up`,                            |
|                   | :kbd:`c-down`                           |
+-------------------+-----------------------------------------+
| Other control     | :kbd:`c-@`,                             |
| keys              | :kbd:`c-\\`,                            |
|                   | :kbd:`c-]`,                             |
|                   | :kbd:`c-^`,                             |
|                   | :kbd:`c-_`,                             |
|                   | :kbd:`c-delete`                         |
+-------------------+-----------------------------------------+
| Shift + arrow     | :kbd:`s-left`,                          |
|                   | :kbd:`s-right`,                         |
|                   | :kbd:`s-up`,                            |
|                   | :kbd:`s-down`                           |
+-------------------+-----------------------------------------+
| Control + Shift + | :kbd:`c-s-left`,                        |
| arrow             | :kbd:`c-s-right`,                       |
|                   | :kbd:`c-s-up`,                          |
|                   | :kbd:`c-s-down`                         |
+-------------------+-----------------------------------------+
| Other shift       | :kbd:`s-delete`,                        |
| keys              | :kbd:`s-tab`                            |
+-------------------+-----------------------------------------+
| F-keys            | :kbd:`f1`, :kbd:`f2`, :kbd:`f3`,        |
|                   | :kbd:`f4`, :kbd:`f5`, :kbd:`f6`,        |
|                   | :kbd:`f7`, :kbd:`f8`, :kbd:`f9`,        |
|                   | :kbd:`f10`, :kbd:`f11`, :kbd:`f12`,     |
|                   |                                         |
|                   | :kbd:`f13`, :kbd:`f14`, :kbd:`f15`,     |
|                   | :kbd:`f16`, :kbd:`f17`, :kbd:`f18`,     |
|                   | :kbd:`f19`, :kbd:`f20`, :kbd:`f21`,     |
|                   | :kbd:`f22`, :kbd:`f23`, :kbd:`f24`      |
+-------------------+-----------------------------------------+

There are a couple of useful aliases as well:

+-------------------+-------------------+
| :kbd:`c-h`        | :kbd:`backspace`  |
+-------------------+-------------------+
| :kbd:`c-@`        | :kbd:`c-space`    |
+-------------------+-------------------+
| :kbd:`c-m`        | :kbd:`enter`      |
+-------------------+-------------------+
| :kbd:`c-i`        | :kbd:`tab`        |
+-------------------+-------------------+

.. note::

    Note that the supported keys are limited to what typical VT100 terminals
    offer. Binding :kbd:`c-7` (control + number 7) for instance is not
    supported.


Binding alt+something, option+something or meta+something
---------------------------------------------------------

Vt100 terminals translate the alt key into a leading :kbd:`escape` key.
For instance, in order to handle :kbd:`alt-f`, we have to handle
:kbd:`escape` + :kbd:`f`. Notice that we receive this as two individual keys.
This means that it's exactly the same as first typing :kbd:`escape` and then
typing :kbd:`f`. Something this alt-key is also known as option or meta.

In code that looks as follows:

.. code:: python

    @bindings.add('escape', 'f')
    def _(event):
        " Do something if alt-f or meta-f have been pressed. "


Wildcards
---------

Sometimes you want to catch any key that follows after a certain key stroke.
This is possible by binding the '<any>' key:

.. code:: python

    @bindings.add('a', '<any>')
    def _(event):
        ...

This will handle `aa`, `ab`, `ac`, etcetera. The key binding can check the
`event` object for which keys exactly have been pressed.


Attaching a filter (condition)
------------------------------

In order to enable a key binding according to a certain condition, we have to
pass it a :class:`~prompt_toolkit.filters.Filter`, usually a
:class:`~prompt_toolkit.filters.Condition` instance. (:ref:`Read more about
filters <filters>`.)

.. code:: python

    from prompt_toolkit.filters import Condition

    @Condition
    def is_active():
        " Only activate key binding on the second half of each minute. "
        return datetime.datetime.now().second > 30

    @bindings.add('c-t', filter=is_active)
    def _(event):
        # ...
        pass

The key binding will be ignored when this condition is not satisfied.


ConditionalKeyBindings: Disabling a set of key bindings
-------------------------------------------------------

Sometimes you want to enable or disable a whole set of key bindings according
to a certain condition. This is possible by wrapping it in a
:class:`~prompt_toolkit.key_binding.ConditionalKeyBindings` object.

.. code:: python

    from prompt_toolkit.key_binding import ConditionalKeyBindings

    @Condition
    def is_active():
        " Only activate key binding on the second half of each minute. "
        return datetime.datetime.now().second > 30

     bindings = ConditionalKeyBindings(
         key_bindings=my_bindings,
         filter=is_active)

If the condition is not satisfied, all the key bindings in `my_bindings` above
will be ignored.


Merging key bindings
--------------------

Sometimes you have different parts of your application generate a collection of
key bindings. It is possible to merge them together through the
:func:`~prompt_toolkit.key_binding.merge_key_bindings` function. This is
preferred above passing a :class:`~prompt_toolkit.key_binding.KeyBindings`
object around and having everyone populate it.

.. code:: python

    from prompt_toolkit.key_binding import merge_key_bindings

    bindings = merge_key_bindings([
        bindings1,
        bindings2,
    ])


Eager
-----

Usually not required, but if ever you have to override an existing key binding,
the `eager` flag can be useful.

Suppose that there is already an active binding for `ab` and you'd like to add
a second binding that only handles `a`. When the user presses only `a`,
prompt_toolkit has to wait for the next key press in order to know which
handler to call.

By passing the `eager` flag to this second binding, we are actually saying that
prompt_toolkit shouldn't wait for longer matches when all the keys in this key
binding are matched. So, if `a` has been pressed, this second binding will be
called, even if there's an active `ab` binding.

.. code:: python

    @bindings.add('a', 'b')
    def binding_1(event):
        ...

    @bindings.add('a', eager=True)
    def binding_2(event):
        ...

This is mainly useful in order to conditionally override another binding.

Asyncio coroutines
------------------

Key binding handlers can be asyncio coroutines.

.. code:: python

    from prompt_toolkit.application import in_terminal

    @bindings.add('x')
    async def print_hello(event):
        """
        Pressing 'x' will print 5 times "hello" in the background above the
        prompt.
        """
        for i in range(5):
            # Print hello above the current prompt.
            async with in_terminal():
                print('hello')

            # Sleep, but allow further input editing in the meantime.
            await asyncio.sleep(1)

If the user accepts the input on the prompt, while this coroutine is not yet
finished , an `asyncio.CancelledError` exception will be thrown in this
coroutine.


Timeouts
--------

There are two timeout settings that effect the handling of keys.

- ``Application.ttimeoutlen``: Like Vim's `ttimeoutlen` option.
  When to flush the input (For flushing escape keys.) This is important on
  terminals that use vt100 input. We can't distinguish the escape key from for
  instance the left-arrow key, if we don't know what follows after "\x1b". This
  little timer will consider "\x1b" to be escape if nothing did follow in this
  time span.  This seems to work like the `ttimeoutlen` option in Vim.

- ``KeyProcessor.timeoutlen``: like Vim's `timeoutlen` option.
  This can be `None` or a float.  For instance, suppose that we have a key
  binding AB and a second key binding A. If the uses presses A and then waits,
  we don't handle this binding yet (unless it was marked 'eager'), because we
  don't know what will follow. This timeout is the maximum amount of time that
  we wait until we call the handlers anyway. Pass `None` to disable this
  timeout.


Recording macros
----------------

Both Emacs and Vi mode allow macro recording. By default, all key presses are
recorded during a macro, but it is possible to exclude certain keys by setting
the `record_in_macro` parameter to `False`:

.. code:: python

    @bindings.add('c-t', record_in_macro=False)
    def _(event):
        # ...
        pass


Creating new Vi text objects and operators
------------------------------------------

We tried very hard to ship prompt_toolkit with as many as possible Vi text
objects and operators, so that text editing feels as natural as possible to Vi
users.

If you wish to create a new text object or key binding, that is actually
possible. Check the `custom-vi-operator-and-text-object.py` example for more
information.


Handling SIGINT
---------------

The SIGINT Unix signal can be handled by binding ``<sigint>``. For instance:

.. code:: python

    @bindings.add('<sigint>')
    def _(event):
        # ...
        pass

This will handle a SIGINT that was sent by an external application into the
process. Handling control-c should be done by binding ``c-c``. (The terminal
input is set to raw mode, which means that a ``c-c`` won't be translated into a
SIGINT.)

For a ``PromptSession``, there is a default binding for ``<sigint>`` that
corresponds to ``c-c``: it will exit the prompt, raising a
``KeyboardInterrupt`` exception.


Processing `.inputrc`
---------------------

GNU readline can be configured using an `.inputrc` configuration file. This file
contains key bindings as well as certain settings. Right now, prompt_toolkit
doesn't support `.inputrc`, but it should be possible in the future.

---

### Pages Advanced Topics Rendering Flow (`docs/pages/advanced_topics/rendering_flow.rst`)

.. _rendering_flow:

The rendering flow
==================

Understanding the rendering flow is important for understanding how
:class:`~prompt_toolkit.layout.Container` and
:class:`~prompt_toolkit.layout.UIControl` objects interact. We will demonstrate
it by explaining the flow around a
:class:`~prompt_toolkit.layout.BufferControl`.

.. note::

    A :class:`~prompt_toolkit.layout.BufferControl` is a
    :class:`~prompt_toolkit.layout.UIControl` for displaying the content of a
    :class:`~prompt_toolkit.buffer.Buffer`. A buffer is the object that holds
    any editable region of text. Like all controls, it has to be wrapped into a
    :class:`~prompt_toolkit.layout.Window`.

Let's take the following code:

.. code:: python

    from prompt_toolkit.enums import DEFAULT_BUFFER
    from prompt_toolkit.layout.containers import Window
    from prompt_toolkit.layout.controls import BufferControl
    from prompt_toolkit.buffer import Buffer

    b = Buffer(name=DEFAULT_BUFFER)
    Window(content=BufferControl(buffer=b))

What happens when a :class:`~prompt_toolkit.renderer.Renderer` objects wants a
:class:`~prompt_toolkit.layout.Container` to be rendered on a certain
:class:`~prompt_toolkit.layout.screen.Screen`?

The visualization happens in several steps:

1. The :class:`~prompt_toolkit.renderer.Renderer` calls the
   :meth:`~prompt_toolkit.layout.Container.write_to_screen` method
   of a :class:`~prompt_toolkit.layout.Container`.
   This is a request to paint the layout in a rectangle of a certain size.

   The :class:`~prompt_toolkit.layout.Window` object then requests
   the :class:`~prompt_toolkit.layout.UIControl` to create a
   :class:`~prompt_toolkit.layout.UIContent` instance (by calling
   :meth:`~prompt_toolkit.layout.UIControl.create_content`).
   The user control receives the dimensions of the window, but can still
   decide to create more or less content.

   Inside the :meth:`~prompt_toolkit.layout.UIControl.create_content`
   method of :class:`~prompt_toolkit.layout.UIControl`, there are several
   steps:

   2. First, the buffer's text is passed to the
      :meth:`~prompt_toolkit.lexers.Lexer.lex_document` method of a
      :class:`~prompt_toolkit.lexers.Lexer`. This returns a function which
      for a given line number, returns a "formatted text list" for that line
      (that's a list of ``(style_string, text)`` tuples).

   3. This list is passed through a list of
      :class:`~prompt_toolkit.layout.processors.Processor` objects.
      Each processor can do a transformation for each line.
      (For instance, they can insert or replace some text, highlight the
      selection or search string, etc...)

   4. The :class:`~prompt_toolkit.layout.UIControl` returns a
      :class:`~prompt_toolkit.layout.UIContent` instance which
      generates such a token lists for each lines.

The :class:`~prompt_toolkit.layout.Window` receives the
:class:`~prompt_toolkit.layout.UIContent` and then:

5. It calculates the horizontal and vertical scrolling, if applicable
   (if the content would take more space than what is available).

6. The content is copied to the correct absolute position
   :class:`~prompt_toolkit.layout.screen.Screen`, as requested by the
   :class:`~prompt_toolkit.renderer.Renderer`. While doing this, the
   :class:`~prompt_toolkit.layout.Window` can possible wrap the
   lines, if line wrapping was configured.

Note that this process is lazy: if a certain line is not displayed in the
:class:`~prompt_toolkit.layout.Window`, then it is not requested
from the :class:`~prompt_toolkit.layout.UIContent`. And from there, the line is
not passed through the processors or even asked from the
:class:`~prompt_toolkit.lexers.Lexer`.

---

### Pages Advanced Topics Rendering Pipeline (`docs/pages/advanced_topics/rendering_pipeline.rst`)

The rendering pipeline
======================

This document is an attempt to describe how prompt_toolkit applications are
rendered. It's a complex but logical process that happens more or less after
every key stroke. We'll go through all the steps from the point where the user
hits a key, until the character appears on the screen.


Waiting for user input
----------------------

Most of the time when a prompt_toolkit application is running, it is idle. It's
sitting in the event loop, waiting for some I/O to happen. The most important
kind of I/O we're waiting for is user input. So, within the event loop, we have
one file descriptor that represents the input device from where we receive key
presses. The details are a little different between operating systems, but it
comes down to a selector (like select or epoll) which waits for one or more
file descriptor. The event loop is then responsible for calling the appropriate
feedback when one of the file descriptors becomes ready.

It is like that when the user presses a key: the input device becomes ready for
reading, and the appropriate callback is called. This is the `read_from_input`
function somewhere in `application.py`. It will read the input from the
:class:`~prompt_toolkit.input.Input` object, by calling
:meth:`~prompt_toolkit.input.Input.read_keys`.


Reading the user input
----------------------

The actual reading is also operating system dependent. For instance, on a Linux
machine with a vt100 terminal, we read the input from the pseudo terminal
device, by calling `os.read`. This however returns a sequence of bytes. There
are two difficulties:

- The input could be UTF-8 encoded, and there is always the possibility that we
  receive only a portion of a multi-byte character.
- vt100 key presses consist of multiple characters. For instance the "left
  arrow" would generate something like ``\x1b[D``. It could be that when we
  read this input stream, that at some point we only get the first part of such
  a key press, and we have to wait for the rest to arrive.

Both problems are implemented using state machines.

- The UTF-8 problem is solved using `codecs.getincrementaldecoder`, which is an
  object in which we can feed the incoming bytes, and it will only return the
  complete UTF-8 characters that we have so far. The rest is buffered for the
  next read operation.
- Vt100 parsing is solved by the
  :class:`~prompt_toolkit.input.vt100_parser.Vt100Parser` state machine. The
  state machine itself is implemented using a generator. We feed the incoming
  characters to the generator, and it will call the appropriate callback for
  key presses once they arrive. One thing here to keep in mind is that the
  characters for some key presses are a prefix of other key presses, like for
  instance, escape (``\x1b``) is a prefix of the left arrow key (``\x1b[D``).
  So for those, we don't know what key is pressed until more data arrives or
  when the input is flushed because of a timeout.

For Windows systems, it's a little different. Here we use Win32 syscalls for
reading the console input.


Processing the key presses
--------------------------

The ``Key`` objects that we receive are then passed to the
:class:`~prompt_toolkit.key_binding.key_processor.KeyProcessor` for matching
against the currently registered and active key bindings.

This is another state machine, because key bindings are linked to a sequence of
key presses. We cannot call the handler until all of these key presses arrive
and until we're sure that this combination is not a prefix of another
combination. For instance, sometimes people bind ``jj`` (a double ``j`` key
press) to ``esc`` in Vi mode. This is convenient, but we want to make sure that
pressing ``j`` once only, followed by a different key will still insert the
``j`` character as usual.

Now, there are hundreds of key bindings in prompt_toolkit (in ptpython, right
now we have 585 bindings). This is mainly caused by the way that Vi key
bindings are generated. In order to make this efficient, we keep a cache of
handlers which match certain sequences of keys.

Of course, key bindings also have filters attached for enabling/disabling them.
So, if at some point, we get a list of handlers from that cache, we still have
to discard the inactive bindings. Luckily, many bindings share exactly the same
filter, and we have to check every filter only once.

:ref:`Read more about key bindings ...<key_bindings>`


The key handlers
----------------

Once a key sequence is matched, the handler is called. This can do things like
text manipulation, changing the focus or anything else.

After the handler is called, the user interface is invalidated and rendered
again.


Rendering the user interface
----------------------------

The rendering is pretty complex for several reasons:

- We have to compute the dimensions of all user interface elements. Sometimes
  they are given, but sometimes this requires calculating the size of
  :class:`~prompt_toolkit.layout.UIControl` objects.
- It needs to be very efficient, because it's something that happens on every
  single key stroke.
- We should output as little as possible on stdout in order to reduce latency
  on slow network connections and older terminals.


Calculating the total UI height
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Unless the application is a full screen application, we have to know how much
vertical space is going to be consumed. The total available width is given, but
the vertical space is more dynamic. We do this by asking the root
:class:`~prompt_toolkit.layout.Container` object to calculate its preferred
height. If this is a :class:`~prompt_toolkit.layout.VSplit` or
:class:`~prompt_toolkit.layout.HSplit` then this involves recursively querying
the child objects for their preferred widths and heights and either summing it
up, or taking maximum values depending on the actual layout.
In the end, we get the preferred height, for which we make sure it's at least
the distance from the cursor position to the bottom of the screen.


Painting to the screen
^^^^^^^^^^^^^^^^^^^^^^

Then we create a :class:`~prompt_toolkit.layout.screen.Screen` object. This is
like a canvas on which user controls can paint their content. The
:meth:`~prompt_toolkit.layout.Container.write_to_screen` method of the root
`Container` is called with the screen dimensions. This will call recursively
:meth:`~prompt_toolkit.layout.Container.write_to_screen` methods of nested
child containers, each time passing smaller dimensions while we traverse what
is a tree of `Container` objects.

The most inner containers are :class:`~prompt_toolkit.layout.Window` objects,
they will do the actual painting of the
:class:`~prompt_toolkit.layout.UIControl` to the screen. This involves line
wrapping the `UIControl`'s text and maybe scrolling the content horizontally or
vertically.


Rendering to stdout
^^^^^^^^^^^^^^^^^^^

Finally, when we have painted the screen, this needs to be rendered to stdout.
This is done by taking the difference of the previously rendered screen and the
new one. The algorithm that we have is heavily optimized to compute this
difference as quickly as possible, and call the appropriate output functions of
the :class:`~prompt_toolkit.output.Output` back-end. At the end, it will
position the cursor in the right place.

---

### Pages Advanced Topics Styling (`docs/pages/advanced_topics/styling.rst`)

.. _styling:

More about styling
==================

This page will attempt to explain in more detail how to use styling in
prompt_toolkit.

To some extent, it is very similar to how `Pygments <http://pygments.org/>`_
styling works.


Style strings
-------------

Many user interface controls, like :class:`~prompt_toolkit.layout.Window`
accept a ``style`` argument which can be used to pass the formatting as a
string. For instance, we can select a foreground color:

- ``"fg:ansired"``  (ANSI color palette)
- ``"fg:ansiblue"`` (ANSI color palette)
- ``"fg:#ffaa33"``  (hexadecimal notation)
- ``"fg:darkred"``  (named color)

Or a background color:

- ``"bg:ansired"``  (ANSI color palette)
- ``"bg:#ffaa33"``  (hexadecimal notation)

Or we can add one of the following flags:

- ``"bold"``
- ``"italic"``
- ``"underline"``
- ``"blink"``
- ``"reverse"``  (reverse foreground and background on the terminal.)
- ``"hidden"``

Or their negative variants:

- ``"nobold"``
- ``"noitalic"``
- ``"nounderline"``
- ``"noblink"``
- ``"noreverse"``
- ``"nohidden"``

All of these formatting options can be combined as well:

- ``"fg:ansiyellow bg:black bold underline"``

The style string can be given to any user control directly, or to a
:class:`~prompt_toolkit.layout.Container` object from where it will propagate
to all its children. A style defined by a parent user control can be overridden
by any of its children. The parent can for instance say ``style="bold
underline"`` where a child overrides this style partly by specifying
``style="nobold bg:ansired"``.

.. note::

    These styles are actually compatible with
    `Pygments <http://pygments.org/>`_ styles, with additional support for
    `reverse` and `blink`. Further, we ignore flags like `roman`, `sans`,
    `mono` and `border`.

The following ANSI colors are available (both for foreground and background):

.. code::

    # Low intensity, dark.  (One or two components 0x80, the other 0x00.)
    ansiblack, ansired, ansigreen, ansiyellow, ansiblue
    ansimagenta, ansicyan, ansigray

    # High intensity, bright.
    ansibrightblack, ansibrightred, ansibrightgreen, ansibrightyellow
    ansibrightblue, ansibrightmagenta, ansibrightcyan, ansiwhite

In order to know which styles are actually used in an application, it is
possible to call :meth:`~Application.get_used_style_strings`, when the
application is done.


Class names
-----------

Like we do for web design, it is not a good habit to specify all styling
inline. Instead, we can attach class names to UI controls and have a style
sheet that refers to these class names. The
:class:`~prompt_toolkit.styles.Style` can be passed as an argument to the
:class:`~prompt_toolkit.application.Application`.

.. code:: python

    from prompt_toolkit.layout import VSplit, Window
    from prompt_toolkit.styles import Style

    layout = VSplit([
        Window(BufferControl(...), style='class:left'),
        HSplit([
            Window(BufferControl(...), style='class:top'),
            Window(BufferControl(...), style='class:bottom'),
        ], style='class:right')
    ])

    style = Style([
         ('left', 'bg:ansired'),
         ('top', 'fg:#00aaaa'),
         ('bottom', 'underline bold'),
     ])

It is possible to add multiple class names to an element. That way we'll
combine the styling for these class names. Multiple classes can be passed by
using a comma separated list, or by using the ``class:`` prefix twice.

.. code:: python

   Window(BufferControl(...), style='class:left,bottom'),
   Window(BufferControl(...), style='class:left class:bottom'),

It is possible to combine class names and inline styling. The order in which
the class names and inline styling is specified determines the order of
priority. In the following example for instance, we'll take first the style of
the "header" class, and then override that with a red background color.

.. code:: python

    Window(BufferControl(...), style='class:header bg:red'),


Dot notation in class names
---------------------------

The dot operator has a special meaning in a class name. If we write:
``style="class:a.b.c"``, then this will actually expand to the following:
``style="class:a class:a.b class:a.b.c"``.

This is mainly added for `Pygments <http://pygments.org/>`_ lexers, which
specify "Tokens" like this, but it's useful in other situations as well.


Multiple classes in a style sheet
---------------------------------

A style sheet can be more complex as well. We can for instance specify two
class names. The following will underline the left part within the header, or
whatever has both the class "left" and the class "header" (the order doesn't
matter).

.. code:: python

    style = Style([
         ('header left', 'underline'),
     ])


If you have a dotted class, then it's required to specify the whole path in the
style sheet (just typing ``c`` or ``b.c`` doesn't work if the class is
``a.b.c``):

.. code:: python

    style = Style([
         ('a.b.c', 'underline'),
     ])

It is possible to combine this:

.. code:: python

    style = Style([
         ('header body left.text', 'underline'),
     ])


Evaluation order of rules in a style sheet
------------------------------------------

The style is determined as follows:

- First, we concatenate all the style strings from the root control through all
  the parents to the child in one big string. (Things at the right take
  precedence anyway.)

  E.g: ``class:body bg:#aaaaaa #000000 class:header.focused class:left.text.highlighted underline``

- Then we go through this style from left to right, starting from the default
  style. Inline styling is applied directly.

  If we come across a class name, then we generate all combinations of the
  class names that we collected so far (this one and all class names to the
  left), and for each combination which includes the new class name, we look
  for matching rules in our style sheet.  All these rules are then applied
  (later rules have higher priority).

  If we find a dotted class name, this will be expanded in the individual names
  (like ``class:left class:left.text class:left.text.highlighted``), and all
  these are applied like any class names.

- Then this final style is applied to this user interface element.


Using a dictionary as a style sheet
-----------------------------------

The order of the rules in a style sheet is meaningful, so typically, we use a
list of tuples to specify the style. But is also possible to use a dictionary
as a style sheet. This makes sense for Python 3.6, where dictionaries remember
their ordering. An ``OrderedDict`` works as well.

.. code:: python

    from prompt_toolkit.styles import Style

    style = Style.from_dict({
         'header body left.text': 'underline',
    })


Loading a style from Pygments
-----------------------------

`Pygments <http://pygments.org/>`_ has a slightly different notation for
specifying styles, because it maps styling to Pygments "Tokens". A Pygments
style can however be loaded and used as follows:

.. code:: python

    from prompt_toolkit.styles.pygments import style_from_pygments_cls
    from pygments.styles import get_style_by_name

    style = style_from_pygments_cls(get_style_by_name('monokai'))


Merging styles together
-----------------------

Multiple :class:`~prompt_toolkit.styles.Style` objects can be merged together as
follows:

.. code:: python

    from prompt_toolkit.styles import merge_styles

    style = merge_styles([
        style1,
        style2,
        style3
    ])


Color depths
------------

There are four different levels of color depths available:

+--------+-----------------+-----------------------------+---------------------------------+
| 1 bit  | Black and white | ``ColorDepth.DEPTH_1_BIT``  | ``ColorDepth.MONOCHROME``       |
+--------+-----------------+-----------------------------+---------------------------------+
| 4 bit  | ANSI colors     | ``ColorDepth.DEPTH_4_BIT``  | ``ColorDepth.ANSI_COLORS_ONLY`` |
+--------+-----------------+-----------------------------+---------------------------------+
| 8 bit  | 256 colors      | ``ColorDepth.DEPTH_8_BIT``  | ``ColorDepth.DEFAULT``          |
+--------+-----------------+-----------------------------+---------------------------------+
| 24 bit | True colors     | ``ColorDepth.DEPTH_24_BIT`` | ``ColorDepth.TRUE_COLOR``       |
+--------+-----------------+-----------------------------+---------------------------------+

By default, 256 colors are used, because this is what most terminals support
these days. If the ``TERM`` environment variable is set to ``linux`` or
``eterm-color``, then only ANSI colors are used, because of these terminals. The 24
bit true color output needs to be enabled explicitly. When 4 bit color output
is chosen, all colors will be mapped to the closest ANSI color.

Setting the default color depth for any prompt_toolkit application can be done
by setting the ``PROMPT_TOOLKIT_COLOR_DEPTH`` environment variable. You could
for instance copy the following into your `.bashrc` file.

.. code:: shell

    # export PROMPT_TOOLKIT_COLOR_DEPTH=DEPTH_1_BIT
    export PROMPT_TOOLKIT_COLOR_DEPTH=DEPTH_4_BIT
    # export PROMPT_TOOLKIT_COLOR_DEPTH=DEPTH_8_BIT
    # export PROMPT_TOOLKIT_COLOR_DEPTH=DEPTH_24_BIT

An application can also decide to set the color depth manually by passing a
:class:`~prompt_toolkit.output.ColorDepth` value to the
:class:`~prompt_toolkit.application.Application` object:

.. code:: python

    from prompt_toolkit.output.color_depth import ColorDepth

    app = Application(
        color_depth=ColorDepth.ANSI_COLORS_ONLY,
        # ...
    )


Style transformations
---------------------

Prompt_toolkit supports a way to apply certain transformations to the styles
near the end of the rendering pipeline. This can be used for instance to change
certain colors to improve the rendering in some terminals.

One useful example is the
:class:`~prompt_toolkit.styles.AdjustBrightnessStyleTransformation` class,
which takes `min_brightness` and `max_brightness` as arguments which by default
have 0.0 and 1.0 as values. In the following code snippet, we increase the
minimum brightness to improve rendering on terminals with a dark background.

.. code:: python

    from prompt_toolkit.styles import AdjustBrightnessStyleTransformation

    app = Application(
        style_transformation=AdjustBrightnessStyleTransformation(
            min_brightness=0.5,  # Increase the minimum brightness.
            max_brightness=1.0,
        )
        # ...
    )

---

### Pages Advanced Topics Unit Testing (`docs/pages/advanced_topics/unit_testing.rst`)

.. _unit_testing:

Unit testing
============

Testing user interfaces is not always obvious. Here are a few tricks for
testing prompt_toolkit applications.


`PosixPipeInput` and `DummyOutput`
----------------------------------

During the creation of a prompt_toolkit
:class:`~prompt_toolkit.application.Application`, we can specify what input and
output device to be used. By default, these are output objects that correspond
with `sys.stdin` and `sys.stdout`. In unit tests however, we want to replace
these.

- For the input, we want a "pipe input". This is an input device, in which we
  can programmatically send some input. It can be created with
  :func:`~prompt_toolkit.input.create_pipe_input`, and that return either a
  :class:`~prompt_toolkit.input.posix_pipe.PosixPipeInput` or a
  :class:`~prompt_toolkit.input.win32_pipe.Win32PipeInput` depending on the
  platform.
- For the output, we want a :class:`~prompt_toolkit.output.DummyOutput`. This is
  an output device that doesn't render anything. We don't want to render
  anything to `sys.stdout` in the unit tests.

.. note::

    Typically, we don't want to test the bytes that are written to
    `sys.stdout`, because these can change any time when the rendering
    algorithm changes, and are not so meaningful anyway. Instead, we want to
    test the return value from the
    :class:`~prompt_toolkit.application.Application` or test how data
    structures (like text buffers) change over time.

So we programmatically feed some input to the input pipe, have the key
bindings process the input and then test what comes out of it.

In the following example we use a
:class:`~prompt_toolkit.shortcuts.PromptSession`, but the same works for any
:class:`~prompt_toolkit.application.Application`.

.. code:: python

    from prompt_toolkit.shortcuts import PromptSession
    from prompt_toolkit.input import create_pipe_input
    from prompt_toolkit.output import DummyOutput

    def test_prompt_session():
        with create_pipe_input() as inp:
            inp.send_text("hello\n")
            session = PromptSession(
                input=inp,
                output=DummyOutput(),
            )

            result = session.prompt()

        assert result == "hello"

In the above example, don't forget to send the `\\n` character to accept the
prompt, otherwise the :class:`~prompt_toolkit.application.Application` will
wait forever for some more input to receive.

Using an :class:`~prompt_toolkit.application.current.AppSession`
----------------------------------------------------------------

Sometimes it's not convenient to pass input or output objects to the
:class:`~prompt_toolkit.application.Application`, and in some situations it's
not even possible at all.
This happens when these parameters are not passed down the call stack, through
all function calls.

An easy way to specify which input/output to use for all applications, is by
creating an :class:`~prompt_toolkit.application.current.AppSession` with this
input/output and running all code in that
:class:`~prompt_toolkit.application.current.AppSession`. This way, we don't
need to inject it into every :class:`~prompt_toolkit.application.Application`
or :func:`~prompt_toolkit.shortcuts.print_formatted_text` call.

Here is an example where we use
:func:`~prompt_toolkit.application.create_app_session`:

.. code:: python

    from prompt_toolkit.application import create_app_session
    from prompt_toolkit.shortcuts import print_formatted_text
    from prompt_toolkit.output import DummyOutput

    def test_something():
        with create_app_session(output=DummyOutput()):
            ...
            print_formatted_text('Hello world')
            ...

Pytest fixtures
---------------

In order to get rid of the boilerplate of creating the input, the
:class:`~prompt_toolkit.output.DummyOutput`, and the
:class:`~prompt_toolkit.application.current.AppSession`, we create a
single fixture that does it for every test. Something like this:

.. code:: python

    import pytest
    from prompt_toolkit.application import create_app_session
    from prompt_toolkit.input import create_pipe_input
    from prompt_toolkit.output import DummyOutput

    @pytest.fixture(autouse=True, scope="function")
    def mock_input():
        with create_pipe_input() as pipe_input:
            with create_app_session(input=pipe_input, output=DummyOutput()):
                yield pipe_input

For compatibility with pytest's ``capsys`` fixture, we have to create a new
:class:`~prompt_toolkit.application.current.AppSession` for every test. This
can be done in an autouse fixture. Pytest replaces ``sys.stdout`` with a new
object in every test that uses ``capsys`` and the following will ensure that
the new :class:`~prompt_toolkit.application.current.AppSession` will each time
refer to the latest output.

.. code:: python

    from prompt_toolkit.application import create_app_session

    @fixture(autouse=True, scope="function")
    def _pt_app_session()
        with create_app_session():
            yield

Type checking
-------------

Prompt_toolkit 3.0 is fully type annotated. This means that if a
prompt_toolkit application is typed too, it can be verified with mypy. This is
complementary to unit tests, but also great for testing for correctness.

---

### Pages Tutorials Index (`docs/pages/tutorials/index.rst`)

.. _tutorials:

Tutorials
=========

.. toctree::
    :caption: Contents:
    :maxdepth: 1

    repl

---

### Pages Tutorials Repl (`docs/pages/tutorials/repl.rst`)

.. _tutorial_repl:

Tutorial: Build an SQLite REPL
==============================

The aim of this tutorial is to build an interactive command line interface for
an SQLite database using prompt_toolkit_.

First, install the library using pip, if you haven't done this already.

.. code::

    pip install prompt_toolkit


Read User Input
---------------

Let's start accepting input using the
:func:`~prompt_toolkit.shortcuts.prompt()` function. This will ask the user for
input, and echo back whatever the user typed. We wrap it in a ``main()``
function as a good practice.

.. code:: python

    from prompt_toolkit import prompt

    def main():
        text = prompt('> ')
        print('You entered:', text)

    if __name__ == '__main__':
        main()

.. image:: ../../images/repl/sqlite-1.png


Loop The REPL
-------------

Now we want to call the :meth:`~prompt_toolkit.shortcuts.PromptSession.prompt`
method in a loop. In order to keep the history, the easiest way to do it is to
use a :class:`~prompt_toolkit.shortcuts.PromptSession`. This uses an
:class:`~prompt_toolkit.history.InMemoryHistory` underneath that keeps track of
the history, so that if the user presses the up-arrow, they'll see the previous
entries.

The :meth:`~prompt_toolkit.shortcuts.PromptSession.prompt` method raises
``KeyboardInterrupt`` when ControlC has been pressed and ``EOFError`` when
ControlD has been pressed. This is what people use for cancelling commands and
exiting in a REPL. The try/except below handles these error conditions and make
sure that we go to the next iteration of the loop or quit the loop
respectively.

.. code:: python

    from prompt_toolkit import PromptSession

    def main():
        session = PromptSession()

        while True:
            try:
                text = session.prompt('> ')
            except KeyboardInterrupt:
                continue
            except EOFError:
                break
            else:
                print('You entered:', text)
        print('GoodBye!')

    if __name__ == '__main__':
        main()

.. image:: ../../images/repl/sqlite-2.png


Syntax Highlighting
-------------------

This is where things get really interesting. Let's step it up a notch by adding
syntax highlighting to the user input. We know that users will be entering SQL
statements, so we can leverage the Pygments_ library for coloring the input.
The ``lexer`` parameter allows us to set the syntax lexer. We're going to use
the ``SqlLexer`` from the Pygments_ library for highlighting.

Notice that in order to pass a Pygments lexer to prompt_toolkit, it needs to be
wrapped into a :class:`~prompt_toolkit.lexers.PygmentsLexer`.

.. code:: python

    from prompt_toolkit import PromptSession
    from prompt_toolkit.lexers import PygmentsLexer
    from pygments.lexers.sql import SqlLexer

    def main():
        session = PromptSession(lexer=PygmentsLexer(SqlLexer))

        while True:
            try:
                text = session.prompt('> ')
            except KeyboardInterrupt:
                continue
            except EOFError:
                break
            else:
                print('You entered:', text)
        print('GoodBye!')

    if __name__ == '__main__':
        main()

.. image:: ../../images/repl/sqlite-3.png


Auto-completion
---------------

Now we are going to add auto completion. We'd like to display a drop down menu
of `possible keywords <https://www.sqlite.org/lang_keywords.html>`_ when the
user starts typing.

We can do this by creating an `sql_completer` object from the
:class:`~prompt_toolkit.completion.WordCompleter` class, defining a set of
`keywords` for the auto-completion.

Like the lexer, this ``sql_completer`` instance can be passed to either the
:class:`~prompt_toolkit.shortcuts.PromptSession` class or the
:meth:`~prompt_toolkit.shortcuts.PromptSession.prompt` method.

.. code:: python

    from prompt_toolkit import PromptSession
    from prompt_toolkit.completion import WordCompleter
    from prompt_toolkit.lexers import PygmentsLexer
    from pygments.lexers.sql import SqlLexer

    sql_completer = WordCompleter([
        'abort', 'action', 'add', 'after', 'all', 'alter', 'analyze', 'and',
        'as', 'asc', 'attach', 'autoincrement', 'before', 'begin', 'between',
        'by', 'cascade', 'case', 'cast', 'check', 'collate', 'column',
        'commit', 'conflict', 'constraint', 'create', 'cross', 'current_date',
        'current_time', 'current_timestamp', 'database', 'default',
        'deferrable', 'deferred', 'delete', 'desc', 'detach', 'distinct',
        'drop', 'each', 'else', 'end', 'escape', 'except', 'exclusive',
        'exists', 'explain', 'fail', 'for', 'foreign', 'from', 'full', 'glob',
        'group', 'having', 'if', 'ignore', 'immediate', 'in', 'index',
        'indexed', 'initially', 'inner', 'insert', 'instead', 'intersect',
        'into', 'is', 'isnull', 'join', 'key', 'left', 'like', 'limit',
        'match', 'natural', 'no', 'not', 'notnull', 'null', 'of', 'offset',
        'on', 'or', 'order', 'outer', 'plan', 'pragma', 'primary', 'query',
        'raise', 'recursive', 'references', 'regexp', 'reindex', 'release',
        'rename', 'replace', 'restrict', 'right', 'rollback', 'row',
        'savepoint', 'select', 'set', 'table', 'temp', 'temporary', 'then',
        'to', 'transaction', 'trigger', 'union', 'unique', 'update', 'using',
        'vacuum', 'values', 'view', 'virtual', 'when', 'where', 'with',
        'without'], ignore_case=True)

    def main():
        session = PromptSession(
            lexer=PygmentsLexer(SqlLexer), completer=sql_completer)

        while True:
            try:
                text = session.prompt('> ')
            except KeyboardInterrupt:
                continue
            except EOFError:
                break
            else:
                print('You entered:', text)
        print('GoodBye!')

    if __name__ == '__main__':
        main()

.. image:: ../../images/repl/sqlite-4.png

In about 30 lines of code we got ourselves an auto completing, syntax
highlighting REPL. Let's make it even better.


Styling the menus
-----------------

If we want, we can now change the colors of the completion menu. This is
possible by creating a :class:`~prompt_toolkit.styles.Style` instance and
passing it to the :meth:`~prompt_toolkit.shortcuts.PromptSession.prompt`
function.

.. code:: python

    from prompt_toolkit import PromptSession
    from prompt_toolkit.completion import WordCompleter
    from prompt_toolkit.lexers import PygmentsLexer
    from prompt_toolkit.styles import Style
    from pygments.lexers.sql import SqlLexer

    sql_completer = WordCompleter([
        'abort', 'action', 'add', 'after', 'all', 'alter', 'analyze', 'and',
        'as', 'asc', 'attach', 'autoincrement', 'before', 'begin', 'between',
        'by', 'cascade', 'case', 'cast', 'check', 'collate', 'column',
        'commit', 'conflict', 'constraint', 'create', 'cross', 'current_date',
        'current_time', 'current_timestamp', 'database', 'default',
        'deferrable', 'deferred', 'delete', 'desc', 'detach', 'distinct',
        'drop', 'each', 'else', 'end', 'escape', 'except', 'exclusive',
        'exists', 'explain', 'fail', 'for', 'foreign', 'from', 'full', 'glob',
        'group', 'having', 'if', 'ignore', 'immediate', 'in', 'index',
        'indexed', 'initially', 'inner', 'insert', 'instead', 'intersect',
        'into', 'is', 'isnull', 'join', 'key', 'left', 'like', 'limit',
        'match', 'natural', 'no', 'not', 'notnull', 'null', 'of', 'offset',
        'on', 'or', 'order', 'outer', 'plan', 'pragma', 'primary', 'query',
        'raise', 'recursive', 'references', 'regexp', 'reindex', 'release',
        'rename', 'replace', 'restrict', 'right', 'rollback', 'row',
        'savepoint', 'select', 'set', 'table', 'temp', 'temporary', 'then',
        'to', 'transaction', 'trigger', 'union', 'unique', 'update', 'using',
        'vacuum', 'values', 'view', 'virtual', 'when', 'where', 'with',
        'without'], ignore_case=True)

    style = Style.from_dict({
        'completion-menu.completion': 'bg:#008888 #ffffff',
        'completion-menu.completion.current': 'bg:#00aaaa #000000',
        'scrollbar.background': 'bg:#88aaaa',
        'scrollbar.button': 'bg:#222222',
    })

    def main():
       session = PromptSession(
           lexer=PygmentsLexer(SqlLexer), completer=sql_completer, style=style)

       while True:
           try:
               text = session.prompt('> ')
           except KeyboardInterrupt:
               continue
           except EOFError:
               break
           else:
               print('You entered:', text)
       print('GoodBye!')

    if __name__ == '__main__':
        main()

.. image:: ../../images/repl/sqlite-5.png

All that's left is hooking up the sqlite backend, which is left as an exercise
for the reader. Just kidding... Keep reading.


Hook up Sqlite
--------------

This step is the final step to make the SQLite REPL actually work. It's time
to relay the input to SQLite.

Obviously I haven't done the due diligence to deal with the errors. But it
gives a good idea of how to get started.

.. code:: python

    #!/usr/bin/env python
    import sys
    import sqlite3

    from prompt_toolkit import PromptSession
    from prompt_toolkit.completion import WordCompleter
    from prompt_toolkit.lexers import PygmentsLexer
    from prompt_toolkit.styles import Style
    from pygments.lexers.sql import SqlLexer

    sql_completer = WordCompleter([
        'abort', 'action', 'add', 'after', 'all', 'alter', 'analyze', 'and',
        'as', 'asc', 'attach', 'autoincrement', 'before', 'begin', 'between',
        'by', 'cascade', 'case', 'cast', 'check', 'collate', 'column',
        'commit', 'conflict', 'constraint', 'create', 'cross', 'current_date',
        'current_time', 'current_timestamp', 'database', 'default',
        'deferrable', 'deferred', 'delete', 'desc', 'detach', 'distinct',
        'drop', 'each', 'else', 'end', 'escape', 'except', 'exclusive',
        'exists', 'explain', 'fail', 'for', 'foreign', 'from', 'full', 'glob',
        'group', 'having', 'if', 'ignore', 'immediate', 'in', 'index',
        'indexed', 'initially', 'inner', 'insert', 'instead', 'intersect',
        'into', 'is', 'isnull', 'join', 'key', 'left', 'like', 'limit',
        'match', 'natural', 'no', 'not', 'notnull', 'null', 'of', 'offset',
        'on', 'or', 'order', 'outer', 'plan', 'pragma', 'primary', 'query',
        'raise', 'recursive', 'references', 'regexp', 'reindex', 'release',
        'rename', 'replace', 'restrict', 'right', 'rollback', 'row',
        'savepoint', 'select', 'set', 'table', 'temp', 'temporary', 'then',
        'to', 'transaction', 'trigger', 'union', 'unique', 'update', 'using',
        'vacuum', 'values', 'view', 'virtual', 'when', 'where', 'with',
        'without'], ignore_case=True)

    style = Style.from_dict({
        'completion-menu.completion': 'bg:#008888 #ffffff',
        'completion-menu.completion.current': 'bg:#00aaaa #000000',
        'scrollbar.background': 'bg:#88aaaa',
        'scrollbar.button': 'bg:#222222',
    })

    def main(database):
        connection = sqlite3.connect(database)
        session = PromptSession(
            lexer=PygmentsLexer(SqlLexer), completer=sql_completer, style=style)

        while True:
            try:
                text = session.prompt('> ')
            except KeyboardInterrupt:
                continue  # Control-C pressed. Try again.
            except EOFError:
                break  # Control-D pressed.

            with connection:
                try:
                    messages = connection.execute(text)
                except Exception as e:
                    print(repr(e))
                else:
                    for message in messages:
                        print(message)

        print('GoodBye!')

    if __name__ == '__main__':
        if len(sys.argv) < 2:
            db = ':memory:'
        else:
            db = sys.argv[1]

        main(db)

.. image:: ../../images/repl/sqlite-6.png

I hope that gives an idea of how to get started on building command line
interfaces.

The End.

.. _prompt_toolkit: https://github.com/prompt-toolkit/python-prompt-toolkit
.. _Pygments: http://pygments.org/

---

### Pages Upgrading 2.0 (`docs/pages/upgrading/2.0.rst`)

.. _upgrading_2_0:

Upgrading to prompt_toolkit 2.0
===============================

Prompt_toolkit 2.0 is not compatible with 1.0, however you probably want to
upgrade your applications. This page explains why we have these differences and
how to upgrade.

If you experience some difficulties or you feel that some information is
missing from this page, don't hesitate to open a GitHub issue for help.


Why all these breaking changes?
-------------------------------

After more and more custom prompt_toolkit applications were developed, it
became clear that prompt_toolkit 1.0 was not flexible enough for certain use
cases. Mostly, the development of full screen applications was not really
natural. All the important components, like the rendering, key bindings, input
and output handling were present, but the API was in the first place designed
for simple command line prompts. This was mostly notably in the following two
places:

- First, there was the focus which was always pointing to a
  :class:`~prompt_toolkit.buffer.Buffer` (or text input widget), but in full
  screen applications there are other widgets, like menus and buttons which
  can be focused.
- And secondly, it was impossible to make reusable UI components. All the key
  bindings for the entire applications were stored together in one
  ``KeyBindings`` object, and similar, all
  :class:`~prompt_toolkit.buffer.Buffer` objects were stored together in one
  dictionary. This didn't work well. You want reusable components to define
  their own key bindings and everything. It's the idea of encapsulation.

For simple prompts, the changes wouldn't be that invasive, but given that there
would be some, I took the opportunity to fix a couple of other things. For
instance:

- In prompt_toolkit 1.0, we translated `\\r` into `\\n` during the input
  processing. This was not a good idea, because some people wanted to handle
  these keys individually. This makes sense if you keep in mind that they
  correspond to `Control-M` and `Control-J`. However, we couldn't fix this
  without breaking everyone's enter key, which happens to be the most important
  key in prompts.

Given that we were going to break compatibility anyway, we changed a couple of
other important things that effect both simple prompt applications and
full screen applications. These are the most important:

- We no longer depend on Pygments for styling. While we like Pygments, it was
  not flexible enough to provide all the styling options that we need, and the
  Pygments tokens were not ideal for styling anything besides tokenized text.

  Instead we created something similar to CSS. All UI components can attach
  classnames to themselves, as well as define an inline style. The final style is
  then computed by combining the inline styles, the classnames and the style
  sheet.

  There are still adaptors available for using Pygments lexers as well as for
  Pygments styles.

- The way that key bindings were defined was too complex.
  ``KeyBindingsManager`` was too complex and no longer exists. Every set of key
  bindings is now a
  :class:`~prompt_toolkit.key_binding.KeyBindings` object and multiple of these
  can be merged together at any time. The runtime performance remains the same,
  but it's now easier for users.

- The separation between the ``CommandLineInterface`` and
  :class:`~prompt_toolkit.application.Application` class was confusing and in
  the end, didn't really had an advantage. These two are now merged together in
  one :class:`~prompt_toolkit.application.Application` class.

- We no longer pass around the active ``CommandLineInterface``. This was one of
  the most annoying things. Key bindings need it in order to change anything
  and filters need it in order to evaluate their state. It was pretty annoying,
  especially because there was usually only one application active at a time.
  So, :class:`~prompt_toolkit.application.Application` became a ``TaskLocal``.
  That is like a global variable, but scoped in the current coroutine or
  context. The way this works is still not 100% correct, but good enough for
  the projects that need it (like Pymux), and hopefully Python will get support
  for this in the future thanks to PEP521, PEP550 or PEP555.

All of these changes have been tested for many months, and I can say with
confidence that prompt_toolkit 2.0 is a better prompt_toolkit.


Some new features
-----------------

Apart from the breaking changes above, there are also some exciting new
features.

- We now support vt100 escape codes for Windows consoles on Windows 10. This
  means much faster rendering, and full color support.

- We have a concept of formatted text. This is an object that evaluates to
  styled text. Every input that expects some text, like the message in a
  prompt, or the text in a toolbar, can take any kind of formatted text as input.
  This means you can pass in a plain string, but also a list of `(style,
  text)` tuples (similar to a Pygments tokenized string), or an
  :class:`~prompt_toolkit.formatted_text.HTML` object. This simplifies many
  APIs.

- New utilities were added. We now have function for printing formatted text
  and an experimental module for displaying progress bars.

- Autocompletion, input validation, and auto suggestion can now either be
  asynchronous or synchronous. By default they are synchronous, but by wrapping
  them in :class:`~prompt_toolkit.completion.ThreadedCompleter`,
  :class:`~prompt_toolkit.validation.ThreadedValidator` or
  :class:`~prompt_toolkit.auto_suggest.ThreadedAutoSuggest`, they will become
  asynchronous by running in a background thread.

  Further, if the autocompletion code runs in a background thread, we will show
  the completions as soon as they arrive. This means that the autocompletion
  algorithm could for instance first yield the most trivial completions and then
  take time to produce the completions that take more time.


Upgrading
---------

More guidelines on how to upgrade will follow.


`AbortAction` has been removed
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Prompt_toolkit 1.0 had an argument ``abort_action`` for both the
``Application`` class as well as for the ``prompt`` function. This has been
removed. The recommended way to handle this now is by capturing
``KeyboardInterrupt`` and ``EOFError`` manually.


Calling `create_eventloop` usually not required anymore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Prompt_toolkit 2.0 will automatically create the appropriate event loop when
it's needed for the first time. There is no need to create one and pass it
around. If you want to run an application on top of asyncio (without using an
executor), it still needs to be activated by calling
:func:`~prompt_toolkit.eventloop.use_asyncio_event_loop` at the beginning.


Pygments styles and tokens
^^^^^^^^^^^^^^^^^^^^^^^^^^

prompt_toolkit 2.0 no longer depends on `Pygments <http://pygments.org/>`_, but
that definitely doesn't mean that you can't use any Pygments functionality
anymore. The only difference is that Pygments stuff needs to be wrapped in an
adaptor to make it compatible with the native prompt_toolkit objects.

- For instance, if you have a list of ``(pygments.Token, text)`` tuples for
  formatting, then this needs to be wrapped in a
  :class:`~prompt_toolkit.formatted_text.PygmentsTokens` object. This is an
  adaptor that turns it into prompt_toolkit "formatted text". Feel free to keep
  using this.

- Pygments lexers need to be wrapped in a
  :class:`~prompt_toolkit.lexers.PygmentsLexer`. This will convert the list of
  Pygments tokens into prompt_toolkit formatted text.

- If you have a Pygments style, then this needs to be converted as well. A
  Pygments style class can be converted in a prompt_toolkit
  :class:`~prompt_toolkit.styles.Style` with the
  :func:`~prompt_toolkit.styles.pygments.style_from_pygments_cls` function
  (which used to be called ``style_from_pygments``). A Pygments style
  dictionary can be converted using
  :func:`~prompt_toolkit.styles.pygments.style_from_pygments_dict`.

  Multiple styles can be merged together using
  :func:`~prompt_toolkit.styles.merge_styles`.


Wordcompleter
^^^^^^^^^^^^^

`WordCompleter` was moved from
:class:`prompt_toolkit.contrib.completers.base.WordCompleter` to
:class:`prompt_toolkit.completion.word_completer.WordCompleter`.


Asynchronous autocompletion
^^^^^^^^^^^^^^^^^^^^^^^^^^^

By default, prompt_toolkit 2.0 completion is now synchronous. If you still want
asynchronous auto completion (which is often good thing), then you have to wrap
the completer in a :class:`~prompt_toolkit.completion.ThreadedCompleter`.


Filters
^^^^^^^

We don't distinguish anymore between `CLIFilter` and `SimpleFilter`, because the
application object is no longer passed around. This means that all filters are
a `Filter` from now on.

All filters have been turned into functions. For instance, `IsDone` became
`is_done` and `HasCompletions` became `has_completions`.

This was done because almost all classes were called without any arguments in
the `__init__` causing additional braces everywhere. This means that
`HasCompletions()` has to be replaced by `has_completions` (without
parenthesis).

The few filters that took arguments as input, became functions, but still have
to be called with the given arguments.

For new filters, it is recommended to use the `@Condition` decorator,
rather then inheriting from `Filter`. For instance:

.. code:: python

    from prompt_toolkit.filters import Condition

    @Condition
    def my_filter();
        return True  # Or False

---

### Pages Upgrading 3.0 (`docs/pages/upgrading/3.0.rst`)

.. _upgrading_3_0:

Upgrading to prompt_toolkit 3.0
===============================

There are two major changes in 3.0 to be aware of:

- First, prompt_toolkit uses the asyncio event loop natively, rather then using
  its own implementations of event loops. This means that all coroutines are
  now asyncio coroutines, and all Futures are asyncio futures. Asynchronous
  generators became real asynchronous generators as well.

- Prompt_toolkit uses type annotations (almost) everywhere. This should not
  break any code, but its very helpful in many ways.

There are some minor breaking changes:

- The dialogs API had to change (see below).


Detecting the prompt_toolkit version
------------------------------------

Detecting whether version 3 is being used can be done as follows:

.. code:: python

    from prompt_toolkit import __version__ as ptk_version

    PTK3 = ptk_version.startswith('3.')


Fixing calls to `get_event_loop`
--------------------------------

Every usage of ``get_event_loop`` has to be fixed. An easy way to do this is by
changing the imports like this:

.. code:: python

    if PTK3:
        from asyncio import get_event_loop
    else:
        from prompt_toolkit.eventloop import get_event_loop

Notice that for prompt_toolkit 2.0, ``get_event_loop`` returns a prompt_toolkit
``EventLoop`` object. This is not an asyncio eventloop, but the API is
similar.

There are some changes to the eventloop API:

+-----------------------------------+--------------------------------------+
| version 2.0                       | version 3.0 (asyncio)                |
+===================================+======================================+
| loop.run_in_executor(callback)    | loop.run_in_executor(None, callback) |
+-----------------------------------+--------------------------------------+
| loop.call_from_executor(callback) | loop.call_soon_threadsafe(callback)  |
+-----------------------------------+--------------------------------------+


Running on top of asyncio
-------------------------

For 2.0, you had tell prompt_toolkit to run on top of the asyncio event loop.
Now it's the default. So, you can simply remove the following two lines:

.. code::

    from prompt_toolkit.eventloop.defaults import use_asyncio_event_loop
    use_asyncio_event_loop()

There is a few little breaking changes though. The following:

.. code::

    # For 2.0
    result = await PromptSession().prompt('Say something: ', async_=True)

has to be changed into:

.. code::

    # For 3.0
    result = await PromptSession().prompt_async('Say something: ')

Further, it's impossible to call the `prompt()` function within an asyncio
application (within a coroutine), because it will try to run the event loop
again. In that case, always use `prompt_async()`.


Changes to the dialog functions
-------------------------------

The original way of using dialog boxes looked like this:

.. code:: python

    from prompt_toolkit.shortcuts import input_dialog

    result = input_dialog(title='...', text='...')

Now, the dialog functions return a prompt_toolkit Application object. You have
to call either its ``run`` or ``run_async`` method to display the dialog. The
``async_`` parameter has been removed everywhere.

.. code:: python

    if PTK3:
        result = input_dialog(title='...', text='...').run()
    else:
        result = input_dialog(title='...', text='...')

    # Or

    if PTK3:
        result = await input_dialog(title='...', text='...').run_async()
    else:
        result = await input_dialog(title='...', text='...', async_=True)

---

### Pages Upgrading Index (`docs/pages/upgrading/index.rst`)

.. _upgrading:

Upgrading
=========

.. toctree::
    :caption: Contents:
    :maxdepth: 1

    2.0
    3.0

---

--- METRICS ---
- Files Extracted: 28
- Estimated Token Budget: ~44973 tokens
- Canonical Reference: https://codewiki.google/github.com/prompt-toolkit/python-prompt-toolkit
