From 76dfb9654b1ea469ca957a0312ef9ab536dc0f3e Mon Sep 17 00:00:00 2001 From: Will McGugan <willmcgugan@gmail.com> Date: Mon, 11 Jul 2022 12:49:56 +0100 Subject: [PATCH] optimized divide --- CHANGELOG.md | 4 ++- pyproject.toml | 2 +- rich/console.py | 1 + rich/segment.py | 62 +++++++++++++++++++++++++-------------------- tests/test_panel.py | 3 ++- 5 files changed, 42 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60204d2dd..767f3f8eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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). -## [12.4.5] - Unreleased +## [12.5.0] - Unreleased ### Added @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Default width of Jupyter console size is increased to 115 +- Optimized Segment.divide ### Fixed @@ -26,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 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 +- Fixed bug in `Segment.split_and_crop_lines` ### Changed diff --git a/pyproject.toml b/pyproject.toml index 7bb6bda18..3ebe0eac3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "rich" homepage = "https://github.com/willmcgugan/rich" documentation = "https://rich.readthedocs.io/en/latest/" -version = "12.4.4" +version = "12.5.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" authors = ["Will McGugan <willmcgugan@gmail.com>"] license = "MIT" diff --git a/rich/console.py b/rich/console.py index 5b8eb751e..8c6049a49 100644 --- a/rich/console.py +++ b/rich/console.py @@ -1349,6 +1349,7 @@ def render_lines( render_options.max_width, include_new_lines=new_lines, pad=pad, + style=style, ), None, render_height, diff --git a/rich/segment.py b/rich/segment.py index d825cfca4..75d13d052 100644 --- a/rich/segment.py +++ b/rich/segment.py @@ -18,6 +18,7 @@ from .cells import ( _is_single_cell_widths, + cached_cell_len, cell_len, get_character_cell_size, set_cell_size, @@ -290,11 +291,11 @@ def split_and_crop_lines( for segment in segments: if "\n" in segment.text and not segment.control: - text, style, _ = segment + text, segment_style, _ = segment while text: _text, new_line, text = text.partition("\n") if _text: - append(cls(_text, style)) + append(cls(_text, segment_style)) if new_line: cropped_line = adjust_line_length( line, length, style=style, pad=pad @@ -611,41 +612,48 @@ def divide( yield [] pos = 0 - _cell_len = cell_len + segments_clear = split_segments.clear + segments_copy = split_segments.copy + + _cell_len = cached_cell_len for segment in segments: text, _style, control = segment while text: - if control: - end_pos = pos - else: - end_pos = pos + _cell_len(text) + end_pos = pos if control else pos + _cell_len(text) if end_pos < cut: add_segment(segment) pos = end_pos break - try: - if end_pos == cut: - add_segment(segment) - yield split_segments[:] - del split_segments[:] - pos = end_pos - break - else: - before, segment = segment.split_cells(cut - pos) - text, _style, control = segment - add_segment(before) - yield split_segments[:] - del split_segments[:] - pos = cut - finally: - try: - cut = next(iter_cuts) - except StopIteration: + if end_pos == cut: + add_segment(segment) + yield segments_copy() + segments_clear() + pos = end_pos + + cut = next(iter_cuts, -1) + if cut == -1: if split_segments: - yield split_segments[:] + yield segments_copy() return - yield split_segments[:] + + break + + else: + before, segment = segment.split_cells(cut - pos) + text, _style, control = segment + add_segment(before) + yield segments_copy() + segments_clear() + pos = cut + + cut = next(iter_cuts, -1) + if cut == -1: + if split_segments: + yield segments_copy() + return + + yield segments_copy() class Segments: diff --git a/tests/test_panel.py b/tests/test_panel.py index 040288cfe..5ae3babee 100644 --- a/tests/test_panel.py +++ b/tests/test_panel.py @@ -73,7 +73,8 @@ def test_render_size(): Segment(" ", Style()), Segment("foo"), Segment( - " " + " ", + Style(), ), Segment(" ", Style()), Segment("│", Style()),