v2.2.0 (#395)
Co-authored-by: Quentin Torroba <quentin.torroba@mistral.ai> Co-authored-by: Clément Siriex <clement.sirieix@mistral.ai> Co-authored-by: Kim-Adeline Miguel <kimadeline.miguel@mistral.ai> Co-authored-by: Michel Thomazo <michel.thomazo@mistral.ai> Co-authored-by: Clément Drouin <clement.drouin@mistral.ai>
This commit is contained in:
parent
51fecc67d9
commit
ec7f3b25ea
107 changed files with 8002 additions and 535 deletions
127
vibe/cli/textual_ui/widgets/proxy_setup_app.py
Normal file
127
vibe/cli/textual_ui/widgets/proxy_setup_app.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import ClassVar
|
||||
|
||||
from textual import events
|
||||
from textual.app import ComposeResult
|
||||
from textual.binding import Binding, BindingType
|
||||
from textual.containers import Container, Vertical
|
||||
from textual.message import Message
|
||||
from textual.widgets import Input, Static
|
||||
|
||||
from vibe.cli.textual_ui.widgets.no_markup_static import NoMarkupStatic
|
||||
from vibe.core.proxy_setup import (
|
||||
SUPPORTED_PROXY_VARS,
|
||||
get_current_proxy_settings,
|
||||
set_proxy_var,
|
||||
unset_proxy_var,
|
||||
)
|
||||
|
||||
|
||||
class ProxySetupApp(Container):
|
||||
can_focus = True
|
||||
can_focus_children = True
|
||||
|
||||
BINDINGS: ClassVar[list[BindingType]] = [
|
||||
Binding("up", "focus_previous", "Up", show=False),
|
||||
Binding("down", "focus_next", "Down", show=False),
|
||||
]
|
||||
|
||||
class ProxySetupClosed(Message):
|
||||
def __init__(self, saved: bool, error: str | None = None) -> None:
|
||||
super().__init__()
|
||||
self.saved = saved
|
||||
self.error = error
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(id="proxysetup-app")
|
||||
self.inputs: dict[str, Input] = {}
|
||||
self.initial_values: dict[str, str | None] = {}
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
self.initial_values = get_current_proxy_settings()
|
||||
|
||||
with Vertical(id="proxysetup-content"):
|
||||
yield NoMarkupStatic("Proxy Configuration", classes="settings-title")
|
||||
yield NoMarkupStatic("")
|
||||
|
||||
for key, description in SUPPORTED_PROXY_VARS.items():
|
||||
yield Static(
|
||||
f"[bold ansi_blue]{key}[/] [dim]{description}[/dim]",
|
||||
classes="proxy-label-line",
|
||||
)
|
||||
|
||||
initial_value = self.initial_values.get(key) or ""
|
||||
input_widget = Input(
|
||||
value=initial_value,
|
||||
placeholder="NOT SET",
|
||||
id=f"proxy-input-{key}",
|
||||
classes="proxy-input",
|
||||
)
|
||||
self.inputs[key] = input_widget
|
||||
yield input_widget
|
||||
|
||||
yield NoMarkupStatic("")
|
||||
|
||||
yield NoMarkupStatic(
|
||||
"↑↓ navigate Enter save & exit ESC cancel", classes="settings-help"
|
||||
)
|
||||
|
||||
def focus(self, scroll_visible: bool = True) -> ProxySetupApp:
|
||||
"""Override focus to focus the first input widget."""
|
||||
if self.inputs:
|
||||
first_input = list(self.inputs.values())[0]
|
||||
first_input.focus(scroll_visible=scroll_visible)
|
||||
else:
|
||||
super().focus(scroll_visible=scroll_visible)
|
||||
return self
|
||||
|
||||
def action_focus_next(self) -> None:
|
||||
inputs = list(self.inputs.values())
|
||||
focused = self.screen.focused
|
||||
if focused is not None and isinstance(focused, Input) and focused in inputs:
|
||||
idx = inputs.index(focused)
|
||||
next_idx = (idx + 1) % len(inputs)
|
||||
inputs[next_idx].focus()
|
||||
|
||||
def action_focus_previous(self) -> None:
|
||||
inputs = list(self.inputs.values())
|
||||
focused = self.screen.focused
|
||||
if focused is not None and isinstance(focused, Input) and focused in inputs:
|
||||
idx = inputs.index(focused)
|
||||
prev_idx = (idx - 1) % len(inputs)
|
||||
inputs[prev_idx].focus()
|
||||
|
||||
def on_input_submitted(self, event: Input.Submitted) -> None:
|
||||
self._save_and_close()
|
||||
|
||||
def on_blur(self, _event: events.Blur) -> None:
|
||||
self.call_after_refresh(self._refocus_if_needed)
|
||||
|
||||
def on_input_blurred(self, _event: Input.Blurred) -> None:
|
||||
self.call_after_refresh(self._refocus_if_needed)
|
||||
|
||||
def _refocus_if_needed(self) -> None:
|
||||
if self.has_focus or any(inp.has_focus for inp in self.inputs.values()):
|
||||
return
|
||||
self.focus()
|
||||
|
||||
def _save_and_close(self) -> None:
|
||||
try:
|
||||
for key, input_widget in self.inputs.items():
|
||||
new_value = input_widget.value.strip()
|
||||
old_value = self.initial_values.get(key) or ""
|
||||
|
||||
if new_value != old_value:
|
||||
if new_value:
|
||||
set_proxy_var(key, new_value)
|
||||
else:
|
||||
unset_proxy_var(key)
|
||||
except Exception as e:
|
||||
self.post_message(self.ProxySetupClosed(saved=False, error=str(e)))
|
||||
return
|
||||
|
||||
self.post_message(self.ProxySetupClosed(saved=True))
|
||||
|
||||
def action_close(self) -> None:
|
||||
self.post_message(self.ProxySetupClosed(saved=False))
|
||||
Loading…
Add table
Add a link
Reference in a new issue