SSH remote ui (#15129)

Still TODO:
* [x] hide this UI unless you have some ssh projects in settings
* [x] add the "open folder" flow with the new open picker
* [ ] integrate with recent projects / workspace restoration

Release Notes:

- N/A
This commit is contained in:
Conrad Irwin 2024-07-26 16:45:44 -06:00 committed by GitHub
parent be86852f95
commit 3e31955b7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 1162 additions and 436 deletions

View file

@ -33,6 +33,7 @@ rpc.workspace = true
settings.workspace = true
serde.workspace = true
serde_json.workspace = true
shellexpand.workspace = true
smol.workspace = true
util.workspace = true
worktree.workspace = true

View file

@ -12,6 +12,7 @@ use rpc::{
TypedEnvelope,
};
use settings::{Settings as _, SettingsStore};
use smol::stream::StreamExt;
use std::{
path::{Path, PathBuf},
sync::{atomic::AtomicUsize, Arc},
@ -45,6 +46,7 @@ impl HeadlessProject {
cx.subscribe(&buffer_store, Self::on_buffer_store_event)
.detach();
session.add_request_handler(this.clone(), Self::handle_list_remote_directory);
session.add_request_handler(this.clone(), Self::handle_add_worktree);
session.add_request_handler(this.clone(), Self::handle_open_buffer_by_path);
@ -87,10 +89,11 @@ impl HeadlessProject {
message: TypedEnvelope<proto::AddWorktree>,
mut cx: AsyncAppContext,
) -> Result<proto::AddWorktreeResponse> {
let path = shellexpand::tilde(&message.payload.path).to_string();
let worktree = this
.update(&mut cx.clone(), |this, _| {
Worktree::local(
Path::new(&message.payload.path),
Path::new(&path),
true,
this.fs.clone(),
this.next_entry_id.clone(),
@ -157,6 +160,24 @@ impl HeadlessProject {
})
}
pub async fn handle_list_remote_directory(
this: Model<Self>,
envelope: TypedEnvelope<proto::ListRemoteDirectory>,
cx: AsyncAppContext,
) -> Result<proto::ListRemoteDirectoryResponse> {
let expanded = shellexpand::tilde(&envelope.payload.path).to_string();
let fs = cx.read_model(&this, |this, _| this.fs.clone())?;
let mut entries = Vec::new();
let mut response = fs.read_dir(Path::new(&expanded)).await?;
while let Some(path) = response.next().await {
if let Some(file_name) = path?.file_name() {
entries.push(file_name.to_string_lossy().to_string());
}
}
Ok(proto::ListRemoteDirectoryResponse { entries })
}
pub fn on_buffer_store_event(
&mut self,
_: Model<BufferStore>,