Initial public release of Warp.

Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
David Stern
2026-04-28 08:43:33 -05:00
commit 0dbd3d567a
4982 changed files with 1431549 additions and 0 deletions
+123
View File
@@ -0,0 +1,123 @@
use std::{
collections::HashMap,
path::{Path, PathBuf},
sync::{Arc, Weak},
};
use warpui::{Entity, EntityId, ModelContext, SingletonEntity, WindowId};
use crate::terminal::model::session::Session;
/// The active terminal session in each window. The active session of a window is the current
/// session of the most-recently-focused terminal pane of the active tab of the window's workspace.
///
/// #### When to use `ActiveSession`
/// Generally, if a more specific session is available, it should be preferred. For example, when
/// opening a Markdown file from a file link in a block's output, that block's session should be
/// the basis. However, sometimes there is no contextual session (such as when opening a file
/// in Warp from Finder, or when starting from a cloud object). In that case, the `ActiveSession`
/// might be used, but it's often still better to be context-independent.
#[derive(Default)]
pub struct ActiveSession {
window_sessions: HashMap<WindowId, WindowActiveSession>,
}
/// Active session information for an individual window.
#[derive(Default)]
struct WindowActiveSession {
/// The [`Session`] model for the active session. This is a weak reference so that it doesn't
/// prevent cleaning up the session when it closes, in case no other session is activated.
session: Option<Weak<Session>>,
/// The active session's working directory, if it's local.
path_if_local: Option<PathBuf>,
/// The [`EntityId`]` for the [`TerminalView`] for the active session, if there is one.
terminal_view_id: Option<EntityId>,
}
impl ActiveSession {
/// The workspace's active session, if there is one.
pub fn session(&self, window_id: WindowId) -> Option<Arc<Session>> {
self.window_sessions
.get(&window_id)?
.session
.as_ref()?
.upgrade()
}
pub fn terminal_view_id(&self, window_id: WindowId) -> Option<EntityId> {
self.window_sessions.get(&window_id)?.terminal_view_id
}
/// The current working directory of the active session, if it's local.
pub fn path_if_local(&self, window_id: WindowId) -> Option<&Path> {
self.window_sessions
.get(&window_id)?
.path_if_local
.as_deref()
}
/// Set the current session, for use in tests.
#[cfg(test)]
pub fn set_session_for_test(
&mut self,
window_id: WindowId,
session: Arc<Session>,
path_if_local: Option<impl Into<PathBuf>>,
terminal_view_id: Option<EntityId>,
ctx: &mut ModelContext<Self>,
) {
self.set_session_state(
window_id,
Some(session),
path_if_local.map(Into::into),
terminal_view_id,
ctx,
);
}
pub(super) fn set_session_state(
&mut self,
window_id: WindowId,
session: Option<Arc<Session>>,
path_if_local: Option<PathBuf>,
terminal_view_id: Option<EntityId>,
ctx: &mut ModelContext<Self>,
) {
let window_state = self.window_sessions.entry(window_id).or_default();
let session = session.map(|session| Arc::downgrade(&session));
if window_state.session.is_some() != session.is_some() {
window_state.session = session;
ctx.notify();
} else if let Some((prev_session, next_session)) =
window_state.session.as_ref().zip(session)
{
// Session IDs can't necessarily be compared across terminal panes, so check if the backing
// allocation is the same. We can do this because each `Session` is a singleton.
if !Weak::ptr_eq(prev_session, &next_session) {
window_state.session = Some(next_session);
ctx.notify();
}
}
if window_state.path_if_local != path_if_local {
window_state.path_if_local = path_if_local;
ctx.notify();
}
if window_state.terminal_view_id != terminal_view_id {
window_state.terminal_view_id = terminal_view_id;
ctx.notify();
}
}
pub(super) fn close_workspace(&mut self, window_id: WindowId) {
self.window_sessions.remove(&window_id);
}
}
impl Entity for ActiveSession {
type Event = ();
}
impl SingletonEntity for ActiveSession {}