Created
December 12, 2024 19:27
-
-
Save r0x0d/f4f25257cdb294b1e79fc0e3f30918ed to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import shutil | |
import time | |
from pathlib import Path | |
from typing import List, Tuple | |
from command_line_assistant.rendering.decorators.colors import ColorDecorator | |
from command_line_assistant.rendering.decorators.style import StyleDecorator | |
from command_line_assistant.rendering.decorators.text import ( | |
EmojiDecorator, | |
TextWrapDecorator, | |
WriteOnceDecorator, | |
) | |
from command_line_assistant.rendering.renders.spinner import Frames, SpinnerRenderer | |
from command_line_assistant.rendering.renders.text import TextRenderer | |
from command_line_assistant.rendering.stream import StdoutStream | |
def get_terminal_width() -> int: | |
"""Get current terminal width.""" | |
return shutil.get_terminal_size().columns | |
def render_row(items: List[Tuple[TextRenderer, str]], column_width: int = 30) -> None: | |
"""Render a row of items with proper spacing.""" | |
for renderer, text in items: | |
formatted_text = f"{text:<{column_width}}" | |
renderer.render(formatted_text) | |
print() # New line after each row | |
def chunk_list(lst: list, chunk_size: int) -> List[list]: | |
"""Split list into chunks of specified size.""" | |
return [lst[i:i + chunk_size] for i in range(0, len(lst), chunk_size)] | |
def demo_color_decorator(): | |
print("\nColor Decorator Demo") | |
print("=" * get_terminal_width()) | |
# Calculate widths for formatting | |
name_width = 15 | |
sample_width = 20 | |
total_width = name_width + sample_width + 5 # 5 for spacing | |
columns = get_terminal_width() // total_width | |
def print_color_row(colors: List[str], is_background: bool = False): | |
for i in range(0, len(colors), columns): | |
chunk = colors[i:i + columns] | |
# Print each color in the chunk | |
for color in chunk: | |
# Print color name without decoration | |
print(f"{color:<{name_width}}", end="") | |
# Print sample text with color decoration | |
renderer = TextRenderer() | |
if is_background: | |
renderer.update(ColorDecorator(foreground="white", background=color)) | |
sample_text = "Sample Text" | |
else: | |
renderer.update(ColorDecorator(foreground=color)) | |
sample_text = "Sample Text" | |
renderer.render(f"{sample_text:<{sample_width}}") | |
print() # New line after each row | |
# Foreground Colors | |
print("\nForeground Colors:") | |
print("-" * get_terminal_width()) | |
foreground_colors = list(ColorDecorator.FOREGROUND_COLORS.keys()) | |
print_color_row(foreground_colors) | |
# Background Colors | |
print("\nBackground Colors:") | |
print("-" * get_terminal_width()) | |
background_colors = list(ColorDecorator.BACKGROUND_COLORS.keys()) | |
print_color_row(background_colors, is_background=True) | |
def demo_style_decorator(): | |
print("\nStyle Decorator Demo:") | |
print("--------------------") | |
terminal_width = get_terminal_width() | |
columns_per_row = terminal_width // 30 | |
items = [] | |
for style in StyleDecorator.STYLES.keys(): | |
renderer = TextRenderer() | |
renderer.update(StyleDecorator(style=style)) | |
items.append((renderer, f"Style {style}")) | |
rows = chunk_list(items, columns_per_row) | |
for row in rows: | |
render_row(row) | |
def demo_emoji_decorator(): | |
print("\nEmoji Decorator Demo:") | |
print("--------------------") | |
emoji_samples = [ | |
("U+1F600", "Grinning Face"), | |
("U+1F4BB", "Laptop"), | |
("U+2728", "Sparkles"), | |
("U+1F680", "Rocket"), | |
("U+1F4A1", "Light Bulb"), | |
("U+1F431", "Cat Face"), | |
("U+1F436", "Dog Face"), | |
("U+1F951", "Avocado"), | |
("U+1F389", "Party Popper"), | |
("U+1F3C6", "Trophy"), | |
] | |
terminal_width = get_terminal_width() | |
columns_per_row = terminal_width // 35 # Wider columns for emojis | |
items = [] | |
for code, description in emoji_samples: | |
renderer = TextRenderer() | |
renderer.update(EmojiDecorator(code)) | |
items.append((renderer, description)) | |
rows = chunk_list(items, columns_per_row) | |
for row in rows: | |
render_row(row, column_width=35) | |
def demo_text_wrap_decorator(): | |
print("\nText Wrap Decorator Demo:") | |
print("-----------------------") | |
sample_text = "This is a sample text that demonstrates wrapping. It should show different wrapping styles and indentation options available in the TextWrapDecorator." | |
# Default wrap | |
print("\nDefault wrap:") | |
renderer = TextRenderer() | |
renderer.update(TextWrapDecorator()) | |
renderer.render(sample_text) | |
# Custom width wrap | |
print("\nCustom width (40 chars):") | |
renderer = TextRenderer() | |
renderer.update(TextWrapDecorator(width=40)) | |
renderer.render(sample_text) | |
# Indented wrap | |
print("\nIndented wrap:") | |
renderer = TextRenderer() | |
renderer.update(TextWrapDecorator(indent=" ")) | |
renderer.render(sample_text) | |
def demo_write_once_decorator(): | |
print("\nWrite Once Decorator Demo") | |
print("========================") | |
# First, ensure we clean up any existing state files | |
state_dir = Path("~/.local/state/command-line-assistant").expanduser() | |
if state_dir.exists(): | |
for file in state_dir.glob("demo_*"): | |
file.unlink() | |
messages = [ | |
("demo_1", "This message should appear only once"), | |
("demo_2", "This is another one-time message"), | |
("demo_1", "This won't appear because demo_1 was already shown"), | |
("demo_2", "This won't appear because demo_2 was already shown"), | |
("demo_3", "But this new message with demo_3 will appear") | |
] | |
print("\nRunning multiple writes with different state files:") | |
print("------------------------------------------------") | |
for state_file, message in messages: | |
renderer = TextRenderer() | |
renderer.update(WriteOnceDecorator(state_filename=state_file)) | |
renderer.render(message) | |
print("\nRunning the same messages again:") | |
print("-------------------------------") | |
for state_file, message in messages: | |
renderer = TextRenderer() | |
renderer.update(WriteOnceDecorator(state_filename=state_file)) | |
renderer.render(message) | |
def demo_stdout_stream(): | |
print("\nStdout Stream Demo") | |
print("=================") | |
renderer = TextRenderer() # Default is stdout | |
renderer.update(ColorDecorator(foreground="green")) | |
print("Standard output:", end="\t") | |
renderer.render("This message goes to stdout") | |
def demo_stderr_stream(): | |
from command_line_assistant.rendering.stream import StderrStream | |
print("\nStderr Stream Demo") | |
print("=================") | |
renderer = TextRenderer(stream=StderrStream()) | |
renderer.update(ColorDecorator(foreground="red")) | |
print("Standard error:") | |
renderer.render("This message goes to stderr") | |
def demo_spinner_renderer(): | |
print("\nSpinner Renderer Demo") | |
print("====================") | |
# Basic spinner with color | |
print("\nBasic spinner with color:") | |
spinner = SpinnerRenderer( | |
message="Loading with green color", | |
stream=StdoutStream(end=""), | |
delay=0.1 | |
) | |
spinner.update(ColorDecorator(foreground="green")) | |
with spinner: | |
time.sleep(2) | |
# Spinner with emoji and color | |
print("\nSpinner with emoji and color:") | |
spinner = SpinnerRenderer( | |
message="Processing with robot emoji", | |
stream=StdoutStream(end=""), | |
delay=0.1 | |
) | |
spinner.update(EmojiDecorator("U+1F916")) | |
spinner.update(ColorDecorator(foreground="cyan")) | |
with spinner: | |
time.sleep(2) | |
# Spinner with multiple decorators | |
print("\nSpinner with multiple decorators:") | |
spinner = SpinnerRenderer( | |
message="Complex spinner demonstrating multiple decorators working together seamlessly", | |
stream=StdoutStream(end=""), | |
frames=Frames.moving, | |
delay=0.1 | |
) | |
spinner.update(EmojiDecorator("U+1F680")) | |
spinner.update(ColorDecorator(foreground="magenta")) | |
with spinner: | |
time.sleep(2) | |
def main(): | |
print(f"Rendering Library Demo (Terminal width: {get_terminal_width()} columns)") | |
print("="* get_terminal_width()) | |
demo_spinner_renderer() | |
# --- | |
demo_color_decorator() | |
demo_style_decorator() | |
demo_emoji_decorator() | |
demo_text_wrap_decorator() | |
demo_write_once_decorator() | |
# --- | |
demo_stdout_stream() | |
demo_stderr_stream() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment