Move "async move" a few characters to the left in cx.spawn() (#26758)

This is the core change:
https://github.com/zed-industries/zed/pull/26758/files#diff-044302c0d57147af17e68a0009fee3e8dcdfb4f32c27a915e70cfa80e987f765R1052

TODO:
- [x] Use AsyncFn instead of Fn() -> Future in GPUI spawn methods
- [x] Implement it in the whole app
- [x] Implement it in the debugger 
- [x] Glance at the RPC crate, and see if those box future methods can
be switched over. Answer: It can't directly, as you can't make an
AsyncFn* into a trait object. There's ways around that, but they're all
more complex than just keeping the code as is.
- [ ] Fix platform specific code

Release Notes:

- N/A
This commit is contained in:
Mikayla Maki
2025-03-19 02:09:02 +00:00
committed by GitHub
parent 7f2e3fb5bd
commit 1aefa5178b
256 changed files with 3110 additions and 3200 deletions
+4 -4
View File
@@ -40,9 +40,9 @@ impl BlinkManager {
let epoch = self.next_blink_epoch();
let interval = self.blink_interval;
cx.spawn(|this, mut cx| async move {
cx.spawn(async move |this, cx| {
Timer::after(interval).await;
this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx))
this.update(cx, |this, cx| this.resume_cursor_blinking(epoch, cx))
})
.detach();
}
@@ -62,10 +62,10 @@ impl BlinkManager {
let epoch = self.next_blink_epoch();
let interval = self.blink_interval;
cx.spawn(|this, mut cx| async move {
cx.spawn(async move |this, cx| {
Timer::after(interval).await;
if let Some(this) = this.upgrade() {
this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx))
this.update(cx, |this, cx| this.blink_cursors(epoch, cx))
.ok();
}
})
+2 -2
View File
@@ -51,7 +51,7 @@ pub fn switch_source_header(
cx,
)
});
cx.spawn_in(window, |_editor, mut cx| async move {
cx.spawn_in(window, async move |_editor, cx| {
let switch_source_header = switch_source_header_task
.await
.with_context(|| format!("Switch source/header LSP request for path \"{source_file}\" failed"))?;
@@ -72,7 +72,7 @@ pub fn switch_source_header(
})?;
workspace
.update_in(&mut cx, |workspace, window, cx| {
.update_in(cx, |workspace, window, cx| {
workspace.open_abs_path(path, OpenOptions { visible: Some(OpenVisible::None), ..Default::default() }, window, cx)
})
.with_context(|| {
+2 -2
View File
@@ -416,9 +416,9 @@ impl CompletionsMenu {
cx,
);
cx.spawn(move |editor, mut cx| async move {
cx.spawn(async move |editor, cx| {
if let Some(true) = resolve_task.await.log_err() {
editor.update(&mut cx, |_, cx| cx.notify()).ok();
editor.update(cx, |_, cx| cx.notify()).ok();
}
})
.detach();
+4 -4
View File
@@ -198,9 +198,9 @@ impl WrapMap {
self.edits_since_sync = self.edits_since_sync.compose(&edits);
}
Err(wrap_task) => {
self.background_task = Some(cx.spawn(|this, mut cx| async move {
self.background_task = Some(cx.spawn(async move |this, cx| {
let (snapshot, edits) = wrap_task.await;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.snapshot = snapshot;
this.edits_since_sync = this
.edits_since_sync
@@ -276,9 +276,9 @@ impl WrapMap {
self.edits_since_sync = self.edits_since_sync.compose(&output_edits);
}
Err(update_task) => {
self.background_task = Some(cx.spawn(|this, mut cx| async move {
self.background_task = Some(cx.spawn(async move |this, cx| {
let (snapshot, edits) = update_task.await;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.snapshot = snapshot;
this.edits_since_sync = this
.edits_since_sync
+142 -153
View File
@@ -185,7 +185,7 @@ use ui::{
h_flex, prelude::*, ButtonSize, ButtonStyle, Disclosure, IconButton, IconName, IconSize, Key,
Tooltip,
};
use util::{defer, maybe, post_inc, RangeExt, ResultExt, TryFutureExt};
use util::{maybe, post_inc, RangeExt, ResultExt, TryFutureExt};
use workspace::{
item::{ItemHandle, PreviewTabsSettings},
ItemId, RestoreOnStartupBehavior,
@@ -1715,9 +1715,9 @@ impl Editor {
let project = workspace.project().clone();
let create = project.update(cx, |project, cx| project.create_buffer(cx));
cx.spawn_in(window, |workspace, mut cx| async move {
cx.spawn_in(window, async move |workspace, cx| {
let buffer = create.await?;
workspace.update_in(&mut cx, |workspace, window, cx| {
workspace.update_in(cx, |workspace, window, cx| {
let editor =
cx.new(|cx| Editor::for_buffer(buffer, Some(project.clone()), window, cx));
workspace.add_item_to_active_pane(Box::new(editor.clone()), None, true, window, cx);
@@ -1753,9 +1753,9 @@ impl Editor {
let project = workspace.project().clone();
let create = project.update(cx, |project, cx| project.create_buffer(cx));
cx.spawn_in(window, |workspace, mut cx| async move {
cx.spawn_in(window, async move |workspace, cx| {
let buffer = create.await?;
workspace.update_in(&mut cx, move |workspace, window, cx| {
workspace.update_in(cx, move |workspace, window, cx| {
workspace.split_item(
direction,
Box::new(
@@ -2184,12 +2184,12 @@ impl Editor {
drop(context_menu);
let query = Self::completion_query(buffer, cursor_position);
cx.spawn(move |this, mut cx| async move {
cx.spawn(async move |this, cx| {
completion_menu
.filter(query.as_deref(), cx.background_executor().clone())
.await;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
let mut context_menu = this.context_menu.borrow_mut();
let Some(CodeContextMenu::Completions(menu)) = context_menu.as_ref()
else {
@@ -4050,16 +4050,16 @@ impl Editor {
cx,
)
});
Some(cx.spawn_in(window, |editor, mut cx| async move {
Some(cx.spawn_in(window, async move |editor, cx| {
if let Some(transaction) = on_type_formatting.await? {
if push_to_client_history {
buffer
.update(&mut cx, |buffer, _| {
.update(cx, |buffer, _| {
buffer.push_transaction(transaction, Instant::now());
})
.ok();
}
editor.update(&mut cx, |editor, cx| {
editor.update(cx, |editor, cx| {
editor.refresh_document_highlights(cx);
})?;
}
@@ -4215,9 +4215,9 @@ impl Editor {
.map_or(true, |provider| provider.sort_completions());
let id = post_inc(&mut self.next_completion_id);
let task = cx.spawn_in(window, |editor, mut cx| {
let task = cx.spawn_in(window, async move |editor, cx| {
async move {
editor.update(&mut cx, |this, _| {
editor.update(cx, |this, _| {
this.completion_tasks.retain(|(task_id, _)| *task_id >= id);
})?;
@@ -4267,7 +4267,7 @@ impl Editor {
menu.visible().then_some(menu)
};
editor.update_in(&mut cx, |editor, window, cx| {
editor.update_in(cx, |editor, window, cx| {
match editor.context_menu.borrow().as_ref() {
None => {}
Some(CodeContextMenu::Completions(prev_menu)) => {
@@ -4308,6 +4308,7 @@ impl Editor {
anyhow::Ok(())
}
.log_err()
.await
});
self.completion_tasks.push((id, task));
@@ -4550,13 +4551,13 @@ impl Editor {
let deployed_from_indicator = action.deployed_from_indicator;
let mut task = self.code_actions_task.take();
let action = action.clone();
cx.spawn_in(window, |editor, mut cx| async move {
cx.spawn_in(window, async move |editor, cx| {
while let Some(prev_task) = task {
prev_task.await.log_err();
task = editor.update(&mut cx, |this, _| this.code_actions_task.take())?;
task = editor.update(cx, |this, _| this.code_actions_task.take())?;
}
let spawned_test_task = editor.update_in(&mut cx, |editor, window, cx| {
let spawned_test_task = editor.update_in(cx, |editor, window, cx| {
if editor.focus_handle.is_focused(window) {
let multibuffer_point = action
.deployed_from_indicator
@@ -4605,7 +4606,7 @@ impl Editor {
Self::build_tasks_context(&project, &buffer, buffer_row, tasks, cx)
});
Some(cx.spawn_in(window, |editor, mut cx| async move {
Some(cx.spawn_in(window, async move |editor, cx| {
let task_context = match task_context {
Some(task_context) => task_context.await,
None => None,
@@ -4626,7 +4627,7 @@ impl Editor {
&& code_actions
.as_ref()
.map_or(true, |actions| actions.is_empty());
if let Ok(task) = editor.update_in(&mut cx, |editor, window, cx| {
if let Ok(task) = editor.update_in(cx, |editor, window, cx| {
*editor.context_menu.borrow_mut() =
Some(CodeContextMenu::CodeActions(CodeActionsMenu {
buffer,
@@ -4709,7 +4710,7 @@ impl Editor {
let apply_code_action =
provider.apply_code_action(buffer, action, excerpt_id, true, window, cx);
let workspace = workspace.downgrade();
Some(cx.spawn_in(window, |editor, cx| async move {
Some(cx.spawn_in(window, async move |editor, cx| {
let project_transaction = apply_code_action.await?;
Self::open_project_transaction(
&editor,
@@ -4729,7 +4730,7 @@ impl Editor {
workspace: WeakEntity<Workspace>,
transaction: ProjectTransaction,
title: String,
mut cx: AsyncWindowContext,
cx: &mut AsyncWindowContext,
) -> Result<()> {
let mut entries = transaction.0.into_iter().collect::<Vec<_>>();
cx.update(|_, cx| {
@@ -4743,7 +4744,7 @@ impl Editor {
if let Some((buffer, transaction)) = entries.first() {
if entries.len() == 1 {
let excerpt = this.update(&mut cx, |editor, cx| {
let excerpt = this.update(cx, |editor, cx| {
editor
.buffer()
.read(cx)
@@ -4751,7 +4752,7 @@ impl Editor {
})?;
if let Some((_, excerpted_buffer, excerpt_range)) = excerpt {
if excerpted_buffer == *buffer {
let all_edits_within_excerpt = buffer.read_with(&cx, |buffer, _| {
let all_edits_within_excerpt = buffer.read_with(cx, |buffer, _| {
let excerpt_range = excerpt_range.to_offset(buffer);
buffer
.edited_ranges_for_transaction::<usize>(transaction)
@@ -4791,7 +4792,7 @@ impl Editor {
multibuffer
})?;
workspace.update_in(&mut cx, |workspace, window, cx| {
workspace.update_in(cx, |workspace, window, cx| {
let project = workspace.project().clone();
let editor =
cx.new(|cx| Editor::for_multibuffer(excerpt_buffer, Some(project), window, cx));
@@ -4854,12 +4855,12 @@ impl Editor {
return None;
}
self.code_actions_task = Some(cx.spawn_in(window, |this, mut cx| async move {
self.code_actions_task = Some(cx.spawn_in(window, async move |this, cx| {
cx.background_executor()
.timer(CODE_ACTIONS_DEBOUNCE_TIMEOUT)
.await;
let (providers, tasks) = this.update_in(&mut cx, |this, window, cx| {
let (providers, tasks) = this.update_in(cx, |this, window, cx| {
let providers = this.code_action_providers.clone();
let tasks = this
.code_action_providers
@@ -4884,7 +4885,7 @@ impl Editor {
}
}
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.available_code_actions = if actions.is_empty() {
None
} else {
@@ -4907,10 +4908,10 @@ impl Editor {
self.show_git_blame_inline = false;
self.show_git_blame_inline_delay_task =
Some(cx.spawn_in(window, |this, mut cx| async move {
Some(cx.spawn_in(window, async move |this, cx| {
cx.background_executor().timer(delay).await;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.show_git_blame_inline = true;
cx.notify();
})
@@ -4935,7 +4936,7 @@ impl Editor {
return None;
}
let debounce = EditorSettings::get_global(cx).lsp_highlight_debounce;
self.document_highlights_task = Some(cx.spawn(|this, mut cx| async move {
self.document_highlights_task = Some(cx.spawn(async move |this, cx| {
cx.background_executor()
.timer(Duration::from_millis(debounce))
.await;
@@ -4953,7 +4954,7 @@ impl Editor {
};
if let Some(highlights) = highlights {
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
if this.pending_rename.is_some() {
return;
}
@@ -5046,12 +5047,12 @@ impl Editor {
return;
}
let debounce = EditorSettings::get_global(cx).selection_highlight_debounce;
self.selection_highlight_task = Some(cx.spawn_in(window, |editor, mut cx| async move {
self.selection_highlight_task = Some(cx.spawn_in(window, async move |editor, cx| {
cx.background_executor()
.timer(Duration::from_millis(debounce))
.await;
let Some(Some(matches_task)) = editor
.update_in(&mut cx, |editor, _, cx| {
.update_in(cx, |editor, _, cx| {
if editor.selections.count() != 1 || editor.selections.line_mode {
editor.clear_background_highlights::<SelectedTextHighlight>(cx);
return None;
@@ -5116,7 +5117,7 @@ impl Editor {
};
let matches = matches_task.await;
editor
.update_in(&mut cx, |editor, _, cx| {
.update_in(cx, |editor, _, cx| {
editor.clear_background_highlights::<SelectedTextHighlight>(cx);
if !matches.is_empty() {
editor.highlight_background::<SelectedTextHighlight>(
@@ -5342,9 +5343,9 @@ impl Editor {
fn show_cursor_names(&mut self, window: &mut Window, cx: &mut Context<Self>) {
self.show_cursor_names = true;
cx.notify();
cx.spawn_in(window, |this, mut cx| async move {
cx.spawn_in(window, async move |this, cx| {
cx.background_executor().timer(CURSORS_VISIBLE_FOR).await;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.show_cursor_names = false;
cx.notify()
})
@@ -6230,7 +6231,7 @@ impl Editor {
let reveal_strategy = action.reveal;
let task_context = Self::build_tasks_context(&project, &buffer, buffer_row, &tasks, cx);
cx.spawn_in(window, |_, mut cx| async move {
cx.spawn_in(window, async move |_, cx| {
let context = task_context.await?;
let (task_source_kind, mut resolved_task) = tasks.resolve(&context).next()?;
@@ -6238,7 +6239,7 @@ impl Editor {
resolved.reveal = reveal_strategy;
workspace
.update(&mut cx, |workspace, cx| {
.update(cx, |workspace, cx| {
workspace::tasks::schedule_resolved_task(
workspace,
task_source_kind,
@@ -11806,19 +11807,19 @@ impl Editor {
return Task::ready(());
}
let project = self.project.as_ref().map(Entity::downgrade);
cx.spawn_in(window, |this, mut cx| async move {
cx.spawn_in(window, async move |this, cx| {
cx.background_executor().timer(UPDATE_DEBOUNCE).await;
let Some(project) = project.and_then(|p| p.upgrade()) else {
return;
};
let Ok(display_snapshot) = this.update(&mut cx, |this, cx| {
let Ok(display_snapshot) = this.update(cx, |this, cx| {
this.display_map.update(cx, |map, cx| map.snapshot(cx))
}) else {
return;
};
let hide_runnables = project
.update(&mut cx, |project, cx| {
.update(cx, |project, cx| {
// Do not display any test indicators in non-dev server remote projects.
project.is_via_collab() && project.ssh_connection_string(cx).is_none()
})
@@ -11836,7 +11837,7 @@ impl Editor {
.await;
let rows = Self::runnable_rows(project, display_snapshot, new_rows, cx.clone());
this.update(&mut cx, |this, _| {
this.update(cx, |this, _| {
this.clear_tasks();
for (key, value) in rows {
this.insert_tasks(key, value);
@@ -12425,11 +12426,11 @@ impl Editor {
) -> Task<Result<Navigated>> {
let definition =
self.go_to_definition_of_kind(GotoDefinitionKind::Symbol, false, window, cx);
cx.spawn_in(window, |editor, mut cx| async move {
cx.spawn_in(window, async move |editor, cx| {
if definition.await? == Navigated::Yes {
return Ok(Navigated::Yes);
}
match editor.update_in(&mut cx, |editor, window, cx| {
match editor.update_in(cx, |editor, window, cx| {
editor.find_all_references(&FindAllReferences, window, cx)
})? {
Some(references) => references.await,
@@ -12523,10 +12524,10 @@ impl Editor {
return Task::ready(Ok(Navigated::No));
};
cx.spawn_in(window, |editor, mut cx| async move {
cx.spawn_in(window, async move |editor, cx| {
let definitions = definitions.await?;
let navigated = editor
.update_in(&mut cx, |editor, window, cx| {
.update_in(cx, |editor, window, cx| {
editor.navigate_to_hover_links(
Some(kind),
definitions
@@ -12566,7 +12567,7 @@ impl Editor {
None
};
let url_finder = cx.spawn_in(window, |editor, mut cx| async move {
let url_finder = cx.spawn_in(window, async move |editor, cx| {
let url = if let Some(end_pos) = end_position {
find_url_from_range(&buffer, start_position..end_pos, cx.clone())
} else {
@@ -12574,7 +12575,7 @@ impl Editor {
};
if let Some(url) = url {
editor.update(&mut cx, |_, cx| {
editor.update(cx, |_, cx| {
cx.open_url(&url);
})
} else {
@@ -12605,12 +12606,12 @@ impl Editor {
let project = self.project.clone();
cx.spawn_in(window, |_, mut cx| async move {
let result = find_file(&buffer, project, buffer_position, &mut cx).await;
cx.spawn_in(window, async move |_, cx| {
let result = find_file(&buffer, project, buffer_position, cx).await;
if let Some((_, path)) = result {
workspace
.update_in(&mut cx, |workspace, window, cx| {
.update_in(cx, |workspace, window, cx| {
workspace.open_resolved_path(path, window, cx)
})?
.await?;
@@ -12655,9 +12656,9 @@ impl Editor {
}
HoverLink::File(path) => {
if let Some(workspace) = self.workspace() {
cx.spawn_in(window, |_, mut cx| async move {
cx.spawn_in(window, async move |_, cx| {
workspace
.update_in(&mut cx, |workspace, window, cx| {
.update_in(cx, |workspace, window, cx| {
workspace.open_resolved_path(path, window, cx)
})?
.await
@@ -12668,14 +12669,14 @@ impl Editor {
}
}
};
cx.spawn_in(window, |editor, mut cx| async move {
cx.spawn_in(window, async move |editor, cx| {
let target = match target_task.await.context("target resolution task")? {
TargetTaskResult::AlreadyNavigated => return Ok(Navigated::Yes),
TargetTaskResult::Location(None) => return Ok(Navigated::No),
TargetTaskResult::Location(Some(target)) => target,
};
editor.update_in(&mut cx, |editor, window, cx| {
editor.update_in(cx, |editor, window, cx| {
let Some(workspace) = editor.workspace() else {
return Navigated::No;
};
@@ -12721,9 +12722,9 @@ impl Editor {
})
})
} else if !definitions.is_empty() {
cx.spawn_in(window, |editor, mut cx| async move {
cx.spawn_in(window, async move |editor, cx| {
let (title, location_tasks, workspace) = editor
.update_in(&mut cx, |editor, window, cx| {
.update_in(cx, |editor, window, cx| {
let tab_kind = match kind {
Some(GotoDefinitionKind::Implementation) => "Implementations",
_ => "Definitions",
@@ -12771,7 +12772,7 @@ impl Editor {
return Ok(Navigated::No);
};
let opened = workspace
.update_in(&mut cx, |workspace, window, cx| {
.update_in(cx, |workspace, window, cx| {
Self::open_locations_in_multibuffer(
workspace,
locations,
@@ -12802,8 +12803,8 @@ impl Editor {
return Task::ready(Ok(None));
};
cx.spawn_in(window, move |editor, mut cx| async move {
let location_task = editor.update(&mut cx, |_, cx| {
cx.spawn_in(window, async move |editor, cx| {
let location_task = editor.update(cx, |_, cx| {
project.update(cx, |project, cx| {
let language_server_name = project
.language_server_statuses(cx)
@@ -12822,7 +12823,7 @@ impl Editor {
let location = match location_task {
Some(task) => Some({
let target_buffer_handle = task.await.context("open local buffer")?;
let range = target_buffer_handle.update(&mut cx, |target_buffer, _| {
let range = target_buffer_handle.update(cx, |target_buffer, _| {
let target_start = target_buffer
.clip_point_utf16(point_from_lsp(lsp_location.range.start), Bias::Left);
let target_end = target_buffer
@@ -12880,21 +12881,13 @@ impl Editor {
let workspace = self.workspace()?;
let project = workspace.read(cx).project().clone();
let references = project.update(cx, |project, cx| project.references(&buffer, head, cx));
Some(cx.spawn_in(window, |editor, mut cx| async move {
let _cleanup = defer({
let mut cx = cx.clone();
move || {
let _ = editor.update(&mut cx, |editor, _| {
if let Ok(i) =
editor
.find_all_references_task_sources
.binary_search_by(|anchor| {
anchor.cmp(&head_anchor, &multi_buffer_snapshot)
})
{
editor.find_all_references_task_sources.remove(i);
}
});
Some(cx.spawn_in(window, async move |editor, cx| {
let _cleanup = cx.on_drop(&editor, move |editor, _| {
if let Ok(i) = editor
.find_all_references_task_sources
.binary_search_by(|anchor| anchor.cmp(&head_anchor, &multi_buffer_snapshot))
{
editor.find_all_references_task_sources.remove(i);
}
});
@@ -12903,7 +12896,7 @@ impl Editor {
return anyhow::Ok(Navigated::No);
}
workspace.update_in(&mut cx, |workspace, window, cx| {
workspace.update_in(cx, |workspace, window, cx| {
let title = locations
.first()
.as_ref()
@@ -13067,11 +13060,11 @@ impl Editor {
.unwrap_or_else(|| Task::ready(Ok(None)));
drop(snapshot);
Some(cx.spawn_in(window, |this, mut cx| async move {
Some(cx.spawn_in(window, async move |this, cx| {
let rename_range = if let Some(range) = prepare_rename.await? {
Some(range)
} else {
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
let buffer = this.buffer.read(cx).snapshot(cx);
let mut buffer_highlights = this
.document_highlights_for_position(selection.head(), &buffer)
@@ -13085,7 +13078,7 @@ impl Editor {
})?
};
if let Some(rename_range) = rename_range {
this.update_in(&mut cx, |this, window, cx| {
this.update_in(cx, |this, window, cx| {
let snapshot = cursor_buffer.read(cx).snapshot();
let rename_buffer_range = rename_range.to_offset(&snapshot);
let cursor_offset_in_rename_range =
@@ -13258,18 +13251,18 @@ impl Editor {
cx,
)?;
Some(cx.spawn_in(window, |editor, mut cx| async move {
Some(cx.spawn_in(window, async move |editor, cx| {
let project_transaction = rename.await?;
Self::open_project_transaction(
&editor,
workspace,
project_transaction,
format!("Rename: {} → {}", old_name, new_name),
cx.clone(),
cx,
)
.await?;
editor.update(&mut cx, |editor, cx| {
editor.update(cx, |editor, cx| {
editor.refresh_document_highlights(cx);
})?;
Ok(())
@@ -13416,7 +13409,7 @@ impl Editor {
project.format(buffers, target, true, trigger, cx)
});
cx.spawn_in(window, |_, mut cx| async move {
cx.spawn_in(window, async move |_, cx| {
let transaction = futures::select_biased! {
transaction = format.log_err().fuse() => transaction,
() = timeout => {
@@ -13426,7 +13419,7 @@ impl Editor {
};
buffer
.update(&mut cx, |buffer, cx| {
.update(cx, |buffer, cx| {
if let Some(transaction) = transaction {
if !buffer.is_singleton() {
buffer.push_transaction(&transaction.0, cx);
@@ -13471,7 +13464,7 @@ impl Editor {
let apply_action = project.update(cx, |project, cx| {
project.apply_code_action_kind(buffers, kind, true, cx)
});
cx.spawn_in(window, |_, mut cx| async move {
cx.spawn_in(window, async move |_, cx| {
let transaction = futures::select_biased! {
() = timeout => {
log::warn!("timed out waiting for executing code action");
@@ -13480,7 +13473,7 @@ impl Editor {
transaction = apply_action.log_err().fuse() => transaction,
};
buffer
.update(&mut cx, |buffer, cx| {
.update(cx, |buffer, cx| {
// check if we need this
if let Some(transaction) = transaction {
if !buffer.is_singleton() {
@@ -13695,12 +13688,12 @@ impl Editor {
} else {
None
};
self.inline_diagnostics_update = cx.spawn_in(window, |editor, mut cx| async move {
self.inline_diagnostics_update = cx.spawn_in(window, async move |editor, cx| {
if let Some(debounce) = debounce {
cx.background_executor().timer(debounce).await;
}
let Some(snapshot) = editor
.update(&mut cx, |editor, cx| editor.buffer().read(cx).snapshot(cx))
.update(cx, |editor, cx| editor.buffer().read(cx).snapshot(cx))
.ok()
else {
return;
@@ -13741,7 +13734,7 @@ impl Editor {
.await;
editor
.update(&mut cx, |editor, cx| {
.update(cx, |editor, cx| {
editor.inline_diagnostics = new_inline_diagnostics;
cx.notify();
})
@@ -14042,9 +14035,9 @@ impl Editor {
self.fold_creases(fold_ranges, true, window, cx);
} else {
self.toggle_fold_multiple_buffers = cx.spawn_in(window, |editor, mut cx| async move {
self.toggle_fold_multiple_buffers = cx.spawn_in(window, async move |editor, cx| {
editor
.update_in(&mut cx, |editor, _, cx| {
.update_in(cx, |editor, _, cx| {
for buffer_id in editor.buffer.read(cx).excerpt_buffer_ids() {
editor.fold_buffer(buffer_id, cx);
}
@@ -14218,9 +14211,9 @@ impl Editor {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
self.unfold_ranges(&[0..display_map.buffer_snapshot.len()], true, true, cx);
} else {
self.toggle_fold_multiple_buffers = cx.spawn(|editor, mut cx| async move {
self.toggle_fold_multiple_buffers = cx.spawn(async move |editor, cx| {
editor
.update(&mut cx, |editor, cx| {
.update(cx, |editor, cx| {
for buffer_id in editor.buffer.read(cx).excerpt_buffer_ids() {
editor.unfold_buffer(buffer_id, cx);
}
@@ -14507,9 +14500,9 @@ impl Editor {
cx: &mut Context<Self>,
) {
let task = self.save_buffers_for_ranges_if_needed(&ranges, cx);
cx.spawn(|this, mut cx| async move {
cx.spawn(async move |this, cx| {
task.await?;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
let snapshot = this.buffer.read(cx).snapshot(cx);
let chunk_by = this
.diff_hunks_in_ranges(&ranges, &snapshot)
@@ -15463,34 +15456,32 @@ impl Editor {
let permalink_task = self.get_permalink_to_line(cx);
let workspace = self.workspace();
cx.spawn_in(window, |_, mut cx| async move {
match permalink_task.await {
Ok(permalink) => {
cx.update(|_, cx| {
cx.write_to_clipboard(ClipboardItem::new_string(permalink.to_string()));
})
.ok();
}
Err(err) => {
let message = format!("Failed to copy permalink: {err}");
cx.spawn_in(window, async move |_, cx| match permalink_task.await {
Ok(permalink) => {
cx.update(|_, cx| {
cx.write_to_clipboard(ClipboardItem::new_string(permalink.to_string()));
})
.ok();
}
Err(err) => {
let message = format!("Failed to copy permalink: {err}");
Err::<(), anyhow::Error>(err).log_err();
Err::<(), anyhow::Error>(err).log_err();
if let Some(workspace) = workspace {
workspace
.update_in(&mut cx, |workspace, _, cx| {
struct CopyPermalinkToLine;
if let Some(workspace) = workspace {
workspace
.update_in(cx, |workspace, _, cx| {
struct CopyPermalinkToLine;
workspace.show_toast(
Toast::new(
NotificationId::unique::<CopyPermalinkToLine>(),
message,
),
cx,
)
})
.ok();
}
workspace.show_toast(
Toast::new(
NotificationId::unique::<CopyPermalinkToLine>(),
message,
),
cx,
)
})
.ok();
}
}
})
@@ -15520,34 +15511,32 @@ impl Editor {
let permalink_task = self.get_permalink_to_line(cx);
let workspace = self.workspace();
cx.spawn_in(window, |_, mut cx| async move {
match permalink_task.await {
Ok(permalink) => {
cx.update(|_, cx| {
cx.open_url(permalink.as_ref());
})
.ok();
}
Err(err) => {
let message = format!("Failed to open permalink: {err}");
cx.spawn_in(window, async move |_, cx| match permalink_task.await {
Ok(permalink) => {
cx.update(|_, cx| {
cx.open_url(permalink.as_ref());
})
.ok();
}
Err(err) => {
let message = format!("Failed to open permalink: {err}");
Err::<(), anyhow::Error>(err).log_err();
Err::<(), anyhow::Error>(err).log_err();
if let Some(workspace) = workspace {
workspace
.update(&mut cx, |workspace, cx| {
struct OpenPermalinkToLine;
if let Some(workspace) = workspace {
workspace
.update(cx, |workspace, cx| {
struct OpenPermalinkToLine;
workspace.show_toast(
Toast::new(
NotificationId::unique::<OpenPermalinkToLine>(),
message,
),
cx,
)
})
.ok();
}
workspace.show_toast(
Toast::new(
NotificationId::unique::<OpenPermalinkToLine>(),
message,
),
cx,
)
})
.ok();
}
}
})
@@ -15619,8 +15608,8 @@ impl Editor {
let title = multibuffer.title(cx).to_string();
cx.spawn_in(window, |_, mut cx| async move {
workspace.update_in(&mut cx, |workspace, window, cx| {
cx.spawn_in(window, async move |_, cx| {
workspace.update_in(cx, |workspace, window, cx| {
Self::open_locations_in_multibuffer(
workspace,
locations,
@@ -17008,12 +16997,12 @@ impl Editor {
}
tasks
});
cx.spawn_in(window, |_, mut cx| async move {
cx.spawn_in(window, async move |_, cx| {
for (buffer, task) in save_tasks {
let result = task.await;
if result.is_err() {
let Some(path) = buffer
.read_with(&cx, |buffer, cx| buffer.project_path(cx))
.read_with(cx, |buffer, cx| buffer.project_path(cx))
.ok()
else {
continue;
@@ -17212,10 +17201,10 @@ fn get_uncommitted_diff_for_buffer(
tasks.push(project.open_uncommitted_diff(buffer.clone(), cx))
}
});
cx.spawn(|mut cx| async move {
cx.spawn(async move |cx| {
let diffs = future::join_all(tasks).await;
buffer
.update(&mut cx, |buffer, cx| {
.update(cx, |buffer, cx| {
for diff in diffs.into_iter().flatten() {
buffer.add_diff(diff, cx);
}
@@ -18069,13 +18058,13 @@ impl SemanticsProvider for Entity<Project> {
Some(self.update(cx, |project, cx| {
let buffer = buffer.clone();
let task = project.prepare_rename(buffer.clone(), position, cx);
cx.spawn(|_, mut cx| async move {
cx.spawn(async move |_, cx| {
Ok(match task.await? {
PrepareRenameResponse::Success(range) => Some(range),
PrepareRenameResponse::InvalidPosition => None,
PrepareRenameResponse::OnlyUnpreparedRenameSupported => {
// Fallback on using TreeSitter info to determine identifier range
buffer.update(&mut cx, |buffer, _| {
buffer.update(cx, |buffer, _| {
let snapshot = buffer.snapshot();
let (range, kind) = snapshot.surrounding_word(position);
if kind != Some(CharKind::Word) {
+1
View File
@@ -9312,6 +9312,7 @@ async fn test_word_completion(cx: &mut TestAppContext) {
.server
.on_request::<lsp::request::Completion, _, _>(move |_, cx| {
let lsp_throttle_completions = lsp_throttle_completions.clone();
let cx = cx.clone();
async move {
if lsp_throttle_completions.load(atomic::Ordering::Acquire) {
cx.background_executor()
+4 -4
View File
@@ -973,10 +973,10 @@ impl EditorElement {
};
editor.hovered_cursors.insert(
key.clone(),
cx.spawn_in(window, |editor, mut cx| async move {
cx.spawn_in(window, async move |editor, cx| {
cx.background_executor().timer(CURSORS_VISIBLE_FOR).await;
editor
.update(&mut cx, |editor, cx| {
.update(cx, |editor, cx| {
editor.hovered_cursors.remove(&key);
cx.notify();
})
@@ -5199,7 +5199,7 @@ impl EditorElement {
editor.scrollbar_marker_state.dirty = false;
editor.scrollbar_marker_state.pending_refresh =
Some(cx.spawn_in(window, |editor, mut cx| async move {
Some(cx.spawn_in(window, async move |editor, cx| {
let scrollbar_size = scrollbar_layout.hitbox.size;
let scrollbar_markers = cx
.background_spawn(async move {
@@ -5346,7 +5346,7 @@ impl EditorElement {
})
.await;
editor.update(&mut cx, |editor, cx| {
editor.update(cx, |editor, cx| {
editor.scrollbar_marker_state.markers = scrollbar_markers;
editor.scrollbar_marker_state.scrollbar_size = scrollbar_size;
editor.scrollbar_marker_state.pending_refresh = None;
+4 -4
View File
@@ -363,7 +363,7 @@ impl GitBlame {
let blame = self.project.read(cx).blame_buffer(&self.buffer, None, cx);
let provider_registry = GitHostingProviderRegistry::default_global(cx);
self.task = cx.spawn(|this, mut cx| async move {
self.task = cx.spawn(async move |this, cx| {
let result = cx
.background_spawn({
let snapshot = snapshot.clone();
@@ -386,7 +386,7 @@ impl GitBlame {
})
.await;
this.update(&mut cx, |this, cx| match result {
this.update(cx, |this, cx| match result {
Ok(None) => {
// Nothing to do, e.g. no repository found
}
@@ -417,12 +417,12 @@ impl GitBlame {
}
fn regenerate_on_edit(&mut self, cx: &mut Context<Self>) {
self.regenerate_on_edit_task = cx.spawn(|this, mut cx| async move {
self.regenerate_on_edit_task = cx.spawn(async move |this, cx| {
cx.background_executor()
.timer(REGENERATE_ON_EDIT_DEBOUNCE_INTERVAL)
.await;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.generate(cx);
})
})
+7 -6
View File
@@ -167,10 +167,10 @@ impl Editor {
cx: &mut Context<Editor>,
) {
let reveal_task = self.cmd_click_reveal_task(point, modifiers, window, cx);
cx.spawn_in(window, |editor, mut cx| async move {
cx.spawn_in(window, async move |editor, cx| {
let definition_revealed = reveal_task.await.log_err().unwrap_or(Navigated::No);
let find_references = editor
.update_in(&mut cx, |editor, window, cx| {
.update_in(cx, |editor, window, cx| {
if definition_revealed == Navigated::Yes {
return None;
}
@@ -529,12 +529,12 @@ pub fn show_link_definition(
let provider = editor.semantics_provider.clone();
let snapshot = snapshot.buffer_snapshot.clone();
hovered_link_state.task = Some(cx.spawn_in(window, |this, mut cx| {
hovered_link_state.task = Some(cx.spawn_in(window, async move |this, cx| {
async move {
let result = match &trigger_point {
TriggerPoint::Text(_) => {
if let Some((url_range, url)) = find_url(&buffer, buffer_position, cx.clone()) {
this.update(&mut cx, |_, _| {
this.update(cx, |_, _| {
let range = maybe!({
let start =
snapshot.anchor_in_excerpt(excerpt_id, url_range.start)?;
@@ -545,7 +545,7 @@ pub fn show_link_definition(
})
.ok()
} else if let Some((filename_range, filename)) =
find_file(&buffer, project.clone(), buffer_position, &mut cx).await
find_file(&buffer, project.clone(), buffer_position, cx).await
{
let range = maybe!({
let start =
@@ -589,7 +589,7 @@ pub fn show_link_definition(
)),
};
this.update(&mut cx, |editor, cx| {
this.update(cx, |editor, cx| {
// Clear any existing highlights
editor.clear_highlights::<HoveredLinkState>(cx);
let Some(hovered_link_state) = editor.hovered_link_state.as_mut() else {
@@ -647,6 +647,7 @@ pub fn show_link_definition(
Ok::<_, anyhow::Error>(())
}
.log_err()
.await
}));
editor.hovered_link_state = Some(hovered_link_state);
+15 -14
View File
@@ -149,18 +149,18 @@ pub fn hover_at_inlay(
let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay;
let task = cx.spawn_in(window, |this, mut cx| {
let task = cx.spawn_in(window, async move |this, cx| {
async move {
cx.background_executor()
.timer(Duration::from_millis(hover_popover_delay))
.await;
this.update(&mut cx, |this, _| {
this.update(cx, |this, _| {
this.hover_state.diagnostic_popover = None;
})?;
let language_registry = project.update(&mut cx, |p, _| p.languages().clone())?;
let language_registry = project.update(cx, |p, _| p.languages().clone())?;
let blocks = vec![inlay_hover.tooltip];
let parsed_content = parse_blocks(&blocks, &language_registry, None, &mut cx).await;
let parsed_content = parse_blocks(&blocks, &language_registry, None, cx).await;
let scroll_handle = ScrollHandle::new();
let hover_popover = InfoPopover {
@@ -172,7 +172,7 @@ pub fn hover_at_inlay(
anchor: None,
};
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
// TODO: no background highlights happen for inlays currently
this.hover_state.info_popovers = vec![hover_popover];
cx.notify();
@@ -181,6 +181,7 @@ pub fn hover_at_inlay(
anyhow::Ok(())
}
.log_err()
.await
});
editor.hover_state.info_task = Some(task);
@@ -257,7 +258,7 @@ fn show_hover(
let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay;
let task = cx.spawn_in(window, |this, mut cx| {
let task = cx.spawn_in(window, async move |this, cx| {
async move {
// If we need to delay, delay a set amount initially before making the lsp request
let delay = if ignore_timeout {
@@ -375,7 +376,7 @@ fn show_hover(
None
};
this.update(&mut cx, |this, _| {
this.update(cx, |this, _| {
this.hover_state.diagnostic_popover = diagnostic_popover;
})?;
@@ -409,7 +410,7 @@ fn show_hover(
} else {
Vec::new()
};
let snapshot = this.update_in(&mut cx, |this, window, cx| this.snapshot(window, cx))?;
let snapshot = this.update_in(cx, |this, window, cx| this.snapshot(window, cx))?;
let mut hover_highlights = Vec::with_capacity(hovers_response.len());
let mut info_popovers = Vec::with_capacity(
hovers_response.len() + if invisible_char.is_some() { 1 } else { 0 },
@@ -420,7 +421,7 @@ fn show_hover(
text: format!("Unicode character U+{:02X}", invisible as u32),
kind: HoverBlockKind::PlainText,
}];
let parsed_content = parse_blocks(&blocks, &language_registry, None, &mut cx).await;
let parsed_content = parse_blocks(&blocks, &language_registry, None, cx).await;
let scroll_handle = ScrollHandle::new();
info_popovers.push(InfoPopover {
symbol_range: RangeInEditor::Text(range),
@@ -459,8 +460,7 @@ fn show_hover(
let blocks = hover_result.contents;
let language = hover_result.language;
let parsed_content =
parse_blocks(&blocks, &language_registry, language, &mut cx).await;
let parsed_content = parse_blocks(&blocks, &language_registry, language, cx).await;
let scroll_handle = ScrollHandle::new();
hover_highlights.push(range.clone());
info_popovers.push(InfoPopover {
@@ -473,7 +473,7 @@ fn show_hover(
});
}
this.update_in(&mut cx, |editor, window, cx| {
this.update_in(cx, |editor, window, cx| {
if hover_highlights.is_empty() {
editor.clear_background_highlights::<HoverState>(cx);
} else {
@@ -493,6 +493,7 @@ fn show_hover(
anyhow::Ok(())
}
.log_err()
.await
});
editor.hover_state.info_task = Some(task);
@@ -642,7 +643,7 @@ pub fn open_markdown_url(link: SharedString, window: &mut Window, cx: &mut App)
cx,
);
cx.spawn_in(window, |_, mut cx| async move {
cx.spawn_in(window, async move |_, cx| {
let item = task.await?;
// Ruby LSP uses URLs with #L1,1-4,4
// we'll just take the first number and assume it's a line number
@@ -664,7 +665,7 @@ pub fn open_markdown_url(link: SharedString, window: &mut Window, cx: &mut App)
let Some(editor) = cx.update(|_, cx| item.act_as::<Editor>(cx))? else {
return Ok(());
};
editor.update_in(&mut cx, |editor, window, cx| {
editor.update_in(cx, |editor, window, cx| {
editor.change_selections(
Some(Autoscroll::fit()),
window,
+9 -10
View File
@@ -111,16 +111,15 @@ impl Editor {
{
Ok(result) => state.active_indent_range = result,
Err(future) => {
state.pending_refresh =
Some(cx.spawn_in(window, |editor, mut cx| async move {
let result = cx.background_spawn(future).await;
editor
.update(&mut cx, |editor, _| {
editor.active_indent_guides_state.active_indent_range = result;
editor.active_indent_guides_state.pending_refresh = None;
})
.log_err();
}));
state.pending_refresh = Some(cx.spawn_in(window, async move |editor, cx| {
let result = cx.background_spawn(future).await;
editor
.update(cx, |editor, _| {
editor.active_indent_guides_state.active_indent_range = result;
editor.active_indent_guides_state.pending_refresh = None;
})
.log_err();
}));
return None;
}
}
+17 -17
View File
@@ -412,13 +412,13 @@ impl InlayHintCache {
} else {
self.append_debounce
};
self.refresh_task = cx.spawn(|editor, mut cx| async move {
self.refresh_task = cx.spawn(async move |editor, cx| {
if let Some(debounce_duration) = debounce_duration {
cx.background_executor().timer(debounce_duration).await;
}
editor
.update(&mut cx, |editor, cx| {
.update(cx, |editor, cx| {
spawn_new_update_tasks(
editor,
reason_description,
@@ -626,8 +626,8 @@ impl InlayHintCache {
let server_id = *server_id;
cached_hint.resolve_state = ResolveState::Resolving;
drop(guard);
cx.spawn_in(window, |editor, mut cx| async move {
let resolved_hint_task = editor.update(&mut cx, |editor, cx| {
cx.spawn_in(window, async move |editor, cx| {
let resolved_hint_task = editor.update(cx, |editor, cx| {
let buffer = editor.buffer().read(cx).buffer(buffer_id)?;
editor.semantics_provider.as_ref()?.resolve_inlay_hint(
hint_to_resolve,
@@ -639,7 +639,7 @@ impl InlayHintCache {
if let Some(resolved_hint_task) = resolved_hint_task {
let mut resolved_hint =
resolved_hint_task.await.context("hint resolve task")?;
editor.update(&mut cx, |editor, _| {
editor.update(cx, |editor, _| {
if let Some(excerpt_hints) =
editor.inlay_hint_cache.hints.get(&excerpt_id)
{
@@ -846,14 +846,14 @@ fn new_update_task(
excerpt_buffer: Entity<Buffer>,
cx: &mut Context<Editor>,
) -> Task<()> {
cx.spawn(move |editor, mut cx| async move {
cx.spawn(async move |editor, cx| {
let visible_range_update_results = future::join_all(
query_ranges
.visible
.into_iter()
.filter_map(|visible_range| {
let fetch_task = editor
.update(&mut cx, |_, cx| {
.update(cx, |_, cx| {
fetch_and_update_hints(
excerpt_buffer.clone(),
query,
@@ -891,7 +891,7 @@ fn new_update_task(
for (range, result) in visible_range_update_results {
if let Err(e) = result {
query_range_failed(&range, e, &mut cx);
query_range_failed(&range, e, cx);
}
}
@@ -903,7 +903,7 @@ fn new_update_task(
.chain(query_ranges.after_visible.into_iter())
.filter_map(|invisible_range| {
let fetch_task = editor
.update(&mut cx, |_, cx| {
.update(cx, |_, cx| {
fetch_and_update_hints(
excerpt_buffer.clone(),
query,
@@ -919,7 +919,7 @@ fn new_update_task(
.await;
for (range, result) in invisible_range_update_results {
if let Err(e) = result {
query_range_failed(&range, e, &mut cx);
query_range_failed(&range, e, cx);
}
}
})
@@ -932,10 +932,10 @@ fn fetch_and_update_hints(
invalidate: bool,
cx: &mut Context<Editor>,
) -> Task<anyhow::Result<()>> {
cx.spawn(|editor, mut cx| async move {
let buffer_snapshot = excerpt_buffer.update(&mut cx, |buffer, _| buffer.snapshot())?;
cx.spawn(async move |editor, cx|{
let buffer_snapshot = excerpt_buffer.update(cx, |buffer, _| buffer.snapshot())?;
let (lsp_request_limiter, multi_buffer_snapshot) =
editor.update(&mut cx, |editor, cx| {
editor.update(cx, |editor, cx| {
let multi_buffer_snapshot =
editor.buffer().update(cx, |buffer, cx| buffer.snapshot(cx));
let lsp_request_limiter = Arc::clone(&editor.inlay_hint_cache.lsp_request_limiter);
@@ -953,7 +953,7 @@ fn fetch_and_update_hints(
let fetch_range_to_log = fetch_range.start.to_point(&buffer_snapshot)
..fetch_range.end.to_point(&buffer_snapshot);
let inlay_hints_fetch_task = editor
.update(&mut cx, |editor, cx| {
.update(cx, |editor, cx| {
if got_throttled {
let query_not_around_visible_range = match editor
.excerpts_for_inlay_hints_query(None, cx)
@@ -997,7 +997,7 @@ fn fetch_and_update_hints(
.ok()
.flatten();
let cached_excerpt_hints = editor.update(&mut cx, |editor, _| {
let cached_excerpt_hints = editor.update(cx, |editor, _| {
editor
.inlay_hint_cache
.hints
@@ -1005,7 +1005,7 @@ fn fetch_and_update_hints(
.cloned()
})?;
let visible_hints = editor.update(&mut cx, |editor, cx| editor.visible_inlay_hints(cx))?;
let visible_hints = editor.update(cx, |editor, cx| editor.visible_inlay_hints(cx))?;
let new_hints = match inlay_hints_fetch_task {
Some(fetch_task) => {
log::debug!(
@@ -1050,7 +1050,7 @@ fn fetch_and_update_hints(
);
log::trace!("New update: {new_update:?}");
editor
.update(&mut cx, |editor, cx| {
.update(cx, |editor, cx| {
apply_hint_update(
editor,
new_update,
+26 -28
View File
@@ -87,7 +87,7 @@ impl FollowableItem for Editor {
.collect::<Result<Vec<_>>>()
});
Some(window.spawn(cx, |mut cx| async move {
Some(window.spawn(cx, async move |cx| {
let mut buffers = futures::future::try_join_all(buffers?)
.await
.debug_assert_ok("leaders don't share views for unshared buffers")?;
@@ -147,7 +147,7 @@ impl FollowableItem for Editor {
scroll_y: state.scroll_y,
..Default::default()
},
&mut cx,
cx,
)
.await?;
@@ -319,8 +319,8 @@ impl FollowableItem for Editor {
) -> Task<Result<()>> {
let update_view::Variant::Editor(message) = message;
let project = project.clone();
cx.spawn_in(window, |this, mut cx| async move {
update_editor_from_message(this, project, message, &mut cx).await
cx.spawn_in(window, async move |this, cx| {
update_editor_from_message(this, project, message, cx).await
})
}
@@ -776,9 +776,9 @@ impl Item for Editor {
.into_iter()
.map(|handle| handle.read(cx).base_buffer().unwrap_or(handle.clone()))
.collect::<HashSet<_>>();
cx.spawn_in(window, |this, mut cx| async move {
cx.spawn_in(window, async move |this, cx| {
if format {
this.update_in(&mut cx, |editor, window, cx| {
this.update_in(cx, |editor, window, cx| {
editor.perform_format(
project.clone(),
FormatTrigger::Save,
@@ -793,7 +793,7 @@ impl Item for Editor {
if buffers.len() == 1 {
// Apply full save routine for singleton buffers, to allow to `touch` the file via the editor.
project
.update(&mut cx, |project, cx| project.save_buffers(buffers, cx))?
.update(cx, |project, cx| project.save_buffers(buffers, cx))?
.await?;
} else {
// For multi-buffers, only format and save the buffers with changes.
@@ -801,20 +801,16 @@ impl Item for Editor {
// so that language servers or other downstream listeners of save events get notified.
let (dirty_buffers, clean_buffers) = buffers.into_iter().partition(|buffer| {
buffer
.update(&mut cx, |buffer, _| {
buffer.is_dirty() || buffer.has_conflict()
})
.update(cx, |buffer, _| buffer.is_dirty() || buffer.has_conflict())
.unwrap_or(false)
});
project
.update(&mut cx, |project, cx| {
project.save_buffers(dirty_buffers, cx)
})?
.update(cx, |project, cx| project.save_buffers(dirty_buffers, cx))?
.await?;
for buffer in clean_buffers {
buffer
.update(&mut cx, |buffer, cx| {
.update(cx, |buffer, cx| {
let version = buffer.saved_version().clone();
let mtime = buffer.saved_mtime();
buffer.did_save(version, mtime, cx);
@@ -859,13 +855,13 @@ impl Item for Editor {
let buffers = self.buffer.read(cx).all_buffers();
let reload_buffers =
project.update(cx, |project, cx| project.reload_buffers(buffers, true, cx));
cx.spawn_in(window, |this, mut cx| async move {
cx.spawn_in(window, async move |this, cx| {
let transaction = reload_buffers.log_err().await;
this.update(&mut cx, |editor, cx| {
this.update(cx, |editor, cx| {
editor.request_autoscroll(Autoscroll::fit(), cx)
})?;
buffer
.update(&mut cx, |buffer, cx| {
.update(cx, |buffer, cx| {
if let Some(transaction) = transaction {
if !buffer.is_singleton() {
buffer.push_transaction(&transaction.0, cx);
@@ -996,7 +992,9 @@ impl SerializableItem for Editor {
window: &mut Window,
cx: &mut App,
) -> Task<Result<()>> {
window.spawn(cx, |_| DB.delete_unloaded_items(workspace_id, alive_items))
window.spawn(cx, async move |_| {
DB.delete_unloaded_items(workspace_id, alive_items).await
})
}
fn deserialize(
@@ -1040,11 +1038,11 @@ impl SerializableItem for Editor {
contents: Some(contents),
language,
..
} => window.spawn(cx, |mut cx| {
} => window.spawn(cx, {
let project = project.clone();
async move {
async move |cx| {
let language_registry =
project.update(&mut cx, |project, _| project.languages().clone())?;
project.update(cx, |project, _| project.languages().clone())?;
let language = if let Some(language_name) = language {
// We don't fail here, because we'd rather not set the language if the name changed
@@ -1059,11 +1057,11 @@ impl SerializableItem for Editor {
// First create the empty buffer
let buffer = project
.update(&mut cx, |project, cx| project.create_buffer(cx))?
.update(cx, |project, cx| project.create_buffer(cx))?
.await?;
// Then set the text so that the dirty bit is set correctly
buffer.update(&mut cx, |buffer, cx| {
buffer.update(cx, |buffer, cx| {
buffer.set_language_registry(language_registry);
if let Some(language) = language {
buffer.set_language(Some(language), cx);
@@ -1102,7 +1100,7 @@ impl SerializableItem for Editor {
match project_item {
Some(project_item) => {
window.spawn(cx, |mut cx| async move {
window.spawn(cx, async move |cx| {
let (_, project_item) = project_item.await?;
let buffer = project_item.downcast::<Buffer>().map_err(|_| {
anyhow!("Project item at stored path was not a buffer")
@@ -1114,7 +1112,7 @@ impl SerializableItem for Editor {
// simple, because we don't have to persist all of the metadata that we get
// by loading the file (git diff base, ...).
if let Some(buffer_text) = contents {
buffer.update(&mut cx, |buffer, cx| {
buffer.update(cx, |buffer, cx| {
// If we did restore an mtime, we want to store it on the buffer
// so that the next edit will mark the buffer as dirty/conflicted.
if mtime.is_some() {
@@ -1166,9 +1164,9 @@ impl SerializableItem for Editor {
cx,
)
});
window.spawn(cx, |mut cx| async move {
window.spawn(cx, async move |cx| {
let editor = open_by_abs_path?.await?.downcast::<Editor>().with_context(|| format!("Failed to downcast to Editor after opening abs path {abs_path:?}"))?;
editor.update_in(&mut cx, |editor, window, cx| {
editor.update_in(cx, |editor, window, cx| {
editor.read_selections_from_db(item_id, workspace_id, window, cx);
editor.read_scroll_position_from_db(item_id, workspace_id, window, cx);
})?;
@@ -1228,7 +1226,7 @@ impl SerializableItem for Editor {
let snapshot = buffer.read(cx).snapshot();
Some(cx.spawn_in(window, |_this, cx| async move {
Some(cx.spawn_in(window, async move |_this, cx| {
cx.background_spawn(async move {
let (contents, language) = if serialize_dirty_buffers && is_dirty {
let contents = snapshot.text();
+8 -8
View File
@@ -434,7 +434,7 @@ pub(crate) fn handle_from(
let (buffer_version_initial, mut buffer_parse_status_rx) =
buffer.read_with(cx, |buffer, _| (buffer.version(), buffer.parse_status()));
cx.spawn_in(window, |this, mut cx| async move {
cx.spawn_in(window, async move |this, cx| {
let Some(buffer_parse_status) = buffer_parse_status_rx.recv().await.ok() else {
return Some(());
};
@@ -445,7 +445,7 @@ pub(crate) fn handle_from(
};
}
let buffer_snapshot = buffer.read_with(&cx, |buf, _| buf.snapshot()).ok()?;
let buffer_snapshot = buffer.read_with(cx, |buf, _| buf.snapshot()).ok()?;
let Some(edit_behavior_state) =
should_auto_close(&buffer_snapshot, &edited_ranges, &jsx_tag_auto_close_config)
@@ -456,7 +456,7 @@ pub(crate) fn handle_from(
let ensure_no_edits_since_start = || -> Option<()> {
// <div>wef,wefwef
let has_edits_since_start = this
.read_with(&cx, |this, cx| {
.read_with(cx, |this, cx| {
this.buffer.read_with(cx, |buffer, cx| {
buffer.buffer(buffer_id).map_or(true, |buffer| {
buffer.read_with(cx, |buffer, _| {
@@ -506,7 +506,7 @@ pub(crate) fn handle_from(
ensure_no_edits_since_start()?;
let multi_buffer_snapshot = this
.read_with(&cx, |this, cx| {
.read_with(cx, |this, cx| {
this.buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx))
})
.ok()?;
@@ -516,7 +516,7 @@ pub(crate) fn handle_from(
{
let selections = this
.read_with(&cx, |this, _| this.selections.disjoint_anchors().clone())
.read_with(cx, |this, _| this.selections.disjoint_anchors().clone())
.ok()?;
for selection in selections.iter() {
let Some(selection_buffer_offset_head) =
@@ -576,14 +576,14 @@ pub(crate) fn handle_from(
}
buffer
.update(&mut cx, |buffer, cx| {
.update(cx, |buffer, cx| {
buffer.edit(edits, None, cx);
})
.ok()?;
if any_selections_need_update {
let multi_buffer_snapshot = this
.read_with(&cx, |this, cx| {
.read_with(cx, |this, cx| {
this.buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx))
})
.ok()?;
@@ -601,7 +601,7 @@ pub(crate) fn handle_from(
selection.map(|anchor| anchor.to_offset(&multi_buffer_snapshot))
})
.collect::<Vec<_>>();
this.update_in(&mut cx, |this, window, cx| {
this.update_in(cx, |this, window, cx| {
this.change_selections_inner(None, false, window, cx, |s| {
s.select(base_selections);
});
+4 -4
View File
@@ -49,12 +49,12 @@ pub(super) fn refresh_linked_ranges(
}
let project = editor.project.as_ref()?.downgrade();
editor.linked_editing_range_task = Some(cx.spawn_in(window, |editor, mut cx| async move {
editor.linked_editing_range_task = Some(cx.spawn_in(window, async move |editor, cx| {
cx.background_executor().timer(UPDATE_DEBOUNCE).await;
let mut applicable_selections = Vec::new();
editor
.update(&mut cx, |editor, cx| {
.update(cx, |editor, cx| {
let selections = editor.selections.all::<usize>(cx);
let snapshot = editor.buffer.read(cx).snapshot(cx);
let buffer = editor.buffer.read(cx);
@@ -84,7 +84,7 @@ pub(super) fn refresh_linked_ranges(
}
let highlights = project
.update(&mut cx, |project, cx| {
.update(cx, |project, cx| {
let mut linked_edits_tasks = vec![];
for (buffer, start, end) in &applicable_selections {
@@ -133,7 +133,7 @@ pub(super) fn refresh_linked_ranges(
let highlights = futures::future::join_all(highlights).await;
editor
.update(&mut cx, |this, cx| {
.update(cx, |this, cx| {
this.linked_edit_ranges.0.clear();
if this.pending_rename.is_some() {
return;
+2 -2
View File
@@ -77,7 +77,7 @@ impl ProposedChangesEditor {
title: title.into(),
buffer_entries: Vec::new(),
recalculate_diffs_tx,
_recalculate_diffs_task: cx.spawn_in(window, |this, mut cx| async move {
_recalculate_diffs_task: cx.spawn_in(window, async move |this, cx| {
let mut buffers_to_diff = HashSet::default();
while let Some(mut recalculate_diff) = recalculate_diffs_rx.next().await {
buffers_to_diff.insert(recalculate_diff.buffer);
@@ -99,7 +99,7 @@ impl ProposedChangesEditor {
}
let recalculate_diff_futures = this
.update(&mut cx, |this, cx| {
.update(cx, |this, cx| {
buffers_to_diff
.drain()
.filter_map(|buffer| {
+5 -5
View File
@@ -66,7 +66,7 @@ pub fn expand_macro_recursively(
cx,
)
});
cx.spawn_in(window, |_editor, mut cx| async move {
cx.spawn_in(window, async move |_editor, cx| {
let macro_expansion = expand_macro_task.await.context("expand macro")?;
if macro_expansion.is_empty() {
log::info!("Empty macro expansion for position {position:?}");
@@ -74,9 +74,9 @@ pub fn expand_macro_recursively(
}
let buffer = project
.update(&mut cx, |project, cx| project.create_buffer(cx))?
.update(cx, |project, cx| project.create_buffer(cx))?
.await?;
workspace.update_in(&mut cx, |workspace, window, cx| {
workspace.update_in(cx, |workspace, window, cx| {
buffer.update(cx, |buffer, cx| {
buffer.set_text(macro_expansion.expansion, cx);
buffer.set_language(Some(rust_language), cx);
@@ -134,7 +134,7 @@ pub fn open_docs(editor: &mut Editor, _: &OpenDocs, window: &mut Window, cx: &mu
)
});
cx.spawn_in(window, |_editor, mut cx| async move {
cx.spawn_in(window, async move |_editor, cx| {
let docs_urls = open_docs_task.await.context("open docs")?;
if docs_urls.is_empty() {
log::debug!("Empty docs urls for position {position:?}");
@@ -143,7 +143,7 @@ pub fn open_docs(editor: &mut Editor, _: &OpenDocs, window: &mut Window, cx: &mu
log::debug!("{:?}", docs_urls);
}
workspace.update(&mut cx, |_workspace, cx| {
workspace.update(cx, |_workspace, cx| {
// Check if the local document exists, otherwise fallback to the online document.
// Open with the default browser.
if let Some(local_url) = docs_urls.local {
+4 -4
View File
@@ -341,12 +341,12 @@ impl ScrollManager {
}
if cx.default_global::<ScrollbarAutoHide>().0 {
self.hide_scrollbar_task = Some(cx.spawn_in(window, |editor, mut cx| async move {
self.hide_scrollbar_task = Some(cx.spawn_in(window, async move |editor, cx| {
cx.background_executor()
.timer(SCROLLBAR_SHOW_INTERVAL)
.await;
editor
.update(&mut cx, |editor, cx| {
.update(cx, |editor, cx| {
editor.scroll_manager.show_scrollbars = false;
cx.notify();
})
@@ -425,9 +425,9 @@ impl Editor {
let opened_first_time = self.scroll_manager.visible_line_count.is_none();
self.scroll_manager.visible_line_count = Some(lines);
if opened_first_time {
cx.spawn_in(window, |editor, mut cx| async move {
cx.spawn_in(window, async move |editor, cx| {
editor
.update(&mut cx, |editor, cx| {
.update(cx, |editor, cx| {
editor.refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx)
})
.ok()
+2 -2
View File
@@ -77,12 +77,12 @@ impl Editor {
);
self.next_scroll_position = self.next_scroll_position.next();
self._scroll_cursor_center_top_bottom_task = cx.spawn(|editor, mut cx| async move {
self._scroll_cursor_center_top_bottom_task = cx.spawn(async move |editor, cx| {
cx.background_executor()
.timer(SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT)
.await;
editor
.update(&mut cx, |editor, _| {
.update(cx, |editor, _| {
editor.next_scroll_position = NextScrollCursorCenterTopBottom::default();
})
.ok();
+2 -2
View File
@@ -179,10 +179,10 @@ impl Editor {
let language = self.language_at(position, cx);
self.signature_help_state
.set_task(cx.spawn_in(window, move |editor, mut cx| async move {
.set_task(cx.spawn_in(window, async move |editor, cx| {
let signature_help = task.await;
editor
.update(&mut cx, |editor, cx| {
.update(cx, |editor, cx| {
let Some(mut signature_help) = signature_help.into_iter().next() else {
editor
.signature_help_state