diff --git a/src/prompt_toolkit/completion/base.py b/src/prompt_toolkit/completion/base.py index 6e73290ec..323303c41 100644 --- a/src/prompt_toolkit/completion/base.py +++ b/src/prompt_toolkit/completion/base.py @@ -117,6 +117,8 @@ def new_completion_from_position(self, position: int) -> Completion: text=self.text[position - self.start_position :], display=self.display, display_meta=self._display_meta, + style=self.style, + selected_style=self.selected_style, ) diff --git a/tests/test_buffer.py b/tests/test_buffer.py index e636137d5..782e16526 100644 --- a/tests/test_buffer.py +++ b/tests/test_buffer.py @@ -1,8 +1,12 @@ from __future__ import annotations +import asyncio + import pytest from prompt_toolkit.buffer import Buffer +from prompt_toolkit.completion import Completer, Completion +from prompt_toolkit.document import Document @pytest.fixture @@ -110,3 +114,33 @@ def test_swap_characters_before_cursor(_buffer): _buffer.swap_characters_before_cursor() assert _buffer.text == "hello wrold" + + +def test_common_completion_preserves_styles(): + class StyledCompleter(Completer): + def get_completions(self, document, complete_event): + for text, style, selected_style in ( + ("hello", "fg:ansired", "bg:ansigreen"), + ("help", "fg:ansiblue", "bg:ansiyellow"), + ): + yield Completion( + text, + start_position=-2, + style=style, + selected_style=selected_style, + ) + + buffer = Buffer(completer=StyledCompleter(), document=Document("he", 2)) + asyncio.run(buffer._async_completer(insert_common_part=True)) + + assert buffer.text == "hel" + assert buffer.complete_state is not None + completions = buffer.complete_state.completions + assert [(c.text, c.style, c.selected_style) for c in completions] == [ + ("lo", "fg:ansired", "bg:ansigreen"), + ("p", "fg:ansiblue", "bg:ansiyellow"), + ] + buffer.go_to_completion(0) + assert buffer.text == "hello" + buffer.go_to_completion(1) + assert buffer.text == "help" diff --git a/tests/test_completion.py b/tests/test_completion.py index 8b3541af0..11fcbd254 100644 --- a/tests/test_completion.py +++ b/tests/test_completion.py @@ -8,6 +8,7 @@ from prompt_toolkit.completion import ( CompleteEvent, + Completion, FuzzyWordCompleter, NestedCompleter, PathCompleter, @@ -467,3 +468,23 @@ def create_completer(deduplicate: bool): ) ) assert len(completions) == 5 + + +def test_completion_from_position_preserves_styles(): + completion = Completion( + "hello", + start_position=-2, + display=[("bold", "Hello")], + display_meta=lambda: "greeting", + style="fg:ansired", + selected_style="bg:ansigreen", + ) + + suffix = completion.new_completion_from_position(1) + + assert suffix.text == "lo" + assert suffix.start_position == 0 + assert suffix.display == completion.display + assert suffix._display_meta is completion._display_meta + assert suffix.style == completion.style + assert suffix.selected_style == completion.selected_style