Detailed changes
@@ -65,18 +65,14 @@ impl ActivityIndicator {
let mut status_events = languages.language_server_binary_statuses();
cx.spawn(|this, mut cx| async move {
while let Some((language, event)) = status_events.next().await {
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, cx| {
- this.statuses.retain(|s| s.name != language.name());
- this.statuses.push(LspStatus {
- name: language.name(),
- status: event,
- });
- cx.notify();
- })?;
- } else {
- break;
- }
+ this.update(&mut cx, |this, cx| {
+ this.statuses.retain(|s| s.name != language.name());
+ this.statuses.push(LspStatus {
+ name: language.name(),
+ status: event,
+ });
+ cx.notify();
+ })?;
}
anyhow::Ok(())
})
@@ -104,17 +104,15 @@ pub fn notify_of_any_new_update(
cx.spawn(|mut cx| async move {
let should_show_notification = should_show_notification.await?;
if should_show_notification {
- if let Some(workspace) = workspace.upgrade(&cx) {
- workspace.update(&mut cx, |workspace, cx| {
- workspace.show_notification(0, cx, |cx| {
- cx.add_view(|_| UpdateNotification::new(version))
- });
- updater
- .read(cx)
- .set_should_show_update_notification(false, cx)
- .detach_and_log_err(cx);
- })?;
- }
+ workspace.update(&mut cx, |workspace, cx| {
+ workspace.show_notification(0, cx, |cx| {
+ cx.add_view(|_| UpdateNotification::new(version))
+ });
+ updater
+ .read(cx)
+ .set_should_show_update_notification(false, cx)
+ .detach_and_log_err(cx);
+ })?;
}
anyhow::Ok(())
})
@@ -2510,9 +2510,6 @@ impl Editor {
None
};
- let this = this
- .upgrade(&cx)
- .ok_or_else(|| anyhow!("editor was dropped"))?;
this.update(&mut cx, |this, cx| {
this.completion_tasks.retain(|(task_id, _)| *task_id > id);
@@ -2672,30 +2669,25 @@ impl Editor {
cx.spawn(|this, mut cx| async move {
while let Some(prev_task) = task {
prev_task.await;
- task = this
- .upgrade(&cx)
- .ok_or_else(|| anyhow!("editor dropped"))?
- .update(&mut cx, |this, _| this.code_actions_task.take())?;
+ task = this.update(&mut cx, |this, _| this.code_actions_task.take())?;
}
- this.upgrade(&cx)
- .ok_or_else(|| anyhow!("editor dropped"))?
- .update(&mut cx, |this, cx| {
- if this.focused {
- if let Some((buffer, actions)) = this.available_code_actions.clone() {
- this.show_context_menu(
- ContextMenu::CodeActions(CodeActionsMenu {
- buffer,
- actions,
- selected_item: Default::default(),
- list: Default::default(),
- deployed_from_indicator,
- }),
- cx,
- );
- }
+ this.update(&mut cx, |this, cx| {
+ if this.focused {
+ if let Some((buffer, actions)) = this.available_code_actions.clone() {
+ this.show_context_menu(
+ ContextMenu::CodeActions(CodeActionsMenu {
+ buffer,
+ actions,
+ selected_item: Default::default(),
+ list: Default::default(),
+ deployed_from_indicator,
+ }),
+ cx,
+ );
}
- })?;
+ }
+ })?;
Ok::<_, anyhow::Error>(())
})
@@ -2828,19 +2820,17 @@ impl Editor {
});
self.code_actions_task = Some(cx.spawn(|this, mut cx| async move {
let actions = actions.await;
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, cx| {
- this.available_code_actions = actions.log_err().and_then(|actions| {
- if actions.is_empty() {
- None
- } else {
- Some((start_buffer, actions.into()))
- }
- });
- cx.notify();
- })
- .log_err();
- }
+ this.update(&mut cx, |this, cx| {
+ this.available_code_actions = actions.log_err().and_then(|actions| {
+ if actions.is_empty() {
+ None
+ } else {
+ Some((start_buffer, actions.into()))
+ }
+ });
+ cx.notify();
+ })
+ .log_err();
}));
None
}
@@ -2866,8 +2856,7 @@ impl Editor {
});
self.document_highlights_task = Some(cx.spawn(|this, mut cx| async move {
- let highlights = highlights.log_err().await;
- if let Some((this, highlights)) = this.upgrade(&cx).zip(highlights) {
+ if let Some(highlights) = highlights.await.log_err() {
this.update(&mut cx, |this, cx| {
if this.pending_rename.is_some() {
return;
@@ -2976,21 +2965,20 @@ impl Editor {
.flatten()
.collect_vec();
- this.upgrade(&cx)?
- .update(&mut cx, |this, cx| {
- if !completions.is_empty() {
- this.copilot_state.cycled = false;
- this.copilot_state.pending_cycling_refresh = Task::ready(None);
- this.copilot_state.completions.clear();
- this.copilot_state.active_completion_index = 0;
- this.copilot_state.excerpt_id = Some(cursor.excerpt_id);
- for completion in completions {
- this.copilot_state.push_completion(completion);
- }
- this.update_visible_copilot_suggestion(cx);
+ this.update(&mut cx, |this, cx| {
+ if !completions.is_empty() {
+ this.copilot_state.cycled = false;
+ this.copilot_state.pending_cycling_refresh = Task::ready(None);
+ this.copilot_state.completions.clear();
+ this.copilot_state.active_completion_index = 0;
+ this.copilot_state.excerpt_id = Some(cursor.excerpt_id);
+ for completion in completions {
+ this.copilot_state.push_completion(completion);
}
- })
- .log_err()?;
+ this.update_visible_copilot_suggestion(cx);
+ }
+ })
+ .log_err()?;
Some(())
});
@@ -3021,16 +3009,15 @@ impl Editor {
})
.await;
- this.upgrade(&cx)?
- .update(&mut cx, |this, cx| {
- this.copilot_state.cycled = true;
- for completion in completions.log_err().into_iter().flatten() {
- this.copilot_state.push_completion(completion);
- }
- this.copilot_state.cycle_completions(direction);
- this.update_visible_copilot_suggestion(cx);
- })
- .log_err()?;
+ this.update(&mut cx, |this, cx| {
+ this.copilot_state.cycled = true;
+ for completion in completions.log_err().into_iter().flatten() {
+ this.copilot_state.push_completion(completion);
+ }
+ this.copilot_state.cycle_completions(direction);
+ this.update_visible_copilot_suggestion(cx);
+ })
+ .log_err()?;
Some(())
});
@@ -201,15 +201,13 @@ fn show_hover(
})
});
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, _| {
- this.hover_state.diagnostic_popover =
- local_diagnostic.map(|local_diagnostic| DiagnosticPopover {
- local_diagnostic,
- primary_diagnostic,
- });
- })?;
- }
+ this.update(&mut cx, |this, _| {
+ this.hover_state.diagnostic_popover =
+ local_diagnostic.map(|local_diagnostic| DiagnosticPopover {
+ local_diagnostic,
+ primary_diagnostic,
+ });
+ })?;
// Construct new hover popover from hover request
let hover_popover = hover_request.await.ok().flatten().and_then(|hover_result| {
@@ -239,23 +237,22 @@ fn show_hover(
})
});
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, cx| {
- if let Some(hover_popover) = hover_popover.as_ref() {
- // Highlight the selected symbol using a background highlight
- this.highlight_background::<HoverState>(
- vec![hover_popover.symbol_range.clone()],
- |theme| theme.editor.hover_popover.highlight,
- cx,
- );
- } else {
- this.clear_background_highlights::<HoverState>(cx);
- }
+ this.update(&mut cx, |this, cx| {
+ if let Some(hover_popover) = hover_popover.as_ref() {
+ // Highlight the selected symbol using a background highlight
+ this.highlight_background::<HoverState>(
+ vec![hover_popover.symbol_range.clone()],
+ |theme| theme.editor.hover_popover.highlight,
+ cx,
+ );
+ } else {
+ this.clear_background_highlights::<HoverState>(cx);
+ }
+
+ this.hover_state.info_popover = hover_popover;
+ cx.notify();
+ })?;
- this.hover_state.info_popover = hover_popover;
- cx.notify();
- })?;
- }
Ok::<_, anyhow::Error>(())
}
.log_err()
@@ -202,67 +202,65 @@ pub fn show_link_definition(
)
});
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, cx| {
- // Clear any existing highlights
- this.clear_text_highlights::<LinkGoToDefinitionState>(cx);
- this.link_go_to_definition_state.kind = Some(definition_kind);
- this.link_go_to_definition_state.symbol_range = result
- .as_ref()
- .and_then(|(symbol_range, _)| symbol_range.clone());
-
- if let Some((symbol_range, definitions)) = result {
- this.link_go_to_definition_state.definitions = definitions.clone();
-
- let buffer_snapshot = buffer.read(cx).snapshot();
-
- // Only show highlight if there exists a definition to jump to that doesn't contain
- // the current location.
- let any_definition_does_not_contain_current_location =
- definitions.iter().any(|definition| {
- let target = &definition.target;
- if target.buffer == buffer {
- let range = &target.range;
- // Expand range by one character as lsp definition ranges include positions adjacent
- // but not contained by the symbol range
- let start = buffer_snapshot.clip_offset(
- range.start.to_offset(&buffer_snapshot).saturating_sub(1),
- Bias::Left,
- );
- let end = buffer_snapshot.clip_offset(
- range.end.to_offset(&buffer_snapshot) + 1,
- Bias::Right,
- );
- let offset = buffer_position.to_offset(&buffer_snapshot);
- !(start <= offset && end >= offset)
- } else {
- true
- }
- });
-
- if any_definition_does_not_contain_current_location {
- // If no symbol range returned from language server, use the surrounding word.
- let highlight_range = symbol_range.unwrap_or_else(|| {
- let snapshot = &snapshot.buffer_snapshot;
- let (offset_range, _) = snapshot.surrounding_word(trigger_point);
-
- snapshot.anchor_before(offset_range.start)
- ..snapshot.anchor_after(offset_range.end)
- });
-
- // Highlight symbol using theme link definition highlight style
- let style = cx.global::<Settings>().theme.editor.link_definition;
- this.highlight_text::<LinkGoToDefinitionState>(
- vec![highlight_range],
- style,
- cx,
- );
- } else {
- hide_link_definition(this, cx);
- }
+ this.update(&mut cx, |this, cx| {
+ // Clear any existing highlights
+ this.clear_text_highlights::<LinkGoToDefinitionState>(cx);
+ this.link_go_to_definition_state.kind = Some(definition_kind);
+ this.link_go_to_definition_state.symbol_range = result
+ .as_ref()
+ .and_then(|(symbol_range, _)| symbol_range.clone());
+
+ if let Some((symbol_range, definitions)) = result {
+ this.link_go_to_definition_state.definitions = definitions.clone();
+
+ let buffer_snapshot = buffer.read(cx).snapshot();
+
+ // Only show highlight if there exists a definition to jump to that doesn't contain
+ // the current location.
+ let any_definition_does_not_contain_current_location =
+ definitions.iter().any(|definition| {
+ let target = &definition.target;
+ if target.buffer == buffer {
+ let range = &target.range;
+ // Expand range by one character as lsp definition ranges include positions adjacent
+ // but not contained by the symbol range
+ let start = buffer_snapshot.clip_offset(
+ range.start.to_offset(&buffer_snapshot).saturating_sub(1),
+ Bias::Left,
+ );
+ let end = buffer_snapshot.clip_offset(
+ range.end.to_offset(&buffer_snapshot) + 1,
+ Bias::Right,
+ );
+ let offset = buffer_position.to_offset(&buffer_snapshot);
+ !(start <= offset && end >= offset)
+ } else {
+ true
+ }
+ });
+
+ if any_definition_does_not_contain_current_location {
+ // If no symbol range returned from language server, use the surrounding word.
+ let highlight_range = symbol_range.unwrap_or_else(|| {
+ let snapshot = &snapshot.buffer_snapshot;
+ let (offset_range, _) = snapshot.surrounding_word(trigger_point);
+
+ snapshot.anchor_before(offset_range.start)
+ ..snapshot.anchor_after(offset_range.end)
+ });
+
+ // Highlight symbol using theme link definition highlight style
+ let style = cx.global::<Settings>().theme.editor.link_definition;
+ this.highlight_text::<LinkGoToDefinitionState>(
+ vec![highlight_range],
+ style,
+ cx,
+ );
+ } else {
+ hide_link_definition(this, cx);
}
- })?;
- }
+ }
+ })?;
Ok::<_, anyhow::Error>(())
}
@@ -247,14 +247,12 @@ impl ScrollManager {
if cx.default_global::<ScrollbarAutoHide>().0 {
self.hide_scrollbar_task = Some(cx.spawn(|editor, mut cx| async move {
cx.background().timer(SCROLLBAR_SHOW_INTERVAL).await;
- if let Some(editor) = editor.upgrade(&cx) {
- editor
- .update(&mut cx, |editor, cx| {
- editor.scroll_manager.show_scrollbars = false;
- cx.notify();
- })
- .log_err();
- }
+ editor
+ .update(&mut cx, |editor, cx| {
+ editor.scroll_manager.show_scrollbars = false;
+ cx.notify();
+ })
+ .log_err();
}));
} else {
self.hide_scrollbar_task = None;
@@ -104,9 +104,7 @@ impl<V: View> Tooltip<V> {
|view, mut cx| async move {
cx.background().timer(DEBOUNCE_TIMEOUT).await;
state.visible.set(true);
- if let Some(view) = view.upgrade(&cx) {
- view.update(&mut cx, |_, cx| cx.notify()).log_err();
- }
+ view.update(&mut cx, |_, cx| cx.notify()).log_err();
}
}));
}
@@ -162,17 +162,15 @@ impl PickerDelegate for LanguageSelectorDelegate {
.await
};
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, cx| {
- let delegate = this.delegate_mut();
- delegate.matches = matches;
- delegate.selected_index = delegate
- .selected_index
- .min(delegate.matches.len().saturating_sub(1));
- cx.notify();
- })
- .log_err();
- }
+ this.update(&mut cx, |this, cx| {
+ let delegate = this.delegate_mut();
+ delegate.matches = matches;
+ delegate.selected_index = delegate
+ .selected_index
+ .min(delegate.matches.len().saturating_sub(1));
+ cx.notify();
+ })
+ .log_err();
})
}
@@ -240,8 +240,7 @@ impl<D: PickerDelegate> Picker<D> {
self.matches_updated(cx);
self.pending_update_matches = cx.spawn(|this, mut cx| async move {
update.await;
- this.upgrade(&cx)?
- .update(&mut cx, |this, cx| this.matches_updated(cx))
+ this.update(&mut cx, |this, cx| this.matches_updated(cx))
.log_err()
});
}
@@ -1,4 +1,3 @@
-use anyhow::anyhow;
use editor::{
combine_syntax_and_fuzzy_match_highlights, scroll::autoscroll::Autoscroll,
styled_runs_for_code_label, Bias, Editor,
@@ -119,9 +118,6 @@ impl PickerDelegate for ProjectSymbolsDelegate {
let workspace = self.workspace.clone();
cx.spawn(|_, mut cx| async move {
let buffer = buffer.await?;
- let workspace = workspace
- .upgrade(&cx)
- .ok_or_else(|| anyhow!("workspace was dropped"))?;
workspace.update(&mut cx, |workspace, cx| {
let position = buffer
.read(cx)
@@ -163,34 +159,31 @@ impl PickerDelegate for ProjectSymbolsDelegate {
.update(cx, |project, cx| project.symbols(&query, cx));
cx.spawn(|this, mut cx| async move {
let symbols = symbols.await.log_err();
- if let Some(this) = this.upgrade(&cx) {
- if let Some(symbols) = symbols {
- this.update(&mut cx, |this, cx| {
- let delegate = this.delegate_mut();
- let project = delegate.project.read(cx);
- let (visible_match_candidates, external_match_candidates) = symbols
- .iter()
- .enumerate()
- .map(|(id, symbol)| {
- StringMatchCandidate::new(
- id,
- symbol.label.text[symbol.label.filter_range.clone()]
- .to_string(),
- )
- })
- .partition(|candidate| {
- project
- .entry_for_path(&symbols[candidate.id].path, cx)
- .map_or(false, |e| !e.is_ignored)
- });
-
- delegate.visible_match_candidates = visible_match_candidates;
- delegate.external_match_candidates = external_match_candidates;
- delegate.symbols = symbols;
- delegate.filter(&query, cx);
- })
- .log_err();
- }
+ if let Some(symbols) = symbols {
+ this.update(&mut cx, |this, cx| {
+ let delegate = this.delegate_mut();
+ let project = delegate.project.read(cx);
+ let (visible_match_candidates, external_match_candidates) = symbols
+ .iter()
+ .enumerate()
+ .map(|(id, symbol)| {
+ StringMatchCandidate::new(
+ id,
+ symbol.label.text[symbol.label.filter_range.clone()].to_string(),
+ )
+ })
+ .partition(|candidate| {
+ project
+ .entry_for_path(&symbols[candidate.id].path, cx)
+ .map_or(false, |e| !e.is_ignored)
+ });
+
+ delegate.visible_match_candidates = visible_match_candidates;
+ delegate.external_match_candidates = external_match_candidates;
+ delegate.symbols = symbols;
+ delegate.filter(&query, cx);
+ })
+ .log_err();
}
})
}
@@ -196,16 +196,15 @@ impl ToolbarItemView for BufferSearchBar {
if let Some(searchable_item_handle) =
item.and_then(|item| item.to_searchable_item_handle(cx))
{
- let handle = cx.weak_handle();
+ let this = cx.weak_handle();
self.active_searchable_item_subscription =
Some(searchable_item_handle.subscribe_to_search_events(
cx,
Box::new(move |search_event, cx| {
- if let Some(this) = handle.upgrade(cx) {
- this.update(cx, |this, cx| {
- this.on_active_searchable_item_event(search_event, cx)
- });
- }
+ this.update(cx, |this, cx| {
+ this.on_active_searchable_item_event(search_event, cx)
+ })
+ .log_err();
}),
));
@@ -584,34 +583,31 @@ impl BufferSearchBar {
let active_searchable_item = active_searchable_item.downgrade();
self.pending_search = Some(cx.spawn(|this, mut cx| async move {
let matches = matches.await;
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, cx| {
- if let Some(active_searchable_item) = WeakSearchableItemHandle::upgrade(
- active_searchable_item.as_ref(),
- cx,
- ) {
- this.seachable_items_with_matches
- .insert(active_searchable_item.downgrade(), matches);
-
- this.update_match_index(cx);
- if !this.dismissed {
- let matches = this
- .seachable_items_with_matches
- .get(&active_searchable_item.downgrade())
- .unwrap();
- active_searchable_item.update_matches(matches, cx);
- if select_closest_match {
- if let Some(match_ix) = this.active_match_index {
- active_searchable_item
- .activate_match(match_ix, matches, cx);
- }
+ this.update(&mut cx, |this, cx| {
+ if let Some(active_searchable_item) =
+ WeakSearchableItemHandle::upgrade(active_searchable_item.as_ref(), cx)
+ {
+ this.seachable_items_with_matches
+ .insert(active_searchable_item.downgrade(), matches);
+
+ this.update_match_index(cx);
+ if !this.dismissed {
+ let matches = this
+ .seachable_items_with_matches
+ .get(&active_searchable_item.downgrade())
+ .unwrap();
+ active_searchable_item.update_matches(matches, cx);
+ if select_closest_match {
+ if let Some(match_ix) = this.active_match_index {
+ active_searchable_item
+ .activate_match(match_ix, matches, cx);
}
}
- cx.notify();
}
- })
- .log_err();
- }
+ cx.notify();
+ }
+ })
+ .log_err();
}));
}
}
@@ -277,10 +277,8 @@ impl TerminalView {
let epoch = self.next_blink_epoch();
cx.spawn(|this, mut cx| async move {
Timer::after(CURSOR_BLINK_INTERVAL).await;
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx))
- .log_err();
- }
+ this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx))
+ .log_err();
})
.detach();
}
@@ -293,10 +291,8 @@ impl TerminalView {
let epoch = self.next_blink_epoch();
cx.spawn(|this, mut cx| async move {
Timer::after(CURSOR_BLINK_INTERVAL).await;
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx))
- .log_err();
- }
+ this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx))
+ .log_err();
})
.detach();
}
@@ -187,17 +187,15 @@ impl PickerDelegate for ThemeSelectorDelegate {
.await
};
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, cx| {
- let delegate = this.delegate_mut();
- delegate.matches = matches;
- delegate.selected_index = delegate
- .selected_index
- .min(delegate.matches.len().saturating_sub(1));
- delegate.show_selected_theme(cx);
- })
- .log_err();
- }
+ this.update(&mut cx, |this, cx| {
+ let delegate = this.delegate_mut();
+ delegate.matches = matches;
+ delegate.selected_index = delegate
+ .selected_index
+ .min(delegate.matches.len().saturating_sub(1));
+ delegate.show_selected_theme(cx);
+ })
+ .log_err();
})
}
@@ -105,16 +105,14 @@ impl PickerDelegate for BaseKeymapSelectorDelegate {
.await
};
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, _| {
- let delegate = this.delegate_mut();
- delegate.matches = matches;
- delegate.selected_index = delegate
- .selected_index
- .min(delegate.matches.len().saturating_sub(1));
- })
- .log_err();
- }
+ this.update(&mut cx, |this, _| {
+ let delegate = this.delegate_mut();
+ delegate.matches = matches;
+ delegate.selected_index = delegate
+ .selected_index
+ .min(delegate.matches.len().saturating_sub(1));
+ })
+ .log_err();
})
}
@@ -3,7 +3,7 @@ use crate::{
FollowableItemBuilders, ItemNavHistory, Pane, ToolbarItemLocation, ViewId, Workspace,
WorkspaceId,
};
-use anyhow::{anyhow, Result};
+use anyhow::Result;
use client::{proto, Client};
use gpui::{
fonts::HighlightStyle, AnyElement, AnyViewHandle, AppContext, ModelHandle, Task, View,
@@ -481,8 +481,6 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
} else {
cx.spawn(|workspace, mut cx| async move {
workspace
- .upgrade(&cx)
- .ok_or_else(|| anyhow!("workspace was dropped"))?
.update(&mut cx, |workspace, cx| {
item.git_diff_recalc(
workspace.project().clone(),
@@ -2005,9 +2005,11 @@ impl NavHistory {
}
fn did_update(&self, cx: &mut WindowContext) {
- if let Some(pane) = self.pane.upgrade(cx) {
- cx.defer(move |cx| pane.update(cx, |pane, cx| pane.history_updated(cx)));
- }
+ let pane = self.pane.clone();
+ cx.defer(move |cx| {
+ pane.update(cx, |pane, cx| pane.history_updated(cx))
+ .log_err();
+ });
}
}
@@ -6,7 +6,9 @@ use std::{
use anyhow::{Context, Result};
use async_recursion::async_recursion;
-use gpui::{platform::WindowBounds, AsyncAppContext, Axis, ModelHandle, Task, ViewHandle};
+use gpui::{
+ platform::WindowBounds, AsyncAppContext, Axis, ModelHandle, Task, ViewHandle, WeakViewHandle,
+};
use db::sqlez::{
bindable::{Bind, Column, StaticColumnCount},
@@ -97,7 +99,7 @@ impl SerializedPaneGroup {
&self,
project: &ModelHandle<Project>,
workspace_id: WorkspaceId,
- workspace: &ViewHandle<Workspace>,
+ workspace: &WeakViewHandle<Workspace>,
cx: &mut AsyncAppContext,
) -> Option<(Member, Option<ViewHandle<Pane>>)> {
match self {
@@ -172,7 +174,7 @@ impl SerializedPane {
project: &ModelHandle<Project>,
pane_handle: &ViewHandle<Pane>,
workspace_id: WorkspaceId,
- workspace: &ViewHandle<Workspace>,
+ workspace: &WeakViewHandle<Workspace>,
cx: &mut AsyncAppContext,
) -> Result<()> {
let mut active_item_index = None;
@@ -181,13 +183,7 @@ impl SerializedPane {
let item_handle = pane_handle
.update(cx, |_, cx| {
if let Some(deserializer) = cx.global::<ItemDeserializers>().get(&item.kind) {
- deserializer(
- project,
- workspace.downgrade(),
- workspace_id,
- item.item_id,
- cx,
- )
+ deserializer(project, workspace.clone(), workspace_id, item.item_id, cx)
} else {
Task::ready(Err(anyhow::anyhow!(
"Deserializer does not exist for item kind: {}",
@@ -599,13 +599,11 @@ impl DelayedDebouncedEditAction {
_ = timer => {}
}
- if let Some(workspace) = workspace.upgrade(&cx) {
- if let Some(result) = workspace
- .update(&mut cx, |workspace, cx| (f)(workspace, cx))
- .log_err()
- {
- result.await.log_err();
- }
+ if let Some(result) = workspace
+ .update(&mut cx, |workspace, cx| (f)(workspace, cx))
+ .log_err()
+ {
+ result.await.log_err();
}
}));
}
@@ -740,9 +738,7 @@ impl Workspace {
Stream::map(current_user, drop).merge(Stream::map(connection_status, drop));
while stream.recv().await.is_some() {
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |_, cx| cx.notify())?;
- }
+ this.update(&mut cx, |_, cx| cx.notify())?;
}
anyhow::Ok(())
});
@@ -754,8 +750,7 @@ impl Workspace {
mpsc::unbounded::<(PeerId, proto::UpdateFollowers)>();
let _apply_leader_updates = cx.spawn(|this, mut cx| async move {
while let Some((leader_id, update)) = leader_updates_rx.next().await {
- let Some(this) = this.upgrade(&cx) else { break };
- Self::process_leader_update(this, leader_id, update, &mut cx)
+ Self::process_leader_update(&this, leader_id, update, &mut cx)
.await
.log_err();
}
@@ -1977,30 +1972,28 @@ impl Workspace {
Some(cx.spawn(|this, mut cx| async move {
let response = request.await?;
- if let Some(this) = this.upgrade(&cx) {
- this.update(&mut cx, |this, _| {
- let state = this
- .follower_states_by_leader
- .get_mut(&leader_id)
- .and_then(|states_by_pane| states_by_pane.get_mut(&pane))
- .ok_or_else(|| anyhow!("following interrupted"))?;
- state.active_view_id = if let Some(active_view_id) = response.active_view_id {
- Some(ViewId::from_proto(active_view_id)?)
- } else {
- None
- };
- Ok::<_, anyhow::Error>(())
- })??;
- Self::add_views_from_leader(
- this.clone(),
- leader_id,
- vec![pane],
- response.views,
- &mut cx,
- )
- .await?;
- this.update(&mut cx, |this, cx| this.leader_updated(leader_id, cx))?;
- }
+ this.update(&mut cx, |this, _| {
+ let state = this
+ .follower_states_by_leader
+ .get_mut(&leader_id)
+ .and_then(|states_by_pane| states_by_pane.get_mut(&pane))
+ .ok_or_else(|| anyhow!("following interrupted"))?;
+ state.active_view_id = if let Some(active_view_id) = response.active_view_id {
+ Some(ViewId::from_proto(active_view_id)?)
+ } else {
+ None
+ };
+ Ok::<_, anyhow::Error>(())
+ })??;
+ Self::add_views_from_leader(
+ this.clone(),
+ leader_id,
+ vec![pane],
+ response.views,
+ &mut cx,
+ )
+ .await?;
+ this.update(&mut cx, |this, cx| this.leader_updated(leader_id, cx))?;
Ok(())
}))
}
@@ -2303,7 +2296,7 @@ impl Workspace {
}
async fn process_leader_update(
- this: ViewHandle<Self>,
+ this: &WeakViewHandle<Self>,
leader_id: PeerId,
update: proto::UpdateFollowers,
cx: &mut AsyncAppContext,
@@ -2363,7 +2356,7 @@ impl Workspace {
}
async fn add_views_from_leader(
- this: ViewHandle<Self>,
+ this: WeakViewHandle<Self>,
leader_id: PeerId,
panes: Vec<ViewHandle<Pane>>,
views: Vec<proto::View>,
@@ -2691,82 +2684,80 @@ impl Workspace {
cx: &mut AppContext,
) {
cx.spawn(|mut cx| async move {
- if let Some(workspace) = workspace.upgrade(&cx) {
- let (project, dock_pane_handle, old_center_pane) =
- workspace.read_with(&cx, |workspace, _| {
- (
- workspace.project().clone(),
- workspace.dock_pane().clone(),
- workspace.last_active_center_pane.clone(),
- )
- })?;
-
- serialized_workspace
- .dock_pane
- .deserialize_to(
- &project,
- &dock_pane_handle,
- serialized_workspace.id,
- &workspace,
- &mut cx,
+ let (project, dock_pane_handle, old_center_pane) =
+ workspace.read_with(&cx, |workspace, _| {
+ (
+ workspace.project().clone(),
+ workspace.dock_pane().clone(),
+ workspace.last_active_center_pane.clone(),
)
- .await?;
+ })?;
- // Traverse the splits tree and add to things
- let center_group = serialized_workspace
- .center_group
- .deserialize(&project, serialized_workspace.id, &workspace, &mut cx)
- .await;
+ serialized_workspace
+ .dock_pane
+ .deserialize_to(
+ &project,
+ &dock_pane_handle,
+ serialized_workspace.id,
+ &workspace,
+ &mut cx,
+ )
+ .await?;
- // Remove old panes from workspace panes list
- workspace.update(&mut cx, |workspace, cx| {
- if let Some((center_group, active_pane)) = center_group {
- workspace.remove_panes(workspace.center.root.clone(), cx);
+ // Traverse the splits tree and add to things
+ let center_group = serialized_workspace
+ .center_group
+ .deserialize(&project, serialized_workspace.id, &workspace, &mut cx)
+ .await;
- // Swap workspace center group
- workspace.center = PaneGroup::with_root(center_group);
+ // Remove old panes from workspace panes list
+ workspace.update(&mut cx, |workspace, cx| {
+ if let Some((center_group, active_pane)) = center_group {
+ workspace.remove_panes(workspace.center.root.clone(), cx);
- // Change the focus to the workspace first so that we retrigger focus in on the pane.
- cx.focus_self();
+ // Swap workspace center group
+ workspace.center = PaneGroup::with_root(center_group);
- if let Some(active_pane) = active_pane {
- cx.focus(&active_pane);
- } else {
- cx.focus(workspace.panes.last().unwrap());
- }
+ // Change the focus to the workspace first so that we retrigger focus in on the pane.
+ cx.focus_self();
+
+ if let Some(active_pane) = active_pane {
+ cx.focus(&active_pane);
} else {
- let old_center_handle = old_center_pane.and_then(|weak| weak.upgrade(cx));
- if let Some(old_center_handle) = old_center_handle {
- cx.focus(&old_center_handle)
- } else {
- cx.focus_self()
- }
+ cx.focus(workspace.panes.last().unwrap());
}
-
- if workspace.left_sidebar().read(cx).is_open()
- != serialized_workspace.left_sidebar_open
- {
- workspace.toggle_sidebar(SidebarSide::Left, cx);
+ } else {
+ let old_center_handle = old_center_pane.and_then(|weak| weak.upgrade(cx));
+ if let Some(old_center_handle) = old_center_handle {
+ cx.focus(&old_center_handle)
+ } else {
+ cx.focus_self()
}
+ }
- // Note that without after_window, the focus_self() and
- // the focus the dock generates start generating alternating
- // focus due to the deferred execution each triggering each other
- cx.after_window_update(move |workspace, cx| {
- Dock::set_dock_position(
- workspace,
- serialized_workspace.dock_position,
- true,
- cx,
- );
- });
+ if workspace.left_sidebar().read(cx).is_open()
+ != serialized_workspace.left_sidebar_open
+ {
+ workspace.toggle_sidebar(SidebarSide::Left, cx);
+ }
- cx.notify();
- })?;
+ // Note that without after_window, the focus_self() and
+ // the focus the dock generates start generating alternating
+ // focus due to the deferred execution each triggering each other
+ cx.after_window_update(move |workspace, cx| {
+ Dock::set_dock_position(
+ workspace,
+ serialized_workspace.dock_position,
+ true,
+ cx,
+ );
+ });
- // Serialize ourself to make sure our timestamps and any pane / item changes are replicated
- workspace.read_with(&cx, |workspace, cx| workspace.serialize_workspace(cx))?
- }
+ cx.notify();
+ })?;
+
+ // Serialize ourself to make sure our timestamps and any pane / item changes are replicated
+ workspace.read_with(&cx, |workspace, cx| workspace.serialize_workspace(cx))?;
anyhow::Ok(())
})
.detach_and_log_err(cx);
@@ -509,43 +509,43 @@ fn open_log_file(
app_state.fs.load(&paths::LOG)
);
- if let Some(workspace) = workspace.upgrade(&cx) {
- let mut lines = VecDeque::with_capacity(MAX_LINES);
- for line in old_log
- .iter()
- .flat_map(|log| log.lines())
- .chain(new_log.iter().flat_map(|log| log.lines()))
- {
- if lines.len() == MAX_LINES {
- lines.pop_front();
- }
- lines.push_back(line);
+ let mut lines = VecDeque::with_capacity(MAX_LINES);
+ for line in old_log
+ .iter()
+ .flat_map(|log| log.lines())
+ .chain(new_log.iter().flat_map(|log| log.lines()))
+ {
+ if lines.len() == MAX_LINES {
+ lines.pop_front();
}
- let log = lines
- .into_iter()
- .flat_map(|line| [line, "\n"])
- .collect::<String>();
-
- workspace
- .update(&mut cx, |workspace, cx| {
- let project = workspace.project().clone();
- let buffer = project
- .update(cx, |project, cx| project.create_buffer("", None, cx))
- .expect("creating buffers on a local workspace always succeeds");
- buffer.update(cx, |buffer, cx| buffer.edit([(0..0, log)], None, cx));
+ lines.push_back(line);
+ }
+ let log = lines
+ .into_iter()
+ .flat_map(|line| [line, "\n"])
+ .collect::<String>();
- let buffer = cx.add_model(|cx| {
- MultiBuffer::singleton(buffer, cx).with_title("Log".into())
- });
- workspace.add_item(
- Box::new(cx.add_view(|cx| {
+ workspace
+ .update(&mut cx, |workspace, cx| {
+ let project = workspace.project().clone();
+ let buffer = project
+ .update(cx, |project, cx| project.create_buffer("", None, cx))
+ .expect("creating buffers on a local workspace always succeeds");
+ buffer.update(cx, |buffer, cx| buffer.edit([(0..0, log)], None, cx));
+
+ let buffer = cx.add_model(|cx| {
+ MultiBuffer::singleton(buffer, cx).with_title("Log".into())
+ });
+ workspace.add_item(
+ Box::new(
+ cx.add_view(|cx| {
Editor::for_multibuffer(buffer, Some(project), cx)
- })),
- cx,
- );
- })
- .log_err();
- }
+ }),
+ ),
+ cx,
+ );
+ })
+ .log_err();
})
.detach();
})
@@ -559,8 +559,6 @@ fn open_telemetry_log_file(
) {
workspace.with_local_workspace(&app_state.clone(), cx, move |_, cx| {
cx.spawn(|workspace, mut cx| async move {
- let workspace = workspace.upgrade(&cx)?;
-
async fn fetch_log_string(app_state: &Arc<AppState>) -> Option<String> {
let path = app_state.client.telemetry_log_file_path()?;
app_state.fs.load(&path).await.log_err()