summaryrefslogtreecommitdiffstats
path: root/ptpython/layout.py
diff options
context:
space:
mode:
Diffstat (limited to 'ptpython/layout.py')
-rw-r--r--ptpython/layout.py108
1 files changed, 59 insertions, 49 deletions
diff --git a/ptpython/layout.py b/ptpython/layout.py
index 6482cbd..2c1ec15 100644
--- a/ptpython/layout.py
+++ b/ptpython/layout.py
@@ -1,11 +1,13 @@
"""
Creation of the `Layout` instance for the Python input/REPL.
"""
+from __future__ import annotations
+
import platform
import sys
from enum import Enum
from inspect import _ParameterKind as ParameterKind
-from typing import TYPE_CHECKING, Optional
+from typing import TYPE_CHECKING, Any
from prompt_toolkit.application import get_app
from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
@@ -19,6 +21,7 @@ from prompt_toolkit.formatted_text import fragment_list_width, to_formatted_text
from prompt_toolkit.formatted_text.base import StyleAndTextTuples
from prompt_toolkit.key_binding.vi_state import InputMode
from prompt_toolkit.layout.containers import (
+ AnyContainer,
ConditionalContainer,
Container,
Float,
@@ -40,9 +43,10 @@ from prompt_toolkit.layout.processors import (
HighlightIncrementalSearchProcessor,
HighlightMatchingBracketProcessor,
HighlightSelectionProcessor,
+ Processor,
TabsProcessor,
)
-from prompt_toolkit.lexers import SimpleLexer
+from prompt_toolkit.lexers import Lexer, SimpleLexer
from prompt_toolkit.mouse_events import MouseEvent
from prompt_toolkit.selection import SelectionType
from prompt_toolkit.widgets.toolbars import (
@@ -52,9 +56,9 @@ from prompt_toolkit.widgets.toolbars import (
SystemToolbar,
ValidationToolbar,
)
-from pygments.lexers import PythonLexer
from .filters import HasSignature, ShowDocstring, ShowSidebar, ShowSignature
+from .prompt_style import PromptStyle
from .utils import if_mousedown
if TYPE_CHECKING:
@@ -64,33 +68,34 @@ __all__ = ["PtPythonLayout", "CompletionVisualisation"]
class CompletionVisualisation(Enum):
- " Visualisation method for the completions. "
+ "Visualisation method for the completions."
+
NONE = "none"
POP_UP = "pop-up"
MULTI_COLUMN = "multi-column"
TOOLBAR = "toolbar"
-def show_completions_toolbar(python_input: "PythonInput") -> Condition:
+def show_completions_toolbar(python_input: PythonInput) -> Condition:
return Condition(
lambda: python_input.completion_visualisation == CompletionVisualisation.TOOLBAR
)
-def show_completions_menu(python_input: "PythonInput") -> Condition:
+def show_completions_menu(python_input: PythonInput) -> Condition:
return Condition(
lambda: python_input.completion_visualisation == CompletionVisualisation.POP_UP
)
-def show_multi_column_completions_menu(python_input: "PythonInput") -> Condition:
+def show_multi_column_completions_menu(python_input: PythonInput) -> Condition:
return Condition(
lambda: python_input.completion_visualisation
== CompletionVisualisation.MULTI_COLUMN
)
-def python_sidebar(python_input: "PythonInput") -> Window:
+def python_sidebar(python_input: PythonInput) -> Window:
"""
Create the `Layout` for the sidebar with the configurable options.
"""
@@ -98,7 +103,7 @@ def python_sidebar(python_input: "PythonInput") -> Window:
def get_text_fragments() -> StyleAndTextTuples:
tokens: StyleAndTextTuples = []
- def append_category(category: "OptionCategory") -> None:
+ def append_category(category: OptionCategory[Any]) -> None:
tokens.extend(
[
("class:sidebar", " "),
@@ -116,7 +121,7 @@ def python_sidebar(python_input: "PythonInput") -> Window:
@if_mousedown
def goto_next(mouse_event: MouseEvent) -> None:
- " Select item and go to next value. "
+ "Select item and go to next value."
python_input.selected_option_index = index
option = python_input.selected_option
option.activate_next()
@@ -142,7 +147,7 @@ def python_sidebar(python_input: "PythonInput") -> Window:
append_category(category)
for option in category.options:
- append(i, option.title, "%s" % option.get_current_value())
+ append(i, option.title, str(option.get_current_value()))
i += 1
tokens.pop() # Remove last newline.
@@ -150,10 +155,10 @@ def python_sidebar(python_input: "PythonInput") -> Window:
return tokens
class Control(FormattedTextControl):
- def move_cursor_down(self):
+ def move_cursor_down(self) -> None:
python_input.selected_option_index += 1
- def move_cursor_up(self):
+ def move_cursor_up(self) -> None:
python_input.selected_option_index -= 1
return Window(
@@ -165,12 +170,12 @@ def python_sidebar(python_input: "PythonInput") -> Window:
)
-def python_sidebar_navigation(python_input):
+def python_sidebar_navigation(python_input: PythonInput) -> Window:
"""
Create the `Layout` showing the navigation information for the sidebar.
"""
- def get_text_fragments():
+ def get_text_fragments() -> StyleAndTextTuples:
# Show navigation info.
return [
("class:sidebar", " "),
@@ -191,13 +196,13 @@ def python_sidebar_navigation(python_input):
)
-def python_sidebar_help(python_input):
+def python_sidebar_help(python_input: PythonInput) -> Container:
"""
Create the `Layout` for the help text for the current item in the sidebar.
"""
token = "class:sidebar.helptext"
- def get_current_description():
+ def get_current_description() -> str:
"""
Return the description of the selected option.
"""
@@ -209,7 +214,7 @@ def python_sidebar_help(python_input):
i += 1
return ""
- def get_help_text():
+ def get_help_text() -> StyleAndTextTuples:
return [(token, get_current_description())]
return ConditionalContainer(
@@ -225,7 +230,7 @@ def python_sidebar_help(python_input):
)
-def signature_toolbar(python_input):
+def signature_toolbar(python_input: PythonInput) -> Container:
"""
Return the `Layout` for the signature.
"""
@@ -293,13 +298,15 @@ def signature_toolbar(python_input):
content=Window(
FormattedTextControl(get_text_fragments), height=Dimension.exact(1)
),
- filter=
# Show only when there is a signature
- HasSignature(python_input) &
+ filter=HasSignature(python_input)
+ &
# Signature needs to be shown.
- ShowSignature(python_input) &
+ ShowSignature(python_input)
+ &
# And no sidebar is visible.
- ~ShowSidebar(python_input) &
+ ~ShowSidebar(python_input)
+ &
# Not done yet.
~is_done,
)
@@ -311,26 +318,28 @@ class PythonPromptMargin(PromptMargin):
It shows something like "In [1]:".
"""
- def __init__(self, python_input) -> None:
+ def __init__(self, python_input: PythonInput) -> None:
self.python_input = python_input
- def get_prompt_style():
+ def get_prompt_style() -> PromptStyle:
return python_input.all_prompt_styles[python_input.prompt_style]
def get_prompt() -> StyleAndTextTuples:
return to_formatted_text(get_prompt_style().in_prompt())
- def get_continuation(width, line_number, is_soft_wrap):
+ def get_continuation(
+ width: int, line_number: int, is_soft_wrap: bool
+ ) -> StyleAndTextTuples:
if python_input.show_line_numbers and not is_soft_wrap:
text = ("%i " % (line_number + 1)).rjust(width)
return [("class:line-number", text)]
else:
- return get_prompt_style().in2_prompt(width)
+ return to_formatted_text(get_prompt_style().in2_prompt(width))
super().__init__(get_prompt, get_continuation)
-def status_bar(python_input: "PythonInput") -> Container:
+def status_bar(python_input: PythonInput) -> Container:
"""
Create the `Layout` for the status bar.
"""
@@ -403,7 +412,7 @@ def status_bar(python_input: "PythonInput") -> Container:
)
-def get_inputmode_fragments(python_input: "PythonInput") -> StyleAndTextTuples:
+def get_inputmode_fragments(python_input: PythonInput) -> StyleAndTextTuples:
"""
Return current input mode as a list of (token, text) tuples for use in a
toolbar.
@@ -431,7 +440,7 @@ def get_inputmode_fragments(python_input: "PythonInput") -> StyleAndTextTuples:
recording_register = app.vi_state.recording_register
if recording_register:
append((token, " "))
- append((token + " class:record", "RECORD({})".format(recording_register)))
+ append((token + " class:record", f"RECORD({recording_register})"))
append((token, " - "))
if app.current_buffer.selection_state is not None:
@@ -464,7 +473,7 @@ def get_inputmode_fragments(python_input: "PythonInput") -> StyleAndTextTuples:
return result
-def show_sidebar_button_info(python_input: "PythonInput") -> Container:
+def show_sidebar_button_info(python_input: PythonInput) -> Container:
"""
Create `Layout` for the information in the right-bottom corner.
(The right part of the status bar.)
@@ -472,7 +481,7 @@ def show_sidebar_button_info(python_input: "PythonInput") -> Container:
@if_mousedown
def toggle_sidebar(mouse_event: MouseEvent) -> None:
- " Click handler for the menu. "
+ "Click handler for the menu."
python_input.show_sidebar = not python_input.show_sidebar
version = sys.version_info
@@ -510,7 +519,7 @@ def show_sidebar_button_info(python_input: "PythonInput") -> Container:
def create_exit_confirmation(
- python_input: "PythonInput", style="class:exit-confirmation"
+ python_input: PythonInput, style: str = "class:exit-confirmation"
) -> Container:
"""
Create `Layout` for the exit message.
@@ -534,7 +543,7 @@ def create_exit_confirmation(
)
-def meta_enter_message(python_input: "PythonInput") -> Container:
+def meta_enter_message(python_input: PythonInput) -> Container:
"""
Create the `Layout` for the 'Meta+Enter` message.
"""
@@ -544,7 +553,7 @@ def meta_enter_message(python_input: "PythonInput") -> Container:
@Condition
def extra_condition() -> bool:
- " Only show when... "
+ "Only show when..."
b = python_input.default_buffer
return (
@@ -566,23 +575,23 @@ def meta_enter_message(python_input: "PythonInput") -> Container:
class PtPythonLayout:
def __init__(
self,
- python_input: "PythonInput",
- lexer=PythonLexer,
- extra_body=None,
- extra_toolbars=None,
- extra_buffer_processors=None,
- input_buffer_height: Optional[AnyDimension] = None,
+ python_input: PythonInput,
+ lexer: Lexer,
+ extra_body: AnyContainer | None = None,
+ extra_toolbars: list[AnyContainer] | None = None,
+ extra_buffer_processors: list[Processor] | None = None,
+ input_buffer_height: AnyDimension | None = None,
) -> None:
D = Dimension
- extra_body = [extra_body] if extra_body else []
+ extra_body_list: list[AnyContainer] = [extra_body] if extra_body else []
extra_toolbars = extra_toolbars or []
- extra_buffer_processors = extra_buffer_processors or []
+
input_buffer_height = input_buffer_height or D(min=6)
search_toolbar = SearchToolbar(python_input.search_buffer)
- def create_python_input_window():
- def menu_position():
+ def create_python_input_window() -> Window:
+ def menu_position() -> int | None:
"""
When there is no autocompletion menu to be shown, and we have a
signature, set the pop-up position at `bracket_start`.
@@ -593,6 +602,7 @@ class PtPythonLayout:
row, col = python_input.signatures[0].bracket_start
index = b.document.translate_row_col_to_index(row - 1, col)
return index
+ return None
return Window(
BufferControl(
@@ -622,7 +632,7 @@ class PtPythonLayout:
processor=AppendAutoSuggestion(), filter=~is_done
),
]
- + extra_buffer_processors,
+ + (extra_buffer_processors or []),
menu_position=menu_position,
# Make sure that we always see the result of an reverse-i-search:
preview_search=True,
@@ -646,7 +656,7 @@ class PtPythonLayout:
sidebar = python_sidebar(python_input)
self.exit_confirmation = create_exit_confirmation(python_input)
- root_container = HSplit(
+ self.root_container = HSplit(
[
VSplit(
[
@@ -654,7 +664,7 @@ class PtPythonLayout:
[
FloatContainer(
content=HSplit(
- [create_python_input_window()] + extra_body
+ [create_python_input_window()] + extra_body_list
),
floats=[
Float(
@@ -759,5 +769,5 @@ class PtPythonLayout:
]
)
- self.layout = Layout(root_container)
+ self.layout = Layout(self.root_container)
self.sidebar = sidebar