first pass of merging in warp (doesn't build)

This commit is contained in:
Ryan Ward
2026-07-01 16:08:58 -05:00
parent 2f64909469
commit 4770ac06b5
3662 changed files with 414574 additions and 89772 deletions
+2 -1
View File
@@ -2,11 +2,12 @@
//!
//! This calls out to the `CallJsFunctionService` IPC service, which is served by the plugin host
//! process where JS plugins are loaded and executed.
use std::sync::Arc;
use async_trait::async_trait;
use galaxy_completer::completer::{JsExecutionContext, JsExecutionError};
use galaxy_js::{JsFunctionId, SerializedJsValue};
use ipc::ServiceCaller;
use std::sync::Arc;
use crate::plugin::service::{
CallJsFunctionRequest, CallJsFunctionResponse, CallJsFunctionService,
+26 -7
View File
@@ -46,13 +46,29 @@ pub struct SessionContext {
#[cfg(feature = "completions_v2")]
js_ctx: Option<js::SessionJsExecutionContext>,
cached_directory_entries: dashmap::DashMap<TypedPathBuf, Arc<Vec<EngineDirEntry>>>,
/// Directory listings keyed by absolute path. Callers that must reflect a directory's
/// current contents should use `refresh_directory_entries` to re-read from disk.
cached_directory_entries: Arc<dashmap::DashMap<TypedPathBuf, Arc<Vec<EngineDirEntry>>>>,
/// Snapshot of all Warp workflow aliases.
workflow_aliases: HashMap<String, String>,
}
impl SessionContext {
/// Lists `directory` fresh from disk and caches the results.
pub(crate) async fn refresh_directory_entries(
&self,
directory: TypedPathBuf,
) -> Arc<Vec<EngineDirEntry>> {
let result = Arc::new(
self.list_directory_entries_internal(&directory.to_path())
.await,
);
self.cached_directory_entries
.insert(directory, result.clone());
result
}
async fn list_directory_entries_internal(
&self,
directory: &TypedPath<'_>,
@@ -112,7 +128,7 @@ impl SessionContext {
if let Ok(command_output) = command_output_result {
let Ok(output_string) = command_output.to_string() else {
log::warn!(
"Executing `ls` on remote box returned unparseable bytes: `{:?}`",
"Executing `ls` on remote box returned unparsable bytes: `{:?}`",
AsciiDebug(command_output.output())
);
return vec![];
@@ -181,6 +197,10 @@ impl PathCompletionContext for SessionContext {
self.session.home_dir()
}
fn cdpath(&self) -> Option<&str> {
self.session.cdpath()
}
fn pwd(&self) -> TypedPath<'_> {
self.current_working_directory.to_path()
}
@@ -356,7 +376,7 @@ impl SessionContext {
command_registry,
current_working_directory,
js_ctx: js_function_caller.map(js::SessionJsExecutionContext::new),
cached_directory_entries: Default::default(),
cached_directory_entries: Arc::new(Default::default()),
workflow_aliases,
}
} else {
@@ -364,7 +384,7 @@ impl SessionContext {
session: session.into(),
command_registry,
current_working_directory,
cached_directory_entries: Default::default(),
cached_directory_entries: Arc::new(Default::default()),
workflow_aliases,
}
}
@@ -474,9 +494,8 @@ printf '%b' '\0' &&
find . -maxdepth 1 -not -type d -print0
"#
)
// Ensure all newlines are escaped, and that the command is a single line.
// ls_script_for_dir should not contain newlines, as we need to run it as a
// single line for TMUX control mode at this time.
// Ensure all newlines are escaped, and that the command is a single line, since some
// in-band executors run commands a single line at a time.
.replace("\n", " ");
Some(command)
+68 -4
View File
@@ -10,12 +10,11 @@ use itertools::Itertools;
use typed_path::TypedPathBuf;
#[cfg(windows)]
use typed_path::{UnixComponent, WindowsComponent, WindowsPrefix};
use galaxy_completer::completer::{CompletionContext, EngineDirEntry, PathCompletionContext};
use crate::completer::SessionContext;
use crate::terminal::model::session::Session;
use crate::terminal::model::session::{
command_executor::testing::TestCommandExecutor, SessionInfo,
};
use crate::terminal::model::session::command_executor::testing::TestCommandExecutor;
use crate::terminal::model::session::{Session, SessionInfo};
use crate::test_util::{Stub, VirtualFS};
fn test_session_context(session: Session, cwd: TypedPathBuf, app: &App) -> SessionContext {
@@ -372,3 +371,68 @@ pub fn test_session_context_lists_directory_entries_remotely_with_special_charac
perform_special_characters_in_path_test(Session::test_remote(), file_names);
}
#[test]
pub fn test_session_context_refresh_directory_entries_bypasses_cache() {
App::test((), |app| async move {
VirtualFS::test(
"test_session_context_refresh_directory_entries_bypasses_cache",
|dirs, mut sandbox| {
sandbox.touch(vec![Stub::EmptyFile("first.txt")]);
let tests_dir = TypedPathBuf::from(dirs.tests().to_string_lossy().as_bytes());
let ctx = test_session_context(Session::test(), tests_dir.clone(), &app);
// Prime the shared cache with the directory's initial contents.
let cached = warpui::r#async::block_on(
ctx.path_completion_context()
.expect("Path completion context should exist with active session")
.list_directory_entries(tests_dir.clone()),
);
assert_eq!(
HashSet::<EngineDirEntry>::from_iter(Arc::unwrap_or_clone(cached)),
HashSet::from_iter([EngineDirEntry::test_file("first.txt")]),
);
// Add a file on disk after the listing has already been cached.
sandbox.touch(vec![Stub::EmptyFile("second.txt")]);
// `list_directory_entries` keeps returning the stale cached listing.
let stale = warpui::r#async::block_on(
ctx.path_completion_context()
.expect("Path completion context should exist with active session")
.list_directory_entries(tests_dir.clone()),
);
assert_eq!(
HashSet::<EngineDirEntry>::from_iter(Arc::unwrap_or_clone(stale)),
HashSet::from_iter([EngineDirEntry::test_file("first.txt")]),
);
// `refresh_directory_entries` re-reads from disk and overwrites the cached entry.
let refreshed =
warpui::r#async::block_on(ctx.refresh_directory_entries(tests_dir.clone()));
assert_eq!(
HashSet::<EngineDirEntry>::from_iter(Arc::unwrap_or_clone(refreshed)),
HashSet::from_iter([
EngineDirEntry::test_file("first.txt"),
EngineDirEntry::test_file("second.txt"),
]),
);
// Subsequent cached reads now observe the refreshed listing.
let after_refresh = warpui::r#async::block_on(
ctx.path_completion_context()
.expect("Path completion context should exist with active session")
.list_directory_entries(tests_dir),
);
assert_eq!(
HashSet::<EngineDirEntry>::from_iter(Arc::unwrap_or_clone(after_refresh)),
HashSet::from_iter([
EngineDirEntry::test_file("first.txt"),
EngineDirEntry::test_file("second.txt"),
]),
);
},
);
});
}