Rename is_local to is_local_or_ssh (#16717)

Conrad Irwin created

Release Notes:

- N/A

Change summary

crates/assistant/src/assistant_panel.rs                       |  2 
crates/assistant/src/context_store.rs                         | 12 
crates/collab/src/tests/random_project_collaboration_tests.rs | 11 
crates/editor/src/editor.rs                                   |  6 
crates/feedback/src/feedback_modal.rs                         |  2 
crates/file_finder/src/file_finder.rs                         |  2 
crates/language_tools/src/lsp_log.rs                          |  4 
crates/outline_panel/src/outline_panel.rs                     |  2 
crates/project/src/prettier_support.rs                        |  2 
crates/project/src/project.rs                                 | 90 ++--
crates/project_panel/src/project_panel.rs                     |  4 
crates/tasks_ui/src/lib.rs                                    |  2 
crates/tasks_ui/src/modal.rs                                  |  4 
crates/terminal_view/src/terminal_panel.rs                    |  2 
crates/title_bar/src/collab.rs                                |  2 
crates/workspace/src/pane.rs                                  |  2 
crates/workspace/src/workspace.rs                             | 18 
crates/zed/src/zed.rs                                         |  2 
18 files changed, 84 insertions(+), 85 deletions(-)

Detailed changes

crates/assistant/src/assistant_panel.rs 🔗

@@ -878,7 +878,7 @@ impl AssistantPanel {
     }
 
     fn new_context(&mut self, cx: &mut ViewContext<Self>) -> Option<View<ContextEditor>> {
-        if self.project.read(cx).is_remote() {
+        if self.project.read(cx).is_via_collab() {
             let task = self
                 .context_store
                 .update(cx, |store, cx| store.create_remote_context(cx));

crates/assistant/src/context_store.rs 🔗

@@ -161,7 +161,7 @@ impl ContextStore {
     ) -> Result<proto::OpenContextResponse> {
         let context_id = ContextId::from_proto(envelope.payload.context_id);
         let operations = this.update(&mut cx, |this, cx| {
-            if this.project.read(cx).is_remote() {
+            if this.project.read(cx).is_via_collab() {
                 return Err(anyhow!("only the host contexts can be opened"));
             }
 
@@ -190,7 +190,7 @@ impl ContextStore {
         mut cx: AsyncAppContext,
     ) -> Result<proto::CreateContextResponse> {
         let (context_id, operations) = this.update(&mut cx, |this, cx| {
-            if this.project.read(cx).is_remote() {
+            if this.project.read(cx).is_via_collab() {
                 return Err(anyhow!("can only create contexts as the host"));
             }
 
@@ -234,7 +234,7 @@ impl ContextStore {
         mut cx: AsyncAppContext,
     ) -> Result<proto::SynchronizeContextsResponse> {
         this.update(&mut cx, |this, cx| {
-            if this.project.read(cx).is_remote() {
+            if this.project.read(cx).is_via_collab() {
                 return Err(anyhow!("only the host can synchronize contexts"));
             }
 
@@ -356,7 +356,7 @@ impl ContextStore {
         let Some(project_id) = project.remote_id() else {
             return Task::ready(Err(anyhow!("project was not remote")));
         };
-        if project.is_local() {
+        if project.is_local_or_ssh() {
             return Task::ready(Err(anyhow!("cannot create remote contexts as the host")));
         }
 
@@ -487,7 +487,7 @@ impl ContextStore {
         let Some(project_id) = project.remote_id() else {
             return Task::ready(Err(anyhow!("project was not remote")));
         };
-        if project.is_local() {
+        if project.is_local_or_ssh() {
             return Task::ready(Err(anyhow!("cannot open remote contexts as the host")));
         }
 
@@ -589,7 +589,7 @@ impl ContextStore {
         };
 
         // For now, only the host can advertise their open contexts.
-        if self.project.read(cx).is_remote() {
+        if self.project.read(cx).is_via_collab() {
             return;
         }
 

crates/collab/src/tests/random_project_collaboration_tests.rs 🔗

@@ -298,7 +298,8 @@ impl RandomizedTest for ProjectCollaborationTest {
                                 continue;
                             };
                             let project_root_name = root_name_for_project(&project, cx);
-                            let is_local = project.read_with(cx, |project, _| project.is_local());
+                            let is_local =
+                                project.read_with(cx, |project, _| project.is_local_or_ssh());
                             let worktree = project.read_with(cx, |project, cx| {
                                 project
                                     .worktrees(cx)
@@ -334,7 +335,7 @@ impl RandomizedTest for ProjectCollaborationTest {
                         continue;
                     };
                     let project_root_name = root_name_for_project(&project, cx);
-                    let is_local = project.read_with(cx, |project, _| project.is_local());
+                    let is_local = project.read_with(cx, |project, _| project.is_local_or_ssh());
 
                     match rng.gen_range(0..100_u32) {
                         // Manipulate an existing buffer
@@ -1254,7 +1255,7 @@ impl RandomizedTest for ProjectCollaborationTest {
             let buffers = client.buffers().clone();
             for (guest_project, guest_buffers) in &buffers {
                 let project_id = if guest_project.read_with(client_cx, |project, _| {
-                    project.is_local() || project.is_disconnected()
+                    project.is_local_or_ssh() || project.is_disconnected()
                 }) {
                     continue;
                 } else {
@@ -1558,7 +1559,9 @@ async fn ensure_project_shared(
     let first_root_name = root_name_for_project(project, cx);
     let active_call = cx.read(ActiveCall::global);
     if active_call.read_with(cx, |call, _| call.room().is_some())
-        && project.read_with(cx, |project, _| project.is_local() && !project.is_shared())
+        && project.read_with(cx, |project, _| {
+            project.is_local_or_ssh() && !project.is_shared()
+        })
     {
         match active_call
             .update(cx, |call, cx| call.share_project(project.clone(), cx))

crates/editor/src/editor.rs 🔗

@@ -4081,7 +4081,7 @@ impl Editor {
         // hence we do LSP request & edit on host side only — add formats to host's history.
         let push_to_lsp_host_history = true;
         // If this is not the host, append its history with new edits.
-        let push_to_client_history = project.read(cx).is_remote();
+        let push_to_client_history = project.read(cx).is_via_collab();
 
         let on_type_formatting = project.update(cx, |project, cx| {
             project.on_type_format(
@@ -8605,7 +8605,7 @@ impl Editor {
             let hide_runnables = project
                 .update(&mut cx, |project, cx| {
                     // Do not display any test indicators in non-dev server remote projects.
-                    project.is_remote() && project.ssh_connection_string(cx).is_none()
+                    project.is_via_collab() && project.ssh_connection_string(cx).is_none()
                 })
                 .unwrap_or(true);
             if hide_runnables {
@@ -11430,7 +11430,7 @@ impl Editor {
                             .filter_map(|buffer| {
                                 let buffer = buffer.read(cx);
                                 let language = buffer.language()?;
-                                if project.is_local()
+                                if project.is_local_or_ssh()
                                     && project.language_servers_for_buffer(buffer, cx).count() == 0
                                 {
                                     None

crates/feedback/src/feedback_modal.rs 🔗

@@ -126,7 +126,7 @@ impl FeedbackModal {
                 .language_for_name("Markdown");
 
             let project = workspace.project().clone();
-            let is_local_project = project.read(cx).is_local();
+            let is_local_project = project.read(cx).is_local_or_ssh();
 
             if !is_local_project {
                 struct FeedbackInRemoteProject;

crates/file_finder/src/file_finder.rs 🔗

@@ -788,7 +788,7 @@ impl PickerDelegate for FileFinderDelegate {
                     project
                         .worktree_for_id(history_item.project.worktree_id, cx)
                         .is_some()
-                        || (project.is_local() && history_item.absolute.is_some())
+                        || (project.is_local_or_ssh() && history_item.absolute.is_some())
                 }),
                 self.currently_opened_path.as_ref(),
                 None,

crates/language_tools/src/lsp_log.rs 🔗

@@ -184,7 +184,7 @@ pub fn init(cx: &mut AppContext) {
 
     cx.observe_new_views(move |workspace: &mut Workspace, cx| {
         let project = workspace.project();
-        if project.read(cx).is_local() {
+        if project.read(cx).is_local_or_ssh() {
             log_store.update(cx, |store, cx| {
                 store.add_project(&project, cx);
             });
@@ -193,7 +193,7 @@ pub fn init(cx: &mut AppContext) {
         let log_store = log_store.clone();
         workspace.register_action(move |workspace, _: &OpenLanguageServerLogs, cx| {
             let project = workspace.project().read(cx);
-            if project.is_local() {
+            if project.is_local_or_ssh() {
                 workspace.add_item_to_active_pane(
                     Box::new(cx.new_view(|cx| {
                         LspLogView::new(workspace.project().clone(), log_store.clone(), cx)

crates/outline_panel/src/outline_panel.rs 🔗

@@ -2887,7 +2887,7 @@ impl Render for OutlinePanel {
             .on_action(cx.listener(Self::copy_relative_path))
             .on_action(cx.listener(Self::unfold_directory))
             .on_action(cx.listener(Self::fold_directory))
-            .when(project.is_local(), |el| {
+            .when(project.is_local_or_ssh(), |el| {
                 el.on_action(cx.listener(Self::reveal_in_finder))
                     .on_action(cx.listener(Self::open_in_terminal))
             })

crates/project/src/prettier_support.rs 🔗

@@ -516,7 +516,7 @@ impl Project {
         cx: &mut ModelContext<Self>,
     ) -> Task<Option<(Option<PathBuf>, PrettierTask)>> {
         // todo(ssh remote): prettier support
-        if self.is_remote() || self.ssh_session.is_some() {
+        if self.is_via_collab() || self.ssh_session.is_some() {
             return Task::ready(None);
         }
         let buffer = buffer.read(cx);

crates/project/src/project.rs 🔗

@@ -643,7 +643,7 @@ impl DirectoryLister {
     pub fn is_local(&self, cx: &AppContext) -> bool {
         match self {
             DirectoryLister::Local(_) => true,
-            DirectoryLister::Project(project) => project.read(cx).is_local(),
+            DirectoryLister::Project(project) => project.read(cx).is_local_or_ssh(),
         }
     }
 
@@ -1419,7 +1419,7 @@ impl Project {
     }
 
     pub fn ssh_connection_string(&self, cx: &ModelContext<Self>) -> Option<SharedString> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             return None;
         }
 
@@ -1837,7 +1837,7 @@ impl Project {
     }
 
     fn unshare_internal(&mut self, cx: &mut AppContext) -> Result<()> {
-        if self.is_remote() {
+        if self.is_via_collab() {
             if self.dev_server_project_id().is_some() {
                 if let ProjectClientState::Remote { in_room, .. } = &mut self.client_state {
                     *in_room = false
@@ -1939,28 +1939,21 @@ impl Project {
         self.is_disconnected() || self.capability() == Capability::ReadOnly
     }
 
-    pub fn is_local(&self) -> bool {
+    pub fn is_local_or_ssh(&self) -> bool {
         match &self.client_state {
             ProjectClientState::Local | ProjectClientState::Shared { .. } => true,
             ProjectClientState::Remote { .. } => false,
         }
     }
 
-    pub fn is_ssh(&self) -> bool {
-        match &self.client_state {
-            ProjectClientState::Local | ProjectClientState::Shared { .. } => true,
-            ProjectClientState::Remote { .. } => false,
-        }
-    }
-
-    pub fn is_remote(&self) -> bool {
-        !self.is_local()
+    pub fn is_via_collab(&self) -> bool {
+        !self.is_local_or_ssh()
     }
 
     pub fn create_buffer(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<Model<Buffer>>> {
         self.buffer_store.update(cx, |buffer_store, cx| {
             buffer_store.create_buffer(
-                if self.is_remote() {
+                if self.is_via_collab() {
                     Some((self.client.clone().into(), self.remote_id().unwrap()))
                 } else {
                     None
@@ -1976,7 +1969,7 @@ impl Project {
         language: Option<Arc<Language>>,
         cx: &mut ModelContext<Self>,
     ) -> Model<Buffer> {
-        if self.is_remote() {
+        if self.is_via_collab() {
             panic!("called create_local_buffer on a remote project")
         }
         self.buffer_store.update(cx, |buffer_store, cx| {
@@ -2018,7 +2011,7 @@ impl Project {
         path: impl Into<ProjectPath>,
         cx: &mut ModelContext<Self>,
     ) -> Task<Result<Model<Buffer>>> {
-        if self.is_remote() && self.is_disconnected() {
+        if self.is_via_collab() && self.is_disconnected() {
             return Task::ready(Err(anyhow!(ErrorCode::Disconnected)));
         }
 
@@ -2107,7 +2100,7 @@ impl Project {
     ) -> Task<Result<Model<Buffer>>> {
         if let Some(buffer) = self.buffer_for_id(id, cx) {
             Task::ready(Ok(buffer))
-        } else if self.is_local() {
+        } else if self.is_local_or_ssh() {
             Task::ready(Err(anyhow!("buffer {} does not exist", id)))
         } else if let Some(project_id) = self.remote_id() {
             let request = self.client.request(proto::OpenBufferById {
@@ -2370,7 +2363,7 @@ impl Project {
         let mut changes = rx.ready_chunks(MAX_BATCH_SIZE);
 
         while let Some(changes) = changes.next().await {
-            let is_local = this.update(&mut cx, |this, _| this.is_local())?;
+            let is_local = this.update(&mut cx, |this, _| this.is_local_or_ssh())?;
 
             for change in changes {
                 match change {
@@ -2512,7 +2505,7 @@ impl Project {
             }
 
             BufferEvent::Reloaded => {
-                if self.is_local() {
+                if self.is_local_or_ssh() {
                     if let Some(project_id) = self.remote_id() {
                         let buffer = buffer.read(cx);
                         self.client
@@ -4015,7 +4008,7 @@ impl Project {
         buffers: impl IntoIterator<Item = Model<Buffer>>,
         cx: &mut ModelContext<Self>,
     ) {
-        if self.is_remote() {
+        if self.is_via_collab() {
             let request = self.client.request(proto::RestartLanguageServers {
                 project_id: self.remote_id().unwrap(),
                 buffer_ids: buffers
@@ -4328,7 +4321,7 @@ impl Project {
             cx.notify();
         }
 
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             self.enqueue_buffer_ordered_message(BufferOrderedMessage::LanguageServerUpdate {
                 language_server_id,
                 message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
@@ -4393,7 +4386,7 @@ impl Project {
             cx.notify();
         }
 
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             self.enqueue_buffer_ordered_message(BufferOrderedMessage::LanguageServerUpdate {
                 language_server_id,
                 message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
@@ -4936,7 +4929,7 @@ impl Project {
         trigger: FormatTrigger,
         cx: &mut ModelContext<Project>,
     ) -> Task<anyhow::Result<ProjectTransaction>> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let buffers_with_paths = buffers
                 .into_iter()
                 .map(|buffer_handle| {
@@ -5664,7 +5657,7 @@ impl Project {
     pub fn symbols(&self, query: &str, cx: &mut ModelContext<Self>) -> Task<Result<Vec<Symbol>>> {
         let language_registry = self.languages.clone();
 
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let mut requests = Vec::new();
             for ((worktree_id, _), server_id) in self.language_server_ids.iter() {
                 let Some(worktree_handle) = self.worktree_for_id(*worktree_id, cx) else {
@@ -5821,7 +5814,7 @@ impl Project {
         symbol: &Symbol,
         cx: &mut ModelContext<Self>,
     ) -> Task<Result<Model<Buffer>>> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let language_server_id = if let Some(id) = self.language_server_ids.get(&(
                 symbol.source_worktree_id,
                 symbol.language_server_name.clone(),
@@ -5880,7 +5873,7 @@ impl Project {
         cx: &mut ModelContext<Self>,
     ) -> Task<Vec<SignatureHelp>> {
         let position = position.to_point_utf16(buffer.read(cx));
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let all_actions_task = self.request_multiple_lsp_locally(
                 buffer,
                 Some(position),
@@ -5954,7 +5947,7 @@ impl Project {
         position: PointUtf16,
         cx: &mut ModelContext<Self>,
     ) -> Task<Vec<Hover>> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let all_actions_task = self.request_multiple_lsp_locally(
                 &buffer,
                 Some(position),
@@ -6062,7 +6055,10 @@ impl Project {
             })
             .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
             .next()
-            .or_else(|| self.is_remote().then_some(LanguageServerToQuery::Primary))
+            .or_else(|| {
+                self.is_via_collab()
+                    .then_some(LanguageServerToQuery::Primary)
+            })
             .filter(|_| {
                 maybe!({
                     let language_name = buffer.read(cx).language_at(position)?.name();
@@ -6104,7 +6100,7 @@ impl Project {
     ) -> Task<Result<Vec<Completion>>> {
         let language_registry = self.languages.clone();
 
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let snapshot = buffer.read(cx).snapshot();
             let offset = position.to_offset(&snapshot);
             let scope = snapshot.language_scope_at(offset);
@@ -6214,7 +6210,7 @@ impl Project {
         let client = self.client();
         let language_registry = self.languages().clone();
 
-        let is_remote = self.is_remote();
+        let is_remote = self.is_via_collab();
         let project_id = self.remote_id();
 
         let buffer_id = buffer.read(cx).remote_id();
@@ -6427,7 +6423,7 @@ impl Project {
         let buffer = buffer_handle.read(cx);
         let buffer_id = buffer.remote_id();
 
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let server_id = completion.server_id;
             let lang_server = match self.language_server_for_buffer(buffer, server_id, cx) {
                 Some((_, server)) => server.clone(),
@@ -6539,7 +6535,7 @@ impl Project {
         range: Range<Anchor>,
         cx: &mut ModelContext<Self>,
     ) -> Task<Vec<CodeAction>> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let all_actions_task = self.request_multiple_lsp_locally(
                 &buffer_handle,
                 Some(range.start),
@@ -6630,7 +6626,7 @@ impl Project {
         push_to_history: bool,
         cx: &mut ModelContext<Self>,
     ) -> Task<Result<ProjectTransaction>> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let buffer = buffer_handle.read(cx);
             let (lsp_adapter, lang_server) = if let Some((adapter, server)) =
                 self.language_server_for_buffer(buffer, action.server_id, cx)
@@ -6712,7 +6708,7 @@ impl Project {
         trigger: String,
         cx: &mut ModelContext<Self>,
     ) -> Task<Result<Option<Transaction>>> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             cx.spawn(move |this, mut cx| async move {
                 // Do not allow multiple concurrent formatting requests for the
                 // same buffer.
@@ -7138,7 +7134,7 @@ impl Project {
         let buffer_id = buffer.remote_id().into();
         let lsp_request = InlayHints { range };
 
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let lsp_request_task = self.request_lsp(
                 buffer_handle.clone(),
                 LanguageServerToQuery::Primary,
@@ -7190,7 +7186,7 @@ impl Project {
         server_id: LanguageServerId,
         cx: &mut ModelContext<Self>,
     ) -> Task<anyhow::Result<InlayHint>> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let buffer = buffer_handle.read(cx);
             let (_, lang_server) = if let Some((adapter, server)) =
                 self.language_server_for_buffer(buffer, server_id, cx)
@@ -7252,7 +7248,7 @@ impl Project {
         query: SearchQuery,
         cx: &mut ModelContext<Self>,
     ) -> Receiver<SearchResult> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             self.search_local(query, cx)
         } else if let Some(project_id) = self.remote_id() {
             let (tx, rx) = smol::channel::unbounded();
@@ -7594,7 +7590,7 @@ impl Project {
         <R::LspRequest as lsp::request::Request>::Params: Send,
     {
         let buffer = buffer_handle.read(cx);
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let language_server = match server {
                 LanguageServerToQuery::Primary => {
                     match self.primary_language_server_for_buffer(buffer, cx) {
@@ -7696,7 +7692,7 @@ impl Project {
         <R::LspRequest as lsp::request::Request>::Result: Send,
         <R::LspRequest as lsp::request::Request>::Params: Send,
     {
-        if !self.is_local() {
+        if !self.is_local_or_ssh() {
             debug_panic!("Should not request multiple lsp commands in non-local project");
             return Task::ready(Vec::new());
         }
@@ -7834,7 +7830,7 @@ impl Project {
             return Task::ready(None);
         }
 
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let expanded = PathBuf::from(shellexpand::tilde(&path).into_owned());
 
             if expanded.is_absolute() {
@@ -7909,7 +7905,7 @@ impl Project {
         query: String,
         cx: &mut ModelContext<Self>,
     ) -> Task<Result<Vec<PathBuf>>> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             DirectoryLister::Local(self.fs.clone()).list_directory(query, cx)
         } else if let Some(dev_server) = self.dev_server_project_id().and_then(|id| {
             dev_server_projects::Store::global(cx)
@@ -7940,7 +7936,7 @@ impl Project {
         if !self.loading_worktrees.contains_key(&path) {
             let task = if self.ssh_session.is_some() {
                 self.create_ssh_worktree(abs_path, visible, cx)
-            } else if self.is_local() {
+            } else if self.is_local_or_ssh() {
                 self.create_local_worktree(abs_path, visible, cx)
             } else if self.dev_server_project_id.is_some() {
                 self.create_dev_server_worktree(abs_path, cx)
@@ -8467,7 +8463,7 @@ impl Project {
         }
 
         cx.emit(Event::DiskBasedDiagnosticsStarted { language_server_id });
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             self.enqueue_buffer_ordered_message(BufferOrderedMessage::LanguageServerUpdate {
                 language_server_id,
                 message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
@@ -8491,7 +8487,7 @@ impl Project {
 
         cx.emit(Event::DiskBasedDiagnosticsFinished { language_server_id });
 
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             self.enqueue_buffer_ordered_message(BufferOrderedMessage::LanguageServerUpdate {
                 language_server_id,
                 message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
@@ -8765,7 +8761,7 @@ impl Project {
         mut cx: AsyncAppContext,
     ) -> Result<()> {
         this.update(&mut cx, |this, cx| {
-            if this.is_local() {
+            if this.is_local_or_ssh() {
                 this.unshare(cx)?;
             } else {
                 this.disconnected_from_host(cx);
@@ -10482,7 +10478,7 @@ impl Project {
         location: Location,
         cx: &mut ModelContext<'_, Project>,
     ) -> Task<Option<TaskContext>> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let (worktree_id, cwd) = if let Some(worktree) = self.task_worktree(cx) {
                 (
                     Some(worktree.read(cx).id()),
@@ -10609,7 +10605,7 @@ impl Project {
         location: Option<Location>,
         cx: &mut ModelContext<Self>,
     ) -> Task<Result<Vec<(TaskSourceKind, TaskTemplate)>>> {
-        if self.is_local() {
+        if self.is_local_or_ssh() {
             let (file, language) = location
                 .map(|location| {
                     let buffer = location.buffer.read(cx);

crates/project_panel/src/project_panel.rs 🔗

@@ -461,7 +461,7 @@ impl ProjectPanel {
             let is_unfoldable = auto_fold_dirs && self.is_unfoldable(entry, worktree);
             let worktree_id = worktree.id();
             let is_read_only = project.is_read_only();
-            let is_remote = project.is_remote() && project.dev_server_project_id().is_none();
+            let is_remote = project.is_via_collab() && project.dev_server_project_id().is_none();
 
             let context_menu = ContextMenu::build(cx, |menu, cx| {
                 menu.context(self.focus_handle.clone()).map(|menu| {
@@ -2491,7 +2491,7 @@ impl Render for ProjectPanel {
                             }
                         }))
                 })
-                .when(project.is_local(), |el| {
+                .when(project.is_local_or_ssh(), |el| {
                     el.on_action(cx.listener(Self::reveal_in_finder))
                         .on_action(cx.listener(Self::open_in_terminal))
                 })

crates/tasks_ui/src/lib.rs 🔗

@@ -94,7 +94,7 @@ fn toggle_modal(workspace: &mut Workspace, cx: &mut ViewContext<'_, Workspace>)
         workspace
             .update(&mut cx, |workspace, cx| {
                 if workspace.project().update(cx, |project, cx| {
-                    project.is_local() || project.ssh_connection_string(cx).is_some()
+                    project.is_local_or_ssh() || project.ssh_connection_string(cx).is_some()
                 }) {
                     workspace.toggle_modal(cx, |cx| {
                         TasksModal::new(project, task_context, workspace_handle, cx)

crates/tasks_ui/src/modal.rs 🔗

@@ -222,10 +222,10 @@ impl PickerDelegate for TasksModalDelegate {
                             let resolved_task =
                                 picker.delegate.project.update(cx, |project, cx| {
                                     let ssh_connection_string = project.ssh_connection_string(cx);
-                                    if project.is_remote() && ssh_connection_string.is_none() {
+                                    if project.is_via_collab() && ssh_connection_string.is_none() {
                                         Task::ready((Vec::new(), Vec::new()))
                                     } else {
-                                        let remote_templates = if project.is_local() {
+                                        let remote_templates = if project.is_local_or_ssh() {
                                             None
                                         } else {
                                             project

crates/terminal_view/src/terminal_panel.rs 🔗

@@ -142,7 +142,7 @@ impl TerminalPanel {
             cx.subscribe(&pane, Self::handle_pane_event),
         ];
         let project = workspace.project().read(cx);
-        let enabled = project.is_local() || project.supports_remote_terminal(cx);
+        let enabled = project.is_local_or_ssh() || project.supports_remote_terminal(cx);
         let this = Self {
             pane,
             fs: workspace.app_state().fs.clone(),

crates/title_bar/src/collab.rs 🔗

@@ -284,7 +284,7 @@ impl TitleBar {
 
         let room = room.read(cx);
         let project = self.project.read(cx);
-        let is_local = project.is_local();
+        let is_local = project.is_local_or_ssh();
         let is_dev_server_project = project.dev_server_project_id().is_some();
         let is_shared = (is_local || is_dev_server_project) && project.is_shared();
         let is_muted = room.is_muted();

crates/workspace/src/pane.rs 🔗

@@ -2150,7 +2150,7 @@ impl Pane {
         let is_remote = self
             .workspace
             .update(cx, |workspace, cx| {
-                if workspace.project().read(cx).is_remote() {
+                if workspace.project().read(cx).is_via_collab() {
                     workspace.show_error(
                         &anyhow::anyhow!("Cannot drop files on a remote project"),
                         cx,

crates/workspace/src/workspace.rs 🔗

@@ -1494,7 +1494,7 @@ impl Workspace {
         &mut self,
         cx: &mut ViewContext<Self>,
     ) -> oneshot::Receiver<Option<ProjectPath>> {
-        if self.project.read(cx).is_remote()
+        if self.project.read(cx).is_via_collab()
             || !WorkspaceSettings::get_global(cx).use_system_path_prompts
         {
             let prompt = self.on_prompt_for_new_path.take().unwrap();
@@ -1576,7 +1576,7 @@ impl Workspace {
         T: 'static,
         F: 'static + FnOnce(&mut Workspace, &mut ViewContext<Workspace>) -> T,
     {
-        if self.project.read(cx).is_local() {
+        if self.project.read(cx).is_local_or_ssh() {
             Task::Ready(Some(Ok(callback(self, cx))))
         } else {
             let task = Self::new_local(Vec::new(), self.app_state.clone(), None, cx);
@@ -1889,7 +1889,7 @@ impl Workspace {
         cx: &mut ViewContext<Self>,
     ) -> Task<Result<()>> {
         let window = cx.window_handle().downcast::<Self>();
-        let is_remote = self.project.read(cx).is_remote();
+        let is_remote = self.project.read(cx).is_via_collab();
         let has_worktree = self.project.read(cx).worktrees(cx).next().is_some();
         let has_dirty_items = self.items(cx).any(|item| item.is_dirty(cx));
 
@@ -2028,7 +2028,7 @@ impl Workspace {
 
     fn add_folder_to_project(&mut self, _: &AddFolderToProject, cx: &mut ViewContext<Self>) {
         let project = self.project.read(cx);
-        if project.is_remote() && project.dev_server_project_id().is_none() {
+        if project.is_via_collab() && project.dev_server_project_id().is_none() {
             self.show_error(
                 &anyhow!("You cannot add folders to someone else's project"),
                 cx,
@@ -3388,7 +3388,7 @@ impl Workspace {
             title = "empty project".to_string();
         }
 
-        if project.is_remote() {
+        if project.is_via_collab() {
             title.push_str(" ↙");
         } else if project.is_shared() {
             title.push_str(" ↗");
@@ -3912,7 +3912,7 @@ impl Workspace {
     fn local_paths(&self, cx: &AppContext) -> Option<Vec<Arc<Path>>> {
         let project = self.project().read(cx);
 
-        if project.is_local() {
+        if project.is_local_or_ssh() {
             Some(
                 project
                     .visible_worktrees(cx)
@@ -5104,7 +5104,7 @@ async fn join_channel_internal(
                         return None;
                     }
 
-                    if (project.is_local() || is_dev_server)
+                    if (project.is_local_or_ssh() || is_dev_server)
                         && project.visible_worktrees(cx).any(|tree| {
                             tree.read(cx)
                                 .root_entry()
@@ -5258,7 +5258,7 @@ pub fn local_workspace_windows(cx: &AppContext) -> Vec<WindowHandle<Workspace>>
         .filter(|workspace| {
             workspace
                 .read(cx)
-                .is_ok_and(|workspace| workspace.project.read(cx).is_local())
+                .is_ok_and(|workspace| workspace.project.read(cx).is_local_or_ssh())
         })
         .collect()
 }
@@ -5316,7 +5316,7 @@ pub fn open_paths(
                     for window in local_workspace_windows(cx) {
                         if let Ok(workspace) = window.read(cx) {
                             let project = workspace.project().read(cx);
-                            if project.is_remote() {
+                            if project.is_via_collab() {
                                 continue;
                             }
                             existing = Some(window);

crates/zed/src/zed.rs 🔗

@@ -224,7 +224,7 @@ pub fn initialize_workspace(
 
         let project = workspace.project().clone();
         if project.update(cx, |project, cx| {
-            project.is_local() || project.ssh_connection_string(cx).is_some()
+            project.is_local_or_ssh() || project.ssh_connection_string(cx).is_some()
         }) {
             project.update(cx, |project, cx| {
                 let fs = app_state.fs.clone();