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