diff --git a/CHANGELOG.md b/CHANGELOG.md index a294e9a46f..2533447e73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Changed - Widget.release_mouse will now only release the mouse, if it was captured by self https://github.com/Textualize/textual/pull/5900 +- Some optimizations to TextArea, which may be noticeable during scrolling (note: may break snapshots with a TextArea) https://github.com/Textualize/textual/pull/5925 +- Selecting in the TextArea now hides the cursor until you release the mouse https://github.com/Textualize/textual/pull/5925 +- Read only TextAreas will no longer display a cursor https://github.com/Textualize/textual/pull/5925 ## Added diff --git a/src/textual/document/_document.py b/src/textual/document/_document.py index 47e87eb09b..92d5a12a99 100644 --- a/src/textual/document/_document.py +++ b/src/textual/document/_document.py @@ -466,3 +466,8 @@ def is_empty(self) -> bool: """Return True if the selection has 0 width, i.e. it's just a cursor.""" start, end = self return start == end + + def contains_line(self, y: int) -> bool: + """Check if the given line is within the selection.""" + top, bottom = sorted((self.start[0], self.end[0])) + return y >= top and y <= bottom diff --git a/src/textual/widgets/_text_area.py b/src/textual/widgets/_text_area.py index 1e666699d2..5b89494ddd 100644 --- a/src/textual/widgets/_text_area.py +++ b/src/textual/widgets/_text_area.py @@ -9,12 +9,14 @@ from typing import TYPE_CHECKING, ClassVar, Iterable, Optional, Sequence, Tuple from rich.console import RenderableType +from rich.segment import Segment from rich.style import Style from rich.text import Text from typing_extensions import Literal from textual._text_area_theme import TextAreaTheme from textual._tree_sitter import TREE_SITTER, get_language +from textual.cache import LRUCache from textual.color import Color from textual.document._document import ( Document, @@ -511,6 +513,8 @@ def __init__( self.set_reactive(TextArea.line_number_start, line_number_start) self.set_reactive(TextArea.highlight_cursor_line, highlight_cursor_line) + self._line_cache: LRUCache[tuple, Strip] = LRUCache(1024) + self._set_document(text, language) self.language = language @@ -610,6 +614,9 @@ def _get_builtin_highlight_query(language_name: str) -> str: return highlight_query + def notify_style_update(self) -> None: + self._line_cache.clear() + def check_consume_key(self, key: str, character: str | None = None) -> bool: """Check if the widget may consume the given key. @@ -633,6 +640,7 @@ def check_consume_key(self, key: str, character: str | None = None) -> bool: def _build_highlight_map(self) -> None: """Query the tree for ranges to highlights, and update the internal highlights mapping.""" + self._line_cache.clear() highlights = self._highlights highlights.clear() if not self._highlight_query: @@ -1035,6 +1043,7 @@ def wrap_width(self) -> int: def _rewrap_and_refresh_virtual_size(self) -> None: self.wrapped_document.wrap(self.wrap_width, tab_width=self.indent_width) + self._line_cache.clear() self._refresh_size() @property @@ -1105,11 +1114,60 @@ def get_line(self, line_index: int) -> Text: A `rich.Text` object containing the requested line. """ line_string = self.document.get_line(line_index) - return Text(line_string, end="") + return Text(line_string, end="", no_wrap=True) + + def render_lines(self, crop: Region) -> list[Strip]: + theme = self._theme + if theme: + theme.apply_css(self) + return super().render_lines(crop) def render_line(self, y: int) -> Strip: """Render a single line of the TextArea. Called by Textual. + Args: + y: Y Coordinate of line relative to the widget region. + + Returns: + A rendered line. + """ + scroll_x, scroll_y = self.scroll_offset + absolute_y = scroll_y + y + selection = self.selection + cache_key = ( + self.size, + scroll_x, + absolute_y, + ( + selection + if selection.contains_line(absolute_y) + else selection.end[0] == absolute_y + ), + ( + selection.end + if ( + self._cursor_visible + and self.cursor_blink + and absolute_y == selection.end[0] + ) + else None + ), + self.theme, + self._matching_bracket_location, + self.match_cursor_bracket, + self.soft_wrap, + self.show_line_numbers, + self.read_only, + ) + if (cached_line := self._line_cache.get(cache_key)) is not None: + return cached_line + line = self._render_line(y) + self._line_cache[cache_key] = line + return line + + def _render_line(self, y: int) -> Strip: + """Render a single line of the TextArea. Called by Textual. + Args: y: Y Coordinate of line relative to the widget region. @@ -1117,8 +1175,6 @@ def render_line(self, y: int) -> Strip: A rendered line. """ theme = self._theme - if theme: - theme.apply_css(self) wrapped_document = self.wrapped_document scroll_x, scroll_y = self.scroll_offset @@ -1173,7 +1229,8 @@ def render_line(self, y: int) -> Strip: if selection_style: if line_character_count == 0 and line_index != cursor_row: # A simple highlight to show empty lines are included in the selection - line = Text("▌", end="", style=Style(color=selection_style.bgcolor)) + line.plain = "▌" + line.stylize(Style(color=selection_style.bgcolor)) else: if line_index == selection_top_row == selection_bottom_row: # Selection within a single line @@ -1222,6 +1279,7 @@ def render_line(self, y: int) -> Strip: self.has_focus and not self.cursor_blink or (self.cursor_blink and self._cursor_visible) + and not self.read_only ) if draw_matched_brackets: matching_bracket_style = theme.bracket_matching_style if theme else None @@ -1263,13 +1321,11 @@ def render_line(self, y: int) -> Strip: gutter_content = ( str(line_index + self.line_number_start) if section_offset == 0 else "" ) - gutter = Text( - f"{gutter_content:>{gutter_width_no_margin}} ", - style=gutter_style or "", - end="", - ) + gutter = [ + Segment(f"{gutter_content:>{gutter_width_no_margin}} ", gutter_style) + ] else: - gutter = Text("", end="") + gutter = [] # TODO: Lets not apply the division each time through render_line. # We should cache sections with the edit counts. @@ -1304,17 +1360,10 @@ def render_line(self, y: int) -> Strip: else max(virtual_width, self.region.size.width) ) target_width = base_width - self.gutter_width - console = self.app.console - gutter_segments = console.render(gutter) - - text_segments = list( - console.render(line, console.options.update_width(target_width)) - ) - - gutter_strip = Strip(gutter_segments, cell_length=gutter_width) - text_strip = Strip(text_segments) # Crop the line to show only the visible part (some may be scrolled out of view) + console = self.app.console + text_strip = Strip(line.render(console), cell_length=line.cell_len) if not self.soft_wrap: text_strip = text_strip.crop(scroll_x, scroll_x + virtual_width) @@ -1325,7 +1374,7 @@ def render_line(self, y: int) -> Strip: line_style = theme.base_style if theme else None text_strip = text_strip.extend_cell_length(target_width, line_style) - strip = Strip.join([gutter_strip, text_strip]).simplify() + strip = Strip.join([Strip(gutter, cell_length=gutter_width), text_strip]) return strip.apply_style( theme.base_style @@ -1645,7 +1694,7 @@ async def _on_mouse_down(self, event: events.MouseDown) -> None: # Capture the mouse so that if the cursor moves outside the # TextArea widget while selecting, the widget still scrolls. self.capture_mouse() - self._pause_blink(visible=True) + self._pause_blink(visible=False) self.history.checkpoint() async def _on_mouse_move(self, event: events.MouseMove) -> None: diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_compact.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_compact.svg index 34376a69a8..46754508c2 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_compact.svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_compact.svg @@ -128,7 +128,7 @@ - + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Bar   Foo world                                    diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_percentage_width.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_percentage_width.svg index 607ae43be9..f7fc7d756c 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_percentage_width.svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_percentage_width.svg @@ -19,135 +19,135 @@ font-weight: 700; } - .terminal-3778060113-matrix { + .terminal-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3778060113-title { + .terminal-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3778060113-r1 { fill: #121212 } -.terminal-3778060113-r2 { fill: #e0e0e0 } -.terminal-3778060113-r3 { fill: #c5c8c6 } -.terminal-3778060113-r4 { fill: #ff0000 } -.terminal-3778060113-r5 { fill: #e0e0e0;font-weight: bold } + .terminal-r1 { fill: #121212 } +.terminal-r2 { fill: #e0e0e0 } +.terminal-r3 { fill: #c5c8c6 } +.terminal-r4 { fill: #ff0000 } +.terminal-r5 { fill: #e0e0e0;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - InputVsTextArea + InputVsTextArea - - - - 01234567890123456789012345678901234567890123456789012345678901234567890123456789 -┌──────────────────────────────────────┐ - - - -└──────────────────────────────────────┘ -┌──────────────────────────────────────┐ - - - - -└──────────────────────────────────────┘ -┌──────────────────────────────────────┐ - - - - -└──────────────────────────────────────┘ -┌──────────────────────────────────────┐ - - Button  - - -└──────────────────────────────────────┘ + + + + 01234567890123456789012345678901234567890123456789012345678901234567890123456789 +┌──────────────────────────────────────┐ + + + +└──────────────────────────────────────┘ +┌──────────────────────────────────────┐ + + + + +└──────────────────────────────────────┘ +┌──────────────────────────────────────┐ + + + + +└──────────────────────────────────────┘ +┌──────────────────────────────────────┐ + + Button  + + +└──────────────────────────────────────┘ diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_setting_transparency.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_setting_transparency.svg index 9067444ae6..f4285cfdc5 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_setting_transparency.svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_setting_transparency.svg @@ -35,8 +35,8 @@ .terminal-r1 { fill: #c5c8c6 } .terminal-r2 { fill: #00008b } .terminal-r3 { fill: #0178d4 } -.terminal-r4 { fill: #e0e0e0 } -.terminal-r5 { fill: #121212 } +.terminal-r4 { fill: #121212 } +.terminal-r5 { fill: #e0e0e0 } .terminal-r6 { fill: #191919 } @@ -123,30 +123,30 @@ - + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -Baseline normal TextArea, not transparent      +Baseline normal TextArea, not transparent      ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ -This TextArea made transparent by adding a     -CSS class                                      +This TextArea made transparent by adding a     +CSS class                                      ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ -This TextArea made transparent by setting      -style with python                              +This TextArea made transparent by setting      +style with python                              ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ -1) This is an OptionList +1) This is an OptionList -2) With a transparent background +2) With a transparent background -3) Made transparent by setting style with -python +3) Made transparent by setting style with +python ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_alternate_screen.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_alternate_screen.svg index a3e7102202..4dd6b583b8 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_alternate_screen.svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_alternate_screen.svg @@ -19,78 +19,78 @@ font-weight: 700; } - .terminal-4214779899-matrix { + .terminal-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4214779899-title { + .terminal-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4214779899-r1 { fill: #121212 } -.terminal-4214779899-r2 { fill: #0178d4 } -.terminal-4214779899-r3 { fill: #c5c8c6 } -.terminal-4214779899-r4 { fill: #e0e0e0 } + .terminal-r1 { fill: #121212 } +.terminal-r2 { fill: #0178d4 } +.terminal-r3 { fill: #c5c8c6 } +.terminal-r4 { fill: #e0e0e0 } - + - + - + - + - + - + - + - + - + - + - TABug + TABug - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -foo                                          -bar                                          -baz                                          - - - - - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +foo                                          +bar                                          +baz                                          + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection0].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection0].svg index e3cad34a17..025391ca71 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection0].svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection0].svg @@ -19,72 +19,72 @@ font-weight: 700; } - .terminal-1738498439-matrix { + .terminal-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1738498439-title { + .terminal-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1738498439-r1 { fill: #121212 } -.terminal-1738498439-r2 { fill: #0178d4 } -.terminal-1738498439-r3 { fill: #c5c8c6 } -.terminal-1738498439-r4 { fill: #f8f8f2 } -.terminal-1738498439-r5 { fill: #65686a } -.terminal-1738498439-r6 { fill: #272822 } + .terminal-r1 { fill: #121212 } +.terminal-r2 { fill: #0178d4 } +.terminal-r3 { fill: #c5c8c6 } +.terminal-r4 { fill: #f8f8f2 } +.terminal-r5 { fill: #65686a } +.terminal-r6 { fill: #272822 } - + - + - + - + - + - + - + - + - TextAreaSnapshot + TextAreaSnapshot - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -I am a line. - -I am another line.         - -I am the final line.       - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line. + +I am another line.         + +I am the final line.       + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection1].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection1].svg index ac8ed8617b..914e6127c0 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection1].svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection1].svg @@ -19,72 +19,72 @@ font-weight: 700; } - .terminal-285530678-matrix { + .terminal-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-285530678-title { + .terminal-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-285530678-r1 { fill: #121212 } -.terminal-285530678-r2 { fill: #0178d4 } -.terminal-285530678-r3 { fill: #c5c8c6 } -.terminal-285530678-r4 { fill: #f8f8f2 } -.terminal-285530678-r5 { fill: #272822 } -.terminal-285530678-r6 { fill: #65686a } + .terminal-r1 { fill: #121212 } +.terminal-r2 { fill: #0178d4 } +.terminal-r3 { fill: #c5c8c6 } +.terminal-r4 { fill: #272822 } +.terminal-r5 { fill: #f8f8f2 } +.terminal-r6 { fill: #65686a } - + - + - + - + - + - + - + - + - TextAreaSnapshot + TextAreaSnapshot - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -I am a line. - -I am another line.         - -I am the final line.       - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line. + +I am another line.         + +I am the final line.       + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection2].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection2].svg index 05f3172b39..d912b7920a 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection2].svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection2].svg @@ -19,72 +19,72 @@ font-weight: 700; } - .terminal-1391651187-matrix { + .terminal-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1391651187-title { + .terminal-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1391651187-r1 { fill: #121212 } -.terminal-1391651187-r2 { fill: #0178d4 } -.terminal-1391651187-r3 { fill: #c5c8c6 } -.terminal-1391651187-r4 { fill: #f8f8f2 } -.terminal-1391651187-r5 { fill: #272822 } -.terminal-1391651187-r6 { fill: #65686a } + .terminal-r1 { fill: #121212 } +.terminal-r2 { fill: #0178d4 } +.terminal-r3 { fill: #c5c8c6 } +.terminal-r4 { fill: #272822 } +.terminal-r5 { fill: #f8f8f2 } +.terminal-r6 { fill: #65686a } - + - + - + - + - + - + - + - + - TextAreaSnapshot + TextAreaSnapshot - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -I am a line. - -I am another line. - -I am the final line.       - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line. + +I am another line. + +I am the final line.       + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection3].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection3].svg index d4660bad04..456199a1db 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection3].svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection3].svg @@ -19,72 +19,72 @@ font-weight: 700; } - .terminal-3443945668-matrix { + .terminal-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3443945668-title { + .terminal-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3443945668-r1 { fill: #121212 } -.terminal-3443945668-r2 { fill: #0178d4 } -.terminal-3443945668-r3 { fill: #c5c8c6 } -.terminal-3443945668-r4 { fill: #f8f8f2 } -.terminal-3443945668-r5 { fill: #65686a } -.terminal-3443945668-r6 { fill: #272822 } + .terminal-r1 { fill: #121212 } +.terminal-r2 { fill: #0178d4 } +.terminal-r3 { fill: #c5c8c6 } +.terminal-r4 { fill: #f8f8f2 } +.terminal-r5 { fill: #65686a } +.terminal-r6 { fill: #272822 } - + - + - + - + - + - + - + - + - TextAreaSnapshot + TextAreaSnapshot - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -I am a line. - -I am another line. - -I am the final line. - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line. + +I am another line. + +I am the final line. + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection4].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection4].svg index 3b482cb438..ef5f467e75 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection4].svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection4].svg @@ -19,71 +19,71 @@ font-weight: 700; } - .terminal-3984920137-matrix { + .terminal-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3984920137-title { + .terminal-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3984920137-r1 { fill: #121212 } -.terminal-3984920137-r2 { fill: #0178d4 } -.terminal-3984920137-r3 { fill: #c5c8c6 } -.terminal-3984920137-r4 { fill: #f8f8f2 } -.terminal-3984920137-r5 { fill: #272822 } + .terminal-r1 { fill: #121212 } +.terminal-r2 { fill: #0178d4 } +.terminal-r3 { fill: #c5c8c6 } +.terminal-r4 { fill: #f8f8f2 } +.terminal-r5 { fill: #272822 } - + - + - + - + - + - + - + - + - TextAreaSnapshot + TextAreaSnapshot - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -I am a line.               - -I am another line.         - -I am the final line.       - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line.               + +I am another line.         + +I am the final line.       + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection5].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection5].svg index 99915b4179..54a9c7edcb 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection5].svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection5].svg @@ -19,71 +19,71 @@ font-weight: 700; } - .terminal-1348948452-matrix { + .terminal-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1348948452-title { + .terminal-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1348948452-r1 { fill: #121212 } -.terminal-1348948452-r2 { fill: #0178d4 } -.terminal-1348948452-r3 { fill: #c5c8c6 } -.terminal-1348948452-r4 { fill: #f8f8f2 } -.terminal-1348948452-r5 { fill: #272822 } + .terminal-r1 { fill: #121212 } +.terminal-r2 { fill: #0178d4 } +.terminal-r3 { fill: #c5c8c6 } +.terminal-r4 { fill: #f8f8f2 } +.terminal-r5 { fill: #272822 } - + - + - + - + - + - + - + - + - TextAreaSnapshot + TextAreaSnapshot - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -I am a line.               - -I am another line.         - -I am the final line.       - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line.               + +I am another line.         + +I am the final line.       + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁