Skip to content

Commit 73abb7d

Browse files
committed
Add key-combo press handler to async_commands.py example
Since prompt-toolkit has all of the components for full screen applications built into it, I thought it would be interesting to demonstrate how users can configure their own custom key bindings to trigger a background method on keypress that prints a message above the prompt. This has some limitations at the moment in that it only works while the prompt is being displayed. But its a start to building a more interesting example.
1 parent d11a2f7 commit 73abb7d

File tree

1 file changed

+44
-1
lines changed

1 file changed

+44
-1
lines changed

examples/async_commands.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
#!/usr/bin/env python
2-
"""A simple example demonstrating how to run async commands in a cmd2 app."""
2+
"""A simple example demonstrating how to run async commands in a cmd2 app.
3+
4+
It also demonstrates how to configure keybindings to run a handler method on
5+
key-combo press and how to display colored output above the prompt.
6+
"""
37

48
import asyncio
59
import functools
10+
import random
11+
import shutil
612
import threading
713
from collections.abc import Callable
814
from typing import (
915
Any,
1016
)
1117

18+
from prompt_toolkit import ANSI, print_formatted_text
19+
from prompt_toolkit.key_binding import KeyBindings
20+
from rich.text import Text
21+
1222
import cmd2
1323

1424
# Global event loop and lock
@@ -69,6 +79,14 @@ def __init__(self) -> None:
6979
super().__init__()
7080
self.intro = 'Welcome to the Async Commands example. Type "help" to see available commands.'
7181

82+
if self.session.key_bindings is None:
83+
self.session.key_bindings = KeyBindings()
84+
85+
# Add a custom key binding for <CTRL>+T that calls a method so it has access to self
86+
@self.session.key_bindings.add('c-t')
87+
def _(_event: Any) -> None:
88+
self.handle_control_t(_event)
89+
7290
@with_async_loop
7391
async def do_my_async(self, _: cmd2.Statement) -> None:
7492
"""An example async command that simulates work."""
@@ -92,6 +110,31 @@ def do_sync_command(self, _: cmd2.Statement) -> None:
92110
"""A normal synchronous command."""
93111
self.poutput("This is a normal synchronous command.")
94112

113+
def handle_control_t(self, _event) -> None:
114+
"""Handler method for <CTRL>+T key press.
115+
116+
Prints 'fnord' above the prompt in a random color and random position.
117+
"""
118+
word = 'fnord'
119+
120+
# Generate a random RGB color tuple
121+
r = random.randint(0, 255)
122+
g = random.randint(0, 255)
123+
b = random.randint(0, 255)
124+
125+
# Get terminal width to calculate padding for right-alignment
126+
cols, _ = shutil.get_terminal_size()
127+
extra_width = cols - len(word) - 1
128+
padding_size = random.randint(0, extra_width)
129+
padding = ' ' * padding_size
130+
131+
# Use rich to generate the the overall text to print out
132+
text = Text()
133+
text.append(padding)
134+
text.append(word, style=f'rgb({r},{g},{b})')
135+
136+
print_formatted_text(ANSI(cmd2.rich_utils.rich_text_to_string(text)))
137+
95138

96139
if __name__ == '__main__':
97140
import sys

0 commit comments

Comments
 (0)