fix: The input prompt box supports selection using the up and down arrow keys (#76)
* Add the ability to read text from the system clipboard * The input prompt box supports selection using the up and down arrow keys.
This commit is contained in:
@@ -59,11 +59,17 @@ def _paste_native() -> str | None:
|
||||
result = subprocess.run(
|
||||
["powershell", "-command", "Get-Clipboard"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=2,
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return result.stdout.rstrip("\r\n")
|
||||
# Try UTF-8 first, fall back to system encoding
|
||||
for encoding in ("utf-8", "gbk", "cp936"):
|
||||
try:
|
||||
return result.stdout.decode(encoding).rstrip("\r\n")
|
||||
except UnicodeDecodeError:
|
||||
continue
|
||||
# Last resort: decode with errors ignored
|
||||
return result.stdout.decode("utf-8", errors="ignore").rstrip("\r\n")
|
||||
except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
|
||||
pass
|
||||
else:
|
||||
|
||||
@@ -1604,6 +1604,13 @@ def run_textual_interactive(
|
||||
|
||||
def action_edit_queued(self) -> None:
|
||||
"""Pop the last queued message back into input for editing."""
|
||||
# Handle completion list selection (up key)
|
||||
comp_widget = self.query_one("#completions", Static)
|
||||
if comp_widget.display and self._comp_items:
|
||||
self._comp_index = (self._comp_index - 1) % len(self._comp_items)
|
||||
self._render_completions()
|
||||
return
|
||||
|
||||
# Skip if an ApprovalWidget, AskUserWidget, ThreadPickerWidget, or SkillBrowserWidget has focus
|
||||
focused = self.focused
|
||||
if focused is not None:
|
||||
@@ -1638,6 +1645,13 @@ def run_textual_interactive(
|
||||
|
||||
def action_down_delegate(self) -> None:
|
||||
"""Delegate down key to focused interactive widget."""
|
||||
# Handle completion list selection (down key)
|
||||
comp_widget = self.query_one("#completions", Static)
|
||||
if comp_widget.display and self._comp_items:
|
||||
self._comp_index = (self._comp_index + 1) % len(self._comp_items)
|
||||
self._render_completions()
|
||||
return
|
||||
|
||||
focused = self.focused
|
||||
if focused is not None:
|
||||
from .widgets.approval_widget import ApprovalWidget
|
||||
@@ -1690,23 +1704,26 @@ def run_textual_interactive(
|
||||
event.prevent_default()
|
||||
event.stop()
|
||||
self._comp_index = (self._comp_index + 1) % len(self._comp_items)
|
||||
self._apply_selected_completion()
|
||||
self._render_completions()
|
||||
elif event.key == "up":
|
||||
event.prevent_default()
|
||||
event.stop()
|
||||
self._comp_index = (self._comp_index - 1) % len(self._comp_items)
|
||||
self._apply_selected_completion()
|
||||
self._render_completions()
|
||||
elif event.key == "enter" and self._comp_index >= 0:
|
||||
event.prevent_default()
|
||||
event.stop()
|
||||
self._apply_selected_completion()
|
||||
self._hide_completions()
|
||||
|
||||
def _apply_selected_completion(self) -> None:
|
||||
"""Apply the currently selected completion to the input field."""
|
||||
if self._comp_index < 0 or self._comp_index >= len(self._comp_items):
|
||||
return
|
||||
selected_cmd = self._comp_items[self._comp_index][0]
|
||||
prompt = self.query_one("#prompt", Input)
|
||||
prompt.value = selected_cmd + " "
|
||||
prompt.cursor_position = len(prompt.value)
|
||||
self._render_completions()
|
||||
|
||||
def _hide_completions(self) -> None:
|
||||
self._comp_items = []
|
||||
|
||||
Reference in New Issue
Block a user