grooveondemand/groove/console.py

147 lines
4.0 KiB
Python
Raw Normal View History

import os
2022-12-17 10:50:02 -08:00
from configparser import ConfigParser
from pathlib import Path
from textwrap import dedent
2022-12-21 15:17:13 -08:00
from typing import Union, List
import rich.repr
from rich.console import Console as _Console
from rich.markdown import Markdown
from rich.theme import Theme
2022-12-21 15:17:13 -08:00
from rich.table import Table, Column
from prompt_toolkit import prompt as _toolkit_prompt
from prompt_toolkit.formatted_text import ANSI
from groove.path import theme
BASE_STYLE = {
'help': 'cyan',
'bright': 'white',
'repr.str': 'dim',
'repr.brace': 'dim',
'repr.url': 'blue',
}
2022-12-21 22:50:37 -08:00
def console_theme(theme_name: Union[str, None] = None) -> dict:
2022-12-21 15:17:13 -08:00
"""
Return a console theme as a dictionary.
Args:
theme_name (str):
"""
2022-12-17 10:50:02 -08:00
cfg = ConfigParser()
cfg.read_dict({'styles': BASE_STYLE})
2022-12-21 22:50:37 -08:00
theme_path = theme_name if theme_name else os.environ.get('DEFAULT_THEME', 'blue_train')
2022-12-17 10:50:02 -08:00
cfg.read(theme(
2022-12-21 22:50:37 -08:00
Path(theme_path) / Path('console.cfg')
2022-12-21 21:16:06 -08:00
))
2022-12-17 10:50:02 -08:00
return cfg['styles']
2022-12-21 15:17:13 -08:00
@rich.repr.auto
class Console(_Console):
2022-12-21 15:17:13 -08:00
"""
SYNOPSIS
Subclasses a rich.console.Console to provide an instance with a
reconfigured themes, and convenience methods and attributes.
USAGE
Console([ARGS])
ARGS
theme The name of a theme to load. Defaults to DEFAULT_THEME.
EXAMPLES
Console().print("Can I kick it?")
>>> Can I kick it?
INSTANCE ATTRIBUTES
theme The current theme
"""
def __init__(self, *args, **kwargs):
2022-12-17 10:50:02 -08:00
self._console_theme = console_theme(kwargs.get('theme', None))
2022-12-21 15:17:13 -08:00
self._overflow = 'ellipsis'
2022-12-17 10:50:02 -08:00
kwargs['theme'] = Theme(self._console_theme, inherit=False)
super().__init__(*args, **kwargs)
2022-12-17 10:50:02 -08:00
@property
2022-12-21 15:17:13 -08:00
def theme(self) -> Theme:
2022-12-17 10:50:02 -08:00
return self._console_theme
2022-12-21 15:17:13 -08:00
def prompt(self, lines: List, **kwargs) -> str:
"""
Print a list of lines, using the final line as a prompt.
Example:
Console().prompt(["Can I kick it?", "[Y/n] ")
>>> Can I kick it?
[Y/n]>
"""
for line in lines[:-1]:
super().print(line)
with self.capture() as capture:
super().print(f"[prompt bold]{lines[-1]}>[/] ", end='')
rendered = ANSI(capture.get())
return _toolkit_prompt(rendered, **kwargs)
2022-12-21 15:17:13 -08:00
def mdprint(self, txt: str, **kwargs) -> None:
"""
Like print(), but support markdown. Text will be dedented.
"""
self.print(Markdown(dedent(txt), justify='left'), **kwargs)
2022-12-21 15:17:13 -08:00
def print(self, txt: str, **kwargs) -> None:
"""
Print text to the console, possibly truncated with an ellipsis.
"""
super().print(txt, overflow=self._overflow, **kwargs)
2022-12-31 12:28:07 -08:00
def debug(self, txt: str, **kwargs) -> None:
"""
Print text to the console with the current theme's debug style applied, if debugging is enabled.
"""
if os.environ.get('DEBUG', None):
self.print(dedent(txt), style='debug')
2022-12-21 15:17:13 -08:00
def error(self, txt: str, **kwargs) -> None:
"""
Print text to the console with the current theme's error style applied.
"""
self.print(dedent(txt), style='error')
def table(self, *cols: List[Column], **params) -> None:
"""
Print a rich table to the console with theme elements and styles applied.
parameters and keyword arguments are passed to rich.table.Table.
"""
background_style = f"on {self.theme['background']}"
params.update(
header_style=background_style,
title_style=background_style,
border_style=background_style,
row_styles=[background_style],
caption_style=background_style,
style=background_style,
)
2022-12-17 18:02:12 -08:00
params['min_width'] = 80
2022-12-17 10:50:02 -08:00
width = os.environ.get('CONSOLE_WIDTH', 'auto')
if width == 'expand':
params['expand'] = True
elif width != 'auto':
params['width'] = int(width)
return Table(*cols, **params)