mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Suggestion autocomplete scrolls if required
This commit is contained in:
@@ -20,10 +20,10 @@ words = set(Path("/usr/share/dict/words").read_text().splitlines())
|
||||
|
||||
|
||||
def word_autocompleter(value: str) -> str | None:
|
||||
print(value)
|
||||
# An example autocompleter that uses the Unix dictionary to suggest
|
||||
# word completions
|
||||
for word in words:
|
||||
if word.startswith(value):
|
||||
print("autocompleter suggests: ", word)
|
||||
return word[len(value) :]
|
||||
return None
|
||||
|
||||
@@ -36,6 +36,11 @@ class InputApp(App[str]):
|
||||
text_boxes = Widget(self.fahrenheit, self.celsius)
|
||||
self.mount(inputs=text_boxes)
|
||||
self.mount(spacer=Widget())
|
||||
self.mount(
|
||||
top_search=Widget(
|
||||
TextInput(autocompleter=word_autocompleter, id="topsearchbox")
|
||||
)
|
||||
)
|
||||
self.mount(
|
||||
footer=TextInput(
|
||||
placeholder="Footer Search Bar", autocompleter=word_autocompleter
|
||||
|
||||
@@ -37,12 +37,17 @@ Screen {
|
||||
dock: bottom;
|
||||
}
|
||||
|
||||
#top_search {
|
||||
dock: top;
|
||||
}
|
||||
|
||||
#topsearchbox {
|
||||
width: 10;
|
||||
}
|
||||
|
||||
#footer {
|
||||
background: $primary-darken-2;
|
||||
dock: bottom;
|
||||
height: 1;
|
||||
border: ;
|
||||
}
|
||||
|
||||
#footer :focus {
|
||||
border: heavy $secondary;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ class TextWidgetBase(Widget):
|
||||
self.post_message_no_wait(self.Changed(self, value=self._editor.content))
|
||||
|
||||
self.refresh(layout=True)
|
||||
print("at end of TextWidgetBase.on_key")
|
||||
|
||||
def _apply_cursor_to_text(self, display_text: Text, index: int) -> Text:
|
||||
# Either write a cursor character or apply reverse style to cursor location
|
||||
@@ -160,6 +159,9 @@ class TextInput(TextWidgetBase, can_focus=True):
|
||||
|
||||
def on_resize(self, event: events.Resize) -> None:
|
||||
# Ensure the cursor remains visible when the widget is resized
|
||||
self._reset_visible_range()
|
||||
|
||||
def _reset_visible_range(self):
|
||||
new_visible_range_end = max(
|
||||
self._editor.cursor_index + 1, self.content_region.width
|
||||
)
|
||||
@@ -169,7 +171,6 @@ class TextInput(TextWidgetBase, can_focus=True):
|
||||
|
||||
def render(self, style: Style) -> RenderableType:
|
||||
# First render: Cursor at start of text, visible range goes from cursor to content region width
|
||||
print("inside render")
|
||||
if not self.visible_range:
|
||||
self.visible_range = (self._editor.cursor_index, self.content_region.width)
|
||||
|
||||
@@ -216,11 +217,10 @@ class TextInput(TextWidgetBase, can_focus=True):
|
||||
# If the user has hit the scroll limit
|
||||
self.app.bell()
|
||||
|
||||
print("pressed right", self._suggestion)
|
||||
if self._suggestion and self._editor.cursor_at_end:
|
||||
self._editor.insert_at_cursor(self._suggestion)
|
||||
self._suggestion = ""
|
||||
|
||||
self._reset_visible_range()
|
||||
elif key == "left":
|
||||
if cursor_index == start:
|
||||
if scrollable and self._editor.query_cursor_left():
|
||||
@@ -258,13 +258,16 @@ class TextInput(TextWidgetBase, can_focus=True):
|
||||
# We need to clamp the visible range to ensure we don't use negative indexing
|
||||
start, end = self.visible_range
|
||||
self.visible_range = (max(0, start), end)
|
||||
print("at end of TextInput.on_key")
|
||||
|
||||
def _update_suggestion(self, event: events.Key):
|
||||
def _update_suggestion(self, event: events.Key) -> None:
|
||||
"""Run the autocompleter function, updating the suggestion if necessary"""
|
||||
if self.autocompleter is not None:
|
||||
event.prevent_default()
|
||||
super().on_key(event)
|
||||
self._suggestion = self.autocompleter(self.value)
|
||||
if self.value:
|
||||
self._suggestion = self.autocompleter(self.value)
|
||||
else:
|
||||
self._suggestion = None
|
||||
|
||||
class Submitted(Message, bubble=True):
|
||||
def __init__(self, sender: MessageTarget, value: str) -> None:
|
||||
|
||||
Reference in New Issue
Block a user