diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-01 15:48:22 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-01 15:48:22 +0300 |
| commit | 207be3c771d281baae6e5fa0fb74be9a056e97a2 (patch) | |
| tree | d7b037ecdf629224a048c841d11659efdc23507d /src/workspace.rs | |
| parent | 8a6d697308162874a236c84aac0b0f8c7ac01f83 (diff) | |
refactor: render the shell in the client (#3487)
* feat: add opt-in client-rendered shell
* feat: add client-owned shell mouse controls
* feat: complete client-owned shell chrome
* feat: add client-owned shell settings and notifications
* feat: run client shell custom commands
* feat: render popup terminals in client shell
* feat: add client-owned scrollback and copy mode
* fix: preserve client worktree trust defaults
* feat: render startup diagnostics in client shell
* feat: render onboarding in client shell
* feat: render product announcements in client shell
* feat: render release notes in client shell
* feat: render mobile switcher in client shell
* feat: render kitty graphics in client shell
* fix: preserve client shell lifecycle coherence
* refactor: route client shell commands through endpoint connections
* refactor: make the client-rendered shell the default
* refactor: remove monolithic launch mode
* refactor: complete client-rendered shell cutover
* perf: retain client pane surface updates
* perf: scale retained pane surface updates
* perf: remove remote pane input latency
* test: make client shell checks platform-independent
* fix: prevent client timer starvation
* test: fix client shell platform gates
* test: accept retained surfaces in cross-area checks
* test: make client mode assertions platform-neutral
* fix: badge only outdated integrations
Diffstat (limited to 'src/workspace.rs')
| -rw-r--r-- | src/workspace.rs | 170 |
1 files changed, 16 insertions, 154 deletions
diff --git a/src/workspace.rs b/src/workspace.rs index 0a719ab1..b4bba45d 100644 --- a/src/workspace.rs +++ b/src/workspace.rs @@ -19,8 +19,6 @@ mod aggregate; mod git; mod tab; -#[cfg(test)] -use self::git::git_ahead_behind; use self::git::git_status_cache_key_for_space; pub(crate) use self::{git::git_status_snapshot_for_cwd_with_demand, tab::MovedPane}; pub use self::{ @@ -274,9 +272,6 @@ impl Workspace { } } - // Test modules construct workspaces through the default constructor; production paths - // use the env-aware variant so pane identity env is always explicit. - #[cfg_attr(not(test), allow(dead_code))] pub fn new( initial_cwd: PathBuf, rows: u16, @@ -289,7 +284,7 @@ impl Workspace { render_notify: Arc<Notify>, render_dirty: Arc<RenderSignal>, ) -> std::io::Result<(Self, TerminalState, TerminalRuntime)> { - Self::new_with_extra_env( + Self::new_with_tab( initial_cwd, rows, cols, @@ -300,6 +295,7 @@ impl Workspace { events, render_notify, render_dirty, + None, Vec::new(), ) } @@ -318,6 +314,20 @@ impl Workspace { render_dirty: Arc<RenderSignal>, extra_env: Vec<(String, String)>, ) -> std::io::Result<(Self, TerminalState, TerminalRuntime)> { + if extra_env.is_empty() { + return Self::new( + initial_cwd, + rows, + cols, + scrollback_limit_bytes, + host_terminal_theme, + host_terminal_appearance, + shell_config, + events, + render_notify, + render_dirty, + ); + } Self::new_with_tab( initial_cwd, rows, @@ -334,65 +344,6 @@ impl Workspace { ) } - // Kept for tests that do not need launch-env customization. - #[allow(dead_code)] - pub fn new_argv_command( - initial_cwd: PathBuf, - rows: u16, - cols: u16, - argv: &[String], - scrollback_limit_bytes: usize, - host_terminal_theme: crate::terminal_theme::TerminalTheme, - host_terminal_appearance: Option<crate::terminal_theme::HostAppearance>, - events: mpsc::Sender<AppEvent>, - render_notify: Arc<Notify>, - render_dirty: Arc<RenderSignal>, - ) -> std::io::Result<(Self, TerminalState, TerminalRuntime)> { - Self::new_argv_command_with_extra_env( - initial_cwd, - rows, - cols, - argv, - scrollback_limit_bytes, - host_terminal_theme, - host_terminal_appearance, - events, - render_notify, - render_dirty, - Vec::new(), - ) - } - - #[allow(clippy::too_many_arguments)] - pub fn new_argv_command_with_extra_env( - initial_cwd: PathBuf, - rows: u16, - cols: u16, - argv: &[String], - scrollback_limit_bytes: usize, - host_terminal_theme: crate::terminal_theme::TerminalTheme, - host_terminal_appearance: Option<crate::terminal_theme::HostAppearance>, - events: mpsc::Sender<AppEvent>, - render_notify: Arc<Notify>, - render_dirty: Arc<RenderSignal>, - extra_env: Vec<(String, String)>, - ) -> std::io::Result<(Self, TerminalState, TerminalRuntime)> { - Self::new_with_tab( - initial_cwd, - rows, - cols, - scrollback_limit_bytes, - host_terminal_theme, - host_terminal_appearance, - crate::pane::PaneShellConfig::new("", crate::config::ShellModeConfig::NonLogin), - events, - render_notify, - render_dirty, - Some(argv), - extra_env, - ) - } - #[allow(clippy::too_many_arguments)] fn new_with_tab( initial_cwd: PathBuf, @@ -671,43 +622,6 @@ impl Workspace { self.close_tab(self.active_tab) } - #[cfg(test)] - pub fn split_focused( - &mut self, - direction: Direction, - rows: u16, - cols: u16, - cwd: Option<PathBuf>, - scrollback_limit_bytes: usize, - host_terminal_theme: crate::terminal_theme::TerminalTheme, - host_terminal_appearance: Option<crate::terminal_theme::HostAppearance>, - shell_config: crate::pane::PaneShellConfig<'_>, - extra_env: Vec<(String, String)>, - ) -> std::io::Result<crate::workspace::tab::NewPane> { - let pane_number = self.next_public_pane_number; - let tab_number = self - .active_tab() - .map(|tab| tab.number) - .expect("workspace must always have at least one tab"); - let launch_env = self.launch_env_for_new_pane(tab_number, pane_number, extra_env); - let new_pane = self - .active_tab_mut() - .expect("workspace must always have at least one tab") - .split_focused( - direction, - rows, - cols, - cwd, - scrollback_limit_bytes, - host_terminal_theme, - host_terminal_appearance, - shell_config, - &launch_env, - )?; - self.register_new_pane_with_number(new_pane.pane_id, pane_number); - Ok(new_pane) - } - #[allow(clippy::too_many_arguments)] pub fn split_focused_command( &mut self, @@ -1174,14 +1088,6 @@ impl Workspace { self.worktree_space.as_ref() } - #[cfg(test)] - pub fn refresh_git_ahead_behind(&mut self) { - let cwd = self.resolved_identity_cwd(); - self.cached_git_branch = cwd.as_deref().and_then(git_branch); - self.cached_git_ahead_behind = cwd.as_deref().and_then(git_ahead_behind); - self.cached_git_space = cwd.as_deref().and_then(git_space_metadata); - } - pub fn find_tab_index_for_pane(&self, pane_id: PaneId) -> Option<usize> { self.tabs .iter() @@ -1663,50 +1569,6 @@ mod tests { assert!(!target.tabs[0].panes.contains_key(&source_pane)); } - #[tokio::test] - async fn new_workspace_retains_discovered_git_metadata() { - let stamp = std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .expect("clock should be after unix epoch") - .as_nanos(); - let root = std::env::temp_dir().join(format!( - "herdr-workspace-git-metadata-{}-{stamp}", - std::process::id() - )); - std::fs::create_dir_all(root.join(".git")).expect("create git directory"); - std::fs::write(root.join(".git/HEAD"), "ref: refs/heads/main\n").expect("write git head"); - #[cfg(windows)] - let command = "C:\\Windows\\System32\\whoami.exe"; - #[cfg(not(windows))] - let command = "/usr/bin/true"; - let argv = vec![command.to_string()]; - let (events, _) = mpsc::channel(64); - let render_notify = Arc::new(Notify::new()); - let render_dirty = Arc::new(RenderSignal::new()); - - let (workspace, _terminal, runtime) = Workspace::new_argv_command( - root.clone(), - 24, - 80, - &argv, - 1024, - crate::terminal_theme::TerminalTheme::default(), - None, - events, - render_notify, - render_dirty, - ) - .expect("create workspace"); - - let space = workspace - .git_space() - .expect("workspace should retain discovered git metadata"); - assert_eq!(space.repo_root, root); - - runtime.shutdown(); - std::fs::remove_dir_all(root).expect("remove test repo"); - } - #[test] fn linked_worktree_auto_label_uses_checkout_name_not_repo_name() { let (base, repo, checkout) = |
