//! Vectrum Code: a minimal T3 Code-style desktop client for Claude Code. // GPUI's derive macros expand to `gpui::` paths; route them through the Kit. extern crate gpui_kit as gpui; mod claude; mod clock; mod git; mod http; mod models; mod remote; mod session; mod settings; mod store; mod textgen; mod ui; mod usage; mod worktree; use std::{ path::PathBuf, sync::Mutex, time::{Duration, Instant}, }; use gpui_kit::component::{WindowExt as _, notification::Notification}; use gpui_kit::*; use crate::ui::{icons::AppAssets, metal, workspace::Workspace}; gpui_kit::actions!( vectrum_code, [ NewThread, OpenProject, Interrupt, ToggleSidebar, ToggleProjectPanel, FocusSearch, OpenSettings, CloseSettings, Quit ] ); /// With the Hold quit shortcut, a second Ctrl+Q (or the key repeat of a /// held one) within this long quits. const QUIT_WINDOW: Duration = Duration::from_millis(1200); fn main() { let project = std::env::args_os() .nth(1) .map(PathBuf::from) .map(|project| project.canonicalize().unwrap_or(project)); gpui_kit::application() .with_assets(AppAssets) .run(move |cx| { gpui_kit::init(cx); metal::load_fonts(cx); models::Catalog::init(cx); cx.bind_keys([ KeyBinding::new("ctrl-n", NewThread, None), KeyBinding::new("ctrl-o", OpenProject, None), KeyBinding::new("ctrl-b", ToggleSidebar, None), KeyBinding::new("ctrl-shift-b", ToggleProjectPanel, None), KeyBinding::new("ctrl-k", FocusSearch, None), KeyBinding::new("ctrl-,", OpenSettings, None), KeyBinding::new("ctrl-q", Quit, None), KeyBinding::new("escape", Interrupt, Some("ChatView")), KeyBinding::new("escape", CloseSettings, Some("SettingsView")), ]); cx.on_action(quit); cx.on_window_closed(|cx, _| cx.quit()).detach(); let bounds = Bounds::centered(None, size(px(1280.), px(840.)), cx); let options = WindowOptions { window_bounds: Some(WindowBounds::Windowed(bounds)), titlebar: Some(TitlebarOptions { title: Some("Vectrum Code".into()), ..Default::default() }), app_id: Some("vectrum-code".into()), window_min_size: Some(size(px(820.), px(520.))), ..Default::default() }; gpui_kit::open_window(options, cx, |window, cx| { metal::sync_appearance(window, cx); cx.new(|cx| Workspace::new(project, window, cx)) }) .expect("failed to open the main window"); cx.activate(true); }); } /// Quits, or with the Hold shortcut, asks for the keys to be held or pressed /// again. fn quit(_: &Quit, cx: &mut App) { static FIRST_PRESS: Mutex> = Mutex::new(None); if settings::get(|settings| settings.quit_shortcut) == settings::QuitShortcut::Press { cx.quit(); return; } let mut first = FIRST_PRESS.lock().unwrap_or_else(|poisoned| poisoned.into_inner()); if first.is_some_and(|at| at.elapsed() < QUIT_WINDOW) { cx.quit(); return; } *first = Some(Instant::now()); if let Some(window) = cx.active_window() { let _ = window.update(cx, |_, window, cx| { window.push_notification(Notification::info("Hold Ctrl+Q, or press it again, to quit."), cx); }); } }