summaryrefslogtreecommitdiffstats
path: root/examples/prompts
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 17:35:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 17:35:20 +0000
commite106bf94eff07d9a59771d9ccc4406421e18ab64 (patch)
treeedb6545500e39df9c67aa918a6125bffc8ec1aee /examples/prompts
parentInitial commit. (diff)
downloadprompt-toolkit-e106bf94eff07d9a59771d9ccc4406421e18ab64.tar.xz
prompt-toolkit-e106bf94eff07d9a59771d9ccc4406421e18ab64.zip
Adding upstream version 3.0.36.upstream/3.0.36upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--examples/prompts/accept-default.py16
-rwxr-xr-xexamples/prompts/asyncio-prompt.py69
-rwxr-xr-xexamples/prompts/auto-completion/autocomplete-with-control-space.py75
-rwxr-xr-xexamples/prompts/auto-completion/autocompletion-like-readline.py58
-rwxr-xr-xexamples/prompts/auto-completion/autocompletion.py60
-rwxr-xr-xexamples/prompts/auto-completion/colored-completions-with-formatted-text.py137
-rwxr-xr-xexamples/prompts/auto-completion/colored-completions.py78
-rwxr-xr-xexamples/prompts/auto-completion/combine-multiple-completers.py76
-rwxr-xr-xexamples/prompts/auto-completion/fuzzy-custom-completer.py57
-rwxr-xr-xexamples/prompts/auto-completion/fuzzy-word-completer.py59
-rwxr-xr-xexamples/prompts/auto-completion/multi-column-autocompletion-with-meta.py50
-rwxr-xr-xexamples/prompts/auto-completion/multi-column-autocompletion.py57
-rwxr-xr-xexamples/prompts/auto-completion/nested-autocompletion.py22
-rwxr-xr-xexamples/prompts/auto-completion/slow-completions.py103
-rwxr-xr-xexamples/prompts/auto-suggestion.py48
-rwxr-xr-xexamples/prompts/autocorrection.py44
-rwxr-xr-xexamples/prompts/bottom-toolbar.py80
-rwxr-xr-xexamples/prompts/clock-input.py25
-rwxr-xr-xexamples/prompts/colored-prompt.py81
-rwxr-xr-xexamples/prompts/confirmation-prompt.py9
-rwxr-xr-xexamples/prompts/cursor-shapes.py19
-rwxr-xr-xexamples/prompts/custom-key-binding.py77
-rwxr-xr-xexamples/prompts/custom-lexer.py29
-rwxr-xr-xexamples/prompts/custom-vi-operator-and-text-object.py70
-rwxr-xr-xexamples/prompts/enforce-tty-input-output.py13
-rwxr-xr-xexamples/prompts/fancy-zsh-prompt.py79
-rwxr-xr-xexamples/prompts/finalterm-shell-integration.py43
-rwxr-xr-xexamples/prompts/get-input-vi-mode.py7
-rwxr-xr-xexamples/prompts/get-input-with-default.py12
-rwxr-xr-xexamples/prompts/get-input.py9
-rwxr-xr-xexamples/prompts/get-multiline-input.py29
-rwxr-xr-xexamples/prompts/get-password-with-toggle-display-shortcut.py28
-rwxr-xr-xexamples/prompts/get-password.py6
-rwxr-xr-xexamples/prompts/history/persistent-history.py25
-rwxr-xr-xexamples/prompts/history/slow-history.py48
-rwxr-xr-xexamples/prompts/html-input.py18
-rwxr-xr-xexamples/prompts/input-validation.py35
-rwxr-xr-xexamples/prompts/inputhook.py84
-rwxr-xr-xexamples/prompts/mouse-support.py10
-rwxr-xr-xexamples/prompts/multiline-prompt.py11
-rwxr-xr-xexamples/prompts/no-wrapping.py6
-rwxr-xr-xexamples/prompts/operate-and-get-next.py18
-rwxr-xr-xexamples/prompts/patch-stdout.py41
-rwxr-xr-xexamples/prompts/placeholder-text.py13
-rwxr-xr-xexamples/prompts/regular-language.py108
-rwxr-xr-xexamples/prompts/rprompt.py53
-rwxr-xr-xexamples/prompts/swap-light-and-dark-colors.py78
-rwxr-xr-xexamples/prompts/switch-between-vi-emacs.py36
-rwxr-xr-xexamples/prompts/system-clipboard-integration.py17
-rwxr-xr-xexamples/prompts/system-prompt.py20
-rwxr-xr-xexamples/prompts/terminal-title.py10
-rwxr-xr-xexamples/prompts/up-arrow-partial-string-matching.py41
52 files changed, 2297 insertions, 0 deletions
diff --git a/examples/prompts/accept-default.py b/examples/prompts/accept-default.py
new file mode 100644
index 0000000..311ef46
--- /dev/null
+++ b/examples/prompts/accept-default.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+"""
+Example of `accept_default`, a way to automatically accept the input that the
+user typed without allowing him/her to edit it.
+
+This should display the prompt with all the formatting like usual, but not
+allow any editing.
+"""
+from prompt_toolkit import HTML, prompt
+
+if __name__ == "__main__":
+ answer = prompt(
+ HTML("<b>Type <u>some input</u>: </b>"), accept_default=True, default="test"
+ )
+
+ print("You said: %s" % answer)
diff --git a/examples/prompts/asyncio-prompt.py b/examples/prompts/asyncio-prompt.py
new file mode 100755
index 0000000..5a30e73
--- /dev/null
+++ b/examples/prompts/asyncio-prompt.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+"""
+(Python >= 3.6)
+This is an example of how to prompt inside an application that uses the asyncio
+eventloop. The ``prompt_toolkit`` library will make sure that when other
+coroutines are writing to stdout, they write above the prompt, not destroying
+the input line.
+This example does several things:
+ 1. It starts a simple coroutine, printing a counter to stdout every second.
+ 2. It starts a simple input/echo app loop which reads from stdin.
+Very important is the following patch. If you are passing stdin by reference to
+other parts of the code, make sure that this patch is applied as early as
+possible. ::
+ sys.stdout = app.stdout_proxy()
+"""
+
+import asyncio
+
+from prompt_toolkit.patch_stdout import patch_stdout
+from prompt_toolkit.shortcuts import PromptSession
+
+
+async def print_counter():
+ """
+ Coroutine that prints counters.
+ """
+ try:
+ i = 0
+ while True:
+ print("Counter: %i" % i)
+ i += 1
+ await asyncio.sleep(3)
+ except asyncio.CancelledError:
+ print("Background task cancelled.")
+
+
+async def interactive_shell():
+ """
+ Like `interactive_shell`, but doing things manual.
+ """
+ # Create Prompt.
+ session = PromptSession("Say something: ")
+
+ # Run echo loop. Read text from stdin, and reply it back.
+ while True:
+ try:
+ result = await session.prompt_async()
+ print(f'You said: "{result}"')
+ except (EOFError, KeyboardInterrupt):
+ return
+
+
+async def main():
+ with patch_stdout():
+ background_task = asyncio.create_task(print_counter())
+ try:
+ await interactive_shell()
+ finally:
+ background_task.cancel()
+ print("Quitting event loop. Bye.")
+
+
+if __name__ == "__main__":
+ try:
+ from asyncio import run
+ except ImportError:
+ asyncio.run_until_complete(main())
+ else:
+ asyncio.run(main())
diff --git a/examples/prompts/auto-completion/autocomplete-with-control-space.py b/examples/prompts/auto-completion/autocomplete-with-control-space.py
new file mode 100755
index 0000000..61160a3
--- /dev/null
+++ b/examples/prompts/auto-completion/autocomplete-with-control-space.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+"""
+Example of using the control-space key binding for auto completion.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.completion import WordCompleter
+from prompt_toolkit.key_binding import KeyBindings
+
+animal_completer = WordCompleter(
+ [
+ "alligator",
+ "ant",
+ "ape",
+ "bat",
+ "bear",
+ "beaver",
+ "bee",
+ "bison",
+ "butterfly",
+ "cat",
+ "chicken",
+ "crocodile",
+ "dinosaur",
+ "dog",
+ "dolphin",
+ "dove",
+ "duck",
+ "eagle",
+ "elephant",
+ "fish",
+ "goat",
+ "gorilla",
+ "kangaroo",
+ "leopard",
+ "lion",
+ "mouse",
+ "rabbit",
+ "rat",
+ "snake",
+ "spider",
+ "turkey",
+ "turtle",
+ ],
+ ignore_case=True,
+)
+
+
+kb = KeyBindings()
+
+
+@kb.add("c-space")
+def _(event):
+ """
+ Start auto completion. If the menu is showing already, select the next
+ completion.
+ """
+ b = event.app.current_buffer
+ if b.complete_state:
+ b.complete_next()
+ else:
+ b.start_completion(select_first=False)
+
+
+def main():
+ text = prompt(
+ "Give some animals: ",
+ completer=animal_completer,
+ complete_while_typing=False,
+ key_bindings=kb,
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/autocompletion-like-readline.py b/examples/prompts/auto-completion/autocompletion-like-readline.py
new file mode 100755
index 0000000..613d3e7
--- /dev/null
+++ b/examples/prompts/auto-completion/autocompletion-like-readline.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+"""
+Autocompletion example that displays the autocompletions like readline does by
+binding a custom handler to the Tab key.
+"""
+from prompt_toolkit.completion import WordCompleter
+from prompt_toolkit.shortcuts import CompleteStyle, prompt
+
+animal_completer = WordCompleter(
+ [
+ "alligator",
+ "ant",
+ "ape",
+ "bat",
+ "bear",
+ "beaver",
+ "bee",
+ "bison",
+ "butterfly",
+ "cat",
+ "chicken",
+ "crocodile",
+ "dinosaur",
+ "dog",
+ "dolphin",
+ "dove",
+ "duck",
+ "eagle",
+ "elephant",
+ "fish",
+ "goat",
+ "gorilla",
+ "kangaroo",
+ "leopard",
+ "lion",
+ "mouse",
+ "rabbit",
+ "rat",
+ "snake",
+ "spider",
+ "turkey",
+ "turtle",
+ ],
+ ignore_case=True,
+)
+
+
+def main():
+ text = prompt(
+ "Give some animals: ",
+ completer=animal_completer,
+ complete_style=CompleteStyle.READLINE_LIKE,
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/autocompletion.py b/examples/prompts/auto-completion/autocompletion.py
new file mode 100755
index 0000000..fc9dda0
--- /dev/null
+++ b/examples/prompts/auto-completion/autocompletion.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+"""
+Autocompletion example.
+
+Press [Tab] to complete the current word.
+- The first Tab press fills in the common part of all completions
+ and shows all the completions. (In the menu)
+- Any following tab press cycles through all the possible completions.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.completion import WordCompleter
+
+animal_completer = WordCompleter(
+ [
+ "alligator",
+ "ant",
+ "ape",
+ "bat",
+ "bear",
+ "beaver",
+ "bee",
+ "bison",
+ "butterfly",
+ "cat",
+ "chicken",
+ "crocodile",
+ "dinosaur",
+ "dog",
+ "dolphin",
+ "dove",
+ "duck",
+ "eagle",
+ "elephant",
+ "fish",
+ "goat",
+ "gorilla",
+ "kangaroo",
+ "leopard",
+ "lion",
+ "mouse",
+ "rabbit",
+ "rat",
+ "snake",
+ "spider",
+ "turkey",
+ "turtle",
+ ],
+ ignore_case=True,
+)
+
+
+def main():
+ text = prompt(
+ "Give some animals: ", completer=animal_completer, complete_while_typing=False
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/colored-completions-with-formatted-text.py b/examples/prompts/auto-completion/colored-completions-with-formatted-text.py
new file mode 100755
index 0000000..8a89c7a
--- /dev/null
+++ b/examples/prompts/auto-completion/colored-completions-with-formatted-text.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+"""
+Demonstration of a custom completer class and the possibility of styling
+completions independently by passing formatted text objects to the "display"
+and "display_meta" arguments of "Completion".
+"""
+from prompt_toolkit.completion import Completer, Completion
+from prompt_toolkit.formatted_text import HTML
+from prompt_toolkit.shortcuts import CompleteStyle, prompt
+
+animals = [
+ "alligator",
+ "ant",
+ "ape",
+ "bat",
+ "bear",
+ "beaver",
+ "bee",
+ "bison",
+ "butterfly",
+ "cat",
+ "chicken",
+ "crocodile",
+ "dinosaur",
+ "dog",
+ "dolphin",
+ "dove",
+ "duck",
+ "eagle",
+ "elephant",
+]
+
+animal_family = {
+ "alligator": "reptile",
+ "ant": "insect",
+ "ape": "mammal",
+ "bat": "mammal",
+ "bear": "mammal",
+ "beaver": "mammal",
+ "bee": "insect",
+ "bison": "mammal",
+ "butterfly": "insect",
+ "cat": "mammal",
+ "chicken": "bird",
+ "crocodile": "reptile",
+ "dinosaur": "reptile",
+ "dog": "mammal",
+ "dolphin": "mammal",
+ "dove": "bird",
+ "duck": "bird",
+ "eagle": "bird",
+ "elephant": "mammal",
+}
+
+family_colors = {
+ "mammal": "ansimagenta",
+ "insect": "ansigreen",
+ "reptile": "ansired",
+ "bird": "ansiyellow",
+}
+
+meta = {
+ "alligator": HTML(
+ "An <ansired>alligator</ansired> is a <u>crocodilian</u> in the genus Alligator of the family Alligatoridae."
+ ),
+ "ant": HTML(
+ "<ansired>Ants</ansired> are eusocial <u>insects</u> of the family Formicidae."
+ ),
+ "ape": HTML(
+ "<ansired>Apes</ansired> (Hominoidea) are a branch of Old World tailless anthropoid catarrhine <u>primates</u>."
+ ),
+ "bat": HTML("<ansired>Bats</ansired> are mammals of the order <u>Chiroptera</u>."),
+ "bee": HTML(
+ "<ansired>Bees</ansired> are flying <u>insects</u> closely related to wasps and ants."
+ ),
+ "beaver": HTML(
+ "The <ansired>beaver</ansired> (genus Castor) is a large, primarily <u>nocturnal</u>, semiaquatic <u>rodent</u>."
+ ),
+ "bear": HTML(
+ "<ansired>Bears</ansired> are carnivoran <u>mammals</u> of the family Ursidae."
+ ),
+ "butterfly": HTML(
+ "<ansiblue>Butterflies</ansiblue> are <u>insects</u> in the macrolepidopteran clade Rhopalocera from the order Lepidoptera."
+ ),
+ # ...
+}
+
+
+class AnimalCompleter(Completer):
+ def get_completions(self, document, complete_event):
+ word = document.get_word_before_cursor()
+ for animal in animals:
+ if animal.startswith(word):
+ if animal in animal_family:
+ family = animal_family[animal]
+ family_color = family_colors.get(family, "default")
+
+ display = HTML(
+ "%s<b>:</b> <ansired>(<"
+ + family_color
+ + ">%s</"
+ + family_color
+ + ">)</ansired>"
+ ) % (animal, family)
+ else:
+ display = animal
+
+ yield Completion(
+ animal,
+ start_position=-len(word),
+ display=display,
+ display_meta=meta.get(animal),
+ )
+
+
+def main():
+ # Simple completion menu.
+ print("(The completion menu displays colors.)")
+ prompt("Type an animal: ", completer=AnimalCompleter())
+
+ # Multi-column menu.
+ prompt(
+ "Type an animal: ",
+ completer=AnimalCompleter(),
+ complete_style=CompleteStyle.MULTI_COLUMN,
+ )
+
+ # Readline-like
+ prompt(
+ "Type an animal: ",
+ completer=AnimalCompleter(),
+ complete_style=CompleteStyle.READLINE_LIKE,
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/colored-completions.py b/examples/prompts/auto-completion/colored-completions.py
new file mode 100755
index 0000000..9c5cba3
--- /dev/null
+++ b/examples/prompts/auto-completion/colored-completions.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+"""
+Demonstration of a custom completer class and the possibility of styling
+completions independently.
+"""
+from prompt_toolkit.completion import Completer, Completion
+from prompt_toolkit.output.color_depth import ColorDepth
+from prompt_toolkit.shortcuts import CompleteStyle, prompt
+
+colors = [
+ "red",
+ "blue",
+ "green",
+ "orange",
+ "purple",
+ "yellow",
+ "cyan",
+ "magenta",
+ "pink",
+]
+
+
+class ColorCompleter(Completer):
+ def get_completions(self, document, complete_event):
+ word = document.get_word_before_cursor()
+ for color in colors:
+ if color.startswith(word):
+ yield Completion(
+ color,
+ start_position=-len(word),
+ style="fg:" + color,
+ selected_style="fg:white bg:" + color,
+ )
+
+
+def main():
+ # Simple completion menu.
+ print("(The completion menu displays colors.)")
+ prompt("Type a color: ", completer=ColorCompleter())
+
+ # Multi-column menu.
+ prompt(
+ "Type a color: ",
+ completer=ColorCompleter(),
+ complete_style=CompleteStyle.MULTI_COLUMN,
+ )
+
+ # Readline-like
+ prompt(
+ "Type a color: ",
+ completer=ColorCompleter(),
+ complete_style=CompleteStyle.READLINE_LIKE,
+ )
+
+ # Prompt with true color output.
+ message = [
+ ("#cc2244", "T"),
+ ("#bb4444", "r"),
+ ("#996644", "u"),
+ ("#cc8844", "e "),
+ ("#ccaa44", "C"),
+ ("#bbaa44", "o"),
+ ("#99aa44", "l"),
+ ("#778844", "o"),
+ ("#55aa44", "r "),
+ ("#33aa44", "p"),
+ ("#11aa44", "r"),
+ ("#11aa66", "o"),
+ ("#11aa88", "m"),
+ ("#11aaaa", "p"),
+ ("#11aacc", "t"),
+ ("#11aaee", ": "),
+ ]
+ prompt(message, completer=ColorCompleter(), color_depth=ColorDepth.TRUE_COLOR)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/combine-multiple-completers.py b/examples/prompts/auto-completion/combine-multiple-completers.py
new file mode 100755
index 0000000..273ebe5
--- /dev/null
+++ b/examples/prompts/auto-completion/combine-multiple-completers.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+"""
+Example of multiple individual completers that are combined into one.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.completion import Completer, WordCompleter, merge_completers
+
+animal_completer = WordCompleter(
+ [
+ "alligator",
+ "ant",
+ "ape",
+ "bat",
+ "bear",
+ "beaver",
+ "bee",
+ "bison",
+ "butterfly",
+ "cat",
+ "chicken",
+ "crocodile",
+ "dinosaur",
+ "dog",
+ "dolphin",
+ "dove",
+ "duck",
+ "eagle",
+ "elephant",
+ "fish",
+ "goat",
+ "gorilla",
+ "kangaroo",
+ "leopard",
+ "lion",
+ "mouse",
+ "rabbit",
+ "rat",
+ "snake",
+ "spider",
+ "turkey",
+ "turtle",
+ ],
+ ignore_case=True,
+)
+
+color_completer = WordCompleter(
+ [
+ "red",
+ "green",
+ "blue",
+ "yellow",
+ "white",
+ "black",
+ "orange",
+ "gray",
+ "pink",
+ "purple",
+ "cyan",
+ "magenta",
+ "violet",
+ ],
+ ignore_case=True,
+)
+
+
+def main():
+ completer = merge_completers([animal_completer, color_completer])
+
+ text = prompt(
+ "Give some animals: ", completer=completer, complete_while_typing=False
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/fuzzy-custom-completer.py b/examples/prompts/auto-completion/fuzzy-custom-completer.py
new file mode 100755
index 0000000..4052929
--- /dev/null
+++ b/examples/prompts/auto-completion/fuzzy-custom-completer.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+"""
+Demonstration of a custom completer wrapped in a `FuzzyCompleter` for fuzzy
+matching.
+"""
+from prompt_toolkit.completion import Completer, Completion, FuzzyCompleter
+from prompt_toolkit.output.color_depth import ColorDepth
+from prompt_toolkit.shortcuts import CompleteStyle, prompt
+
+colors = [
+ "red",
+ "blue",
+ "green",
+ "orange",
+ "purple",
+ "yellow",
+ "cyan",
+ "magenta",
+ "pink",
+]
+
+
+class ColorCompleter(Completer):
+ def get_completions(self, document, complete_event):
+ word = document.get_word_before_cursor()
+ for color in colors:
+ if color.startswith(word):
+ yield Completion(
+ color,
+ start_position=-len(word),
+ style="fg:" + color,
+ selected_style="fg:white bg:" + color,
+ )
+
+
+def main():
+ # Simple completion menu.
+ print("(The completion menu displays colors.)")
+ prompt("Type a color: ", completer=FuzzyCompleter(ColorCompleter()))
+
+ # Multi-column menu.
+ prompt(
+ "Type a color: ",
+ completer=FuzzyCompleter(ColorCompleter()),
+ complete_style=CompleteStyle.MULTI_COLUMN,
+ )
+
+ # Readline-like
+ prompt(
+ "Type a color: ",
+ completer=FuzzyCompleter(ColorCompleter()),
+ complete_style=CompleteStyle.READLINE_LIKE,
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/fuzzy-word-completer.py b/examples/prompts/auto-completion/fuzzy-word-completer.py
new file mode 100755
index 0000000..329c0c1
--- /dev/null
+++ b/examples/prompts/auto-completion/fuzzy-word-completer.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+"""
+Autocompletion example.
+
+Press [Tab] to complete the current word.
+- The first Tab press fills in the common part of all completions
+ and shows all the completions. (In the menu)
+- Any following tab press cycles through all the possible completions.
+"""
+from prompt_toolkit.completion import FuzzyWordCompleter
+from prompt_toolkit.shortcuts import prompt
+
+animal_completer = FuzzyWordCompleter(
+ [
+ "alligator",
+ "ant",
+ "ape",
+ "bat",
+ "bear",
+ "beaver",
+ "bee",
+ "bison",
+ "butterfly",
+ "cat",
+ "chicken",
+ "crocodile",
+ "dinosaur",
+ "dog",
+ "dolphin",
+ "dove",
+ "duck",
+ "eagle",
+ "elephant",
+ "fish",
+ "goat",
+ "gorilla",
+ "kangaroo",
+ "leopard",
+ "lion",
+ "mouse",
+ "rabbit",
+ "rat",
+ "snake",
+ "spider",
+ "turkey",
+ "turtle",
+ ]
+)
+
+
+def main():
+ text = prompt(
+ "Give some animals: ", completer=animal_completer, complete_while_typing=True
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/multi-column-autocompletion-with-meta.py b/examples/prompts/auto-completion/multi-column-autocompletion-with-meta.py
new file mode 100755
index 0000000..5ba3ab5
--- /dev/null
+++ b/examples/prompts/auto-completion/multi-column-autocompletion-with-meta.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+"""
+Autocompletion example that shows meta-information alongside the completions.
+"""
+from prompt_toolkit.completion import WordCompleter
+from prompt_toolkit.shortcuts import CompleteStyle, prompt
+
+animal_completer = WordCompleter(
+ [
+ "alligator",
+ "ant",
+ "ape",
+ "bat",
+ "bear",
+ "beaver",
+ "bee",
+ "bison",
+ "butterfly",
+ "cat",
+ "chicken",
+ "crocodile",
+ "dinosaur",
+ "dog",
+ "dolphin",
+ "dove",
+ "duck",
+ "eagle",
+ "elephant",
+ ],
+ meta_dict={
+ "alligator": "An alligator is a crocodilian in the genus Alligator of the family Alligatoridae.",
+ "ant": "Ants are eusocial insects of the family Formicidae",
+ "ape": "Apes (Hominoidea) are a branch of Old World tailless anthropoid catarrhine primates ",
+ "bat": "Bats are mammals of the order Chiroptera",
+ },
+ ignore_case=True,
+)
+
+
+def main():
+ text = prompt(
+ "Give some animals: ",
+ completer=animal_completer,
+ complete_style=CompleteStyle.MULTI_COLUMN,
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/multi-column-autocompletion.py b/examples/prompts/auto-completion/multi-column-autocompletion.py
new file mode 100755
index 0000000..7fcfc52
--- /dev/null
+++ b/examples/prompts/auto-completion/multi-column-autocompletion.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+"""
+Similar to the autocompletion example. But display all the completions in multiple columns.
+"""
+from prompt_toolkit.completion import WordCompleter
+from prompt_toolkit.shortcuts import CompleteStyle, prompt
+
+animal_completer = WordCompleter(
+ [
+ "alligator",
+ "ant",
+ "ape",
+ "bat",
+ "bear",
+ "beaver",
+ "bee",
+ "bison",
+ "butterfly",
+ "cat",
+ "chicken",
+ "crocodile",
+ "dinosaur",
+ "dog",
+ "dolphin",
+ "dove",
+ "duck",
+ "eagle",
+ "elephant",
+ "fish",
+ "goat",
+ "gorilla",
+ "kangaroo",
+ "leopard",
+ "lion",
+ "mouse",
+ "rabbit",
+ "rat",
+ "snake",
+ "spider",
+ "turkey",
+ "turtle",
+ ],
+ ignore_case=True,
+)
+
+
+def main():
+ text = prompt(
+ "Give some animals: ",
+ completer=animal_completer,
+ complete_style=CompleteStyle.MULTI_COLUMN,
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/nested-autocompletion.py b/examples/prompts/auto-completion/nested-autocompletion.py
new file mode 100755
index 0000000..cd85b8c
--- /dev/null
+++ b/examples/prompts/auto-completion/nested-autocompletion.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""
+Example of nested autocompletion.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.completion import NestedCompleter
+
+completer = NestedCompleter.from_nested_dict(
+ {
+ "show": {"version": None, "clock": None, "ip": {"interface": {"brief": None}}},
+ "exit": None,
+ }
+)
+
+
+def main():
+ text = prompt("Type a command: ", completer=completer)
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-completion/slow-completions.py b/examples/prompts/auto-completion/slow-completions.py
new file mode 100755
index 0000000..cce9d59
--- /dev/null
+++ b/examples/prompts/auto-completion/slow-completions.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+"""
+An example of how to deal with slow auto completion code.
+
+- Running the completions in a thread is possible by wrapping the
+ `Completer` object in a `ThreadedCompleter`. This makes sure that the
+ ``get_completions`` generator is executed in a background thread.
+
+ For the `prompt` shortcut, we don't have to wrap the completer ourselves.
+ Passing `complete_in_thread=True` is sufficient.
+
+- We also set a `loading` boolean in the completer function to keep track of
+ when the completer is running, and display this in the toolbar.
+"""
+import time
+
+from prompt_toolkit.completion import Completer, Completion
+from prompt_toolkit.shortcuts import CompleteStyle, prompt
+
+WORDS = [
+ "alligator",
+ "ant",
+ "ape",
+ "bat",
+ "bear",
+ "beaver",
+ "bee",
+ "bison",
+ "butterfly",
+ "cat",
+ "chicken",
+ "crocodile",
+ "dinosaur",
+ "dog",
+ "dolphin",
+ "dove",
+ "duck",
+ "eagle",
+ "elephant",
+ "fish",
+ "goat",
+ "gorilla",
+ "kangaroo",
+ "leopard",
+ "lion",
+ "mouse",
+ "rabbit",
+ "rat",
+ "snake",
+ "spider",
+ "turkey",
+ "turtle",
+]
+
+
+class SlowCompleter(Completer):
+ """
+ This is a completer that's very slow.
+ """
+
+ def __init__(self):
+ self.loading = 0
+
+ def get_completions(self, document, complete_event):
+ # Keep count of how many completion generators are running.
+ self.loading += 1
+ word_before_cursor = document.get_word_before_cursor()
+
+ try:
+ for word in WORDS:
+ if word.startswith(word_before_cursor):
+ time.sleep(0.2) # Simulate slowness.
+ yield Completion(word, -len(word_before_cursor))
+
+ finally:
+ # We use try/finally because this generator can be closed if the
+ # input text changes before all completions are generated.
+ self.loading -= 1
+
+
+def main():
+ # We wrap it in a ThreadedCompleter, to make sure it runs in a different
+ # thread. That way, we don't block the UI while running the completions.
+ slow_completer = SlowCompleter()
+
+ # Add a bottom toolbar that display when completions are loading.
+ def bottom_toolbar():
+ return " Loading completions... " if slow_completer.loading > 0 else ""
+
+ # Display prompt.
+ text = prompt(
+ "Give some animals: ",
+ completer=slow_completer,
+ complete_in_thread=True,
+ complete_while_typing=True,
+ bottom_toolbar=bottom_toolbar,
+ complete_style=CompleteStyle.MULTI_COLUMN,
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/auto-suggestion.py b/examples/prompts/auto-suggestion.py
new file mode 100755
index 0000000..6660777
--- /dev/null
+++ b/examples/prompts/auto-suggestion.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+"""
+Simple example of a CLI that demonstrates fish-style auto suggestion.
+
+When you type some input, it will match the input against the history. If One
+entry of the history starts with the given input, then it will show the
+remaining part as a suggestion. Pressing the right arrow will insert this
+suggestion.
+"""
+from prompt_toolkit import PromptSession
+from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
+from prompt_toolkit.history import InMemoryHistory
+
+
+def main():
+ # Create some history first. (Easy for testing.)
+ history = InMemoryHistory()
+ history.append_string("import os")
+ history.append_string('print("hello")')
+ history.append_string('print("world")')
+ history.append_string("import path")
+
+ # Print help.
+ print("This CLI has fish-style auto-suggestion enable.")
+ print('Type for instance "pri", then you\'ll see a suggestion.')
+ print("Press the right arrow to insert the suggestion.")
+ print("Press Control-C to retry. Control-D to exit.")
+ print()
+
+ session = PromptSession(
+ history=history,
+ auto_suggest=AutoSuggestFromHistory(),
+ enable_history_search=True,
+ )
+
+ while True:
+ try:
+ text = session.prompt("Say something: ")
+ except KeyboardInterrupt:
+ pass # Ctrl-C pressed. Try again.
+ else:
+ break
+
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/autocorrection.py b/examples/prompts/autocorrection.py
new file mode 100755
index 0000000..6378132
--- /dev/null
+++ b/examples/prompts/autocorrection.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+"""
+Example of implementing auto correction while typing.
+
+The word "impotr" will be corrected when the user types a space afterwards.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.key_binding import KeyBindings
+
+# Database of words to be replaced by typing.
+corrections = {
+ "impotr": "import",
+ "wolrd": "world",
+}
+
+
+def main():
+ # We start with a `KeyBindings` for our extra key bindings.
+ bindings = KeyBindings()
+
+ # We add a custom key binding to space.
+ @bindings.add(" ")
+ def _(event):
+ """
+ When space is pressed, we check the word before the cursor, and
+ autocorrect that.
+ """
+ b = event.app.current_buffer
+ w = b.document.get_word_before_cursor()
+
+ if w is not None:
+ if w in corrections:
+ b.delete_before_cursor(count=len(w))
+ b.insert_text(corrections[w])
+
+ b.insert_text(" ")
+
+ # Read input.
+ text = prompt("Say something: ", key_bindings=bindings)
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/bottom-toolbar.py b/examples/prompts/bottom-toolbar.py
new file mode 100755
index 0000000..4980e5b
--- /dev/null
+++ b/examples/prompts/bottom-toolbar.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+"""
+A few examples of displaying a bottom toolbar.
+
+The ``prompt`` function takes a ``bottom_toolbar`` attribute.
+This can be any kind of formatted text (plain text, HTML or ANSI), or
+it can be a callable that takes an App and returns an of these.
+
+The bottom toolbar will always receive the style 'bottom-toolbar', and the text
+inside will get 'bottom-toolbar.text'. These can be used to change the default
+style.
+"""
+import time
+
+from prompt_toolkit import prompt
+from prompt_toolkit.formatted_text import ANSI, HTML
+from prompt_toolkit.styles import Style
+
+
+def main():
+ # Example 1: fixed text.
+ text = prompt("Say something: ", bottom_toolbar="This is a toolbar")
+ print("You said: %s" % text)
+
+ # Example 2: fixed text from a callable:
+ def get_toolbar():
+ return "Bottom toolbar: time=%r" % time.time()
+
+ text = prompt("Say something: ", bottom_toolbar=get_toolbar, refresh_interval=0.5)
+ print("You said: %s" % text)
+
+ # Example 3: Using HTML:
+ text = prompt(
+ "Say something: ",
+ bottom_toolbar=HTML(
+ '(html) <b>This</b> <u>is</u> a <style bg="ansired">toolbar</style>'
+ ),
+ )
+ print("You said: %s" % text)
+
+ # Example 4: Using ANSI:
+ text = prompt(
+ "Say something: ",
+ bottom_toolbar=ANSI(
+ "(ansi): \x1b[1mThis\x1b[0m \x1b[4mis\x1b[0m a \x1b[91mtoolbar"
+ ),
+ )
+ print("You said: %s" % text)
+
+ # Example 5: styling differently.
+ style = Style.from_dict(
+ {
+ "bottom-toolbar": "#aaaa00 bg:#ff0000",
+ "bottom-toolbar.text": "#aaaa44 bg:#aa4444",
+ }
+ )
+
+ text = prompt("Say something: ", bottom_toolbar="This is a toolbar", style=style)
+ print("You said: %s" % text)
+
+ # Example 6: Using a list of tokens.
+ def get_bottom_toolbar():
+ return [
+ ("", " "),
+ ("bg:#ff0000 fg:#000000", "This"),
+ ("", " is a "),
+ ("bg:#ff0000 fg:#000000", "toolbar"),
+ ("", ". "),
+ ]
+
+ text = prompt("Say something: ", bottom_toolbar=get_bottom_toolbar)
+ print("You said: %s" % text)
+
+ # Example 7: multiline fixed text.
+ text = prompt("Say something: ", bottom_toolbar="This is\na multiline toolbar")
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/clock-input.py b/examples/prompts/clock-input.py
new file mode 100755
index 0000000..e43abd8
--- /dev/null
+++ b/examples/prompts/clock-input.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+"""
+Example of a 'dynamic' prompt. On that shows the current time in the prompt.
+"""
+import datetime
+
+from prompt_toolkit.shortcuts import prompt
+
+
+def get_prompt():
+ "Tokens to be shown before the prompt."
+ now = datetime.datetime.now()
+ return [
+ ("bg:#008800 #ffffff", f"{now.hour}:{now.minute}:{now.second}"),
+ ("bg:cornsilk fg:maroon", " Enter something: "),
+ ]
+
+
+def main():
+ result = prompt(get_prompt, refresh_interval=0.5)
+ print("You said: %s" % result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/colored-prompt.py b/examples/prompts/colored-prompt.py
new file mode 100755
index 0000000..1e63e29
--- /dev/null
+++ b/examples/prompts/colored-prompt.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+"""
+Example of a colored prompt.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.formatted_text import ANSI, HTML
+from prompt_toolkit.styles import Style
+
+style = Style.from_dict(
+ {
+ # Default style.
+ "": "#ff0066",
+ # Prompt.
+ "username": "#884444 italic",
+ "at": "#00aa00",
+ "colon": "#00aa00",
+ "pound": "#00aa00",
+ "host": "#000088 bg:#aaaaff",
+ "path": "#884444 underline",
+ # Make a selection reverse/underlined.
+ # (Use Control-Space to select.)
+ "selected-text": "reverse underline",
+ }
+)
+
+
+def example_1():
+ """
+ Style and list of (style, text) tuples.
+ """
+ # Not that we can combine class names and inline styles.
+ prompt_fragments = [
+ ("class:username", "john"),
+ ("class:at", "@"),
+ ("class:host", "localhost"),
+ ("class:colon", ":"),
+ ("class:path", "/user/john"),
+ ("bg:#00aa00 #ffffff", "#"),
+ ("", " "),
+ ]
+
+ answer = prompt(prompt_fragments, style=style)
+ print("You said: %s" % answer)
+
+
+def example_2():
+ """
+ Using HTML for the formatting.
+ """
+ answer = prompt(
+ HTML(
+ "<username>john</username><at>@</at>"
+ "<host>localhost</host>"
+ "<colon>:</colon>"
+ "<path>/user/john</path>"
+ '<style bg="#00aa00" fg="#ffffff">#</style> '
+ ),
+ style=style,
+ )
+ print("You said: %s" % answer)
+
+
+def example_3():
+ """
+ Using ANSI for the formatting.
+ """
+ answer = prompt(
+ ANSI(
+ "\x1b[31mjohn\x1b[0m@"
+ "\x1b[44mlocalhost\x1b[0m:"
+ "\x1b[4m/user/john\x1b[0m"
+ "# "
+ )
+ )
+ print("You said: %s" % answer)
+
+
+if __name__ == "__main__":
+ example_1()
+ example_2()
+ example_3()
diff --git a/examples/prompts/confirmation-prompt.py b/examples/prompts/confirmation-prompt.py
new file mode 100755
index 0000000..bd52b9e
--- /dev/null
+++ b/examples/prompts/confirmation-prompt.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+"""
+Example of a confirmation prompt.
+"""
+from prompt_toolkit.shortcuts import confirm
+
+if __name__ == "__main__":
+ answer = confirm("Should we do that?")
+ print("You said: %s" % answer)
diff --git a/examples/prompts/cursor-shapes.py b/examples/prompts/cursor-shapes.py
new file mode 100755
index 0000000..e668243
--- /dev/null
+++ b/examples/prompts/cursor-shapes.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+"""
+Example of cursor shape configurations.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.cursor_shapes import CursorShape, ModalCursorShapeConfig
+
+# NOTE: We pass `enable_suspend=True`, so that we can easily see what happens
+# to the cursor shapes when the application is suspended.
+
+prompt("(block): ", cursor=CursorShape.BLOCK, enable_suspend=True)
+prompt("(underline): ", cursor=CursorShape.UNDERLINE, enable_suspend=True)
+prompt("(beam): ", cursor=CursorShape.BEAM, enable_suspend=True)
+prompt(
+ "(modal - according to vi input mode): ",
+ cursor=ModalCursorShapeConfig(),
+ vi_mode=True,
+ enable_suspend=True,
+)
diff --git a/examples/prompts/custom-key-binding.py b/examples/prompts/custom-key-binding.py
new file mode 100755
index 0000000..32d889e
--- /dev/null
+++ b/examples/prompts/custom-key-binding.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+"""
+Example of adding a custom key binding to a prompt.
+"""
+import asyncio
+
+from prompt_toolkit import prompt
+from prompt_toolkit.application import in_terminal, run_in_terminal
+from prompt_toolkit.key_binding import KeyBindings
+
+
+def main():
+ # We start with a `KeyBindings` of default key bindings.
+ bindings = KeyBindings()
+
+ # Add our own key binding.
+ @bindings.add("f4")
+ def _(event):
+ """
+ When F4 has been pressed. Insert "hello world" as text.
+ """
+ event.app.current_buffer.insert_text("hello world")
+
+ @bindings.add("x", "y")
+ def _(event):
+ """
+ (Useless, but for demoing.)
+ Typing 'xy' will insert 'z'.
+
+ Note that when you type for instance 'xa', the insertion of 'x' is
+ postponed until the 'a' is typed. because we don't know earlier whether
+ or not a 'y' will follow. However, prompt-toolkit should already give
+ some visual feedback of the typed character.
+ """
+ event.app.current_buffer.insert_text("z")
+
+ @bindings.add("a", "b", "c")
+ def _(event):
+ "Typing 'abc' should insert 'd'."
+ event.app.current_buffer.insert_text("d")
+
+ @bindings.add("c-t")
+ def _(event):
+ """
+ Print 'hello world' in the terminal when ControlT is pressed.
+
+ We use ``run_in_terminal``, because that ensures that the prompt is
+ hidden right before ``print_hello`` gets executed and it's drawn again
+ after it. (Otherwise this would destroy the output.)
+ """
+
+ def print_hello():
+ print("hello world")
+
+ run_in_terminal(print_hello)
+
+ @bindings.add("c-k")
+ async def _(event):
+ """
+ Example of asyncio coroutine as a key binding.
+ """
+ try:
+ for i in range(5):
+ async with in_terminal():
+ print("hello")
+ await asyncio.sleep(1)
+ except asyncio.CancelledError:
+ print("Prompt terminated before we completed.")
+
+ # Read input.
+ print('Press F4 to insert "hello world", type "xy" to insert "z":')
+ text = prompt("> ", key_bindings=bindings)
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/custom-lexer.py b/examples/prompts/custom-lexer.py
new file mode 100755
index 0000000..1255d9f
--- /dev/null
+++ b/examples/prompts/custom-lexer.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+"""
+An example of a custom lexer that prints the input text in random colors.
+"""
+from prompt_toolkit.lexers import Lexer
+from prompt_toolkit.shortcuts import prompt
+from prompt_toolkit.styles.named_colors import NAMED_COLORS
+
+
+class RainbowLexer(Lexer):
+ def lex_document(self, document):
+ colors = list(sorted(NAMED_COLORS, key=NAMED_COLORS.get))
+
+ def get_line(lineno):
+ return [
+ (colors[i % len(colors)], c)
+ for i, c in enumerate(document.lines[lineno])
+ ]
+
+ return get_line
+
+
+def main():
+ answer = prompt("Give me some input: ", lexer=RainbowLexer())
+ print("You said: %s" % answer)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/custom-vi-operator-and-text-object.py b/examples/prompts/custom-vi-operator-and-text-object.py
new file mode 100755
index 0000000..7478afc
--- /dev/null
+++ b/examples/prompts/custom-vi-operator-and-text-object.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+"""
+Example of adding a custom Vi operator and text object.
+(Note that this API is not guaranteed to remain stable.)
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.enums import EditingMode
+from prompt_toolkit.key_binding import KeyBindings
+from prompt_toolkit.key_binding.bindings.vi import (
+ TextObject,
+ create_operator_decorator,
+ create_text_object_decorator,
+)
+
+
+def main():
+ # We start with a `Registry` of default key bindings.
+ bindings = KeyBindings()
+
+ # Create the decorators to be used for registering text objects and
+ # operators in this registry.
+ operator = create_operator_decorator(bindings)
+ text_object = create_text_object_decorator(bindings)
+
+ # Create a custom operator.
+
+ @operator("R")
+ def _(event, text_object):
+ "Custom operator that reverses text."
+ buff = event.current_buffer
+
+ # Get relative start/end coordinates.
+ start, end = text_object.operator_range(buff.document)
+ start += buff.cursor_position
+ end += buff.cursor_position
+
+ text = buff.text[start:end]
+ text = "".join(reversed(text))
+
+ event.app.current_buffer.text = buff.text[:start] + text + buff.text[end:]
+
+ # Create a text object.
+
+ @text_object("A")
+ def _(event):
+ "A custom text object that involves everything."
+ # Note that a `TextObject` has coordinates, relative to the cursor position.
+ buff = event.current_buffer
+ return TextObject(
+ -buff.document.cursor_position, # The start.
+ len(buff.text) - buff.document.cursor_position,
+ ) # The end.
+
+ # Read input.
+ print('There is a custom text object "A" that applies to everything')
+ print('and a custom operator "r" that reverses the text object.\n')
+
+ print("Things that are possible:")
+ print("- Riw - reverse inner word.")
+ print("- yA - yank everything.")
+ print("- RA - reverse everything.")
+
+ text = prompt(
+ "> ", default="hello world", key_bindings=bindings, editing_mode=EditingMode.VI
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/enforce-tty-input-output.py b/examples/prompts/enforce-tty-input-output.py
new file mode 100755
index 0000000..93b43ee
--- /dev/null
+++ b/examples/prompts/enforce-tty-input-output.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+"""
+This will display a prompt that will always use the terminal for input and
+output, even if sys.stdin/stdout are connected to pipes.
+
+For testing, run as:
+ cat /dev/null | python ./enforce-tty-input-output.py > /dev/null
+"""
+from prompt_toolkit.application import create_app_session_from_tty
+from prompt_toolkit.shortcuts import prompt
+
+with create_app_session_from_tty():
+ prompt(">")
diff --git a/examples/prompts/fancy-zsh-prompt.py b/examples/prompts/fancy-zsh-prompt.py
new file mode 100755
index 0000000..4761c08
--- /dev/null
+++ b/examples/prompts/fancy-zsh-prompt.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+"""
+Example of the fancy ZSH prompt that @anki-code was using.
+
+The theme is coming from the xonsh plugin from the xxh project:
+https://github.com/xxh/xxh-plugin-xonsh-theme-bar
+
+See:
+- https://github.com/xonsh/xonsh/issues/3356
+- https://github.com/prompt-toolkit/python-prompt-toolkit/issues/1111
+"""
+import datetime
+
+from prompt_toolkit import prompt
+from prompt_toolkit.application import get_app
+from prompt_toolkit.formatted_text import (
+ HTML,
+ fragment_list_width,
+ merge_formatted_text,
+ to_formatted_text,
+)
+from prompt_toolkit.styles import Style
+
+style = Style.from_dict(
+ {
+ "username": "#aaaaaa italic",
+ "path": "#ffffff bold",
+ "branch": "bg:#666666",
+ "branch exclamation-mark": "#ff0000",
+ "env": "bg:#666666",
+ "left-part": "bg:#444444",
+ "right-part": "bg:#444444",
+ "padding": "bg:#444444",
+ }
+)
+
+
+def get_prompt() -> HTML:
+ """
+ Build the prompt dynamically every time its rendered.
+ """
+ left_part = HTML(
+ "<left-part>"
+ " <username>root</username> "
+ " abc "
+ "<path>~/.oh-my-zsh/themes</path>"
+ "</left-part>"
+ )
+ right_part = HTML(
+ "<right-part> "
+ "<branch> master<exclamation-mark>!</exclamation-mark> </branch> "
+ " <env> py36 </env> "
+ " <time>%s</time> "
+ "</right-part>"
+ ) % (datetime.datetime.now().isoformat(),)
+
+ used_width = sum(
+ [
+ fragment_list_width(to_formatted_text(left_part)),
+ fragment_list_width(to_formatted_text(right_part)),
+ ]
+ )
+
+ total_width = get_app().output.get_size().columns
+ padding_size = total_width - used_width
+
+ padding = HTML("<padding>%s</padding>") % (" " * padding_size,)
+
+ return merge_formatted_text([left_part, padding, right_part, "\n", "# "])
+
+
+def main() -> None:
+ while True:
+ answer = prompt(get_prompt, style=style, refresh_interval=1)
+ print("You said: %s" % answer)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/finalterm-shell-integration.py b/examples/prompts/finalterm-shell-integration.py
new file mode 100755
index 0000000..30c7a7f
--- /dev/null
+++ b/examples/prompts/finalterm-shell-integration.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+"""
+Mark the start and end of the prompt with Final term (iterm2) escape sequences.
+See: https://iterm2.com/finalterm.html
+"""
+import sys
+
+from prompt_toolkit import prompt
+from prompt_toolkit.formatted_text import ANSI
+
+BEFORE_PROMPT = "\033]133;A\a"
+AFTER_PROMPT = "\033]133;B\a"
+BEFORE_OUTPUT = "\033]133;C\a"
+AFTER_OUTPUT = (
+ "\033]133;D;{command_status}\a" # command_status is the command status, 0-255
+)
+
+
+def get_prompt_text():
+ # Generate the text fragments for the prompt.
+ # Important: use the `ZeroWidthEscape` fragment only if you are sure that
+ # writing this as raw text to the output will not introduce any
+ # cursor movements.
+ return [
+ ("[ZeroWidthEscape]", BEFORE_PROMPT),
+ ("", "Say something: # "),
+ ("[ZeroWidthEscape]", AFTER_PROMPT),
+ ]
+
+
+if __name__ == "__main__":
+ # Option 1: Using a `get_prompt_text` function:
+ answer = prompt(get_prompt_text)
+
+ # Option 2: Using ANSI escape sequences.
+ before = "\001" + BEFORE_PROMPT + "\002"
+ after = "\001" + AFTER_PROMPT + "\002"
+ answer = prompt(ANSI(f"{before}Say something: # {after}"))
+
+ # Output.
+ sys.stdout.write(BEFORE_OUTPUT)
+ print("You said: %s" % answer)
+ sys.stdout.write(AFTER_OUTPUT.format(command_status=0))
diff --git a/examples/prompts/get-input-vi-mode.py b/examples/prompts/get-input-vi-mode.py
new file mode 100755
index 0000000..566ffd5
--- /dev/null
+++ b/examples/prompts/get-input-vi-mode.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+from prompt_toolkit import prompt
+
+if __name__ == "__main__":
+ print("You have Vi keybindings here. Press [Esc] to go to navigation mode.")
+ answer = prompt("Give me some input: ", multiline=False, vi_mode=True)
+ print("You said: %s" % answer)
diff --git a/examples/prompts/get-input-with-default.py b/examples/prompts/get-input-with-default.py
new file mode 100755
index 0000000..67446d5
--- /dev/null
+++ b/examples/prompts/get-input-with-default.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+"""
+Example of a call to `prompt` with a default value.
+The input is pre-filled, but the user can still edit the default.
+"""
+import getpass
+
+from prompt_toolkit import prompt
+
+if __name__ == "__main__":
+ answer = prompt("What is your name: ", default="%s" % getpass.getuser())
+ print("You said: %s" % answer)
diff --git a/examples/prompts/get-input.py b/examples/prompts/get-input.py
new file mode 100755
index 0000000..5529bbb
--- /dev/null
+++ b/examples/prompts/get-input.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+"""
+The most simple prompt example.
+"""
+from prompt_toolkit import prompt
+
+if __name__ == "__main__":
+ answer = prompt("Give me some input: ")
+ print("You said: %s" % answer)
diff --git a/examples/prompts/get-multiline-input.py b/examples/prompts/get-multiline-input.py
new file mode 100755
index 0000000..eda35be
--- /dev/null
+++ b/examples/prompts/get-multiline-input.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+from prompt_toolkit import prompt
+from prompt_toolkit.formatted_text import HTML
+
+
+def prompt_continuation(width, line_number, wrap_count):
+ """
+ The continuation: display line numbers and '->' before soft wraps.
+
+ Notice that we can return any kind of formatted text from here.
+
+ The prompt continuation doesn't have to be the same width as the prompt
+ which is displayed before the first line, but in this example we choose to
+ align them. The `width` input that we receive here represents the width of
+ the prompt.
+ """
+ if wrap_count > 0:
+ return " " * (width - 3) + "-> "
+ else:
+ text = ("- %i - " % (line_number + 1)).rjust(width)
+ return HTML("<strong>%s</strong>") % text
+
+
+if __name__ == "__main__":
+ print("Press [Meta+Enter] or [Esc] followed by [Enter] to accept input.")
+ answer = prompt(
+ "Multiline input: ", multiline=True, prompt_continuation=prompt_continuation
+ )
+ print("You said: %s" % answer)
diff --git a/examples/prompts/get-password-with-toggle-display-shortcut.py b/examples/prompts/get-password-with-toggle-display-shortcut.py
new file mode 100755
index 0000000..b89cb41
--- /dev/null
+++ b/examples/prompts/get-password-with-toggle-display-shortcut.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+"""
+get_password function that displays asterisks instead of the actual characters.
+With the addition of a ControlT shortcut to hide/show the input.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.filters import Condition
+from prompt_toolkit.key_binding import KeyBindings
+
+
+def main():
+ hidden = [True] # Nonlocal
+ bindings = KeyBindings()
+
+ @bindings.add("c-t")
+ def _(event):
+ "When ControlT has been pressed, toggle visibility."
+ hidden[0] = not hidden[0]
+
+ print("Type Control-T to toggle password visible.")
+ password = prompt(
+ "Password: ", is_password=Condition(lambda: hidden[0]), key_bindings=bindings
+ )
+ print("You said: %s" % password)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/get-password.py b/examples/prompts/get-password.py
new file mode 100755
index 0000000..1c9517c
--- /dev/null
+++ b/examples/prompts/get-password.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+from prompt_toolkit import prompt
+
+if __name__ == "__main__":
+ password = prompt("Password: ", is_password=True)
+ print("You said: %s" % password)
diff --git a/examples/prompts/history/persistent-history.py b/examples/prompts/history/persistent-history.py
new file mode 100755
index 0000000..2bdb758
--- /dev/null
+++ b/examples/prompts/history/persistent-history.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+"""
+Simple example of a CLI that keeps a persistent history of all the entered
+strings in a file. When you run this script for a second time, pressing
+arrow-up will go back in history.
+"""
+from prompt_toolkit import PromptSession
+from prompt_toolkit.history import FileHistory
+
+
+def main():
+ our_history = FileHistory(".example-history-file")
+
+ # The history needs to be passed to the `PromptSession`. It can't be passed
+ # to the `prompt` call because only one history can be used during a
+ # session.
+ session = PromptSession(history=our_history)
+
+ while True:
+ text = session.prompt("Say something: ")
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/history/slow-history.py b/examples/prompts/history/slow-history.py
new file mode 100755
index 0000000..5b6a7a2
--- /dev/null
+++ b/examples/prompts/history/slow-history.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+"""
+Simple example of a custom, very slow history, that is loaded asynchronously.
+
+By wrapping it in `ThreadedHistory`, the history will load in the background
+without blocking any user interaction.
+"""
+import time
+
+from prompt_toolkit import PromptSession
+from prompt_toolkit.history import History, ThreadedHistory
+
+
+class SlowHistory(History):
+ """
+ Example class that loads the history very slowly...
+ """
+
+ def load_history_strings(self):
+ for i in range(1000):
+ time.sleep(1) # Emulate slowness.
+ yield f"item-{i}"
+
+ def store_string(self, string):
+ pass # Don't store strings.
+
+
+def main():
+ print(
+ "Asynchronous loading of history. Notice that the up-arrow will work "
+ "for as far as the completions are loaded.\n"
+ "Even when the input is accepted, loading will continue in the "
+ "background and when the next prompt is displayed.\n"
+ )
+ our_history = ThreadedHistory(SlowHistory())
+
+ # The history needs to be passed to the `PromptSession`. It can't be passed
+ # to the `prompt` call because only one history can be used during a
+ # session.
+ session = PromptSession(history=our_history)
+
+ while True:
+ text = session.prompt("Say something: ")
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/html-input.py b/examples/prompts/html-input.py
new file mode 100755
index 0000000..4c51737
--- /dev/null
+++ b/examples/prompts/html-input.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+"""
+Simple example of a syntax-highlighted HTML input line.
+(This requires Pygments to be installed.)
+"""
+from pygments.lexers.html import HtmlLexer
+
+from prompt_toolkit import prompt
+from prompt_toolkit.lexers import PygmentsLexer
+
+
+def main():
+ text = prompt("Enter HTML: ", lexer=PygmentsLexer(HtmlLexer))
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/input-validation.py b/examples/prompts/input-validation.py
new file mode 100755
index 0000000..d8bd3ee
--- /dev/null
+++ b/examples/prompts/input-validation.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+"""
+Simple example of input validation.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.validation import Validator
+
+
+def is_valid_email(text):
+ return "@" in text
+
+
+validator = Validator.from_callable(
+ is_valid_email,
+ error_message="Not a valid e-mail address (Does not contain an @).",
+ move_cursor_to_end=True,
+)
+
+
+def main():
+ # Validate when pressing ENTER.
+ text = prompt(
+ "Enter e-mail address: ", validator=validator, validate_while_typing=False
+ )
+ print("You said: %s" % text)
+
+ # While typing
+ text = prompt(
+ "Enter e-mail address: ", validator=validator, validate_while_typing=True
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/inputhook.py b/examples/prompts/inputhook.py
new file mode 100755
index 0000000..8520790
--- /dev/null
+++ b/examples/prompts/inputhook.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+"""
+An example that demonstrates how inputhooks can be used in prompt-toolkit.
+
+An inputhook is a callback that an eventloop calls when it's idle. For
+instance, readline calls `PyOS_InputHook`. This allows us to do other work in
+the same thread, while waiting for input. Important however is that we give the
+control back to prompt-toolkit when some input is ready to be processed.
+
+There are two ways to know when input is ready. One way is to poll
+`InputHookContext.input_is_ready()`. Another way is to check for
+`InputHookContext.fileno()` to be ready. In this example we do the latter.
+"""
+import gobject
+import gtk
+from pygments.lexers.python import PythonLexer
+
+from prompt_toolkit.eventloop.defaults import create_event_loop
+from prompt_toolkit.lexers import PygmentsLexer
+from prompt_toolkit.patch_stdout import patch_stdout
+from prompt_toolkit.shortcuts import PromptSession
+
+
+def hello_world_window():
+ """
+ Create a GTK window with one 'Hello world' button.
+ """
+ # Create a new window.
+ window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ window.set_border_width(50)
+
+ # Create a new button with the label "Hello World".
+ button = gtk.Button("Hello World")
+ window.add(button)
+
+ # Clicking the button prints some text.
+ def clicked(data):
+ print("Button clicked!")
+
+ button.connect("clicked", clicked)
+
+ # Display the window.
+ button.show()
+ window.show()
+
+
+def inputhook(context):
+ """
+ When the eventloop of prompt-toolkit is idle, call this inputhook.
+
+ This will run the GTK main loop until the file descriptor
+ `context.fileno()` becomes ready.
+
+ :param context: An `InputHookContext` instance.
+ """
+
+ def _main_quit(*a, **kw):
+ gtk.main_quit()
+ return False
+
+ gobject.io_add_watch(context.fileno(), gobject.IO_IN, _main_quit)
+ gtk.main()
+
+
+def main():
+ # Create user interface.
+ hello_world_window()
+
+ # Enable threading in GTK. (Otherwise, GTK will keep the GIL.)
+ gtk.gdk.threads_init()
+
+ # Read input from the command line, using an event loop with this hook.
+ # We use `patch_stdout`, because clicking the button will print something;
+ # and that should print nicely 'above' the input line.
+ with patch_stdout():
+ session = PromptSession(
+ "Python >>> ", inputhook=inputhook, lexer=PygmentsLexer(PythonLexer)
+ )
+ result = session.prompt()
+ print("You said: %s" % result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/mouse-support.py b/examples/prompts/mouse-support.py
new file mode 100755
index 0000000..1e4ee76
--- /dev/null
+++ b/examples/prompts/mouse-support.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+from prompt_toolkit import prompt
+
+if __name__ == "__main__":
+ print(
+ "This is multiline input. press [Meta+Enter] or [Esc] followed by [Enter] to accept input."
+ )
+ print("You can click with the mouse in order to select text.")
+ answer = prompt("Multiline input: ", multiline=True, mouse_support=True)
+ print("You said: %s" % answer)
diff --git a/examples/prompts/multiline-prompt.py b/examples/prompts/multiline-prompt.py
new file mode 100755
index 0000000..d6a7698
--- /dev/null
+++ b/examples/prompts/multiline-prompt.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+"""
+Demonstration of how the input can be indented.
+"""
+from prompt_toolkit import prompt
+
+if __name__ == "__main__":
+ answer = prompt(
+ "Give me some input: (ESCAPE followed by ENTER to accept)\n > ", multiline=True
+ )
+ print("You said: %s" % answer)
diff --git a/examples/prompts/no-wrapping.py b/examples/prompts/no-wrapping.py
new file mode 100755
index 0000000..371486e
--- /dev/null
+++ b/examples/prompts/no-wrapping.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+from prompt_toolkit import prompt
+
+if __name__ == "__main__":
+ answer = prompt("Give me some input: ", wrap_lines=False, multiline=True)
+ print("You said: %s" % answer)
diff --git a/examples/prompts/operate-and-get-next.py b/examples/prompts/operate-and-get-next.py
new file mode 100755
index 0000000..6ea4d79
--- /dev/null
+++ b/examples/prompts/operate-and-get-next.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+"""
+Demo of "operate-and-get-next".
+
+(Actually, this creates one prompt application, and keeps running the same app
+over and over again. -- For now, this is the only way to get this working.)
+"""
+from prompt_toolkit.shortcuts import PromptSession
+
+
+def main():
+ session = PromptSession("prompt> ")
+ while True:
+ session.prompt()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/patch-stdout.py b/examples/prompts/patch-stdout.py
new file mode 100755
index 0000000..1c83524
--- /dev/null
+++ b/examples/prompts/patch-stdout.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+"""
+An example that demonstrates how `patch_stdout` works.
+
+This makes sure that output from other threads doesn't disturb the rendering of
+the prompt, but instead is printed nicely above the prompt.
+"""
+import threading
+import time
+
+from prompt_toolkit import prompt
+from prompt_toolkit.patch_stdout import patch_stdout
+
+
+def main():
+ # Print a counter every second in another thread.
+ running = True
+
+ def thread():
+ i = 0
+ while running:
+ i += 1
+ print("i=%i" % i)
+ time.sleep(1)
+
+ t = threading.Thread(target=thread)
+ t.daemon = True
+ t.start()
+
+ # Now read the input. The print statements of the other thread
+ # should not disturb anything.
+ with patch_stdout():
+ result = prompt("Say something: ")
+ print("You said: %s" % result)
+
+ # Stop thread.
+ running = False
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/placeholder-text.py b/examples/prompts/placeholder-text.py
new file mode 100755
index 0000000..e113330
--- /dev/null
+++ b/examples/prompts/placeholder-text.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+"""
+Example of a placeholer that's displayed as long as no input is given.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.formatted_text import HTML
+
+if __name__ == "__main__":
+ answer = prompt(
+ "Give me some input: ",
+ placeholder=HTML('<style color="#888888">(please type something)</style>'),
+ )
+ print("You said: %s" % answer)
diff --git a/examples/prompts/regular-language.py b/examples/prompts/regular-language.py
new file mode 100755
index 0000000..cbe7256
--- /dev/null
+++ b/examples/prompts/regular-language.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+"""
+This is an example of "prompt_toolkit.contrib.regular_languages" which
+implements a little calculator.
+
+Type for instance::
+
+ > add 4 4
+ > sub 4 4
+ > sin 3.14
+
+This example shows how you can define the grammar of a regular language and how
+to use variables in this grammar with completers and tokens attached.
+"""
+import math
+
+from prompt_toolkit import prompt
+from prompt_toolkit.completion import WordCompleter
+from prompt_toolkit.contrib.regular_languages.compiler import compile
+from prompt_toolkit.contrib.regular_languages.completion import GrammarCompleter
+from prompt_toolkit.contrib.regular_languages.lexer import GrammarLexer
+from prompt_toolkit.lexers import SimpleLexer
+from prompt_toolkit.styles import Style
+
+operators1 = ["add", "sub", "div", "mul"]
+operators2 = ["cos", "sin"]
+
+
+def create_grammar():
+ return compile(
+ r"""
+ (\s* (?P<operator1>[a-z]+) \s+ (?P<var1>[0-9.]+) \s+ (?P<var2>[0-9.]+) \s*) |
+ (\s* (?P<operator2>[a-z]+) \s+ (?P<var1>[0-9.]+) \s*)
+ """
+ )
+
+
+example_style = Style.from_dict(
+ {
+ "operator": "#33aa33 bold",
+ "number": "#ff0000 bold",
+ "trailing-input": "bg:#662222 #ffffff",
+ }
+)
+
+
+if __name__ == "__main__":
+ g = create_grammar()
+
+ lexer = GrammarLexer(
+ g,
+ lexers={
+ "operator1": SimpleLexer("class:operator"),
+ "operator2": SimpleLexer("class:operator"),
+ "var1": SimpleLexer("class:number"),
+ "var2": SimpleLexer("class:number"),
+ },
+ )
+
+ completer = GrammarCompleter(
+ g,
+ {
+ "operator1": WordCompleter(operators1),
+ "operator2": WordCompleter(operators2),
+ },
+ )
+
+ try:
+ # REPL loop.
+ while True:
+ # Read input and parse the result.
+ text = prompt(
+ "Calculate: ", lexer=lexer, completer=completer, style=example_style
+ )
+ m = g.match(text)
+ if m:
+ vars = m.variables()
+ else:
+ print("Invalid command\n")
+ continue
+
+ print(vars)
+ if vars.get("operator1") or vars.get("operator2"):
+ try:
+ var1 = float(vars.get("var1", 0))
+ var2 = float(vars.get("var2", 0))
+ except ValueError:
+ print("Invalid command (2)\n")
+ continue
+
+ # Turn the operator string into a function.
+ operator = {
+ "add": (lambda a, b: a + b),
+ "sub": (lambda a, b: a - b),
+ "mul": (lambda a, b: a * b),
+ "div": (lambda a, b: a / b),
+ "sin": (lambda a, b: math.sin(a)),
+ "cos": (lambda a, b: math.cos(a)),
+ }[vars.get("operator1") or vars.get("operator2")]
+
+ # Execute and print the result.
+ print("Result: %s\n" % (operator(var1, var2)))
+
+ elif vars.get("operator2"):
+ print("Operator 2")
+
+ except EOFError:
+ pass
diff --git a/examples/prompts/rprompt.py b/examples/prompts/rprompt.py
new file mode 100755
index 0000000..f7656b7
--- /dev/null
+++ b/examples/prompts/rprompt.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+"""
+Example of a right prompt. This is an additional prompt that is displayed on
+the right side of the terminal. It will be hidden automatically when the input
+is long enough to cover the right side of the terminal.
+
+This is similar to RPROMPT is Zsh.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.formatted_text import ANSI, HTML
+from prompt_toolkit.styles import Style
+
+example_style = Style.from_dict(
+ {
+ # The 'rprompt' gets by default the 'rprompt' class. We can use this
+ # for the styling.
+ "rprompt": "bg:#ff0066 #ffffff",
+ }
+)
+
+
+def get_rprompt_text():
+ return [
+ ("", " "),
+ ("underline", "<rprompt>"),
+ ("", " "),
+ ]
+
+
+def main():
+ # Option 1: pass a string to 'rprompt':
+ answer = prompt("> ", rprompt=" <rprompt> ", style=example_style)
+ print("You said: %s" % answer)
+
+ # Option 2: pass HTML:
+ answer = prompt("> ", rprompt=HTML(" <u>&lt;rprompt&gt;</u> "), style=example_style)
+ print("You said: %s" % answer)
+
+ # Option 3: pass ANSI:
+ answer = prompt(
+ "> ", rprompt=ANSI(" \x1b[4m<rprompt>\x1b[0m "), style=example_style
+ )
+ print("You said: %s" % answer)
+
+ # Option 4: Pass a callable. (This callable can either return plain text,
+ # an HTML object, an ANSI object or a list of (style, text)
+ # tuples.
+ answer = prompt("> ", rprompt=get_rprompt_text, style=example_style)
+ print("You said: %s" % answer)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/swap-light-and-dark-colors.py b/examples/prompts/swap-light-and-dark-colors.py
new file mode 100755
index 0000000..e602449
--- /dev/null
+++ b/examples/prompts/swap-light-and-dark-colors.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+"""
+Demonstration of swapping light/dark colors in prompt_toolkit using the
+`swap_light_and_dark_colors` parameter.
+
+Notice that this doesn't swap foreground and background like "reverse" does. It
+turns light green into dark green and the other way around. Foreground and
+background are independent of each other.
+"""
+from pygments.lexers.html import HtmlLexer
+
+from prompt_toolkit import prompt
+from prompt_toolkit.completion import WordCompleter
+from prompt_toolkit.filters import Condition
+from prompt_toolkit.formatted_text import HTML
+from prompt_toolkit.key_binding import KeyBindings
+from prompt_toolkit.lexers import PygmentsLexer
+
+html_completer = WordCompleter(
+ [
+ "<body>",
+ "<div>",
+ "<head>",
+ "<html>",
+ "<img>",
+ "<li>",
+ "<link>",
+ "<ol>",
+ "<p>",
+ "<span>",
+ "<table>",
+ "<td>",
+ "<th>",
+ "<tr>",
+ "<ul>",
+ ],
+ ignore_case=True,
+)
+
+
+def main():
+ swapped = [False] # Nonlocal
+ bindings = KeyBindings()
+
+ @bindings.add("c-t")
+ def _(event):
+ "When ControlT has been pressed, toggle light/dark colors."
+ swapped[0] = not swapped[0]
+
+ def bottom_toolbar():
+ if swapped[0]:
+ on = "on=true"
+ else:
+ on = "on=false"
+
+ return (
+ HTML(
+ 'Press <style bg="#222222" fg="#ff8888">[control-t]</style> '
+ "to swap between dark/light colors. "
+ '<style bg="ansiblack" fg="ansiwhite">[%s]</style>'
+ )
+ % on
+ )
+
+ text = prompt(
+ HTML('<style fg="#aaaaaa">Give some animals</style>: '),
+ completer=html_completer,
+ complete_while_typing=True,
+ bottom_toolbar=bottom_toolbar,
+ key_bindings=bindings,
+ lexer=PygmentsLexer(HtmlLexer),
+ swap_light_and_dark_colors=Condition(lambda: swapped[0]),
+ )
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/prompts/switch-between-vi-emacs.py b/examples/prompts/switch-between-vi-emacs.py
new file mode 100755
index 0000000..249c7ef
--- /dev/null
+++ b/examples/prompts/switch-between-vi-emacs.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+"""
+Example that displays how to switch between Emacs and Vi input mode.
+
+"""
+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 `KeyBindings` that contains the default key bindings.
+ bindings = KeyBindings()
+
+ # Add an additional key binding for toggling this flag.
+ @bindings.add("f4")
+ def _(event):
+ "Toggle between Emacs and Vi mode."
+ if event.app.editing_mode == EditingMode.VI:
+ event.app.editing_mode = EditingMode.EMACS
+ else:
+ event.app.editing_mode = EditingMode.VI
+
+ def bottom_toolbar():
+ "Display the current input mode."
+ if get_app().editing_mode == EditingMode.VI:
+ return " [F4] Vi "
+ else:
+ return " [F4] Emacs "
+
+ prompt("> ", key_bindings=bindings, bottom_toolbar=bottom_toolbar)
+
+
+if __name__ == "__main__":
+ run()
diff --git a/examples/prompts/system-clipboard-integration.py b/examples/prompts/system-clipboard-integration.py
new file mode 100755
index 0000000..f605921
--- /dev/null
+++ b/examples/prompts/system-clipboard-integration.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+"""
+Demonstration of a custom clipboard class.
+This requires the 'pyperclip' library to be installed.
+"""
+from prompt_toolkit import prompt
+from prompt_toolkit.clipboard.pyperclip import PyperclipClipboard
+
+if __name__ == "__main__":
+ print("Emacs shortcuts:")
+ print(" Press Control-Y to paste from the system clipboard.")
+ print(" Press Control-Space or Control-@ to enter selection mode.")
+ print(" Press Control-W to cut to clipboard.")
+ print("")
+
+ answer = prompt("Give me some input: ", clipboard=PyperclipClipboard())
+ print("You said: %s" % answer)
diff --git a/examples/prompts/system-prompt.py b/examples/prompts/system-prompt.py
new file mode 100755
index 0000000..47aa2a5
--- /dev/null
+++ b/examples/prompts/system-prompt.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+from prompt_toolkit import prompt
+
+if __name__ == "__main__":
+ # System prompt.
+ print(
+ "(1/3) If you press meta-! or esc-! at the following prompt, you can enter system commands."
+ )
+ answer = prompt("Give me some input: ", enable_system_prompt=True)
+ print("You said: %s" % answer)
+
+ # Enable suspend.
+ print("(2/3) If you press Control-Z, the application will suspend.")
+ answer = prompt("Give me some input: ", enable_suspend=True)
+ print("You said: %s" % answer)
+
+ # Enable open_in_editor
+ print("(3/3) If you press Control-X Control-E, the prompt will open in $EDITOR.")
+ answer = prompt("Give me some input: ", enable_open_in_editor=True)
+ print("You said: %s" % answer)
diff --git a/examples/prompts/terminal-title.py b/examples/prompts/terminal-title.py
new file mode 100755
index 0000000..14f9459
--- /dev/null
+++ b/examples/prompts/terminal-title.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+from prompt_toolkit import prompt
+from prompt_toolkit.shortcuts import set_title
+
+if __name__ == "__main__":
+ set_title("This is the terminal title")
+ answer = prompt("Give me some input: ")
+ set_title("")
+
+ print("You said: %s" % answer)
diff --git a/examples/prompts/up-arrow-partial-string-matching.py b/examples/prompts/up-arrow-partial-string-matching.py
new file mode 100755
index 0000000..742a12e
--- /dev/null
+++ b/examples/prompts/up-arrow-partial-string-matching.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+"""
+Simple example of a CLI that demonstrates up-arrow partial string matching.
+
+When you type some input, it's possible to use the up arrow to filter the
+history on the items starting with the given input text.
+"""
+from prompt_toolkit import PromptSession
+from prompt_toolkit.history import InMemoryHistory
+
+
+def main():
+ # Create some history first. (Easy for testing.)
+ history = InMemoryHistory()
+ history.append_string("import os")
+ history.append_string('print("hello")')
+ history.append_string('print("world")')
+ history.append_string("import path")
+
+ # Print help.
+ print("This CLI has up-arrow partial string matching enabled.")
+ print('Type for instance "pri" followed by up-arrow and you')
+ print('get the last items starting with "pri".')
+ print("Press Control-C to retry. Control-D to exit.")
+ print()
+
+ session = PromptSession(history=history, enable_history_search=True)
+
+ while True:
+ try:
+ text = session.prompt("Say something: ")
+ except KeyboardInterrupt:
+ pass # Ctrl-C pressed. Try again.
+ else:
+ break
+
+ print("You said: %s" % text)
+
+
+if __name__ == "__main__":
+ main()