This reverts commit 8a1e8e37bb (PR #17435)
because it creates a panic when joining a collab project.
Stack trace of the panic:
```
Thread "main" panicked with "ProjectLspAdapterDelegate cannot be constructedd on an ssh-remote yet" at crates/project/src/lsp_store.rs:6332:13
0: backtrace::backtrace::libunwind::trace
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/backtrace-0.3.73/src/backtrace/libunwind.rs:116:5
backtrace::backtrace::trace_unsynchronized::<<backtrace::capture::Backtrace>::create::{closure#0}>
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/backtrace-0.3.73/src/backtrace/mod.rs:66:5
1: backtrace::backtrace::trace::<<backtrace::capture::Backtrace>::create::{closure#0}>
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/backtrace-0.3.73/src/backtrace/mod.rs:53:14
2: <backtrace::capture::Backtrace>::create
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/backtrace-0.3.73/src/capture.rs:197:9
3: <backtrace::capture::Backtrace>::new
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/backtrace-0.3.73/src/capture.rs:162:22
4: zed::reliability::init_panic_hook::{closure#0}
at /Users/thorstenball/work/zed/crates/zed/src/reliability.rs:58:29
5: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/alloc/src/boxed.rs:2084:9
std::panicking::rust_panic_with_hook
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:808:13
6: std::panicking::begin_panic_handler::{{closure}}
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:667:13
7: std::sys::backtrace::__rust_end_short_backtrace
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:168:18
8: rust_begin_unwind
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:665:5
9: core::panicking::panic_fmt
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/panicking.rs:74:14
10: <project::lsp_store::ProjectLspAdapterDelegate>::new
at /Users/thorstenball/work/zed/crates/project/src/lsp_store.rs:6332:13
11: assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}::{closure#1}
at /Users/thorstenball/work/zed/crates/assistant/src/assistant_panel.rs:5159:16
12: <gpui::app::AppContext as gpui::Context>::update_model::<project::lsp_store::LspStore, core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}::{closure#1}>::{closure#0}
at /Users/thorstenball/work/zed/crates/gpui/src/app.rs:1365:26
13: <gpui::app::AppContext>::update::<core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, <gpui::app::AppContext as gpui::Context>::update_model<project::lsp_store::LspStore, core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}::{closure#1}>::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/app.rs:362:22
14: <gpui::app::AppContext as gpui::Context>::update_model::<project::lsp_store::LspStore, core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}::{closure#1}>
at /Users/thorstenball/work/zed/crates/gpui/src/app.rs:1363:9
15: <gpui::app::model_context::ModelContext<project::Project> as gpui::Context>::update_model::<project::lsp_store::LspStore, core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}::{closure#1}>
at /Users/thorstenball/work/zed/crates/gpui/src/app/model_context.rs:250:9
16: <gpui::app::entity_map::Model<project::lsp_store::LspStore>>::update::<gpui::app::model_context::ModelContext<project::Project>, core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}::{closure#1}>
at /Users/thorstenball/work/zed/crates/gpui/src/app/entity_map.rs:422:9
17: assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}
at /Users/thorstenball/work/zed/crates/assistant/src/assistant_panel.rs:5158:9
18: <gpui::app::AppContext as gpui::Context>::update_model::<project::Project, core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}>::{closure#0}
at /Users/thorstenball/work/zed/crates/gpui/src/app.rs:1365:26
19: <gpui::app::AppContext>::update::<core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, <gpui::app::AppContext as gpui::Context>::update_model<project::Project, core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}>::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/app.rs:362:22
20: <gpui::app::AppContext as gpui::Context>::update_model::<project::Project, core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/app.rs:1363:9
21: <gpui::app::entity_map::Model<project::Project>>::update::<gpui::app::AppContext, core::result::Result<alloc::sync::Arc<dyn language::LspAdapterDelegate>, anyhow::Error>, assistant::assistant_panel::make_lsp_adapter_delegate::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/app/entity_map.rs:422:9
22: assistant::assistant_panel::make_lsp_adapter_delegate
at /Users/thorstenball/work/zed/crates/assistant/src/assistant_panel.rs:5152:5
23: <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}
at /Users/thorstenball/work/zed/crates/assistant/src/assistant_panel.rs:960:48
24: <gpui::window::WindowContext as gpui::VisualContext>::update_view::<assistant::assistant_panel::AssistantPanel, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/window.rs:3940:22
25: <gpui::app::async_context::AsyncWindowContext as gpui::VisualContext>::update_view::<assistant::assistant_panel::AssistantPanel, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>::{closure#0}
at /Users/thorstenball/work/zed/crates/gpui/src/app/async_context.rs:387:35
26: <gpui::app::AppContext as gpui::Context>::update_window::<core::result::Result<(), anyhow::Error>, <gpui::app::async_context::AsyncWindowContext as gpui::VisualContext>::update_view<assistant::assistant_panel::AssistantPanel, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>::{closure#0}
at /Users/thorstenball/work/zed/crates/gpui/src/app.rs:1396:26
27: <gpui::app::AppContext>::update::<core::result::Result<core::result::Result<(), anyhow::Error>, anyhow::Error>, <gpui::app::AppContext as gpui::Context>::update_window<core::result::Result<(), anyhow::Error>, <gpui::app::async_context::AsyncWindowContext as gpui::VisualContext>::update_view<assistant::assistant_panel::AssistantPanel, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/app.rs:362:22
28: <gpui::app::AppContext as gpui::Context>::update_window::<core::result::Result<(), anyhow::Error>, <gpui::app::async_context::AsyncWindowContext as gpui::VisualContext>::update_view<assistant::assistant_panel::AssistantPanel, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/app.rs:1387:9
29: <gpui::app::async_context::AsyncAppContext as gpui::Context>::update_window::<core::result::Result<(), anyhow::Error>, <gpui::app::async_context::AsyncWindowContext as gpui::VisualContext>::update_view<assistant::assistant_panel::AssistantPanel, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/app/async_context.rs:91:9
30: <gpui::app::async_context::AsyncWindowContext as gpui::Context>::update_window::<core::result::Result<(), anyhow::Error>, <gpui::app::async_context::AsyncWindowContext as gpui::VisualContext>::update_view<assistant::assistant_panel::AssistantPanel, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/app/async_context.rs:354:9
31: <gpui::window::AnyWindowHandle>::update::<gpui::app::async_context::AsyncWindowContext, core::result::Result<(), anyhow::Error>, <gpui::app::async_context::AsyncWindowContext as gpui::VisualContext>::update_view<assistant::assistant_panel::AssistantPanel, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/window.rs:4800:9
32: <gpui::app::async_context::AsyncWindowContext as gpui::VisualContext>::update_view::<assistant::assistant_panel::AssistantPanel, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/app/async_context.rs:386:9
33: <gpui::view::View<assistant::assistant_panel::AssistantPanel>>::update::<gpui::app::async_context::AsyncWindowContext, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/view.rs:76:9
34: <gpui::view::WeakView<assistant::assistant_panel::AssistantPanel>>::update::<gpui::app::async_context::AsyncWindowContext, core::result::Result<(), anyhow::Error>, <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}::{closure#0}>
at /Users/thorstenball/work/zed/crates/gpui/src/view.rs:192:12
35: <assistant::assistant_panel::AssistantPanel>::new_context::{closure#1}::{closure#0}
at /Users/thorstenball/work/zed/crates/assistant/src/assistant_panel.rs:957:17
36: <core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = core::result::Result<(), anyhow::Error>>>> as core::future::future::Future>::poll
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/future/future.rs:123:9
37: <<async_task::runnable::Builder<_>>::spawn_local::Checked<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = core::result::Result<(), anyhow::Error>>>>> as core::future::future::Future>::poll
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/async-task-4.7.1/src/runnable.rs:455:26
38: <async_task::raw::RawTask<<async_task::runnable::Builder<_>>::spawn_local::Checked<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = core::result::Result<(), anyhow::Error>>>>>, core::result::Result<(), anyhow::Error>, <gpui::executor::ForegroundExecutor>::spawn::inner<core::result::Result<(), anyhow::Error>>::{closure#0}, ()>>::run
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/async-task-4.7.1/src/raw.rs:557:17
39: <async_task::runnable::Runnable>::run
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/async-task-4.7.1/src/runnable.rs:781:18
40: gpui::platform::mac::dispatcher::trampoline
at /Users/thorstenball/work/zed/crates/gpui/src/platform/mac/dispatcher.rs:106:5
41: <unknown>
42: <unknown>
43: <unknown>
44: <unknown>
45: <unknown>
46: <unknown>
47: <unknown>
48: <unknown>
49: <unknown>
50: <unknown>
51: <unknown>
52: <unknown>
53: <() as objc::message::MessageArguments>::invoke::<()>
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/objc-0.2.7/src/message/mod.rs:128:17
54: objc::message::platform::send_unverified::<objc::runtime::Object, (), ()>
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/objc-0.2.7/src/message/apple/mod.rs:27:9
55: objc::message::send_message::<objc::runtime::Object, (), ()>
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/objc-0.2.7/src/message/mod.rs:178:5
<*mut objc::runtime::Object as cocoa::appkit::NSApplication>::run
at /Users/thorstenball/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cocoa-0.26.0/src/appkit.rs:628:9
56: <gpui::platform::mac::platform::MacPlatform as gpui::platform::Platform>::run
at /Users/thorstenball/work/zed/crates/gpui/src/platform/mac/platform.rs:427:13
57: <gpui::app::App>::run::<zed::main::{closure#3}>
at /Users/thorstenball/work/zed/crates/gpui/src/app.rs:159:9
58: zed::main
at /Users/thorstenball/work/zed/crates/zed/src/main.rs:439:5
59: <fn() as core::ops::function::FnOnce<()>>::call_once
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ops/function.rs:250:5
60: std::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:152:18
61: std::rt::lang_start::<()>::{closure#0}
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:162:18
62: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ops/function.rs:284:13
std::panicking
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:557:40
std::panicking::try
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:521:19
std::panic::catch_unwind
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panic.rs:350:14
std::rt::lang_start_internal::{{closure}}
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:141:48
std::panicking::try::do_call
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:557:40
std::panicking::try
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:521:19
std::panic::catch_unwind
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panic.rs:350:14
std::rt::lang_start_internal
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:141:20
63: std::rt::lang_start::<()>
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:161:17
64: _main
```
Closes #ISSUE
Release Notes:
- Added/Fixed/Improved ...
Optionally, include screenshots / media showcasing your addition that
can be included in the release notes.
### Or...
Closes #ISSUE
Release Notes:
- N/A
Co-authored-by: Bennet <bennet@zed.dev>
228 lines
8.2 KiB
Rust
228 lines
8.2 KiB
Rust
use anyhow::{anyhow, Result};
|
|
use fs::Fs;
|
|
use gpui::{AppContext, AsyncAppContext, Context, Model, ModelContext, Task};
|
|
use language::LanguageRegistry;
|
|
use project::{
|
|
buffer_store::BufferStore, project_settings::SettingsObserver, search::SearchQuery,
|
|
worktree_store::WorktreeStore, LspStore, ProjectPath, WorktreeId, WorktreeSettings,
|
|
};
|
|
use remote::SshSession;
|
|
use rpc::{
|
|
proto::{self, AnyProtoClient, SSH_PEER_ID, SSH_PROJECT_ID},
|
|
TypedEnvelope,
|
|
};
|
|
use settings::Settings as _;
|
|
use smol::stream::StreamExt;
|
|
use std::{
|
|
path::{Path, PathBuf},
|
|
sync::{atomic::AtomicUsize, Arc},
|
|
};
|
|
use worktree::Worktree;
|
|
|
|
pub struct HeadlessProject {
|
|
pub fs: Arc<dyn Fs>,
|
|
pub session: AnyProtoClient,
|
|
pub worktree_store: Model<WorktreeStore>,
|
|
pub buffer_store: Model<BufferStore>,
|
|
pub lsp_store: Model<LspStore>,
|
|
pub settings_observer: Model<SettingsObserver>,
|
|
pub next_entry_id: Arc<AtomicUsize>,
|
|
}
|
|
|
|
impl HeadlessProject {
|
|
pub fn init(cx: &mut AppContext) {
|
|
settings::init(cx);
|
|
language::init(cx);
|
|
WorktreeSettings::register(cx);
|
|
}
|
|
|
|
pub fn new(session: Arc<SshSession>, fs: Arc<dyn Fs>, cx: &mut ModelContext<Self>) -> Self {
|
|
// TODO: we should load the env correctly (as we do in login_shell_env_loaded when stdout is not a pty). Can we re-use the ProjectEnvironment for that?
|
|
let languages = Arc::new(LanguageRegistry::new(
|
|
Task::ready(()),
|
|
cx.background_executor().clone(),
|
|
));
|
|
|
|
let worktree_store = cx.new_model(|_| WorktreeStore::new(true, fs.clone()));
|
|
let buffer_store = cx.new_model(|cx| {
|
|
let mut buffer_store =
|
|
BufferStore::new(worktree_store.clone(), Some(SSH_PROJECT_ID), cx);
|
|
buffer_store.shared(SSH_PROJECT_ID, session.clone().into(), cx);
|
|
buffer_store
|
|
});
|
|
let settings_observer = cx.new_model(|cx| {
|
|
let mut observer = SettingsObserver::new_local(fs.clone(), worktree_store.clone(), cx);
|
|
observer.shared(SSH_PROJECT_ID, session.clone().into(), cx);
|
|
observer
|
|
});
|
|
let environment = project::ProjectEnvironment::new(&worktree_store, None, cx);
|
|
let lsp_store = cx.new_model(|cx| {
|
|
LspStore::new(
|
|
buffer_store.clone(),
|
|
worktree_store.clone(),
|
|
Some(environment),
|
|
languages,
|
|
None,
|
|
fs.clone(),
|
|
Some(session.clone().into()),
|
|
None,
|
|
Some(0),
|
|
cx,
|
|
)
|
|
});
|
|
|
|
let client: AnyProtoClient = session.clone().into();
|
|
|
|
session.subscribe_to_entity(SSH_PROJECT_ID, &worktree_store);
|
|
session.subscribe_to_entity(SSH_PROJECT_ID, &buffer_store);
|
|
session.subscribe_to_entity(SSH_PROJECT_ID, &cx.handle());
|
|
session.subscribe_to_entity(SSH_PROJECT_ID, &lsp_store);
|
|
session.subscribe_to_entity(SSH_PROJECT_ID, &settings_observer);
|
|
|
|
client.add_request_handler(cx.weak_model(), Self::handle_list_remote_directory);
|
|
|
|
client.add_model_request_handler(Self::handle_add_worktree);
|
|
client.add_model_request_handler(Self::handle_open_buffer_by_path);
|
|
client.add_model_request_handler(Self::handle_find_search_candidates);
|
|
|
|
client.add_model_request_handler(BufferStore::handle_update_buffer);
|
|
client.add_model_message_handler(BufferStore::handle_close_buffer);
|
|
|
|
BufferStore::init(&client);
|
|
WorktreeStore::init(&client);
|
|
SettingsObserver::init(&client);
|
|
|
|
HeadlessProject {
|
|
session: client,
|
|
settings_observer,
|
|
fs,
|
|
worktree_store,
|
|
buffer_store,
|
|
lsp_store,
|
|
next_entry_id: Default::default(),
|
|
}
|
|
}
|
|
|
|
pub async fn handle_add_worktree(
|
|
this: Model<Self>,
|
|
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(&path),
|
|
true,
|
|
this.fs.clone(),
|
|
this.next_entry_id.clone(),
|
|
&mut cx,
|
|
)
|
|
})?
|
|
.await?;
|
|
|
|
this.update(&mut cx, |this, cx| {
|
|
let session = this.session.clone();
|
|
this.worktree_store.update(cx, |worktree_store, cx| {
|
|
worktree_store.add(&worktree, cx);
|
|
});
|
|
worktree.update(cx, |worktree, cx| {
|
|
worktree.observe_updates(0, cx, move |update| {
|
|
session.send(update).ok();
|
|
futures::future::ready(true)
|
|
});
|
|
proto::AddWorktreeResponse {
|
|
worktree_id: worktree.id().to_proto(),
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
pub async fn handle_open_buffer_by_path(
|
|
this: Model<Self>,
|
|
message: TypedEnvelope<proto::OpenBufferByPath>,
|
|
mut cx: AsyncAppContext,
|
|
) -> Result<proto::OpenBufferResponse> {
|
|
let worktree_id = WorktreeId::from_proto(message.payload.worktree_id);
|
|
let (buffer_store, buffer) = this.update(&mut cx, |this, cx| {
|
|
let buffer_store = this.buffer_store.clone();
|
|
let buffer = this.buffer_store.update(cx, |buffer_store, cx| {
|
|
buffer_store.open_buffer(
|
|
ProjectPath {
|
|
worktree_id,
|
|
path: PathBuf::from(message.payload.path).into(),
|
|
},
|
|
cx,
|
|
)
|
|
});
|
|
anyhow::Ok((buffer_store, buffer))
|
|
})??;
|
|
|
|
let buffer = buffer.await?;
|
|
let buffer_id = buffer.read_with(&cx, |b, _| b.remote_id())?;
|
|
buffer_store.update(&mut cx, |buffer_store, cx| {
|
|
buffer_store
|
|
.create_buffer_for_peer(&buffer, SSH_PEER_ID, cx)
|
|
.detach_and_log_err(cx);
|
|
})?;
|
|
|
|
Ok(proto::OpenBufferResponse {
|
|
buffer_id: buffer_id.to_proto(),
|
|
})
|
|
}
|
|
|
|
pub async fn handle_find_search_candidates(
|
|
this: Model<Self>,
|
|
envelope: TypedEnvelope<proto::FindSearchCandidates>,
|
|
mut cx: AsyncAppContext,
|
|
) -> Result<proto::FindSearchCandidatesResponse> {
|
|
let message = envelope.payload;
|
|
let query = SearchQuery::from_proto(
|
|
message
|
|
.query
|
|
.ok_or_else(|| anyhow!("missing query field"))?,
|
|
)?;
|
|
let mut results = this.update(&mut cx, |this, cx| {
|
|
this.buffer_store.update(cx, |buffer_store, cx| {
|
|
buffer_store.find_search_candidates(&query, message.limit as _, this.fs.clone(), cx)
|
|
})
|
|
})?;
|
|
|
|
let mut response = proto::FindSearchCandidatesResponse {
|
|
buffer_ids: Vec::new(),
|
|
};
|
|
|
|
let buffer_store = this.read_with(&cx, |this, _| this.buffer_store.clone())?;
|
|
|
|
while let Some(buffer) = results.next().await {
|
|
let buffer_id = buffer.update(&mut cx, |this, _| this.remote_id())?;
|
|
response.buffer_ids.push(buffer_id.to_proto());
|
|
buffer_store
|
|
.update(&mut cx, |buffer_store, cx| {
|
|
buffer_store.create_buffer_for_peer(&buffer, SSH_PEER_ID, cx)
|
|
})?
|
|
.await?;
|
|
}
|
|
|
|
Ok(response)
|
|
}
|
|
|
|
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 })
|
|
}
|
|
}
|