Skip to content

Commit 74a2c90

Browse files
authored
Merge pull request #5294 from Textualize/command-markup
Allow console markup in commands
2 parents b276fd2 + 8e4ba84 commit 74a2c90

File tree

7 files changed

+225
-16
lines changed

7 files changed

+225
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1010
### Fixed
1111

1212
- Fixed infinite loop in `Widget.anchor` https://github.com/Textualize/textual/pull/5290
13+
- Restores the ability to supply console markup to command list https://github.com/Textualize/textual/pull/5294
1314
- Fixed delayed App Resize event https://github.com/Textualize/textual/pull/5296
1415

1516
## [0.87.1] - 2024-11-24

src/textual/color.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from rich.color import Color as RichColor
4141
from rich.color import ColorType
4242
from rich.color_triplet import ColorTriplet
43+
from rich.terminal_theme import TerminalTheme
4344
from typing_extensions import Final
4445

4546
from textual._color_constants import ANSI_COLORS, COLOR_NAME_TO_RGB
@@ -176,18 +177,21 @@ def automatic(cls, alpha_percentage: float = 100.0) -> Color:
176177
return cls(0, 0, 0, alpha_percentage / 100.0, auto=True)
177178

178179
@classmethod
179-
def from_rich_color(cls, rich_color: RichColor | None) -> Color:
180+
def from_rich_color(
181+
cls, rich_color: RichColor | None, theme: TerminalTheme | None = None
182+
) -> Color:
180183
"""Create a new color from Rich's Color class.
181184
182185
Args:
183186
rich_color: An instance of [Rich color][rich.color.Color].
187+
theme: Optional Rich [terminal theme][rich.terminal_theme.TerminalTheme].
184188
185189
Returns:
186190
A new Color instance.
187191
"""
188192
if rich_color is None:
189193
return TRANSPARENT
190-
r, g, b = rich_color.get_truecolor()
194+
r, g, b = rich_color.get_truecolor(theme)
191195
return cls(r, g, b)
192196

193197
@classmethod

src/textual/command.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ def build_prompt() -> Iterable[Content]:
11201120
help_style = VisualStyle.from_styles(
11211121
self.get_component_styles("command-palette--help-text")
11221122
)
1123-
yield Content.styled(hit.help, help_style)
1123+
yield Content.from_rich_text(hit.help).stylize_before(help_style)
11241124

11251125
prompt = Content("\n").join(build_prompt())
11261126

src/textual/content.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
from rich.cells import set_cell_size
2020
from rich.console import OverflowMethod
2121
from rich.segment import Segment, Segments
22+
from rich.terminal_theme import TerminalTheme
2223
from rich.text import Text
2324

2425
from textual._cells import cell_len
26+
from textual._context import active_app
2527
from textual._loop import loop_last
2628
from textual.color import Color
2729
from textual.css.types import TextAlign
@@ -180,15 +182,28 @@ def from_rich_text(
180182
New Content.
181183
"""
182184
if isinstance(text, str):
183-
return cls(text, align=align, no_wrap=no_wrap, ellipsis=ellipsis)
184-
spans = [
185-
Span(
186-
start,
187-
end,
188-
style if isinstance(style, str) else Style.from_rich_style(style),
189-
)
190-
for start, end, style in text._spans
191-
]
185+
text = Text.from_markup(text)
186+
if text._spans:
187+
ansi_theme: TerminalTheme | None
188+
try:
189+
ansi_theme = active_app.get().ansi_theme
190+
except LookupError:
191+
ansi_theme = None
192+
spans = [
193+
Span(
194+
start,
195+
end,
196+
(
197+
style
198+
if isinstance(style, str)
199+
else Style.from_rich_style(style, ansi_theme)
200+
),
201+
)
202+
for start, end, style in text._spans
203+
]
204+
else:
205+
spans = []
206+
192207
return cls(
193208
text.plain,
194209
spans,
@@ -681,9 +696,15 @@ def render(
681696
return
682697

683698
if parse_style is None:
699+
app = active_app.get()
700+
# TODO: Update when we add Content.from_markup
684701

685702
def get_style(style: str, /) -> Style:
686-
return TRANSPARENT_STYLE if isinstance(style, str) else style
703+
return (
704+
Style.from_rich_style(app.console.get_style(style), app.ansi_theme)
705+
if isinstance(style, str)
706+
else style
707+
)
687708

688709
else:
689710
get_style = parse_style

src/textual/visual.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from rich.protocol import is_renderable, rich_cast
1414
from rich.segment import Segment
1515
from rich.style import Style as RichStyle
16+
from rich.terminal_theme import TerminalTheme
1617
from rich.text import Text
1718

1819
from textual._context import active_app
@@ -141,18 +142,21 @@ def __add__(self, other: object) -> Style:
141142
return new_style
142143

143144
@classmethod
144-
def from_rich_style(cls, rich_style: RichStyle) -> Style:
145+
def from_rich_style(
146+
cls, rich_style: RichStyle, theme: TerminalTheme | None = None
147+
) -> Style:
145148
"""Build a Style from a (Rich) Style.
146149
147150
Args:
148151
rich_style: A Rich Style object.
152+
theme: Optional Rich [terminal theme][rich.terminal_theme.TerminalTheme].
149153
150154
Returns:
151155
New Style.
152156
"""
153157
return Style(
154-
Color.from_rich_color(rich_style.bgcolor),
155-
Color.from_rich_color(rich_style.color),
158+
Color.from_rich_color(rich_style.bgcolor, theme),
159+
Color.from_rich_color(rich_style.color, theme),
156160
bold=rich_style.bold,
157161
dim=rich_style.dim,
158162
italic=rich_style.italic,
Lines changed: 160 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)