From 91b82731409952761bd91bc57f8194ff7d172964 Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Thu, 19 Dec 2024 14:05:22 +0100 Subject: [PATCH 1/2] Minimal changes to allow multiline suggestions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'm trying to be the least invasive; But the idea is to allow access to previous lines when rendering a line in order to shift them down; and display multiline sugestions. With this I can add minimal modification into IPython that allows multiline suggestion (typically would be created by an LLM – while not a big fan, there is a lot of requests for it. I'm going to assume there is no willingness tochange the current API for transformers to get at least a ranges of lines instead of lines, it would be easier to handle. I do not include any update to the transformers we use in IPython to display those completions; but once battled tested a bit more, I'm happy to contribute it as well. --- src/prompt_toolkit/layout/controls.py | 17 ++++++++++++++--- src/prompt_toolkit/layout/processors.py | 8 +++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/prompt_toolkit/layout/controls.py b/src/prompt_toolkit/layout/controls.py index 222e471c5..5083c8286 100644 --- a/src/prompt_toolkit/layout/controls.py +++ b/src/prompt_toolkit/layout/controls.py @@ -667,7 +667,11 @@ def _create_get_processed_line_func( merged_processor = merge_processors(input_processors) - def transform(lineno: int, fragments: StyleAndTextTuples) -> _ProcessedLine: + def transform( + lineno: int, + fragments: StyleAndTextTuples, + get_line: Callable[[int], StyleAndTextTuples], + ) -> _ProcessedLine: "Transform the fragments for a given line number." # Get cursor position at this line. @@ -679,7 +683,14 @@ def source_to_display(i: int) -> int: transformation = merged_processor.apply_transformation( TransformationInput( - self, document, lineno, source_to_display, fragments, width, height + self, + document, + lineno, + source_to_display, + fragments, + width, + height, + get_line, ) ) @@ -697,7 +708,7 @@ def get_processed_line(i: int) -> _ProcessedLine: try: return cache[i] except KeyError: - processed_line = transform(i, get_line(i)) + processed_line = transform(i, get_line(i), get_line) cache[i] = processed_line return processed_line diff --git a/src/prompt_toolkit/layout/processors.py b/src/prompt_toolkit/layout/processors.py index b10ecf718..be7ac7d50 100644 --- a/src/prompt_toolkit/layout/processors.py +++ b/src/prompt_toolkit/layout/processors.py @@ -10,7 +10,7 @@ import re from abc import ABCMeta, abstractmethod -from typing import TYPE_CHECKING, Callable, Hashable, cast +from typing import TYPE_CHECKING, Callable, Hashable, cast, Optional from prompt_toolkit.application.current import get_app from prompt_toolkit.cache import SimpleCache @@ -86,6 +86,9 @@ class TransformationInput: previous processors into account.) :param fragments: List of fragments that we can transform. (Received from the previous processor.) + :param get_line: Optional ; a callable that returns the fragments of another + line in the current buffer; This can be used to create processors capable + of affecting transforms across multiple lines. """ def __init__( @@ -97,6 +100,7 @@ def __init__( fragments: StyleAndTextTuples, width: int, height: int, + get_line: Optional[Callable[[int], StyleAndTextTuples]] = None, ) -> None: self.buffer_control = buffer_control self.document = document @@ -105,6 +109,7 @@ def __init__( self.fragments = fragments self.width = width self.height = height + self.get_line = get_line def unpack( self, @@ -987,6 +992,7 @@ def source_to_display(i: int) -> int: fragments, ti.width, ti.height, + ti.get_line, ) ) fragments = transformation.fragments From 32acf59619e1fd7a941935ee467297d0ed5c11c2 Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Thu, 19 Dec 2024 15:40:53 +0100 Subject: [PATCH 2/2] ruff formatting --- src/prompt_toolkit/layout/processors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prompt_toolkit/layout/processors.py b/src/prompt_toolkit/layout/processors.py index be7ac7d50..8208018d0 100644 --- a/src/prompt_toolkit/layout/processors.py +++ b/src/prompt_toolkit/layout/processors.py @@ -10,7 +10,7 @@ import re from abc import ABCMeta, abstractmethod -from typing import TYPE_CHECKING, Callable, Hashable, cast, Optional +from typing import TYPE_CHECKING, Callable, Hashable, cast from prompt_toolkit.application.current import get_app from prompt_toolkit.cache import SimpleCache @@ -100,7 +100,7 @@ def __init__( fragments: StyleAndTextTuples, width: int, height: int, - get_line: Optional[Callable[[int], StyleAndTextTuples]] = None, + get_line: Callable[[int], StyleAndTextTuples] | None = None, ) -> None: self.buffer_control = buffer_control self.document = document