Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Textualize/rich
Browse files Browse the repository at this point in the history
  • Loading branch information
darrenburns committed Jun 21, 2022
2 parents 30498f5 + 8c4032c commit 53cda57
Show file tree
Hide file tree
Showing 19 changed files with 311 additions and 173 deletions.
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ 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).

## [Unreleased]
## [12.4.5] - Unreleased

### Added

- Environment variables `JUPYTER_COLUMNS` and `JUPYTER_LINES` to control width and height of console in Jupyter

### Changed

- Default width of Jupyter console size is increased to 115

### Fixed

Expand All @@ -14,6 +22,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Allow exceptions that are raised while a Live is rendered to be displayed and/or processed https://github.com/Textualize/rich/pull/2305
- Fix crashes that can happen with `inspect` when docstrings contain some special control codes https://github.com/Textualize/rich/pull/2294
- Fix edges used in first row of tables when `show_header=False` https://github.com/Textualize/rich/pull/2330
- Fix interaction between `Capture` contexts and `Console(record=True)` https://github.com/Textualize/rich/pull/2343
- Fixed hash issue in Styles class https://github.com/Textualize/rich/pull/2346

### Changed

- `Style.__add__` will no longer return `NotImplemented`
- Remove rich.\_lru_cache

## [12.4.4] - 2022-05-24

Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The following people have contributed to the development of Rich:
- [Pete Davison](https://github.com/pd93)
- [James Estevez](https://github.com/jstvz)
- [Oleksis Fraga](https://github.com/oleksis)
- [Andy Gimblett](https://github.com/gimbo)
- [Michał Górny](https://github.com/mgorny)
- [Leron Gray](https://github.com/daddycocoaman)
- [Kenneth Hoste](https://github.com/boegel)
Expand All @@ -24,6 +25,7 @@ The following people have contributed to the development of Rich:
- [Alexander Mancevice](https://github.com/amancevice)
- [Will McGugan](https://github.com/willmcgugan)
- [Paul McGuire](https://github.com/ptmcg)
- [Antony Milne](https://github.com/AntonyMilneQB)
- [Nathan Page](https://github.com/nathanrpage97)
- [Avi Perl](https://github.com/avi-perl)
- [Laurent Peuch](https://github.com/psycojoker)
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
alabaster==0.7.12
Sphinx==4.5.0
Sphinx==5.0.2
sphinx-rtd-theme==1.0.0
sphinx-copybutton==0.5.0
2 changes: 2 additions & 0 deletions docs/source/console.rst
Original file line number Diff line number Diff line change
Expand Up @@ -421,3 +421,5 @@ Rich respects some standard environment variables.
Setting the environment variable ``TERM`` to ``"dumb"`` or ``"unknown"`` will disable color/style and some features that require moving the cursor, such as progress bars.

If the environment variable ``NO_COLOR`` is set, Rich will disable all color in the output.

If ``width``/``height`` arguments are not explicitly provided as arguments to ``Console`` then the environment variables ``COLUMNS``/``LINES`` can be used to set the console width/height. ``JUPYTER_COLUMNS``/``JUPYTER_LINES`` behave similarly and are used in Jupyter.
50 changes: 25 additions & 25 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jupyter = ["ipywidgets"]
[tool.poetry.dev-dependencies]
pytest = "^7.0.0"
black = "^22.3"
mypy = "^0.950"
mypy = "^0.961"
pytest-cov = "^3.0.0"
attrs = "^21.4.0"
types-dataclasses = "^0.6.4"
Expand Down
38 changes: 0 additions & 38 deletions rich/_lru_cache.py

This file was deleted.

28 changes: 19 additions & 9 deletions rich/cells.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import re
from functools import lru_cache
from typing import Dict, List
from typing import Callable, List

from ._cell_widths import CELL_WIDTHS
from ._lru_cache import LRUCache

# Regex to match sequence of the most common character ranges
_is_single_cell_widths = re.compile("^[\u0020-\u006f\u00a0\u02ff\u0370-\u0482]*$").match


def cell_len(text: str, _cache: Dict[str, int] = LRUCache(1024 * 4)) -> int:
@lru_cache(4096)
def _cached_cell_len(text: str) -> int:
"""Get the number of cells required to display text.
Args:
Expand All @@ -18,14 +18,24 @@ def cell_len(text: str, _cache: Dict[str, int] = LRUCache(1024 * 4)) -> int:
Returns:
int: Get the number of cells required to display text.
"""
cached_result = _cache.get(text, None)
if cached_result is not None:
return cached_result
_get_size = get_character_cell_size
total_size = sum(_get_size(character) for character in text)
return total_size


def cell_len(text: str, _cell_len: Callable[[str], int] = _cached_cell_len) -> int:
"""Get the number of cells required to display text.
Args:
text (str): Text to display.
Returns:
int: Get the number of cells required to display text.
"""
if len(text) < 512:
return _cell_len(text)
_get_size = get_character_cell_size
total_size = sum(_get_size(character) for character in text)
if len(text) <= 512:
_cache[text] = total_size
return total_size


Expand Down Expand Up @@ -80,7 +90,7 @@ def set_cell_size(text: str, total: int) -> str:
return text + " " * (total - size)
return text[:total]

if not total:
if total <= 0:
return ""
cell_size = cell_len(text)
if cell_size == total:
Expand Down
24 changes: 18 additions & 6 deletions rich/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
from .live import Live
from .status import Status

JUPYTER_DEFAULT_COLUMNS = 115
JUPYTER_DEFAULT_LINES = 100
WINDOWS = platform.system() == "Windows"

HighlighterType = Callable[[Union[str, "Text"]], "Text"]
Expand Down Expand Up @@ -656,8 +658,18 @@ def __init__(

self.is_jupyter = _is_jupyter() if force_jupyter is None else force_jupyter
if self.is_jupyter:
width = width or 93
height = height or 100
if width is None:
jupyter_columns = self._environ.get("JUPYTER_COLUMNS")
if jupyter_columns is not None and jupyter_columns.isdigit():
width = int(jupyter_columns)
else:
width = JUPYTER_DEFAULT_COLUMNS
if height is None:
jupyter_lines = self._environ.get("JUPYTER_LINES")
if jupyter_lines is not None and jupyter_lines.isdigit():
height = int(jupyter_lines)
else:
height = JUPYTER_DEFAULT_LINES

self.soft_wrap = soft_wrap
self._width = width
Expand Down Expand Up @@ -1959,11 +1971,11 @@ def _check_buffer(self) -> None:
del self._buffer[:]
return
with self._lock:
if self._buffer_index == 0:
if self.record:
with self._record_buffer_lock:
self._record_buffer.extend(self._buffer[:])

if self.record:
with self._record_buffer_lock:
self._record_buffer.extend(self._buffer[:])
if self._buffer_index == 0:

if self.is_jupyter: # pragma: no cover
from .jupyter import display
Expand Down
2 changes: 2 additions & 0 deletions rich/diagnose.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ def report() -> None: # pragma: no cover
"TERM_PROGRAM",
"COLUMNS",
"LINES",
"JUPYTER_COLUMNS",
"JUPYTER_LINES",
"JPY_PARENT_PID",
"VSCODE_VERBOSE_LOGGING",
)
Expand Down
37 changes: 28 additions & 9 deletions rich/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .cells import cell_len, set_cell_size
from .console import Console, ConsoleOptions, RenderResult
from .jupyter import JupyterMixin
from .measure import Measurement
from .style import Style
from .text import Text

Expand Down Expand Up @@ -62,10 +63,7 @@ def __rich_console__(

chars_len = cell_len(characters)
if not self.title:
rule_text = Text(characters * ((width // chars_len) + 1), self.style)
rule_text.truncate(width)
rule_text.plain = set_cell_size(rule_text.plain, width)
yield rule_text
yield self._rule_line(chars_len, width)
return

if isinstance(self.title, Text):
Expand All @@ -75,10 +73,16 @@ def __rich_console__(

title_text.plain = title_text.plain.replace("\n", " ")
title_text.expand_tabs()
rule_text = Text(end=self.end)

required_space = 4 if self.align == "center" else 2
truncate_width = max(0, width - required_space)
if not truncate_width:
yield self._rule_line(chars_len, width)
return

rule_text = Text(end=self.end)
if self.align == "center":
title_text.truncate(width - 4, overflow="ellipsis")
title_text.truncate(truncate_width, overflow="ellipsis")
side_width = (width - cell_len(title_text.plain)) // 2
left = Text(characters * (side_width // chars_len + 1))
left.truncate(side_width - 1)
Expand All @@ -89,27 +93,42 @@ def __rich_console__(
rule_text.append(title_text)
rule_text.append(" " + right.plain, self.style)
elif self.align == "left":
title_text.truncate(width - 2, overflow="ellipsis")
title_text.truncate(truncate_width, overflow="ellipsis")
rule_text.append(title_text)
rule_text.append(" ")
rule_text.append(characters * (width - rule_text.cell_len), self.style)
elif self.align == "right":
title_text.truncate(width - 2, overflow="ellipsis")
title_text.truncate(truncate_width, overflow="ellipsis")
rule_text.append(characters * (width - title_text.cell_len - 1), self.style)
rule_text.append(" ")
rule_text.append(title_text)

rule_text.plain = set_cell_size(rule_text.plain, width)
yield rule_text

def _rule_line(self, chars_len: int, width: int) -> Text:
rule_text = Text(self.characters * ((width // chars_len) + 1), self.style)
rule_text.truncate(width)
rule_text.plain = set_cell_size(rule_text.plain, width)
return rule_text

def __rich_measure__(
self, console: Console, options: ConsoleOptions
) -> Measurement:
return Measurement(1, 1)


if __name__ == "__main__": # pragma: no cover
from rich.console import Console
import sys

from rich.console import Console

try:
text = sys.argv[1]
except IndexError:
text = "Hello, World"
console = Console()
console.print(Rule(title=text))

console = Console()
console.print(Rule("foo"), width=4)
Loading

0 comments on commit 53cda57

Please sign in to comment.