tweak for windoze

This commit is contained in:
Will McGugan 2020-02-21 18:09:45 +00:00
parent cce43bd5fa
commit 33361e1d85
6 changed files with 73 additions and 24 deletions

View File

@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.4.0] - Unreleased
### Added
- Added Traceback rendering and handler
- Added rich.constrain
### Fixed
- Fixed unnecessary padding
## [0.3.3] - 2020-02-04
### Fixed

View File

@ -830,7 +830,7 @@ class Console:
if self.record:
self._record_buffer.extend(buffer)
del self.buffer[:]
for line in Segment.split_and_crop_lines(buffer, self.width):
for line in Segment.split_and_crop_lines(buffer, self.width, pad=False):
for text, style in line:
if style:
append(style.render(text, color_system=color_system, reset=True))

View File

@ -41,14 +41,20 @@ class Segment(NamedTuple):
@classmethod
def split_and_crop_lines(
cls, segments: Iterable["Segment"], length: int, style: Style = None
cls,
segments: Iterable["Segment"],
length: int,
style: Style = None,
pad: bool = True,
) -> Iterable[List["Segment"]]:
"""Split segments in to lines, and crop lines greater than a given length.
Args:
segments (Iterable[Segment]): An iterable of segments, probably
generated from console.render.
length (Optional[int]): Desired line length.
length (int): Desired line length.
style (Style, optional): Style to use for any padding.
pad (bool): Enable padding of lines that are less than `length`.
Returns:
Iterable[List[Segment]]: An iterable of lines of segments.
@ -64,31 +70,37 @@ class Segment(NamedTuple):
if _text:
append(cls(_text, style))
if new_line:
yield cls.adjust_line_length(lines[-1], length, style=style)
yield cls.adjust_line_length(
lines[-1], length, style=style, pad=pad
)
lines.append([])
append = lines[-1].append
else:
append(segment)
if lines[-1]:
yield cls.adjust_line_length(lines[-1], length, style=style)
yield cls.adjust_line_length(lines[-1], length, style=style, pad=pad)
@classmethod
def adjust_line_length(
cls, line: List["Segment"], length: int, style: Style = None
cls, line: List["Segment"], length: int, style: Style = None, pad: bool = True
) -> List["Segment"]:
"""Adjust a line to a given width (cropping or padding as required.
"""Adjust a line to a given width (cropping or padding as required).
Args:
segments (Iterable[Segment]): A list of segments in a single line.
length (int): The desired width of the line.
style (Style, optional): The style of padding if used (space on the end). Defaults to None.
pad (bool, optional): Pad lines with spaces if they are shorter than `length`. Defaults to True.
Returns:
List[Segment]: A line of segments with the desired length.
"""
line_length = sum(len(text) for text, _style in line)
if line_length < length:
return line + [Segment(" " * (length - line_length), style)]
if pad:
return line + [cls(" " * (length - line_length), style)]
else:
return line[:]
elif line_length > length:
line_length = 0
new_line: List[Segment] = []
@ -100,7 +112,7 @@ class Segment(NamedTuple):
line_length += segment_length
else:
text, style = segment
append(Segment(text[: length - line_length], style))
append(cls(text[: length - line_length], style))
break
return new_line
return line[:]

View File

@ -1,3 +1,4 @@
import platform
import textwrap
from typing import Any, Dict, Optional, Set, Tuple, Union
@ -14,7 +15,8 @@ from .style import Style
from .text import Text
from ._tools import iter_first
DEFAULT_THEME = "monokai"
WINDOWS = platform.system() == "Windows"
DEFAULT_THEME = "dark"
class Syntax:
@ -166,6 +168,24 @@ class Syntax:
return len(str(self.start_line + self.code.count("\n"))) + 2
return 0
def _get_number_styles(self, console: Console) -> Tuple[Style, Style, Style]:
"""Get background, number, and highlight styles for line numbers."""
background_style = Style(bgcolor=self._pygments_style_class.background_color)
if console.color_system in ("256", "truecolor"):
number_style = Style.chain(
background_style,
self._get_theme_style(Token.Text),
Style(color=self._get_line_numbers_color()),
)
highlight_number_style = Style.chain(
background_style,
self._get_theme_style(Token.Text),
Style(bold=True, color=self._get_line_numbers_color(0.9)),
)
else:
number_style = highlight_number_style = Style()
return background_style, number_style, highlight_number_style
def __console_width__(self, max_width: int) -> "RenderWidth":
if self.code_width is not None:
width = self.code_width + self._numbers_column_width
@ -199,23 +219,20 @@ class Syntax:
numbers_column_width = self._numbers_column_width
render_options = options.update(width=code_width + numbers_column_width)
background_style = Style(bgcolor=self._pygments_style_class.background_color)
number_style = Style.chain(
(
background_style,
self._get_theme_style(Token.Text),
Style(color=self._get_line_numbers_color()),
)
highlight_number_style = Style.chain(
background_style,
self._get_theme_style(Token.Text),
Style(bold=True, color=self._get_line_numbers_color(0.9)),
)
number_style,
highlight_number_style,
) = self._get_number_styles(console)
highlight_line = self.highlight_lines.__contains__
_Segment = Segment
padding = _Segment(" " * numbers_column_width, background_style)
new_line = _Segment("\n")
line_pointer = "->" if WINDOWS else ""
for line_no, line in enumerate(lines, self.start_line + line_offset):
wrapped_lines = console.render_lines(
line, render_options, style=background_style
@ -224,7 +241,7 @@ class Syntax:
if first:
line_column = str(line_no).rjust(numbers_column_width - 2) + " "
if highlight_line(line_no):
yield _Segment("", number_style)
yield _Segment(line_pointer, number_style)
yield _Segment(
line_column, highlight_number_style,
)
@ -252,9 +269,9 @@ def __init__(self):
syntax = Syntax(CODE, "python", line_numbers=False, theme="monokai")
syntax = Syntax.from_path(
"rich/segment.py",
theme="monokai",
theme="fruity",
line_numbers=True,
line_range=(190, 300),
# line_range=(190, 300),
highlight_lines={194},
)
console = Console(record=True)

View File

@ -488,11 +488,13 @@ if __name__ == "__main__": # pragma: no cover
expand=True,
show_footer=True,
show_edge=True,
width=100,
style="on blue",
)
# table.columns[0].width = 50
# table.columns[1].ratio = 1
table.add_row("Hello, World! " * 8, "cake" * 10)
table.add_row("Hello, World! " * 3, "cake" * 10)
from .markdown import Markdown
table.add_row(Markdown("# This is *Markdown*!"), "More text", "Hello WOrld")

View File

@ -2,6 +2,7 @@ from __future__ import absolute_import
from dataclasses import dataclass, field
import sys
import platform
from traceback import extract_tb
from types import TracebackType
from typing import Optional, Type, List
@ -17,6 +18,7 @@ from .constrain import Constrain
from .highlighter import RegexHighlighter, ReprHighlighter
from .padding import Padding
from .panel import Panel
from .pygments_themes.base16_dark import base16_default_dark
from .rule import Rule
from .segment import Segment
from .text import Text
@ -24,6 +26,9 @@ from ._tools import iter_last
from .syntax import Syntax
WINDOWS = platform.system() == "Windows"
def install(width: Optional[int] = 100, extra_lines: int = 2) -> None:
"""Install a rich traceback handler.
@ -205,6 +210,7 @@ class Traceback:
@render_group()
def _render_stack(self, stack: Stack) -> RenderResult:
path_highlighter = PathHighlighter()
theme = "fruity" if WINDOWS else "monokai"
for frame in stack.frames:
text = Text.assemble(
(" File ", "traceback.text"),
@ -220,6 +226,7 @@ class Traceback:
try:
syntax = Syntax.from_path(
frame.filename,
theme=theme,
line_numbers=True,
line_range=(
frame.lineno - self.extra_lines,