Detailed changes
@@ -3012,7 +3012,7 @@ impl CodegenAlternative {
let executor = cx.background_executor().clone();
let message_id = message_id.clone();
let line_based_stream_diff: Task<anyhow::Result<()>> =
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut response_latency = None;
let request_start = Instant::now();
let diff = async {
@@ -3326,8 +3326,7 @@ impl CodegenAlternative {
cx.spawn(|codegen, mut cx| async move {
let (deleted_row_ranges, inserted_row_ranges) = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
let old_text = old_snapshot
.text_for_range(
Point::new(old_range.start.row, 0)
@@ -1149,7 +1149,7 @@ impl Codegen {
let (mut hunks_tx, mut hunks_rx) = mpsc::channel(1);
- let task = cx.background_executor().spawn({
+ let task = cx.background_spawn({
let message_id = message_id.clone();
let executor = cx.background_executor().clone();
async move {
@@ -493,7 +493,7 @@ impl CodegenAlternative {
let executor = cx.background_executor().clone();
let message_id = message_id.clone();
let line_based_stream_diff: Task<anyhow::Result<()>> =
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut response_latency = None;
let request_start = Instant::now();
let diff = async {
@@ -807,8 +807,7 @@ impl CodegenAlternative {
cx.spawn(|codegen, mut cx| async move {
let (deleted_row_ranges, inserted_row_ranges) = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
let old_text = old_snapshot
.text_for_range(
Point::new(old_range.start.row, 0)
@@ -208,8 +208,7 @@ impl PickerDelegate for FetchContextPickerDelegate {
let confirm_behavior = self.confirm_behavior;
cx.spawn_in(window, |this, mut cx| async move {
let text = cx
- .background_executor()
- .spawn(Self::build_message(http_client, url.clone()))
+ .background_spawn(Self::build_message(http_client, url.clone()))
.await?;
this.update_in(&mut cx, |this, window, cx| {
@@ -123,7 +123,7 @@ impl PickerDelegate for ThreadContextPickerDelegate {
};
let executor = cx.background_executor().clone();
- let search_task = cx.background_executor().spawn(async move {
+ let search_task = cx.background_spawn(async move {
if query.is_empty() {
threads
} else {
@@ -4,7 +4,7 @@ use std::sync::Arc;
use anyhow::{anyhow, bail, Result};
use collections::{BTreeMap, HashMap, HashSet};
use futures::{self, future, Future, FutureExt};
-use gpui::{App, AsyncApp, Context, Entity, SharedString, Task, WeakEntity};
+use gpui::{App, AppContext as _, AsyncApp, Context, Entity, SharedString, Task, WeakEntity};
use language::Buffer;
use project::{ProjectPath, Worktree};
use rope::Rope;
@@ -456,9 +456,7 @@ fn collect_buffer_info_and_text(
};
// Important to collect version at the same time as content so that staleness logic is correct.
let content = buffer.as_rope().clone();
- let text_task = cx
- .background_executor()
- .spawn(async move { to_fenced_codeblock(&path, content) });
+ let text_task = cx.background_spawn(async move { to_fenced_codeblock(&path, content) });
(buffer_info, text_task)
}
@@ -1,7 +1,7 @@
use crate::inline_prompt_editor::CodegenStatus;
use client::telemetry::Telemetry;
use futures::{channel::mpsc, SinkExt, StreamExt};
-use gpui::{App, Context, Entity, EventEmitter, Task};
+use gpui::{App, AppContext as _, Context, Entity, EventEmitter, Task};
use language_model::{LanguageModelRegistry, LanguageModelRequest};
use language_models::report_assistant_event;
use std::{sync::Arc, time::Instant};
@@ -53,7 +53,7 @@ impl TerminalCodegen {
let (mut hunks_tx, mut hunks_rx) = mpsc::channel(1);
- let task = cx.background_executor().spawn({
+ let task = cx.background_spawn({
let message_id = message_id.clone();
let executor = cx.background_executor().clone();
async move {
@@ -849,7 +849,7 @@ impl AssistantContext {
.collect::<Vec<_>>();
context_ops.extend(self.pending_ops.iter().cloned());
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let buffer_ops = buffer_ops.await;
context_ops.sort_unstable_by_key(|op| op.timestamp());
buffer_ops
@@ -265,19 +265,18 @@ impl ContextStore {
local_versions.push(context.version(cx).to_proto(context_id.clone()));
let client = this.client.clone();
let project_id = envelope.payload.project_id;
- cx.background_executor()
- .spawn(async move {
- let operations = operations.await;
- for operation in operations {
- client.send(proto::UpdateContext {
- project_id,
- context_id: context_id.to_proto(),
- operation: Some(operation),
- })?;
- }
- anyhow::Ok(())
- })
- .detach_and_log_err(cx);
+ cx.background_spawn(async move {
+ let operations = operations.await;
+ for operation in operations {
+ client.send(proto::UpdateContext {
+ project_id,
+ context_id: context_id.to_proto(),
+ operation: Some(operation),
+ })?;
+ }
+ anyhow::Ok(())
+ })
+ .detach_and_log_err(cx);
}
}
@@ -401,8 +400,7 @@ impl ContextStore {
)
})?;
let operations = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
context_proto
.operations
.into_iter()
@@ -436,7 +434,7 @@ impl ContextStore {
let languages = self.languages.clone();
let project = self.project.clone();
let telemetry = self.telemetry.clone();
- let load = cx.background_executor().spawn({
+ let load = cx.background_spawn({
let path = path.clone();
async move {
let saved_context = fs.load(&path).await?;
@@ -539,8 +537,7 @@ impl ContextStore {
)
})?;
let operations = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
context_proto
.operations
.into_iter()
@@ -693,7 +690,7 @@ impl ContextStore {
pub fn search(&self, query: String, cx: &App) -> Task<Vec<SavedContextMetadata>> {
let metadata = self.contexts_metadata.clone();
let executor = cx.background_executor().clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
if query.is_empty() {
metadata
} else {
@@ -2,7 +2,7 @@ use anyhow::{anyhow, Context as _, Result};
use collections::HashMap;
use editor::ProposedChangesEditor;
use futures::{future, TryFutureExt as _};
-use gpui::{App, AsyncApp, Entity, SharedString};
+use gpui::{App, AppContext as _, AsyncApp, Entity, SharedString};
use language::{AutoindentMode, Buffer, BufferSnapshot};
use project::{Project, ProjectPath};
use std::{cmp, ops::Range, path::Path, sync::Arc};
@@ -258,8 +258,7 @@ impl AssistantEdit {
let snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot())?;
let suggestion = cx
- .background_executor()
- .spawn(async move { kind.resolve(&snapshot) })
+ .background_spawn(async move { kind.resolve(&snapshot) })
.await;
Ok((buffer, suggestion))
@@ -547,7 +546,7 @@ impl Eq for AssistantPatch {}
#[cfg(test)]
mod tests {
use super::*;
- use gpui::{App, AppContext as _};
+ use gpui::App;
use language::{
language_settings::AllLanguageSettings, Language, LanguageConfig, LanguageMatcher,
};
@@ -4,7 +4,7 @@ pub use assistant_slash_command::SlashCommand;
use assistant_slash_command::{AfterCompletion, SlashCommandLine, SlashCommandWorkingSet};
use editor::{CompletionProvider, Editor};
use fuzzy::{match_strings, StringMatchCandidate};
-use gpui::{App, Context, Entity, Task, WeakEntity, Window};
+use gpui::{App, AppContext as _, Context, Entity, Task, WeakEntity, Window};
use language::{Anchor, Buffer, CompletionDocumentation, LanguageServerId, ToPoint};
use parking_lot::Mutex;
use project::CompletionIntent;
@@ -162,7 +162,7 @@ impl SlashCommandCompletionProvider {
let editor = self.editor.clone();
let workspace = self.workspace.clone();
let arguments = arguments.to_vec();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
Ok(completions
.await?
.into_iter()
@@ -102,8 +102,7 @@ impl PickerDelegate for SlashCommandDelegate {
let all_commands = self.all_commands.clone();
cx.spawn_in(window, |this, mut cx| async move {
let filtered_commands = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
if query.is_empty() {
all_commands
} else {
@@ -103,7 +103,7 @@ impl SlashCommand for ExtensionSlashCommand {
) -> Task<Result<Vec<ArgumentCompletion>>> {
let command = self.command.clone();
let arguments = arguments.to_owned();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let completions = self
.extension
.complete_slash_command_argument(command, arguments)
@@ -135,7 +135,7 @@ impl SlashCommand for ExtensionSlashCommand {
) -> Task<SlashCommandResult> {
let command = self.command.clone();
let arguments = arguments.to_owned();
- let output = cx.background_executor().spawn(async move {
+ let output = cx.background_spawn(async move {
let delegate =
delegate.map(|delegate| Arc::new(WorktreeDelegateAdapter(delegate.clone())) as _);
let output = self
@@ -82,7 +82,7 @@ impl SlashCommand for AutoCommand {
project_index.flush_summary_backlogs(cx)
})?;
- cx.background_executor().spawn(task).await;
+ cx.background_spawn(task).await;
anyhow::Ok(Vec::new())
})
@@ -129,7 +129,7 @@ impl SlashCommand for AutoCommand {
// so you don't have to write it again.
let original_prompt = argument.to_string();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let commands = task.await?;
let mut prompt = String::new();
@@ -285,57 +285,56 @@ async fn commands_for_summaries(
})
.collect::<Vec<_>>();
- cx.background_executor()
- .spawn(async move {
- let futures = completion_streams
- .into_iter()
- .enumerate()
- .map(|(ix, (stream, tx))| async move {
- let start = std::time::Instant::now();
- let events = stream.await?;
- log::info!("Time taken for awaiting /await chunk stream #{ix}: {:?}", start.elapsed());
-
- let completion: String = events
- .filter_map(|event| async {
- if let Ok(LanguageModelCompletionEvent::Text(text)) = event {
- Some(text)
- } else {
- None
- }
- })
- .collect()
- .await;
-
- log::info!("Time taken for all /auto chunks to come back for #{ix}: {:?}", start.elapsed());
-
- for line in completion.split('\n') {
- if let Some(first_space) = line.find(' ') {
- let command = &line[..first_space].trim();
- let arg = &line[first_space..].trim();
-
- tx.send(CommandToRun {
- name: command.to_string(),
- arg: arg.to_string(),
- })
- .await?;
- } else if !line.trim().is_empty() {
- // All slash-commands currently supported in context inference need a space for the argument.
- log::warn!(
- "Context inference returned a non-blank line that contained no spaces (meaning no argument for the slash command): {:?}",
- line
- );
+ cx.background_spawn(async move {
+ let futures = completion_streams
+ .into_iter()
+ .enumerate()
+ .map(|(ix, (stream, tx))| async move {
+ let start = std::time::Instant::now();
+ let events = stream.await?;
+ log::info!("Time taken for awaiting /await chunk stream #{ix}: {:?}", start.elapsed());
+
+ let completion: String = events
+ .filter_map(|event| async {
+ if let Ok(LanguageModelCompletionEvent::Text(text)) = event {
+ Some(text)
+ } else {
+ None
}
+ })
+ .collect()
+ .await;
+
+ log::info!("Time taken for all /auto chunks to come back for #{ix}: {:?}", start.elapsed());
+
+ for line in completion.split('\n') {
+ if let Some(first_space) = line.find(' ') {
+ let command = &line[..first_space].trim();
+ let arg = &line[first_space..].trim();
+
+ tx.send(CommandToRun {
+ name: command.to_string(),
+ arg: arg.to_string(),
+ })
+ .await?;
+ } else if !line.trim().is_empty() {
+ // All slash-commands currently supported in context inference need a space for the argument.
+ log::warn!(
+ "Context inference returned a non-blank line that contained no spaces (meaning no argument for the slash command): {:?}",
+ line
+ );
}
+ }
- anyhow::Ok(())
- })
- .collect::<Vec<_>>();
+ anyhow::Ok(())
+ })
+ .collect::<Vec<_>>();
- let _ = futures::future::try_join_all(futures).await.log_err();
+ let _ = futures::future::try_join_all(futures).await.log_err();
- let duration = all_start.elapsed();
- eprintln!("All futures completed in {:?}", duration);
- })
+ let duration = all_start.elapsed();
+ eprintln!("All futures completed in {:?}", duration);
+ })
.await;
drop(tx); // Close the channel so that rx.collect() won't hang. This is safe because all futures have completed.
@@ -132,7 +132,7 @@ impl SlashCommand for CargoWorkspaceSlashCommand {
let project = workspace.project().clone();
let fs = workspace.project().read(cx).fs().clone();
let path = Self::path_to_cargo_toml(project, cx);
- let output = cx.background_executor().spawn(async move {
+ let output = cx.background_spawn(async move {
let path = path.with_context(|| "Cargo.toml not found")?;
Self::build_message(fs, &path).await
});
@@ -54,7 +54,7 @@ impl SlashCommand for DefaultSlashCommand {
cx: &mut App,
) -> Task<SlashCommandResult> {
let store = PromptStore::global(cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let store = store.await?;
let prompts = store.default_prompt_metadata();
@@ -86,7 +86,7 @@ impl SlashCommand for DeltaSlashCommand {
}
}
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut output = SlashCommandOutput::default();
let mut changes_detected = false;
@@ -129,7 +129,7 @@ impl SlashCommand for DiagnosticsSlashCommand {
let paths = self.search_paths(query.clone(), cancellation_flag.clone(), &workspace, cx);
let executor = cx.background_executor().clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut matches: Vec<String> = paths
.await
.into_iter()
@@ -176,7 +176,7 @@ impl SlashCommand for DocsSlashCommand {
.provider()
.ok_or_else(|| anyhow!("no docs provider specified"))
.and_then(|provider| IndexedDocsStore::try_global(provider, cx));
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
fn build_completions(items: Vec<String>) -> Vec<ArgumentCompletion> {
items
.into_iter()
@@ -284,7 +284,7 @@ impl SlashCommand for DocsSlashCommand {
let args = DocsSlashCommandArgs::parse(arguments);
let executor = cx.background_executor().clone();
- let task = cx.background_executor().spawn({
+ let task = cx.background_spawn({
let store = args
.provider()
.ok_or_else(|| anyhow!("no docs provider specified"))
@@ -151,7 +151,7 @@ impl SlashCommand for FetchSlashCommand {
let http_client = workspace.read(cx).client().http_client();
let url = argument.to_string();
- let text = cx.background_executor().spawn({
+ let text = cx.background_spawn({
let url = url.clone();
async move { Self::build_message(http_client, &url).await }
});
@@ -156,7 +156,7 @@ impl SlashCommand for FileSlashCommand {
cx,
);
let comment_id = cx.theme().syntax().highlight_id("comment").map(HighlightId);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
Ok(paths
.await
.into_iter()
@@ -130,49 +130,48 @@ impl SlashCommand for ProjectSlashCommand {
let results = SemanticDb::load_results(results, &fs, &cx).await?;
- cx.background_executor()
- .spawn(async move {
- let mut output = "Project context:\n".to_string();
- let mut sections = Vec::new();
-
- for (ix, query) in search_queries.into_iter().enumerate() {
- let start_ix = output.len();
- writeln!(&mut output, "Results for {query}:").unwrap();
- let mut has_results = false;
- for result in &results {
- if result.query_index == ix {
- add_search_result_section(result, &mut output, &mut sections);
- has_results = true;
- }
- }
- if has_results {
- sections.push(SlashCommandOutputSection {
- range: start_ix..output.len(),
- icon: IconName::MagnifyingGlass,
- label: query.into(),
- metadata: None,
- });
- output.push('\n');
- } else {
- output.truncate(start_ix);
+ cx.background_spawn(async move {
+ let mut output = "Project context:\n".to_string();
+ let mut sections = Vec::new();
+
+ for (ix, query) in search_queries.into_iter().enumerate() {
+ let start_ix = output.len();
+ writeln!(&mut output, "Results for {query}:").unwrap();
+ let mut has_results = false;
+ for result in &results {
+ if result.query_index == ix {
+ add_search_result_section(result, &mut output, &mut sections);
+ has_results = true;
}
}
-
- sections.push(SlashCommandOutputSection {
- range: 0..output.len(),
- icon: IconName::Book,
- label: "Project context".into(),
- metadata: None,
- });
-
- Ok(SlashCommandOutput {
- text: output,
- sections,
- run_commands_in_text: true,
+ if has_results {
+ sections.push(SlashCommandOutputSection {
+ range: start_ix..output.len(),
+ icon: IconName::MagnifyingGlass,
+ label: query.into(),
+ metadata: None,
+ });
+ output.push('\n');
+ } else {
+ output.truncate(start_ix);
}
- .to_event_stream())
- })
- .await
+ }
+
+ sections.push(SlashCommandOutputSection {
+ range: 0..output.len(),
+ icon: IconName::Book,
+ label: "Project context".into(),
+ metadata: None,
+ });
+
+ Ok(SlashCommandOutput {
+ text: output,
+ sections,
+ run_commands_in_text: true,
+ }
+ .to_event_stream())
+ })
+ .await
})
}
}
@@ -43,7 +43,7 @@ impl SlashCommand for PromptSlashCommand {
) -> Task<Result<Vec<ArgumentCompletion>>> {
let store = PromptStore::global(cx);
let query = arguments.to_owned().join(" ");
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let prompts = store.await?.search(query).await;
Ok(prompts
.into_iter()
@@ -77,7 +77,7 @@ impl SlashCommand for PromptSlashCommand {
let store = PromptStore::global(cx);
let title = SharedString::from(title.clone());
- let prompt = cx.background_executor().spawn({
+ let prompt = cx.background_spawn({
let title = title.clone();
async move {
let store = store.await?;
@@ -119,8 +119,7 @@ impl SlashCommand for SearchSlashCommand {
let loaded_results = SemanticDb::load_results(results, &fs, &cx).await?;
let output = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
let mut text = format!("Search results for {query}:\n");
let mut sections = Vec::new();
for loaded_result in &loaded_results {
@@ -63,56 +63,55 @@ impl SlashCommand for StreamingExampleSlashCommand {
cx: &mut App,
) -> Task<SlashCommandResult> {
let (events_tx, events_rx) = mpsc::unbounded();
- cx.background_executor()
- .spawn(async move {
- events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
- icon: IconName::FileRust,
- label: "Section 1".into(),
- metadata: None,
- }))?;
- events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
- SlashCommandContent::Text {
- text: "Hello".into(),
- run_commands_in_text: false,
- },
- )))?;
- events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
-
+ cx.background_spawn(async move {
+ events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
+ icon: IconName::FileRust,
+ label: "Section 1".into(),
+ metadata: None,
+ }))?;
+ events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
+ SlashCommandContent::Text {
+ text: "Hello".into(),
+ run_commands_in_text: false,
+ },
+ )))?;
+ events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
+
+ Timer::after(Duration::from_secs(1)).await;
+
+ events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
+ icon: IconName::FileRust,
+ label: "Section 2".into(),
+ metadata: None,
+ }))?;
+ events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
+ SlashCommandContent::Text {
+ text: "World".into(),
+ run_commands_in_text: false,
+ },
+ )))?;
+ events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
+
+ for n in 1..=10 {
Timer::after(Duration::from_secs(1)).await;
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
- icon: IconName::FileRust,
- label: "Section 2".into(),
+ icon: IconName::StarFilled,
+ label: format!("Section {n}").into(),
metadata: None,
}))?;
events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
SlashCommandContent::Text {
- text: "World".into(),
+ text: "lorem ipsum ".repeat(n).trim().into(),
run_commands_in_text: false,
},
)))?;
events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
+ }
- for n in 1..=10 {
- Timer::after(Duration::from_secs(1)).await;
-
- events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
- icon: IconName::StarFilled,
- label: format!("Section {n}").into(),
- metadata: None,
- }))?;
- events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
- SlashCommandContent::Text {
- text: "lorem ipsum ".repeat(n).trim().into(),
- run_commands_in_text: false,
- },
- )))?;
- events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
- }
-
- anyhow::Ok(())
- })
- .detach_and_log_err(cx);
+ anyhow::Ok(())
+ })
+ .detach_and_log_err(cx);
Task::ready(Ok(events_rx.boxed()))
}
@@ -4,7 +4,7 @@ use assistant_slash_command::{
SlashCommandResult,
};
use editor::Editor;
-use gpui::{Task, WeakEntity};
+use gpui::{AppContext as _, Task, WeakEntity};
use language::{BufferSnapshot, LspAdapterDelegate};
use std::sync::Arc;
use std::{path::Path, sync::atomic::AtomicBool};
@@ -69,7 +69,7 @@ impl SlashCommand for OutlineSlashCommand {
let snapshot = buffer.read(cx).snapshot();
let path = snapshot.resolve_file_path(cx, true);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let outline = snapshot
.outline(None)
.context("no symbols for active tab")?;
@@ -152,7 +152,7 @@ impl SlashCommand for TabSlashCommand {
cx,
);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut output = SlashCommandOutput::default();
for (full_path, buffer, _) in tab_items_search.await? {
append_buffer_to_output(&buffer, full_path.as_deref(), &mut output).log_err();
@@ -212,74 +212,73 @@ fn tab_items_for_queries(
})??;
let background_executor = cx.background_executor().clone();
- cx.background_executor()
- .spawn(async move {
- open_buffers.sort_by_key(|(_, _, timestamp)| *timestamp);
- if empty_query
- || queries
- .iter()
- .any(|query| query == ALL_TABS_COMPLETION_ITEM)
- {
- return Ok(open_buffers);
- }
-
- let matched_items = if strict_match {
- let match_candidates = open_buffers
- .iter()
- .enumerate()
- .filter_map(|(id, (full_path, ..))| {
- let path_string = full_path.as_deref()?.to_string_lossy().to_string();
- Some((id, path_string))
- })
- .fold(HashMap::default(), |mut candidates, (id, path_string)| {
- candidates
- .entry(path_string)
- .or_insert_with(Vec::new)
- .push(id);
- candidates
- });
+ cx.background_spawn(async move {
+ open_buffers.sort_by_key(|(_, _, timestamp)| *timestamp);
+ if empty_query
+ || queries
+ .iter()
+ .any(|query| query == ALL_TABS_COMPLETION_ITEM)
+ {
+ return Ok(open_buffers);
+ }
- queries
- .iter()
- .filter_map(|query| match_candidates.get(query))
- .flatten()
- .copied()
- .filter_map(|id| open_buffers.get(id))
- .cloned()
- .collect()
- } else {
- let match_candidates = open_buffers
- .iter()
- .enumerate()
- .filter_map(|(id, (full_path, ..))| {
- let path_string = full_path.as_deref()?.to_string_lossy().to_string();
- Some(fuzzy::StringMatchCandidate::new(id, &path_string))
- })
- .collect::<Vec<_>>();
- let mut processed_matches = HashSet::default();
- let file_queries = queries.iter().map(|query| {
- fuzzy::match_strings(
- &match_candidates,
- query,
- true,
- usize::MAX,
- &cancel,
- background_executor.clone(),
- )
+ let matched_items = if strict_match {
+ let match_candidates = open_buffers
+ .iter()
+ .enumerate()
+ .filter_map(|(id, (full_path, ..))| {
+ let path_string = full_path.as_deref()?.to_string_lossy().to_string();
+ Some((id, path_string))
+ })
+ .fold(HashMap::default(), |mut candidates, (id, path_string)| {
+ candidates
+ .entry(path_string)
+ .or_insert_with(Vec::new)
+ .push(id);
+ candidates
});
- join_all(file_queries)
- .await
- .into_iter()
- .flatten()
- .filter(|string_match| processed_matches.insert(string_match.candidate_id))
- .filter_map(|string_match| open_buffers.get(string_match.candidate_id))
- .cloned()
- .collect()
- };
- Ok(matched_items)
- })
- .await
+ queries
+ .iter()
+ .filter_map(|query| match_candidates.get(query))
+ .flatten()
+ .copied()
+ .filter_map(|id| open_buffers.get(id))
+ .cloned()
+ .collect()
+ } else {
+ let match_candidates = open_buffers
+ .iter()
+ .enumerate()
+ .filter_map(|(id, (full_path, ..))| {
+ let path_string = full_path.as_deref()?.to_string_lossy().to_string();
+ Some(fuzzy::StringMatchCandidate::new(id, &path_string))
+ })
+ .collect::<Vec<_>>();
+ let mut processed_matches = HashSet::default();
+ let file_queries = queries.iter().map(|query| {
+ fuzzy::match_strings(
+ &match_candidates,
+ query,
+ true,
+ usize::MAX,
+ &cancel,
+ background_executor.clone(),
+ )
+ });
+
+ join_all(file_queries)
+ .await
+ .into_iter()
+ .flatten()
+ .filter(|string_match| processed_matches.insert(string_match.candidate_id))
+ .filter_map(|string_match| open_buffers.get(string_match.candidate_id))
+ .cloned()
+ .collect()
+ };
+ Ok(matched_items)
+ })
+ .await
})
}
@@ -513,7 +513,7 @@ impl AutoUpdater {
should_show: bool,
cx: &App,
) -> Task<Result<()>> {
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
if should_show {
KEY_VALUE_STORE
.write_kvp(
@@ -531,7 +531,7 @@ impl AutoUpdater {
}
pub fn should_show_update_notification(&self, cx: &App) -> Task<Result<bool>> {
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
Ok(KEY_VALUE_STORE
.read_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?
.is_some())
@@ -1,6 +1,6 @@
use futures::{channel::oneshot, future::OptionFuture};
use git2::{DiffLineType as GitDiffLineType, DiffOptions as GitOptions, Patch as GitPatch};
-use gpui::{App, AsyncApp, Context, Entity, EventEmitter};
+use gpui::{App, AppContext as _, AsyncApp, Context, Entity, EventEmitter};
use language::{Language, LanguageRegistry};
use rope::Rope;
use std::{cmp, future::Future, iter, ops::Range, sync::Arc};
@@ -615,11 +615,9 @@ impl BufferDiff {
cx,
)
});
- let base_text_snapshot = cx
- .background_executor()
- .spawn(OptionFuture::from(base_text_snapshot));
+ let base_text_snapshot = cx.background_spawn(OptionFuture::from(base_text_snapshot));
- let hunks = cx.background_executor().spawn({
+ let hunks = cx.background_spawn({
let buffer = buffer.clone();
async move { compute_hunks(diff_base, buffer) }
});
@@ -641,7 +639,7 @@ impl BufferDiff {
.clone()
.map(|buffer| buffer.as_rope().clone()),
);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
BufferDiffInner {
hunks: compute_hunks(diff_base, buffer),
base_text: diff_base_buffer,
@@ -998,7 +996,7 @@ mod tests {
use std::fmt::Write as _;
use super::*;
- use gpui::{AppContext as _, TestAppContext};
+ use gpui::TestAppContext;
use rand::{rngs::StdRng, Rng as _};
use text::{Buffer, BufferId, Rope};
use unindent::Unindent as _;
@@ -241,7 +241,7 @@ impl ActiveCall {
})
.shared();
self.pending_room_creation = Some(room.clone());
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
room.await.map_err(|err| anyhow!("{:?}", err))?;
anyhow::Ok(())
})
@@ -278,7 +278,7 @@ impl ActiveCall {
};
let client = self.client.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
client
.request(proto::CancelCall {
room_id,
@@ -13,7 +13,7 @@ use client::{
use collections::{BTreeMap, HashMap, HashSet};
use fs::Fs;
use futures::{FutureExt, StreamExt};
-use gpui::{App, AppContext, AsyncApp, Context, Entity, EventEmitter, Task, WeakEntity};
+use gpui::{App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, Task, WeakEntity};
use language::LanguageRegistry;
#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
use livekit::{
@@ -255,7 +255,7 @@ impl Room {
fn app_will_quit(&mut self, cx: &mut Context<Self>) -> impl Future<Output = ()> {
let task = if self.status.is_online() {
let leave = self.leave_internal(cx);
- Some(cx.background_executor().spawn(async move {
+ Some(cx.background_spawn(async move {
leave.await.log_err();
}))
} else {
@@ -322,7 +322,7 @@ impl Room {
self.clear_state(cx);
let leave_room = self.client.request(proto::LeaveRoom {});
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
leave_room.await?;
anyhow::Ok(())
})
@@ -1248,7 +1248,7 @@ impl Room {
};
cx.notify();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
client
.request(proto::UpdateParticipantLocation {
room_id,
@@ -1373,11 +1373,10 @@ impl Room {
match publication {
Ok(publication) => {
if canceled {
- cx.background_executor()
- .spawn(async move {
- participant.unpublish_track(&publication.sid()).await
- })
- .detach_and_log_err(cx)
+ cx.background_spawn(async move {
+ participant.unpublish_track(&publication.sid()).await
+ })
+ .detach_and_log_err(cx)
} else {
if live_kit.muted_by_user || live_kit.deafened {
publication.mute();
@@ -1465,11 +1464,10 @@ impl Room {
match publication {
Ok(publication) => {
if canceled {
- cx.background_executor()
- .spawn(async move {
- participant.unpublish_track(&publication.sid()).await
- })
- .detach()
+ cx.background_spawn(async move {
+ participant.unpublish_track(&publication.sid()).await
+ })
+ .detach()
} else {
live_kit.screen_track = LocalTrack::Published {
track_publication: publication,
@@ -1561,9 +1559,10 @@ impl Room {
{
let local_participant = live_kit.room.local_participant();
let sid = track_publication.sid();
- cx.background_executor()
- .spawn(async move { local_participant.unpublish_track(&sid).await })
- .detach_and_log_err(cx);
+ cx.background_spawn(
+ async move { local_participant.unpublish_track(&sid).await },
+ )
+ .detach_and_log_err(cx);
cx.notify();
}
@@ -1722,13 +1721,12 @@ impl LiveKitRoom {
}
let participant = self.room.local_participant();
- cx.background_executor()
- .spawn(async move {
- for sid in tracks_to_unpublish {
- participant.unpublish_track(&sid).await.log_err();
- }
- })
- .detach();
+ cx.background_spawn(async move {
+ for sid in tracks_to_unpublish {
+ participant.unpublish_track(&sid).await.log_err();
+ }
+ })
+ .detach();
}
}
@@ -234,7 +234,7 @@ impl ActiveCall {
})
.shared();
self.pending_room_creation = Some(room.clone());
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
room.await.map_err(|err| anyhow!("{:?}", err))?;
anyhow::Ok(())
})
@@ -271,7 +271,7 @@ impl ActiveCall {
};
let client = self.client.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
client
.request(proto::CancelCall {
room_id,
@@ -311,7 +311,7 @@ impl Room {
fn app_will_quit(&mut self, cx: &mut Context<Self>) -> impl Future<Output = ()> {
let task = if self.status.is_online() {
let leave = self.leave_internal(cx);
- Some(cx.background_executor().spawn(async move {
+ Some(cx.background_spawn(async move {
leave.await.log_err();
}))
} else {
@@ -378,7 +378,7 @@ impl Room {
self.clear_state(cx);
let leave_room = self.client.request(proto::LeaveRoom {});
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
leave_room.await?;
anyhow::Ok(())
})
@@ -1268,7 +1268,7 @@ impl Room {
};
cx.notify();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
client
.request(proto::UpdateParticipantLocation {
room_id,
@@ -1385,9 +1385,7 @@ impl Room {
live_kit.room.unpublish_track(publication);
} else {
if live_kit.muted_by_user || live_kit.deafened {
- cx.background_executor()
- .spawn(publication.set_mute(true))
- .detach();
+ cx.background_spawn(publication.set_mute(true)).detach();
}
live_kit.microphone_track = LocalTrack::Published {
track_publication: publication,
@@ -514,8 +514,7 @@ impl ChannelStore {
}
}
};
- cx.background_executor()
- .spawn(async move { task.await.map_err(|error| anyhow!("{}", error)) })
+ cx.background_spawn(async move { task.await.map_err(|error| anyhow!("{}", error)) })
}
pub fn is_channel_admin(&self, channel_id: ChannelId) -> bool {
@@ -781,7 +780,7 @@ impl ChannelStore {
cx: &mut Context<Self>,
) -> Task<Result<()>> {
let client = self.client.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
client
.request(proto::RespondToChannelInvite {
channel_id: channel_id.0,
@@ -975,21 +974,18 @@ impl ChannelStore {
if let Some(operations) = operations {
let client = this.client.clone();
- cx.background_executor()
- .spawn(async move {
- let operations = operations.await;
- for chunk in
- language::proto::split_operations(operations)
- {
- client
- .send(proto::UpdateChannelBuffer {
- channel_id: channel_id.0,
- operations: chunk,
- })
- .ok();
- }
- })
- .detach();
+ cx.background_spawn(async move {
+ let operations = operations.await;
+ for chunk in language::proto::split_operations(operations) {
+ client
+ .send(proto::UpdateChannelBuffer {
+ channel_id: channel_id.0,
+ operations: chunk,
+ })
+ .ok();
+ }
+ })
+ .detach();
return true;
}
}
@@ -19,7 +19,7 @@ use futures::{
channel::oneshot, future::BoxFuture, AsyncReadExt, FutureExt, SinkExt, Stream, StreamExt,
TryFutureExt as _, TryStreamExt,
};
-use gpui::{actions, App, AsyncApp, Entity, Global, Task, WeakEntity};
+use gpui::{actions, App, AppContext as _, AsyncApp, Entity, Global, Task, WeakEntity};
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
use parking_lot::RwLock;
use postage::watch;
@@ -1064,7 +1064,7 @@ impl Client {
let rpc_url = self.rpc_url(http, release_channel);
let system_id = self.telemetry.system_id();
let metrics_id = self.telemetry.metrics_id();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
use HttpOrHttps::*;
#[derive(Debug)]
@@ -1743,7 +1743,7 @@ mod tests {
use crate::test::FakeServer;
use clock::FakeSystemClock;
- use gpui::{AppContext as _, BackgroundExecutor, TestAppContext};
+ use gpui::{BackgroundExecutor, TestAppContext};
use http_client::FakeHttpClient;
use parking_lot::Mutex;
use proto::TypedEnvelope;
@@ -1806,7 +1806,7 @@ mod tests {
// Time out when client tries to connect.
client.override_authenticate(move |cx| {
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
Ok(Credentials {
user_id,
access_token: "token".into(),
@@ -1814,7 +1814,7 @@ mod tests {
})
});
client.override_establish_connection(|_, cx| {
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
future::pending::<()>().await;
unreachable!()
})
@@ -1848,7 +1848,7 @@ mod tests {
// Time out when re-establishing the connection.
server.allow_connections();
client.override_establish_connection(|_, cx| {
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
future::pending::<()>().await;
unreachable!()
})
@@ -1887,7 +1887,7 @@ mod tests {
move |cx| {
let auth_count = auth_count.clone();
let dropped_auth_count = dropped_auth_count.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
*auth_count.lock() += 1;
let _drop = util::defer(move || *dropped_auth_count.lock() += 1);
future::pending::<()>().await;
@@ -5,7 +5,7 @@ use anyhow::Result;
use clock::SystemClock;
use futures::channel::mpsc;
use futures::{Future, StreamExt};
-use gpui::{App, BackgroundExecutor, Task};
+use gpui::{App, AppContext as _, BackgroundExecutor, Task};
use http_client::{self, AsyncBody, HttpClient, HttpClientWithUrl, Method, Request};
use parking_lot::Mutex;
use release_channel::ReleaseChannel;
@@ -219,18 +219,17 @@ impl Telemetry {
}));
Self::log_file_path();
- cx.background_executor()
- .spawn({
- let state = state.clone();
- let os_version = os_version();
- state.lock().os_version = Some(os_version.clone());
- async move {
- if let Some(tempfile) = File::create(Self::log_file_path()).log_err() {
- state.lock().log_file = Some(tempfile);
- }
+ cx.background_spawn({
+ let state = state.clone();
+ let os_version = os_version();
+ state.lock().os_version = Some(os_version.clone());
+ async move {
+ if let Some(tempfile) = File::create(Self::log_file_path()).log_err() {
+ state.lock().log_file = Some(tempfile);
}
- })
- .detach();
+ }
+ })
+ .detach();
cx.observe_global::<SettingsStore>({
let state = state.clone();
@@ -252,17 +251,16 @@ impl Telemetry {
let (tx, mut rx) = mpsc::unbounded();
::telemetry::init(tx);
- cx.background_executor()
- .spawn({
- let this = Arc::downgrade(&this);
- async move {
- while let Some(event) = rx.next().await {
- let Some(state) = this.upgrade() else { break };
- state.report_event(Event::Flexible(event))
- }
+ cx.background_spawn({
+ let this = Arc::downgrade(&this);
+ async move {
+ while let Some(event) = rx.next().await {
+ let Some(state) = this.upgrade() else { break };
+ state.report_event(Event::Flexible(event))
}
- })
- .detach();
+ }
+ })
+ .detach();
// We should only ever have one instance of Telemetry, leak the subscription to keep it alive
// rather than store in TelemetryState, complicating spawn as subscriptions are not Send
@@ -85,7 +85,7 @@ impl FakeServer {
Connection::in_memory(cx.background_executor().clone());
let (connection_id, io, incoming) =
peer.add_test_connection(server_conn, cx.background_executor().clone());
- cx.background_executor().spawn(io).detach();
+ cx.background_spawn(io).detach();
{
let mut state = state.lock();
state.connection_id = Some(connection_id);
@@ -244,18 +244,17 @@ impl TestServer {
.await
.expect("retrieving user failed")
.unwrap();
- cx.background_executor()
- .spawn(server.handle_connection(
- server_conn,
- client_name,
- Principal::User(user),
- ZedVersion(SemanticVersion::new(1, 0, 0)),
- None,
- None,
- Some(connection_id_tx),
- Executor::Deterministic(cx.background_executor().clone()),
- ))
- .detach();
+ cx.background_spawn(server.handle_connection(
+ server_conn,
+ client_name,
+ Principal::User(user),
+ ZedVersion(SemanticVersion::new(1, 0, 0)),
+ None,
+ None,
+ Some(connection_id_tx),
+ Executor::Deterministic(cx.background_executor().clone()),
+ ))
+ .detach();
let connection_id = connection_id_rx.await.map_err(|e| {
EstablishConnectionError::Other(anyhow!(
"{} (is server shutting down?)",
@@ -201,8 +201,7 @@ impl ChatPanel {
) -> Task<Result<Entity<Self>>> {
cx.spawn(|mut cx| async move {
let serialized_panel = if let Some(panel) = cx
- .background_executor()
- .spawn(async move { KEY_VALUE_STORE.read_kvp(CHAT_PANEL_KEY) })
+ .background_spawn(async move { KEY_VALUE_STORE.read_kvp(CHAT_PANEL_KEY) })
.await
.log_err()
.flatten()
@@ -227,7 +226,7 @@ impl ChatPanel {
fn serialize(&mut self, cx: &mut Context<Self>) {
let width = self.width;
- self.pending_serialization = cx.background_executor().spawn(
+ self.pending_serialization = cx.background_spawn(
async move {
KEY_VALUE_STORE
.write_kvp(
@@ -454,8 +454,7 @@ impl MessageEditor {
mut cx: AsyncWindowContext,
) {
let (buffer, ranges) = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
let ranges = MENTIONS_SEARCH.search(&buffer, None).await;
(buffer, ranges)
})
@@ -319,8 +319,7 @@ impl CollabPanel {
mut cx: AsyncWindowContext,
) -> anyhow::Result<Entity<Self>> {
let serialized_panel = cx
- .background_executor()
- .spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
+ .background_spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
.await
.map_err(|_| anyhow::anyhow!("Failed to read collaboration panel from key value store"))
.log_err()
@@ -351,7 +350,7 @@ impl CollabPanel {
fn serialize(&mut self, cx: &mut Context<Self>) {
let width = self.width;
let collapsed_channels = self.collapsed_channels.clone();
- self.pending_serialization = cx.background_executor().spawn(
+ self.pending_serialization = cx.background_spawn(
async move {
KEY_VALUE_STORE
.write_kvp(
@@ -183,8 +183,7 @@ impl NotificationPanel {
) -> Task<Result<Entity<Self>>> {
cx.spawn(|mut cx| async move {
let serialized_panel = if let Some(panel) = cx
- .background_executor()
- .spawn(async move { KEY_VALUE_STORE.read_kvp(NOTIFICATION_PANEL_KEY) })
+ .background_spawn(async move { KEY_VALUE_STORE.read_kvp(NOTIFICATION_PANEL_KEY) })
.await
.log_err()
.flatten()
@@ -209,7 +208,7 @@ impl NotificationPanel {
fn serialize(&mut self, cx: &mut Context<Self>) {
let width = self.width;
- self.pending_serialization = cx.background_executor().spawn(
+ self.pending_serialization = cx.background_spawn(
async move {
KEY_VALUE_STORE
.write_kvp(
@@ -281,7 +281,7 @@ impl PickerDelegate for CommandPaletteDelegate {
query = alias.to_string();
}
let (mut tx, mut rx) = postage::dispatch::channel(1);
- let task = cx.background_executor().spawn({
+ let task = cx.background_spawn({
let mut commands = self.all_commands.clone();
let hit_counts = cx.global::<HitCounts>().clone();
let executor = cx.background_executor().clone();
@@ -1,7 +1,7 @@
use anyhow::{anyhow, Context as _, Result};
use collections::HashMap;
use futures::{channel::oneshot, io::BufWriter, select, AsyncRead, AsyncWrite, FutureExt};
-use gpui::{AsyncApp, BackgroundExecutor, Task};
+use gpui::{AppContext as _, AsyncApp, BackgroundExecutor, Task};
use parking_lot::Mutex;
use postage::barrier;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
@@ -192,7 +192,7 @@ impl Client {
let (stdout, stderr) = futures::join!(stdout_input_task, stderr_input_task);
stdout.or(stderr)
});
- let output_task = cx.background_executor().spawn({
+ let output_task = cx.background_spawn({
Self::handle_output(
stdin,
outbound_rx,
@@ -234,8 +234,7 @@ impl RegisteredBuffer {
let new_snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot()).ok()?;
let content_changes = cx
- .background_executor()
- .spawn({
+ .background_spawn({
let new_snapshot = new_snapshot.clone();
async move {
new_snapshot
@@ -588,8 +587,7 @@ impl Copilot {
}
};
- cx.background_executor()
- .spawn(task.map_err(|err| anyhow!("{:?}", err)))
+ cx.background_spawn(task.map_err(|err| anyhow!("{:?}", err)))
} else {
// If we're downloading, wait until download is finished
// If we're in a stuck state, display to the user
@@ -601,7 +599,7 @@ impl Copilot {
self.update_sign_in_status(request::SignInStatus::NotSignedIn, cx);
if let CopilotServer::Running(RunningCopilotServer { lsp: server, .. }) = &self.server {
let server = server.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
server
.request::<request::SignOut>(request::SignOutParams {})
.await?;
@@ -631,7 +629,7 @@ impl Copilot {
cx.notify();
- cx.background_executor().spawn(start_task)
+ cx.background_spawn(start_task)
}
pub fn language_server(&self) -> Option<&Arc<LanguageServer>> {
@@ -813,7 +811,7 @@ impl Copilot {
.request::<request::NotifyAccepted>(request::NotifyAcceptedParams {
uuid: completion.uuid.clone(),
});
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
request.await?;
Ok(())
})
@@ -837,7 +835,7 @@ impl Copilot {
.map(|completion| completion.uuid.clone())
.collect(),
});
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
request.await?;
Ok(())
})
@@ -884,7 +882,7 @@ impl Copilot {
.map(|file| file.path().to_path_buf())
.unwrap_or_default();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let (version, snapshot) = snapshot.await?;
let result = lsp
.request::<R>(request::GetCompletionsParams {
@@ -4,7 +4,7 @@ pub mod query;
// Re-export
pub use anyhow;
use anyhow::Context as _;
-use gpui::App;
+use gpui::{App, AppContext};
pub use indoc::indoc;
pub use paths::database_dir;
pub use smol;
@@ -192,8 +192,7 @@ pub fn write_and_log<F>(cx: &App, db_write: impl FnOnce() -> F + Send + 'static)
where
F: Future<Output = anyhow::Result<()>> + Send,
{
- cx.background_executor()
- .spawn(async move { db_write().await.log_err() })
+ cx.background_spawn(async move { db_write().await.log_err() })
.detach()
}
@@ -171,7 +171,7 @@ impl WrapMap {
let text_system = cx.text_system().clone();
let (font, font_size) = self.font_with_size.clone();
- let task = cx.background_executor().spawn(async move {
+ let task = cx.background_spawn(async move {
let mut line_wrapper = text_system.line_wrapper(font, font_size);
let tab_snapshot = new_snapshot.tab_snapshot.clone();
let range = TabPoint::zero()..tab_snapshot.max_point();
@@ -255,7 +255,7 @@ impl WrapMap {
let mut snapshot = self.snapshot.clone();
let text_system = cx.text_system().clone();
let (font, font_size) = self.font_with_size.clone();
- let update_task = cx.background_executor().spawn(async move {
+ let update_task = cx.background_spawn(async move {
let mut edits = Patch::default();
let mut line_wrapper = text_system.line_wrapper(font, font_size);
for (tab_snapshot, tab_edits) in pending_edits {
@@ -4798,7 +4798,7 @@ impl Editor {
let Some(matches_task) = editor
.read_with(&mut cx, |editor, cx| {
let buffer = editor.buffer().read(cx).snapshot(cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut ranges = Vec::new();
let buffer_ranges =
vec![buffer.anchor_before(0)..buffer.anchor_after(buffer.len())];
@@ -10221,13 +10221,12 @@ impl Editor {
return;
}
let new_rows =
- cx.background_executor()
- .spawn({
- let snapshot = display_snapshot.clone();
- async move {
- Self::fetch_runnable_ranges(&snapshot, Anchor::min()..Anchor::max())
- }
- })
+ cx.background_spawn({
+ let snapshot = display_snapshot.clone();
+ async move {
+ Self::fetch_runnable_ranges(&snapshot, Anchor::min()..Anchor::max())
+ }
+ })
.await;
let rows = Self::runnable_rows(project, display_snapshot, new_rows, cx.clone());
@@ -10989,7 +10988,7 @@ impl Editor {
HoverLink::InlayHint(lsp_location, server_id) => {
let computation =
self.compute_target_location(lsp_location, server_id, window, cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let location = computation.await?;
Ok(TargetTaskResult::Location(location))
})
@@ -15587,7 +15586,7 @@ fn snippet_completions(
let scope = language.map(|language| language.default_scope());
let executor = cx.background_executor().clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let classifier = CharClassifier::new(scope).for_completion(true);
let mut last_word = chars
.chars()
@@ -15717,7 +15716,7 @@ impl CompletionProvider for Entity<Project> {
self.update(cx, |project, cx| {
let snippets = snippet_completions(project, buffer, buffer_position, cx);
let project_completions = project.completions(buffer, buffer_position, options, cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut completions = project_completions.await?;
let snippets_completions = snippets.await?;
completions.extend(snippets_completions);
@@ -5264,8 +5264,7 @@ impl EditorElement {
Some(cx.spawn_in(window, |editor, mut cx| async move {
let scrollbar_size = scrollbar_layout.hitbox.size;
let scrollbar_markers = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
let max_point = snapshot.display_snapshot.buffer_snapshot.max_point();
let mut marker_quads = Vec::new();
if scrollbar_settings.git_diff {
@@ -4,7 +4,7 @@ use git::{
blame::{Blame, BlameEntry},
parse_git_remote_url, GitHostingProvider, GitHostingProviderRegistry, Oid,
};
-use gpui::{App, Context, Entity, Subscription, Task};
+use gpui::{App, AppContext as _, Context, Entity, Subscription, Task};
use http_client::HttpClient;
use language::{markdown, Bias, Buffer, BufferSnapshot, Edit, LanguageRegistry, ParsedMarkdown};
use multi_buffer::RowInfo;
@@ -360,8 +360,7 @@ impl GitBlame {
self.task = cx.spawn(|this, mut cx| async move {
let result = cx
- .background_executor()
- .spawn({
+ .background_spawn({
let snapshot = snapshot.clone();
async move {
let Some(Blame {
@@ -549,7 +548,7 @@ async fn parse_markdown(text: &str, language_registry: &Arc<LanguageRegistry>) -
#[cfg(test)]
mod tests {
use super::*;
- use gpui::{AppContext as _, Context};
+ use gpui::Context;
use language::{Point, Rope};
use project::FakeFs;
use rand::prelude::*;
@@ -1,7 +1,7 @@
use collections::{HashMap, HashSet};
use git::diff::DiffHunkStatus;
use gpui::{
- Action, AppContext, Corner, CursorStyle, Focusable as _, Hsla, Model, MouseButton,
+ Action, AppContext as _, Corner, CursorStyle, Focusable as _, Hsla, Model, MouseButton,
Subscription, Task,
};
use language::{Buffer, BufferId, Point};
@@ -372,7 +372,7 @@ impl Editor {
self.diff_map
.hunk_update_tasks
- .insert(None, cx.background_executor().spawn(new_toggle_task));
+ .insert(None, cx.background_spawn(new_toggle_task));
}
pub(super) fn expand_diff_hunk(
@@ -1089,10 +1089,9 @@ impl Editor {
.ok();
});
- diff_map.hunk_update_tasks.insert(
- Some(buffer_id),
- cx.background_executor().spawn(new_sync_task),
- );
+ diff_map
+ .hunk_update_tasks
+ .insert(Some(buffer_id), cx.background_spawn(new_sync_task));
}
fn go_to_subsequent_hunk(
@@ -1,7 +1,7 @@
use std::{ops::Range, time::Duration};
use collections::HashSet;
-use gpui::{App, Context, Task, Window};
+use gpui::{App, AppContext as _, Context, Task, Window};
use language::language_settings::language_settings;
use multi_buffer::{IndentGuide, MultiBufferRow};
use text::{LineIndent, Point};
@@ -102,9 +102,7 @@ impl Editor {
let snapshot = snapshot.clone();
- let task = cx
- .background_executor()
- .spawn(resolve_indented_range(snapshot, cursor_row));
+ let task = cx.background_spawn(resolve_indented_range(snapshot, cursor_row));
// Try to resolve the indent in a short amount of time, otherwise move it to a background task.
match cx
@@ -115,7 +113,7 @@ impl Editor {
Err(future) => {
state.pending_refresh =
Some(cx.spawn_in(window, |editor, mut cx| async move {
- let result = cx.background_executor().spawn(future).await;
+ let result = cx.background_spawn(future).await;
editor
.update(&mut cx, |editor, _| {
editor.active_indent_guides_state.active_indent_range = result;
@@ -19,7 +19,7 @@ use crate::{
use anyhow::Context as _;
use clock::Global;
use futures::future;
-use gpui::{AsyncApp, Context, Entity, Task, Window};
+use gpui::{AppContext as _, AsyncApp, Context, Entity, Task, Window};
use language::{language_settings::InlayHintKind, Buffer, BufferSnapshot};
use parking_lot::RwLock;
use project::{InlayHint, ResolveState};
@@ -996,19 +996,17 @@ fn fetch_and_update_hints(
let background_task_buffer_snapshot = buffer_snapshot.clone();
let background_fetch_range = fetch_range.clone();
- let new_update = cx
- .background_executor()
- .spawn(async move {
- calculate_hint_updates(
- query.excerpt_id,
- invalidate,
- background_fetch_range,
- new_hints,
- &background_task_buffer_snapshot,
- cached_excerpt_hints,
- &visible_hints,
- )
- })
+ let new_update = cx.background_spawn(async move {
+ calculate_hint_updates(
+ query.excerpt_id,
+ invalidate,
+ background_fetch_range,
+ new_hints,
+ &background_task_buffer_snapshot,
+ cached_excerpt_hints,
+ &visible_hints,
+ )
+ })
.await;
if let Some(new_update) = new_update {
log::debug!(
@@ -1225,28 +1225,27 @@ impl SerializableItem for Editor {
let snapshot = buffer.read(cx).snapshot();
Some(cx.spawn_in(window, |_this, cx| async move {
- cx.background_executor()
- .spawn(async move {
- let (contents, language) = if serialize_dirty_buffers && is_dirty {
- let contents = snapshot.text();
- let language = snapshot.language().map(|lang| lang.name().to_string());
- (Some(contents), language)
- } else {
- (None, None)
- };
+ cx.background_spawn(async move {
+ let (contents, language) = if serialize_dirty_buffers && is_dirty {
+ let contents = snapshot.text();
+ let language = snapshot.language().map(|lang| lang.name().to_string());
+ (Some(contents), language)
+ } else {
+ (None, None)
+ };
- let editor = SerializedEditor {
- abs_path,
- contents,
- language,
- mtime,
- };
- DB.save_serialized_editor(item_id, workspace_id, editor)
- .await
- .context("failed to save serialized editor")
- })
- .await
- .context("failed to save contents of buffer")?;
+ let editor = SerializedEditor {
+ abs_path,
+ contents,
+ language,
+ mtime,
+ };
+ DB.save_serialized_editor(item_id, workspace_id, editor)
+ .await
+ .context("failed to save serialized editor")
+ })
+ .await
+ .context("failed to save contents of buffer")?;
Ok(())
}))
@@ -1540,7 +1539,7 @@ impl SearchableItem for Editor {
ranges.iter().cloned().collect::<Vec<_>>()
});
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut ranges = Vec::new();
let search_within_ranges = if search_within_ranges.is_empty() {
@@ -1,6 +1,6 @@
use crate::Editor;
-use gpui::{App, Task as AsyncTask, Window};
+use gpui::{App, AppContext as _, Task as AsyncTask, Window};
use project::Location;
use task::{TaskContext, TaskVariables, VariableName};
use text::{ToOffset, ToPoint};
@@ -88,7 +88,6 @@ pub fn task_context(
};
editor.update(cx, |editor, cx| {
let context_task = task_context_with_editor(editor, window, cx);
- cx.background_executor()
- .spawn(async move { context_task.await.unwrap_or_default() })
+ cx.background_spawn(async move { context_task.await.unwrap_or_default() })
})
}
@@ -324,10 +324,7 @@ impl ExtensionStore {
load_initial_extensions.await;
let mut index_changed = false;
- let mut debounce_timer = cx
- .background_executor()
- .spawn(futures::future::pending())
- .fuse();
+ let mut debounce_timer = cx.background_spawn(futures::future::pending()).fuse();
loop {
select_biased! {
_ = debounce_timer => {
@@ -370,7 +367,7 @@ impl ExtensionStore {
// Watch the installed extensions directory for changes. Whenever changes are
// detected, rebuild the extension index, and load/unload any extensions that
// have been added, removed, or modified.
- this.tasks.push(cx.background_executor().spawn({
+ this.tasks.push(cx.background_spawn({
let fs = this.fs.clone();
let reload_tx = this.reload_tx.clone();
let installed_dir = this.installed_dir.clone();
@@ -886,20 +883,19 @@ impl ExtensionStore {
}
});
- cx.background_executor()
- .spawn({
- let extension_source_path = extension_source_path.clone();
- async move {
- builder
- .compile_extension(
- &extension_source_path,
- &mut extension_manifest,
- CompileExtensionOptions { release: false },
- )
- .await
- }
- })
- .await?;
+ cx.background_spawn({
+ let extension_source_path = extension_source_path.clone();
+ async move {
+ builder
+ .compile_extension(
+ &extension_source_path,
+ &mut extension_manifest,
+ CompileExtensionOptions { release: false },
+ )
+ .await
+ }
+ })
+ .await?;
let output_path = &extensions_dir.join(extension_id.as_ref());
if let Some(metadata) = fs.metadata(output_path).await? {
@@ -937,7 +933,7 @@ impl ExtensionStore {
};
cx.notify();
- let compile = cx.background_executor().spawn(async move {
+ let compile = cx.background_spawn(async move {
let mut manifest = ExtensionManifest::load(fs, &path).await?;
builder
.compile_extension(
@@ -1192,35 +1188,33 @@ impl ExtensionStore {
cx.emit(Event::ExtensionsUpdated);
cx.spawn(|this, mut cx| async move {
- cx.background_executor()
- .spawn({
- let fs = fs.clone();
- async move {
- for theme_path in themes_to_add.into_iter() {
- proxy
- .load_user_theme(theme_path, fs.clone())
- .await
- .log_err();
- }
+ cx.background_spawn({
+ let fs = fs.clone();
+ async move {
+ for theme_path in themes_to_add.into_iter() {
+ proxy
+ .load_user_theme(theme_path, fs.clone())
+ .await
+ .log_err();
+ }
- for (icon_theme_path, icons_root_path) in icon_themes_to_add.into_iter() {
+ for (icon_theme_path, icons_root_path) in icon_themes_to_add.into_iter() {
+ proxy
+ .load_icon_theme(icon_theme_path, icons_root_path, fs.clone())
+ .await
+ .log_err();
+ }
+
+ for snippets_path in &snippets_to_add {
+ if let Some(snippets_contents) = fs.load(snippets_path).await.log_err() {
proxy
- .load_icon_theme(icon_theme_path, icons_root_path, fs.clone())
- .await
+ .register_snippet(snippets_path, &snippets_contents)
.log_err();
}
-
- for snippets_path in &snippets_to_add {
- if let Some(snippets_contents) = fs.load(snippets_path).await.log_err()
- {
- proxy
- .register_snippet(snippets_path, &snippets_contents)
- .log_err();
- }
- }
}
- })
- .await;
+ }
+ })
+ .await;
let mut wasm_extensions = Vec::new();
for extension in extension_entries {
@@ -1304,7 +1298,7 @@ impl ExtensionStore {
let extensions_dir = self.installed_dir.clone();
let index_path = self.index_path.clone();
let proxy = self.proxy.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let start_time = Instant::now();
let mut index = ExtensionIndex::default();
@@ -1494,7 +1488,7 @@ impl ExtensionStore {
return Task::ready(Err(anyhow!("extension no longer installed")));
};
let fs = self.fs.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
const EXTENSION_TOML: &str = "extension.toml";
const EXTENSION_WASM: &str = "extension.wasm";
const CONFIG_TOML: &str = "config.toml";
@@ -1,5 +1,5 @@
use client::telemetry;
-use gpui::{App, Task, Window};
+use gpui::{App, AppContext as _, Task, Window};
use human_bytes::human_bytes;
use release_channel::{AppCommitSha, AppVersion, ReleaseChannel};
use serde::Serialize;
@@ -44,7 +44,7 @@ impl SystemSpecs {
None
};
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let os_version = telemetry::os_version();
SystemSpecs {
app_version,
@@ -127,7 +127,7 @@ impl FileFinder {
let abs_path = abs_path?;
if project.is_local() {
let fs = fs.clone();
- Some(cx.background_executor().spawn(async move {
+ Some(cx.background_spawn(async move {
if fs.is_file(&abs_path).await {
Some(FoundPath::new(project_path, Some(abs_path)))
} else {
@@ -337,7 +337,7 @@ impl GitPanel {
fn serialize(&mut self, cx: &mut Context<Self>) {
let width = self.width;
- self.pending_serialization = cx.background_executor().spawn(
+ self.pending_serialization = cx.background_spawn(
async move {
KEY_VALUE_STORE
.write_kvp(
@@ -1055,8 +1055,7 @@ impl GitPanel {
let task = if self.has_staged_changes() {
// Repository serializes all git operations, so we can just send a commit immediately
let commit_task = active_repository.read(cx).commit(message.into(), None);
- cx.background_executor()
- .spawn(async move { commit_task.await? })
+ cx.background_spawn(async move { commit_task.await? })
} else {
let changed_files = self
.entries
@@ -7,7 +7,7 @@ use editor::{scroll::Autoscroll, Editor, EditorEvent, ToPoint};
use feature_flags::FeatureFlagViewExt;
use futures::StreamExt;
use gpui::{
- actions, AnyElement, AnyView, App, AppContext, AsyncWindowContext, Entity, EventEmitter,
+ actions, AnyElement, AnyView, App, AppContext as _, AsyncWindowContext, Entity, EventEmitter,
FocusHandle, Focusable, Render, Subscription, Task, WeakEntity,
};
use language::{Anchor, Buffer, Capability, OffsetRangeExt, Point};
@@ -177,8 +177,7 @@ impl PickerDelegate for RepositorySelectorDelegate {
cx.spawn_in(window, |this, mut cx| async move {
let filtered_repositories = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
if query.is_empty() {
all_repositories
} else {
@@ -252,7 +252,7 @@ impl SerializableItem for ImageView {
let workspace_id = workspace.database_id()?;
let image_path = self.image_item.read(cx).file.as_local()?.abs_path(cx);
- Some(cx.background_executor().spawn({
+ Some(cx.background_spawn({
async move {
IMAGE_VIEWER
.save_image_path(item_id, workspace_id, image_path)
@@ -2,7 +2,7 @@ use anyhow::Result;
use chrono::{Datelike, Local, NaiveTime, Timelike};
use editor::scroll::Autoscroll;
use editor::Editor;
-use gpui::{actions, App, Context, Window};
+use gpui::{actions, App, AppContext as _, Context, Window};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
@@ -87,7 +87,7 @@ pub fn new_journal_entry(workspace: &Workspace, window: &mut Window, cx: &mut Ap
let now = now.time();
let entry_heading = heading_entry(now, &settings.hour_format);
- let create_entry = cx.background_executor().spawn(async move {
+ let create_entry = cx.background_spawn(async move {
std::fs::create_dir_all(month_dir)?;
OpenOptions::new()
.create(true)
@@ -940,7 +940,7 @@ impl Buffer {
}
let text_operations = self.text.operations().clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let since = since.unwrap_or_default();
operations.extend(
text_operations
@@ -1135,7 +1135,7 @@ impl Buffer {
let old_snapshot = self.text.snapshot();
let mut branch_buffer = self.text.branch();
let mut syntax_snapshot = self.syntax_map.lock().snapshot();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
if !edits.is_empty() {
if let Some(language) = language.clone() {
syntax_snapshot.reparse(&old_snapshot, registry.clone(), language);
@@ -1499,7 +1499,7 @@ impl Buffer {
let mut syntax_snapshot = syntax_map.snapshot();
drop(syntax_map);
- let parse_task = cx.background_executor().spawn({
+ let parse_task = cx.background_spawn({
let language = language.clone();
let language_registry = language_registry.clone();
async move {
@@ -1578,7 +1578,7 @@ impl Buffer {
fn request_autoindent(&mut self, cx: &mut Context<Self>) {
if let Some(indent_sizes) = self.compute_autoindents() {
- let indent_sizes = cx.background_executor().spawn(indent_sizes);
+ let indent_sizes = cx.background_spawn(indent_sizes);
match cx
.background_executor()
.block_with_timeout(Duration::from_micros(500), indent_sizes)
@@ -1907,7 +1907,7 @@ impl Buffer {
let old_text = self.as_rope().clone();
let line_ending = self.line_ending();
let base_version = self.version();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let ranges = trailing_whitespace_ranges(&old_text);
let empty = Arc::<str>::from("");
Diff {
@@ -940,6 +940,8 @@ impl LanguageRegistry {
binary: lsp::LanguageServerBinary,
cx: gpui::AsyncApp,
) -> Option<lsp::LanguageServer> {
+ use gpui::AppContext as _;
+
let mut state = self.state.write();
let fake_entry = state.fake_server_entries.get_mut(&name)?;
let (server, mut fake_server) = lsp::FakeLanguageServer::new(
@@ -956,17 +958,16 @@ impl LanguageRegistry {
}
let tx = fake_entry.tx.clone();
- cx.background_executor()
- .spawn(async move {
- if fake_server
- .try_receive_notification::<lsp::notification::Initialized>()
- .await
- .is_some()
- {
- tx.unbounded_send(fake_server.clone()).ok();
- }
- })
- .detach();
+ cx.background_spawn(async move {
+ if fake_server
+ .try_receive_notification::<lsp::notification::Initialized>()
+ .await
+ .is_some()
+ {
+ tx.unbounded_send(fake_server.clone()).ok();
+ }
+ })
+ .detach();
Some(server)
}
@@ -3,7 +3,9 @@ use std::io::{Cursor, Write};
use crate::role::Role;
use crate::LanguageModelToolUse;
use base64::write::EncoderWriter;
-use gpui::{point, size, App, DevicePixels, Image, ObjectFit, RenderImage, Size, Task};
+use gpui::{
+ point, size, App, AppContext as _, DevicePixels, Image, ObjectFit, RenderImage, Size, Task,
+};
use image::{codecs::png::PngEncoder, imageops::resize, DynamicImage, ImageDecoder};
use serde::{Deserialize, Serialize};
use ui::{px, SharedString};
@@ -30,7 +32,7 @@ const ANTHROPIC_SIZE_LIMT: f32 = 1568.;
impl LanguageModelImage {
pub fn from_image(data: Image, cx: &mut App) -> Task<Option<Self>> {
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
match data.format() {
gpui::ImageFormat::Png
| gpui::ImageFormat::Jpeg
@@ -228,8 +228,7 @@ impl PickerDelegate for LanguageModelPickerDelegate {
cx.spawn_in(window, |this, mut cx| async move {
let filtered_models = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
let displayed_models = if configured_providers.is_empty() {
all_models
} else {
@@ -252,54 +252,53 @@ pub fn count_anthropic_tokens(
request: LanguageModelRequest,
cx: &App,
) -> BoxFuture<'static, Result<usize>> {
- cx.background_executor()
- .spawn(async move {
- let messages = request.messages;
- let mut tokens_from_images = 0;
- let mut string_messages = Vec::with_capacity(messages.len());
+ cx.background_spawn(async move {
+ let messages = request.messages;
+ let mut tokens_from_images = 0;
+ let mut string_messages = Vec::with_capacity(messages.len());
- for message in messages {
- use language_model::MessageContent;
+ for message in messages {
+ use language_model::MessageContent;
- let mut string_contents = String::new();
+ let mut string_contents = String::new();
- for content in message.content {
- match content {
- MessageContent::Text(text) => {
- string_contents.push_str(&text);
- }
- MessageContent::Image(image) => {
- tokens_from_images += image.estimate_tokens();
- }
- MessageContent::ToolUse(_tool_use) => {
- // TODO: Estimate token usage from tool uses.
- }
- MessageContent::ToolResult(tool_result) => {
- string_contents.push_str(&tool_result.content);
- }
+ for content in message.content {
+ match content {
+ MessageContent::Text(text) => {
+ string_contents.push_str(&text);
+ }
+ MessageContent::Image(image) => {
+ tokens_from_images += image.estimate_tokens();
+ }
+ MessageContent::ToolUse(_tool_use) => {
+ // TODO: Estimate token usage from tool uses.
+ }
+ MessageContent::ToolResult(tool_result) => {
+ string_contents.push_str(&tool_result.content);
}
}
+ }
- if !string_contents.is_empty() {
- string_messages.push(tiktoken_rs::ChatCompletionRequestMessage {
- role: match message.role {
- Role::User => "user".into(),
- Role::Assistant => "assistant".into(),
- Role::System => "system".into(),
- },
- content: Some(string_contents),
- name: None,
- function_call: None,
- });
- }
+ if !string_contents.is_empty() {
+ string_messages.push(tiktoken_rs::ChatCompletionRequestMessage {
+ role: match message.role {
+ Role::User => "user".into(),
+ Role::Assistant => "assistant".into(),
+ Role::System => "system".into(),
+ },
+ content: Some(string_contents),
+ name: None,
+ function_call: None,
+ });
}
+ }
- // Tiktoken doesn't yet support these models, so we manually use the
- // same tokenizer as GPT-4.
- tiktoken_rs::num_tokens_from_messages("gpt-4", &string_messages)
- .map(|tokens| tokens + tokens_from_images)
- })
- .boxed()
+ // Tiktoken doesn't yet support these models, so we manually use the
+ // same tokenizer as GPT-4.
+ tiktoken_rs::num_tokens_from_messages("gpt-4", &string_messages)
+ .map(|tokens| tokens + tokens_from_images)
+ })
+ .boxed()
}
impl AnthropicModel {
@@ -3,7 +3,8 @@ use collections::BTreeMap;
use editor::{Editor, EditorElement, EditorStyle};
use futures::{future::BoxFuture, stream::BoxStream, FutureExt, StreamExt};
use gpui::{
- AnyView, AppContext, AsyncApp, Entity, FontStyle, Subscription, Task, TextStyle, WhiteSpace,
+ AnyView, AppContext as _, AsyncApp, Entity, FontStyle, Subscription, Task, TextStyle,
+ WhiteSpace,
};
use http_client::HttpClient;
use language_model::{
@@ -269,26 +270,25 @@ impl LanguageModel for DeepSeekLanguageModel {
request: LanguageModelRequest,
cx: &App,
) -> BoxFuture<'static, Result<usize>> {
- cx.background_executor()
- .spawn(async move {
- let messages = request
- .messages
- .into_iter()
- .map(|message| tiktoken_rs::ChatCompletionRequestMessage {
- role: match message.role {
- Role::User => "user".into(),
- Role::Assistant => "assistant".into(),
- Role::System => "system".into(),
- },
- content: Some(message.string_contents()),
- name: None,
- function_call: None,
- })
- .collect::<Vec<_>>();
+ cx.background_spawn(async move {
+ let messages = request
+ .messages
+ .into_iter()
+ .map(|message| tiktoken_rs::ChatCompletionRequestMessage {
+ role: match message.role {
+ Role::User => "user".into(),
+ Role::Assistant => "assistant".into(),
+ Role::System => "system".into(),
+ },
+ content: Some(message.string_contents()),
+ name: None,
+ function_call: None,
+ })
+ .collect::<Vec<_>>();
- tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
- })
- .boxed()
+ tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
+ })
+ .boxed()
}
fn stream_completion(
@@ -330,28 +330,27 @@ pub fn count_google_tokens(
) -> BoxFuture<'static, Result<usize>> {
// We couldn't use the GoogleLanguageModelProvider to count tokens because the github copilot doesn't have the access to google_ai directly.
// So we have to use tokenizer from tiktoken_rs to count tokens.
- cx.background_executor()
- .spawn(async move {
- let messages = request
- .messages
- .into_iter()
- .map(|message| tiktoken_rs::ChatCompletionRequestMessage {
- role: match message.role {
- Role::User => "user".into(),
- Role::Assistant => "assistant".into(),
- Role::System => "system".into(),
- },
- content: Some(message.string_contents()),
- name: None,
- function_call: None,
- })
- .collect::<Vec<_>>();
+ cx.background_spawn(async move {
+ let messages = request
+ .messages
+ .into_iter()
+ .map(|message| tiktoken_rs::ChatCompletionRequestMessage {
+ role: match message.role {
+ Role::User => "user".into(),
+ Role::Assistant => "assistant".into(),
+ Role::System => "system".into(),
+ },
+ content: Some(message.string_contents()),
+ name: None,
+ function_call: None,
+ })
+ .collect::<Vec<_>>();
- // Tiktoken doesn't yet support these models, so we manually use the
- // same tokenizer as GPT-4.
- tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
- })
- .boxed()
+ // Tiktoken doesn't yet support these models, so we manually use the
+ // same tokenizer as GPT-4.
+ tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
+ })
+ .boxed()
}
struct ConfigurationView {
@@ -281,26 +281,25 @@ impl LanguageModel for MistralLanguageModel {
request: LanguageModelRequest,
cx: &App,
) -> BoxFuture<'static, Result<usize>> {
- cx.background_executor()
- .spawn(async move {
- let messages = request
- .messages
- .into_iter()
- .map(|message| tiktoken_rs::ChatCompletionRequestMessage {
- role: match message.role {
- Role::User => "user".into(),
- Role::Assistant => "assistant".into(),
- Role::System => "system".into(),
- },
- content: Some(message.string_contents()),
- name: None,
- function_call: None,
- })
- .collect::<Vec<_>>();
+ cx.background_spawn(async move {
+ let messages = request
+ .messages
+ .into_iter()
+ .map(|message| tiktoken_rs::ChatCompletionRequestMessage {
+ role: match message.role {
+ Role::User => "user".into(),
+ Role::Assistant => "assistant".into(),
+ Role::System => "system".into(),
+ },
+ content: Some(message.string_contents()),
+ name: None,
+ function_call: None,
+ })
+ .collect::<Vec<_>>();
- tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
- })
- .boxed()
+ tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
+ })
+ .boxed()
}
fn stream_completion(
@@ -343,34 +343,31 @@ pub fn count_open_ai_tokens(
model: open_ai::Model,
cx: &App,
) -> BoxFuture<'static, Result<usize>> {
- cx.background_executor()
- .spawn(async move {
- let messages = request
- .messages
- .into_iter()
- .map(|message| tiktoken_rs::ChatCompletionRequestMessage {
- role: match message.role {
- Role::User => "user".into(),
- Role::Assistant => "assistant".into(),
- Role::System => "system".into(),
- },
- content: Some(message.string_contents()),
- name: None,
- function_call: None,
- })
- .collect::<Vec<_>>();
-
- match model {
- open_ai::Model::Custom { .. }
- | open_ai::Model::O1Mini
- | open_ai::Model::O1
- | open_ai::Model::O3Mini => {
- tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
- }
- _ => tiktoken_rs::num_tokens_from_messages(model.id(), &messages),
- }
- })
- .boxed()
+ cx.background_spawn(async move {
+ let messages = request
+ .messages
+ .into_iter()
+ .map(|message| tiktoken_rs::ChatCompletionRequestMessage {
+ role: match message.role {
+ Role::User => "user".into(),
+ Role::Assistant => "assistant".into(),
+ Role::System => "system".into(),
+ },
+ content: Some(message.string_contents()),
+ name: None,
+ function_call: None,
+ })
+ .collect::<Vec<_>>();
+
+ match model {
+ open_ai::Model::Custom { .. }
+ | open_ai::Model::O1Mini
+ | open_ai::Model::O1
+ | open_ai::Model::O3Mini => tiktoken_rs::num_tokens_from_messages("gpt-4", &messages),
+ _ => tiktoken_rs::num_tokens_from_messages(model.id(), &messages),
+ }
+ })
+ .boxed()
}
struct ConfigurationView {
@@ -302,11 +302,10 @@ impl LivekitWindow {
if let Some(track) = self.screen_share_track.take() {
self.screen_share_stream.take();
let participant = self.room.local_participant();
- cx.background_executor()
- .spawn(async move {
- participant.unpublish_track(&track.sid()).await.unwrap();
- })
- .detach();
+ cx.background_spawn(async move {
+ participant.unpublish_track(&track.sid()).await.unwrap();
+ })
+ .detach();
cx.notify();
} else {
let participant = self.room.local_participant();
@@ -1,7 +1,9 @@
use crate::track::RemoteVideoTrack;
use anyhow::Result;
use futures::StreamExt as _;
-use gpui::{AppContext, Context, Empty, Entity, EventEmitter, IntoElement, Render, Task, Window};
+use gpui::{
+ AppContext as _, Context, Empty, Entity, EventEmitter, IntoElement, Render, Task, Window,
+};
pub struct RemoteVideoTrackView {
track: RemoteVideoTrack,
@@ -6,7 +6,7 @@ pub use lsp_types::*;
use anyhow::{anyhow, Context as _, Result};
use collections::HashMap;
use futures::{channel::oneshot, io::BufWriter, select, AsyncRead, AsyncWrite, Future, FutureExt};
-use gpui::{App, AsyncApp, BackgroundExecutor, SharedString, Task};
+use gpui::{App, AppContext as _, AsyncApp, BackgroundExecutor, SharedString, Task};
use notification::DidChangeWorkspaceFolders;
use parking_lot::{Mutex, RwLock};
use postage::{barrier, prelude::Stream};
@@ -448,7 +448,7 @@ impl LanguageServer {
let (stdout, stderr) = futures::join!(stdout_input_task, stderr_input_task);
stdout.or(stderr)
});
- let output_task = cx.background_executor().spawn({
+ let output_task = cx.background_spawn({
Self::handle_output(
stdin,
outbound_rx,
@@ -178,7 +178,7 @@ impl Markdown {
let text = self.source.clone();
let parse_text_only = self.options.parse_links_only;
- let parsed = cx.background_executor().spawn(async move {
+ let parsed = cx.background_spawn(async move {
let text = SharedString::from(text);
let events = match parse_text_only {
true => Arc::from(parse_links_only(text.as_ref())),
@@ -383,7 +383,7 @@ impl MarkdownPreviewView {
(contents, file_location)
})?;
- let parsing_task = cx.background_executor().spawn(async move {
+ let parsing_task = cx.background_spawn(async move {
parse_markdown(&contents, file_location, Some(language_registry)).await
});
let contents = parsing_task.await;
@@ -13,7 +13,7 @@ use buffer_diff::{
use clock::ReplicaId;
use collections::{BTreeMap, Bound, HashMap, HashSet};
use futures::{channel::mpsc, SinkExt};
-use gpui::{App, Context, Entity, EntityId, EventEmitter, Task};
+use gpui::{App, AppContext as _, Context, Entity, EntityId, EventEmitter, Task};
use itertools::Itertools;
use language::{
language_settings::{language_settings, IndentGuideSettings, LanguageSettings},
@@ -51,9 +51,6 @@ use text::{
use theme::SyntaxTheme;
use util::post_inc;
-#[cfg(any(test, feature = "test-support"))]
-use gpui::AppContext as _;
-
const NEWLINES: &[u8] = &[b'\n'; u8::MAX as usize];
#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
@@ -1580,20 +1577,19 @@ impl MultiBuffer {
buffer_ids.push(buffer_id);
- cx.background_executor()
- .spawn({
- let mut excerpt_ranges_tx = excerpt_ranges_tx.clone();
-
- async move {
- let (excerpt_ranges, counts) =
- build_excerpt_ranges(&buffer_snapshot, &ranges, context_line_count);
- excerpt_ranges_tx
- .send((buffer_id, buffer.clone(), ranges, excerpt_ranges, counts))
- .await
- .ok();
- }
- })
- .detach()
+ cx.background_spawn({
+ let mut excerpt_ranges_tx = excerpt_ranges_tx.clone();
+
+ async move {
+ let (excerpt_ranges, counts) =
+ build_excerpt_ranges(&buffer_snapshot, &ranges, context_line_count);
+ excerpt_ranges_tx
+ .send((buffer_id, buffer.clone(), ranges, excerpt_ranges, counts))
+ .await
+ .ok();
+ }
+ })
+ .detach()
}
cx.spawn(move |this, mut cx| async move {
@@ -171,7 +171,7 @@ impl SearchState {
})
.collect(),
highlight_search_match_tx,
- _search_match_highlighter: cx.background_executor().spawn(async move {
+ _search_match_highlighter: cx.background_spawn(async move {
while let Ok(highlight_arguments) = highlight_search_match_rx.recv().await {
let needs_init = highlight_arguments.search_data.get().is_none();
let search_data = highlight_arguments.search_data.get_or_init(|| {
@@ -681,8 +681,7 @@ impl OutlinePanel {
mut cx: AsyncWindowContext,
) -> anyhow::Result<Entity<Self>> {
let serialized_panel = cx
- .background_executor()
- .spawn(async move { KEY_VALUE_STORE.read_kvp(OUTLINE_PANEL_KEY) })
+ .background_spawn(async move { KEY_VALUE_STORE.read_kvp(OUTLINE_PANEL_KEY) })
.await
.context("loading outline panel")
.log_err()
@@ -849,7 +848,7 @@ impl OutlinePanel {
fn serialize(&mut self, cx: &mut Context<Self>) {
let width = self.width;
let active = Some(self.active);
- self.pending_serialization = cx.background_executor().spawn(
+ self.pending_serialization = cx.background_spawn(
async move {
KEY_VALUE_STORE
.write_kvp(
@@ -2631,8 +2630,7 @@ impl OutlinePanel {
new_depth_map,
new_children_count,
)) = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
let mut processed_external_buffers = HashSet::default();
let mut new_worktree_entries =
BTreeMap::<WorktreeId, HashMap<ProjectEntryId, GitEntry>>::default();
@@ -3224,8 +3222,7 @@ impl OutlinePanel {
(buffer_id, excerpt_id),
cx.spawn_in(window, |outline_panel, mut cx| async move {
let fetched_outlines = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
buffer_snapshot
.outline_items_containing(
excerpt_range.context,
@@ -346,7 +346,7 @@ impl RemoteBufferStore {
fn open_unstaged_diff(&self, buffer_id: BufferId, cx: &App) -> Task<Result<Option<String>>> {
let project_id = self.project_id;
let client = self.upstream_client.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let response = client
.request(proto::OpenUnstagedDiff {
project_id,
@@ -366,7 +366,7 @@ impl RemoteBufferStore {
let project_id = self.project_id;
let client = self.upstream_client.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let response = client
.request(proto::OpenUncommittedDiff {
project_id,
@@ -402,9 +402,7 @@ impl RemoteBufferStore {
return Ok(buffer);
}
- cx.background_executor()
- .spawn(async move { rx.await? })
- .await
+ cx.background_spawn(async move { rx.await? }).await
})
}
@@ -843,8 +841,7 @@ impl LocalBufferStore {
let snapshot =
worktree_handle.update(&mut cx, |tree, _| tree.as_local().unwrap().snapshot())?;
let diff_bases_changes_by_buffer = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
diff_state_updates
.into_iter()
.filter_map(
@@ -1129,8 +1126,7 @@ impl LocalBufferStore {
cx.spawn(move |_, mut cx| async move {
let loaded = load_file.await?;
let text_buffer = cx
- .background_executor()
- .spawn(async move { text::Buffer::new(0, buffer_id, loaded.text) })
+ .background_spawn(async move { text::Buffer::new(0, buffer_id, loaded.text) })
.await;
cx.insert_entity(reservation, |_| {
Buffer::build(text_buffer, Some(loaded.file), Capability::ReadWrite)
@@ -1347,8 +1343,7 @@ impl BufferStore {
}
};
- cx.background_executor()
- .spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
+ cx.background_spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
}
pub fn open_unstaged_diff(
@@ -1388,8 +1383,7 @@ impl BufferStore {
}
};
- cx.background_executor()
- .spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
+ cx.background_spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
}
pub fn open_uncommitted_diff(
@@ -1409,7 +1403,7 @@ impl BufferStore {
BufferStoreState::Local(this) => {
let committed_text = this.load_committed_text(&buffer, cx);
let staged_text = this.load_staged_text(&buffer, cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let committed_text = committed_text.await?;
let staged_text = staged_text.await?;
let diff_bases_change = if committed_text == staged_text {
@@ -1445,8 +1439,7 @@ impl BufferStore {
}
};
- cx.background_executor()
- .spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
+ cx.background_spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
}
async fn open_diff_internal(
@@ -1587,7 +1580,7 @@ impl BufferStore {
anyhow::Ok(Some((repo, relative_path, content)))
});
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let Some((repo, relative_path, content)) = blame_params? else {
return Ok(None);
};
@@ -2106,24 +2099,23 @@ impl BufferStore {
})
.log_err();
- cx.background_executor()
- .spawn(
- async move {
- let operations = operations.await;
- for chunk in split_operations(operations) {
- client
- .request(proto::UpdateBuffer {
- project_id,
- buffer_id: buffer_id.into(),
- operations: chunk,
- })
- .await?;
- }
- anyhow::Ok(())
+ cx.background_spawn(
+ async move {
+ let operations = operations.await;
+ for chunk in split_operations(operations) {
+ client
+ .request(proto::UpdateBuffer {
+ project_id,
+ buffer_id: buffer_id.into(),
+ operations: chunk,
+ })
+ .await?;
}
- .log_err(),
- )
- .detach();
+ anyhow::Ok(())
+ }
+ .log_err(),
+ )
+ .detach();
}
}
Ok(response)
@@ -2558,27 +2550,26 @@ impl BufferStore {
if client.send(initial_state).log_err().is_some() {
let client = client.clone();
- cx.background_executor()
- .spawn(async move {
- let mut chunks = split_operations(operations).peekable();
- while let Some(chunk) = chunks.next() {
- let is_last = chunks.peek().is_none();
- client.send(proto::CreateBufferForPeer {
- project_id,
- peer_id: Some(peer_id),
- variant: Some(proto::create_buffer_for_peer::Variant::Chunk(
- proto::BufferChunk {
- buffer_id: buffer_id.into(),
- operations: chunk,
- is_last,
- },
- )),
- })?;
- }
- anyhow::Ok(())
- })
- .await
- .log_err();
+ cx.background_spawn(async move {
+ let mut chunks = split_operations(operations).peekable();
+ while let Some(chunk) = chunks.next() {
+ let is_last = chunks.peek().is_none();
+ client.send(proto::CreateBufferForPeer {
+ project_id,
+ peer_id: Some(peer_id),
+ variant: Some(proto::create_buffer_for_peer::Variant::Chunk(
+ proto::BufferChunk {
+ buffer_id: buffer_id.into(),
+ operations: chunk,
+ is_last,
+ },
+ )),
+ })?;
+ }
+ anyhow::Ok(())
+ })
+ .await
+ .log_err();
}
Ok(())
})
@@ -135,8 +135,7 @@ impl ProjectEnvironment {
cx.spawn(|this, mut cx| async move {
let (mut shell_env, error_message) = cx
- .background_executor()
- .spawn({
+ .background_spawn({
let worktree_abs_path = worktree_abs_path.clone();
async move {
load_worktree_shell_environment(&worktree_abs_path, &load_direnv).await
@@ -11,8 +11,8 @@ use git::{
status::{GitSummary, TrackedSummary},
};
use gpui::{
- App, AppContext, AsyncApp, Context, Entity, EventEmitter, SharedString, Subscription, Task,
- WeakEntity,
+ App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, SharedString, Subscription,
+ Task, WeakEntity,
};
use language::{Buffer, LanguageRegistry};
use rpc::proto::{git_reset, ToProto};
@@ -242,10 +242,7 @@ impl GitStore {
mpsc::unbounded::<(Message, oneshot::Sender<Result<()>>)>();
cx.spawn(|_, cx| async move {
while let Some((msg, respond)) = update_receiver.next().await {
- let result = cx
- .background_executor()
- .spawn(Self::process_git_msg(msg))
- .await;
+ let result = cx.background_spawn(Self::process_git_msg(msg)).await;
respond.send(result).ok();
}
})
@@ -841,15 +838,14 @@ impl Repository {
match self.git_repo.clone() {
GitRepo::Local(git_repository) => {
let commit = commit.to_string();
- cx.background_executor()
- .spawn(async move { git_repository.show(&commit) })
+ cx.background_spawn(async move { git_repository.show(&commit) })
}
GitRepo::Remote {
project_id,
client,
worktree_id,
work_directory_id,
- } => cx.background_executor().spawn(async move {
+ } => cx.background_spawn(async move {
let resp = client
.request(proto::GitShow {
project_id: project_id.0,
@@ -404,7 +404,7 @@ impl ImageStore {
}
};
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
Self::wait_for_loading_image(loading_watch)
.await
.map_err(|e| e.cloned())
@@ -2144,7 +2144,7 @@ impl LocalLspStore {
cx: &mut Context<LspStore>,
) -> Task<Result<Vec<(Range<Anchor>, String)>>> {
let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let snapshot = snapshot?;
let mut lsp_edits = lsp_edits
.into_iter()
@@ -3282,16 +3282,15 @@ impl LspStore {
}
} else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
let buffer_id = buffer.read(cx).remote_id().to_proto();
- cx.background_executor()
- .spawn(async move {
- upstream_client
- .request(proto::RegisterBufferWithLanguageServers {
- project_id: upstream_project_id,
- buffer_id,
- })
- .await
- })
- .detach();
+ cx.background_spawn(async move {
+ upstream_client
+ .request(proto::RegisterBufferWithLanguageServers {
+ project_id: upstream_project_id,
+ buffer_id,
+ })
+ .await
+ })
+ .detach();
} else {
panic!("oops!");
}
@@ -6707,7 +6706,7 @@ impl LspStore {
return Err(anyhow!("No language server {id}"));
};
- Ok(cx.background_executor().spawn(async move {
+ Ok(cx.background_spawn(async move {
let can_resolve = server
.capabilities()
.completion_provider
@@ -7375,9 +7374,7 @@ impl LspStore {
.map(|b| b.read(cx).remote_id().to_proto())
.collect(),
});
- cx.background_executor()
- .spawn(request)
- .detach_and_log_err(cx);
+ cx.background_spawn(request).detach_and_log_err(cx);
} else {
let Some(local) = self.as_local_mut() else {
return;
@@ -7406,9 +7403,7 @@ impl LspStore {
.collect::<Vec<_>>();
cx.spawn(|this, mut cx| async move {
- cx.background_executor()
- .spawn(futures::future::join_all(tasks))
- .await;
+ cx.background_spawn(futures::future::join_all(tasks)).await;
this.update(&mut cx, |this, cx| {
for buffer in buffers {
this.register_buffer_with_language_servers(&buffer, true, cx);
@@ -7737,9 +7732,7 @@ impl LspStore {
},
)),
});
- cx.background_executor()
- .spawn(request)
- .detach_and_log_err(cx);
+ cx.background_spawn(request).detach_and_log_err(cx);
} else if let Some(local) = self.as_local() {
let servers = buffers
.into_iter()
@@ -7795,9 +7788,7 @@ impl LspStore {
),
),
});
- cx.background_executor()
- .spawn(request)
- .detach_and_log_err(cx);
+ cx.background_spawn(request).detach_and_log_err(cx);
}
}
@@ -12,7 +12,7 @@ use futures::{
stream::FuturesUnordered,
FutureExt,
};
-use gpui::{AsyncApp, Context, Entity, EventEmitter, Task, WeakEntity};
+use gpui::{AppContext as _, AsyncApp, Context, Entity, EventEmitter, Task, WeakEntity};
use language::{
language_settings::{Formatter, LanguageSettings, SelectedFormatter},
Buffer, LanguageRegistry, LocalFile,
@@ -121,8 +121,7 @@ impl PrettierStore {
let installed_prettiers = self.prettier_instances.keys().cloned().collect();
cx.spawn(|lsp_store, mut cx| async move {
match cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
Prettier::locate_prettier_installation(
fs.as_ref(),
&installed_prettiers,
@@ -234,8 +233,7 @@ impl PrettierStore {
.unwrap_or_default();
cx.spawn(|lsp_store, mut cx| async move {
match cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
Prettier::locate_prettier_ignore(
fs.as_ref(),
&prettier_ignores,
@@ -483,31 +481,30 @@ impl PrettierStore {
}))
.collect::<Vec<_>>();
- cx.background_executor()
- .spawn(async move {
- let _: Vec<()> = future::join_all(prettiers_to_reload.into_iter().map(|(worktree_id, prettier_path, prettier_instance)| {
- async move {
- if let Some(instance) = prettier_instance.prettier {
- match instance.await {
- Ok(prettier) => {
- prettier.clear_cache().log_err().await;
- },
- Err(e) => {
- match prettier_path {
- Some(prettier_path) => log::error!(
- "Failed to clear prettier {prettier_path:?} cache for worktree {worktree_id:?} on prettier settings update: {e:#}"
- ),
- None => log::error!(
- "Failed to clear default prettier cache for worktree {worktree_id:?} on prettier settings update: {e:#}"
- ),
- }
- },
- }
+ cx.background_spawn(async move {
+ let _: Vec<()> = future::join_all(prettiers_to_reload.into_iter().map(|(worktree_id, prettier_path, prettier_instance)| {
+ async move {
+ if let Some(instance) = prettier_instance.prettier {
+ match instance.await {
+ Ok(prettier) => {
+ prettier.clear_cache().log_err().await;
+ },
+ Err(e) => {
+ match prettier_path {
+ Some(prettier_path) => log::error!(
+ "Failed to clear prettier {prettier_path:?} cache for worktree {worktree_id:?} on prettier settings update: {e:#}"
+ ),
+ None => log::error!(
+ "Failed to clear default prettier cache for worktree {worktree_id:?} on prettier settings update: {e:#}"
+ ),
+ }
+ },
}
}
- }))
- .await;
- })
+ }
+ }))
+ .await;
+ })
.detach();
}
}
@@ -539,7 +536,7 @@ impl PrettierStore {
}) {
Some(locate_from) => {
let installed_prettiers = self.prettier_instances.keys().cloned().collect();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
Prettier::locate_prettier_installation(
fs.as_ref(),
&installed_prettiers,
@@ -631,13 +628,12 @@ impl PrettierStore {
})?;
if needs_install {
let installed_plugins = new_plugins.clone();
- cx.background_executor()
- .spawn(async move {
- install_prettier_packages(fs.as_ref(), new_plugins, node).await?;
- // Save the server file last, so the reinstall need could be determined by the absence of the file.
- save_prettier_server_file(fs.as_ref()).await?;
- anyhow::Ok(())
- })
+ cx.background_spawn(async move {
+ install_prettier_packages(fs.as_ref(), new_plugins, node).await?;
+ // Save the server file last, so the reinstall need could be determined by the absence of the file.
+ save_prettier_server_file(fs.as_ref()).await?;
+ anyhow::Ok(())
+ })
.await
.context("prettier & plugins install")
.map_err(Arc::new)?;
@@ -562,7 +562,7 @@ impl DirectoryLister {
}
DirectoryLister::Local(fs) => {
let fs = fs.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut results = vec![];
let expanded = shellexpand::tilde(&path);
let query = Path::new(expanded.as_ref());
@@ -1163,13 +1163,12 @@ impl Project {
.read(cx)
.shutdown_processes(Some(proto::ShutdownRemoteServer {}));
- cx.background_executor()
- .spawn(async move {
- if let Some(shutdown) = shutdown {
- shutdown.await;
- }
- })
- .detach()
+ cx.background_spawn(async move {
+ if let Some(shutdown) = shutdown {
+ shutdown.await;
+ }
+ })
+ .detach()
}
match &self.client_state {
@@ -3138,7 +3137,7 @@ impl Project {
let buffer = buffer.clone();
let query = query.clone();
let snapshot = buffer.read_with(&cx, |buffer, _| buffer.snapshot())?;
- chunk_results.push(cx.background_executor().spawn(async move {
+ chunk_results.push(cx.background_spawn(async move {
let ranges = query
.search(&snapshot, None)
.await
@@ -3377,7 +3376,7 @@ impl Project {
cx: &mut Context<Self>,
) -> Task<Option<ResolvedPath>> {
let resolve_task = self.resolve_abs_path(path, cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let resolved_path = resolve_task.await;
resolved_path.filter(|path| path.is_file())
})
@@ -3391,7 +3390,7 @@ impl Project {
if self.is_local() {
let expanded = PathBuf::from(shellexpand::tilde(&path).into_owned());
let fs = self.fs.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let path = expanded.as_path();
let metadata = fs.metadata(path).await.ok().flatten();
@@ -3409,7 +3408,7 @@ impl Project {
project_id: SSH_PROJECT_ID,
path: request_path.to_proto(),
});
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let response = request.await.log_err()?;
if response.exists {
Some(ResolvedPath::AbsPath {
@@ -3490,7 +3489,7 @@ impl Project {
};
let response = session.read(cx).proto_client().request(request);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let response = response.await?;
Ok(response.entries.into_iter().map(PathBuf::from).collect())
})
@@ -3906,8 +3905,7 @@ impl Project {
if let Some(remote_id) = this.remote_id() {
let mut payload = envelope.payload.clone();
payload.project_id = remote_id;
- cx.background_executor()
- .spawn(this.client.request(payload))
+ cx.background_spawn(this.client.request(payload))
.detach_and_log_err(cx);
}
this.buffer_store.clone()
@@ -3924,8 +3922,7 @@ impl Project {
if let Some(ssh) = &this.ssh_client {
let mut payload = envelope.payload.clone();
payload.project_id = SSH_PROJECT_ID;
- cx.background_executor()
- .spawn(ssh.read(cx).proto_client().request(payload))
+ cx.background_spawn(ssh.read(cx).proto_client().request(payload))
.detach_and_log_err(cx);
}
this.buffer_store.clone()
@@ -4146,7 +4143,7 @@ impl Project {
if let Some(buffer) = this.buffer_for_id(buffer_id, cx) {
let operations =
buffer.read(cx).serialize_ops(Some(remote_version), cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let operations = operations.await;
for chunk in split_operations(operations) {
client
@@ -4169,12 +4166,11 @@ impl Project {
// Any incomplete buffers have open requests waiting. Request that the host sends
// creates these buffers for us again to unblock any waiting futures.
for id in incomplete_buffer_ids {
- cx.background_executor()
- .spawn(client.request(proto::OpenBufferById {
- project_id,
- id: id.into(),
- }))
- .detach();
+ cx.background_spawn(client.request(proto::OpenBufferById {
+ project_id,
+ id: id.into(),
+ }))
+ .detach();
}
futures::future::join_all(send_updates_for_buffers)
@@ -13,7 +13,7 @@ use std::{
};
use collections::HashMap;
-use gpui::{App, AppContext, Context, Entity, EventEmitter, Subscription};
+use gpui::{App, AppContext as _, Context, Entity, EventEmitter, Subscription};
use language::{CachedLspAdapter, LspAdapterDelegate};
use lsp::LanguageServerName;
use path_trie::{LabelPresence, RootPathTrie, TriePath};
@@ -15,7 +15,7 @@ use std::{
};
use collections::{HashMap, IndexMap};
-use gpui::{App, AppContext, Entity, Subscription};
+use gpui::{App, AppContext as _, Entity, Subscription};
use itertools::Itertools;
use language::{
language_settings::AllLanguageSettings, Attach, LanguageName, LanguageRegistry,
@@ -325,16 +325,15 @@ impl LocalToolchainStore {
.ok()?
.await;
- cx.background_executor()
- .spawn(async move {
- let language = registry
- .language_for_name(language_name.as_ref())
- .await
- .ok()?;
- let toolchains = language.toolchain_lister()?;
- Some(toolchains.list(root.to_path_buf(), project_env).await)
- })
- .await
+ cx.background_spawn(async move {
+ let language = registry
+ .language_for_name(language_name.as_ref())
+ .await
+ .ok()?;
+ let toolchains = language.toolchain_lister()?;
+ Some(toolchains.list(root.to_path_buf(), project_env).await)
+ })
+ .await
})
}
pub(crate) fn active_toolchain(
@@ -13,7 +13,9 @@ use futures::{
FutureExt, SinkExt,
};
use git::repository::Branch;
-use gpui::{App, AsyncApp, Context, Entity, EntityId, EventEmitter, Task, WeakEntity};
+use gpui::{
+ App, AppContext as _, AsyncApp, Context, Entity, EntityId, EventEmitter, Task, WeakEntity,
+};
use postage::oneshot;
use rpc::{
proto::{self, FromProto, ToProto, SSH_PROJECT_ID},
@@ -179,8 +181,7 @@ impl WorktreeStore {
Task::ready(Ok((tree, relative_path)))
} else {
let worktree = self.create_worktree(abs_path, visible, cx);
- cx.background_executor()
- .spawn(async move { Ok((worktree.await?, PathBuf::new())) })
+ cx.background_spawn(async move { Ok((worktree.await?, PathBuf::new())) })
}
}
@@ -679,7 +680,7 @@ impl WorktreeStore {
let (output_tx, output_rx) = smol::channel::bounded(64);
let (matching_paths_tx, matching_paths_rx) = smol::channel::unbounded();
- let input = cx.background_executor().spawn({
+ let input = cx.background_spawn({
let fs = fs.clone();
let query = query.clone();
async move {
@@ -696,7 +697,7 @@ impl WorktreeStore {
}
});
const MAX_CONCURRENT_FILE_SCANS: usize = 64;
- let filters = cx.background_executor().spawn(async move {
+ let filters = cx.background_spawn(async move {
let fs = &fs;
let query = &query;
executor
@@ -712,25 +713,24 @@ impl WorktreeStore {
})
.await;
});
- cx.background_executor()
- .spawn(async move {
- let mut matched = 0;
- while let Ok(mut receiver) = output_rx.recv().await {
- let Some(path) = receiver.next().await else {
- continue;
- };
- let Ok(_) = matching_paths_tx.send(path).await else {
- break;
- };
- matched += 1;
- if matched == limit {
- break;
- }
+ cx.background_spawn(async move {
+ let mut matched = 0;
+ while let Ok(mut receiver) = output_rx.recv().await {
+ let Some(path) = receiver.next().await else {
+ continue;
+ };
+ let Ok(_) = matching_paths_tx.send(path).await else {
+ break;
+ };
+ matched += 1;
+ if matched == limit {
+ break;
}
- drop(input);
- drop(filters);
- })
- .detach();
+ }
+ drop(input);
+ drop(filters);
+ })
+ .detach();
matching_paths_rx
}
@@ -934,7 +934,7 @@ impl WorktreeStore {
}),
});
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let response = request.await?;
let branches = response
@@ -1021,7 +1021,7 @@ impl WorktreeStore {
branch_name: new_branch,
});
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
request.await?;
Ok(())
})
@@ -544,8 +544,7 @@ impl ProjectPanel {
mut cx: AsyncWindowContext,
) -> Result<Entity<Self>> {
let serialized_panel = cx
- .background_executor()
- .spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) })
+ .background_spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) })
.await
.map_err(|e| anyhow!("Failed to load project panel: {}", e))
.log_err()
@@ -627,7 +626,7 @@ impl ProjectPanel {
fn serialize(&mut self, cx: &mut Context<Self>) {
let width = self.width;
- self.pending_serialization = cx.background_executor().spawn(
+ self.pending_serialization = cx.background_spawn(
async move {
KEY_VALUE_STORE
.write_kvp(
@@ -218,8 +218,7 @@ impl PickerDelegate for PromptPickerDelegate {
let prev_prompt_id = self.matches.get(self.selected_index).map(|mat| mat.id);
cx.spawn_in(window, |this, mut cx| async move {
let (matches, selected_index) = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
let matches = search.await;
let selected_index = prev_prompt_id
@@ -2,7 +2,7 @@ use anyhow::Result;
use assets::Assets;
use fs::Fs;
use futures::StreamExt;
-use gpui::{App, AssetSource};
+use gpui::{App, AppContext as _, AssetSource};
use handlebars::{Handlebars, RenderError};
use language::{BufferSnapshot, LanguageName, Point};
use parking_lot::Mutex;
@@ -103,103 +103,102 @@ impl PromptBuilder {
handlebars: Arc<Mutex<Handlebars<'static>>>,
) {
let templates_dir = paths::prompt_overrides_dir(params.repo_path.as_deref());
- params.cx.background_executor()
- .spawn(async move {
- let Some(parent_dir) = templates_dir.parent() else {
- return;
- };
-
- let mut found_dir_once = false;
- loop {
- // Check if the templates directory exists and handle its status
- // If it exists, log its presence and check if it's a symlink
- // If it doesn't exist:
- // - Log that we're using built-in prompts
- // - Check if it's a broken symlink and log if so
- // - Set up a watcher to detect when it's created
- // After the first check, set the `found_dir_once` flag
- // This allows us to avoid logging when looping back around after deleting the prompt overrides directory.
- let dir_status = params.fs.is_dir(&templates_dir).await;
- let symlink_status = params.fs.read_link(&templates_dir).await.ok();
- if dir_status {
- let mut log_message = format!("Prompt template overrides directory found at {}", templates_dir.display());
+ params.cx.background_spawn(async move {
+ let Some(parent_dir) = templates_dir.parent() else {
+ return;
+ };
+
+ let mut found_dir_once = false;
+ loop {
+ // Check if the templates directory exists and handle its status
+ // If it exists, log its presence and check if it's a symlink
+ // If it doesn't exist:
+ // - Log that we're using built-in prompts
+ // - Check if it's a broken symlink and log if so
+ // - Set up a watcher to detect when it's created
+ // After the first check, set the `found_dir_once` flag
+ // This allows us to avoid logging when looping back around after deleting the prompt overrides directory.
+ let dir_status = params.fs.is_dir(&templates_dir).await;
+ let symlink_status = params.fs.read_link(&templates_dir).await.ok();
+ if dir_status {
+ let mut log_message = format!("Prompt template overrides directory found at {}", templates_dir.display());
+ if let Some(target) = symlink_status {
+ log_message.push_str(" -> ");
+ log_message.push_str(&target.display().to_string());
+ }
+ log::info!("{}.", log_message);
+ } else {
+ if !found_dir_once {
+ log::info!("No prompt template overrides directory found at {}. Using built-in prompts.", templates_dir.display());
if let Some(target) = symlink_status {
- log_message.push_str(" -> ");
- log_message.push_str(&target.display().to_string());
- }
- log::info!("{}.", log_message);
- } else {
- if !found_dir_once {
- log::info!("No prompt template overrides directory found at {}. Using built-in prompts.", templates_dir.display());
- if let Some(target) = symlink_status {
- log::info!("Symlink found pointing to {}, but target is invalid.", target.display());
- }
+ log::info!("Symlink found pointing to {}, but target is invalid.", target.display());
}
+ }
- if params.fs.is_dir(parent_dir).await {
- let (mut changes, _watcher) = params.fs.watch(parent_dir, Duration::from_secs(1)).await;
- while let Some(changed_paths) = changes.next().await {
- if changed_paths.iter().any(|p| &p.path == &templates_dir) {
- let mut log_message = format!("Prompt template overrides directory detected at {}", templates_dir.display());
- if let Ok(target) = params.fs.read_link(&templates_dir).await {
- log_message.push_str(" -> ");
- log_message.push_str(&target.display().to_string());
- }
- log::info!("{}.", log_message);
- break;
+ if params.fs.is_dir(parent_dir).await {
+ let (mut changes, _watcher) = params.fs.watch(parent_dir, Duration::from_secs(1)).await;
+ while let Some(changed_paths) = changes.next().await {
+ if changed_paths.iter().any(|p| &p.path == &templates_dir) {
+ let mut log_message = format!("Prompt template overrides directory detected at {}", templates_dir.display());
+ if let Ok(target) = params.fs.read_link(&templates_dir).await {
+ log_message.push_str(" -> ");
+ log_message.push_str(&target.display().to_string());
}
+ log::info!("{}.", log_message);
+ break;
}
- } else {
- return;
}
+ } else {
+ return;
}
+ }
- found_dir_once = true;
+ found_dir_once = true;
- // Initial scan of the prompt overrides directory
- if let Ok(mut entries) = params.fs.read_dir(&templates_dir).await {
- while let Some(Ok(file_path)) = entries.next().await {
- if file_path.to_string_lossy().ends_with(".hbs") {
- if let Ok(content) = params.fs.load(&file_path).await {
- let file_name = file_path.file_stem().unwrap().to_string_lossy();
- log::debug!("Registering prompt template override: {}", file_name);
- handlebars.lock().register_template_string(&file_name, content).log_err();
- }
+ // Initial scan of the prompt overrides directory
+ if let Ok(mut entries) = params.fs.read_dir(&templates_dir).await {
+ while let Some(Ok(file_path)) = entries.next().await {
+ if file_path.to_string_lossy().ends_with(".hbs") {
+ if let Ok(content) = params.fs.load(&file_path).await {
+ let file_name = file_path.file_stem().unwrap().to_string_lossy();
+ log::debug!("Registering prompt template override: {}", file_name);
+ handlebars.lock().register_template_string(&file_name, content).log_err();
}
}
}
+ }
- // Watch both the parent directory and the template overrides directory:
- // - Monitor the parent directory to detect if the template overrides directory is deleted.
- // - Monitor the template overrides directory to re-register templates when they change.
- // Combine both watch streams into a single stream.
- let (parent_changes, parent_watcher) = params.fs.watch(parent_dir, Duration::from_secs(1)).await;
- let (changes, watcher) = params.fs.watch(&templates_dir, Duration::from_secs(1)).await;
- let mut combined_changes = futures::stream::select(changes, parent_changes);
-
- while let Some(changed_paths) = combined_changes.next().await {
- if changed_paths.iter().any(|p| &p.path == &templates_dir) {
- if !params.fs.is_dir(&templates_dir).await {
- log::info!("Prompt template overrides directory removed. Restoring built-in prompt templates.");
- Self::register_built_in_templates(&mut handlebars.lock()).log_err();
- break;
- }
+ // Watch both the parent directory and the template overrides directory:
+ // - Monitor the parent directory to detect if the template overrides directory is deleted.
+ // - Monitor the template overrides directory to re-register templates when they change.
+ // Combine both watch streams into a single stream.
+ let (parent_changes, parent_watcher) = params.fs.watch(parent_dir, Duration::from_secs(1)).await;
+ let (changes, watcher) = params.fs.watch(&templates_dir, Duration::from_secs(1)).await;
+ let mut combined_changes = futures::stream::select(changes, parent_changes);
+
+ while let Some(changed_paths) = combined_changes.next().await {
+ if changed_paths.iter().any(|p| &p.path == &templates_dir) {
+ if !params.fs.is_dir(&templates_dir).await {
+ log::info!("Prompt template overrides directory removed. Restoring built-in prompt templates.");
+ Self::register_built_in_templates(&mut handlebars.lock()).log_err();
+ break;
}
- for event in changed_paths {
- if event.path.starts_with(&templates_dir) && event.path.extension().map_or(false, |ext| ext == "hbs") {
- log::info!("Reloading prompt template override: {}", event.path.display());
- if let Some(content) = params.fs.load(&event.path).await.log_err() {
- let file_name = event.path.file_stem().unwrap().to_string_lossy();
- handlebars.lock().register_template_string(&file_name, content).log_err();
- }
+ }
+ for event in changed_paths {
+ if event.path.starts_with(&templates_dir) && event.path.extension().map_or(false, |ext| ext == "hbs") {
+ log::info!("Reloading prompt template override: {}", event.path.display());
+ if let Some(content) = params.fs.load(&event.path).await.log_err() {
+ let file_name = event.path.file_stem().unwrap().to_string_lossy();
+ handlebars.lock().register_template_string(&file_name, content).log_err();
}
}
}
-
- drop(watcher);
- drop(parent_watcher);
}
- })
+
+ drop(watcher);
+ drop(parent_watcher);
+ }
+ })
.detach();
}
@@ -17,7 +17,7 @@ use futures::{
select, select_biased, AsyncReadExt as _, Future, FutureExt as _, StreamExt as _,
};
use gpui::{
- App, AppContext, AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Global,
+ App, AppContext as _, AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Global,
SemanticVersion, Task, WeakEntity,
};
use itertools::Itertools;
@@ -1158,12 +1158,11 @@ impl SshRemoteClient {
c.connections.insert(
opts.clone(),
ConnectionPoolEntry::Connecting(
- cx.background_executor()
- .spawn({
- let connection = connection.clone();
- async move { Ok(connection.clone()) }
- })
- .shared(),
+ cx.background_spawn({
+ let connection = connection.clone();
+ async move { Ok(connection.clone()) }
+ })
+ .shared(),
),
);
})
@@ -1358,7 +1357,7 @@ impl RemoteConnection for SshRemoteConnection {
))
.output();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let output = output.await?;
if !output.status.success() {
@@ -1679,14 +1678,14 @@ impl SshRemoteConnection {
let mut stderr_buffer = Vec::new();
let mut stderr_offset = 0;
- let stdin_task = cx.background_executor().spawn(async move {
+ let stdin_task = cx.background_spawn(async move {
while let Some(outgoing) = outgoing_rx.next().await {
write_message(&mut child_stdin, &mut stdin_buffer, outgoing).await?;
}
anyhow::Ok(())
});
- let stdout_task = cx.background_executor().spawn({
+ let stdout_task = cx.background_spawn({
let mut connection_activity_tx = connection_activity_tx.clone();
async move {
loop {
@@ -1711,7 +1710,7 @@ impl SshRemoteConnection {
}
});
- let stderr_task: Task<anyhow::Result<()>> = cx.background_executor().spawn(async move {
+ let stderr_task: Task<anyhow::Result<()>> = cx.background_spawn(async move {
loop {
stderr_buffer.resize(stderr_offset + 1024, 0);
@@ -2449,7 +2448,7 @@ mod fake {
},
select_biased, FutureExt, SinkExt, StreamExt,
};
- use gpui::{App, AsyncApp, SemanticVersion, Task, TestAppContext};
+ use gpui::{App, AppContext as _, AsyncApp, SemanticVersion, Task, TestAppContext};
use release_channel::ReleaseChannel;
use rpc::proto::Envelope;
@@ -2533,7 +2532,7 @@ mod fake {
&self.server_cx.get(cx),
);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
loop {
select_biased! {
server_to_client = server_outgoing_rx.next().fuse() => {
@@ -240,8 +240,7 @@ impl HeadlessProject {
operation,
is_local: true,
} => cx
- .background_executor()
- .spawn(self.session.request(proto::UpdateBuffer {
+ .background_spawn(self.session.request(proto::UpdateBuffer {
project_id: SSH_PROJECT_ID,
buffer_id: buffer.read(cx).remote_id().to_proto(),
operations: vec![serialize_operation(operation)],
@@ -302,15 +301,14 @@ impl HeadlessProject {
message: prompt.message.clone(),
});
let prompt = prompt.clone();
- cx.background_executor()
- .spawn(async move {
- let response = request.await?;
- if let Some(action_response) = response.action_response {
- prompt.respond(action_response as usize).await;
- }
- anyhow::Ok(())
- })
- .detach();
+ cx.background_spawn(async move {
+ let response = request.await?;
+ if let Some(action_response) = response.action_response {
+ prompt.respond(action_response as usize).await;
+ }
+ anyhow::Ok(())
+ })
+ .detach();
}
_ => {}
}
@@ -311,7 +311,7 @@ fn start_server(
let mut output_buffer = Vec::new();
let (mut stdin_msg_tx, mut stdin_msg_rx) = mpsc::unbounded::<Envelope>();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
while let Ok(msg) = read_message(&mut stdin_stream, &mut input_buffer).await {
if let Err(_) = stdin_msg_tx.send(msg).await {
break;
@@ -487,8 +487,7 @@ pub fn execute_run(
handle_panic_requests(&project, &session);
- cx.background_executor()
- .spawn(async move { cleanup_old_binaries() })
+ cx.background_spawn(async move { cleanup_old_binaries() })
.detach();
mem::forget(project);
@@ -5,7 +5,7 @@ use futures::{
stream::{SelectAll, StreamExt},
AsyncBufReadExt as _, SinkExt as _,
};
-use gpui::{App, Entity, EntityId, Task, Window};
+use gpui::{App, AppContext as _, Entity, EntityId, Task, Window};
use jupyter_protocol::{
connection_info::{ConnectionInfo, Transport},
ExecutionState, JupyterKernelspec, JupyterMessage, JupyterMessageContent, KernelInfoReply,
@@ -211,7 +211,7 @@ impl NativeRunningKernel {
futures::channel::mpsc::channel(100);
let (mut shell_request_tx, mut shell_request_rx) = futures::channel::mpsc::channel(100);
- let routing_task = cx.background_executor().spawn({
+ let routing_task = cx.background_spawn({
async move {
while let Some(message) = request_rx.next().await {
match message.content {
@@ -229,7 +229,7 @@ impl NativeRunningKernel {
}
});
- let shell_task = cx.background_executor().spawn({
+ let shell_task = cx.background_spawn({
async move {
while let Some(message) = shell_request_rx.next().await {
shell_socket.send(message).await.ok();
@@ -240,7 +240,7 @@ impl NativeRunningKernel {
}
});
- let control_task = cx.background_executor().spawn({
+ let control_task = cx.background_spawn({
async move {
while let Some(message) = control_request_rx.next().await {
control_socket.send(message).await.ok();
@@ -1,5 +1,5 @@
use futures::{channel::mpsc, SinkExt as _};
-use gpui::{App, Entity, Task, Window};
+use gpui::{App, AppContext as _, Entity, Task, Window};
use http_client::{AsyncBody, HttpClient, Request};
use jupyter_protocol::{ExecutionState, JupyterKernelspec, JupyterMessage, KernelInfoReply};
@@ -189,7 +189,7 @@ impl RemoteRunningKernel {
let (request_tx, mut request_rx) =
futures::channel::mpsc::channel::<JupyterMessage>(100);
- let routing_task = cx.background_executor().spawn({
+ let routing_task = cx.background_spawn({
async move {
while let Some(message) = request_rx.next().await {
w.send(message).await.ok();
@@ -134,8 +134,7 @@ impl Cell {
cx.spawn_in(window, |this, mut cx| async move {
let parsed_markdown = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
parse_markdown(&source, None, Some(languages)).await
})
.await;
@@ -19,9 +19,8 @@ impl MarkdownView {
pub fn from(text: String, cx: &mut Context<Self>) -> Self {
let task = cx.spawn(|markdown_view, mut cx| {
let text = text.clone();
- let parsed = cx
- .background_executor()
- .spawn(async move { parse_markdown(&text, None, None).await });
+ let parsed =
+ cx.background_spawn(async move { parse_markdown(&text, None, None).await });
async move {
let content = parsed.await;
@@ -164,7 +164,7 @@ impl ReplStore {
let remote_kernel_specifications = self.get_remote_kernel_specifications(cx);
- let all_specs = cx.background_executor().spawn(async move {
+ let all_specs = cx.background_spawn(async move {
let mut all_specs = local_kernel_specifications
.await?
.into_iter()
@@ -10,7 +10,7 @@ use fs::Fs;
use fs::MTime;
use futures::{stream::StreamExt, FutureExt as _};
use futures_batch::ChunksTimeoutStreamExt;
-use gpui::{App, Entity, Task};
+use gpui::{App, AppContext as _, Entity, Task};
use heed::types::{SerdeBincode, Str};
use language::LanguageRegistry;
use log;
@@ -102,7 +102,7 @@ impl EmbeddingIndex {
let db_connection = self.db_connection.clone();
let db = self.db;
let entries_being_indexed = self.entry_ids_being_indexed.clone();
- let task = cx.background_executor().spawn(async move {
+ let task = cx.background_spawn(async move {
let txn = db_connection
.read_txn()
.context("failed to create read transaction")?;
@@ -185,7 +185,7 @@ impl EmbeddingIndex {
let (updated_entries_tx, updated_entries_rx) = channel::bounded(512);
let (deleted_entry_ranges_tx, deleted_entry_ranges_rx) = channel::bounded(128);
let entries_being_indexed = self.entry_ids_being_indexed.clone();
- let task = cx.background_executor().spawn(async move {
+ let task = cx.background_spawn(async move {
for (path, entry_id, status) in updated_entries.iter() {
match status {
project::PathChange::Added
@@ -278,7 +278,7 @@ impl EmbeddingIndex {
) -> EmbedFiles {
let embedding_provider = embedding_provider.clone();
let (embedded_files_tx, embedded_files_rx) = channel::bounded(512);
- let task = cx.background_executor().spawn(async move {
+ let task = cx.background_spawn(async move {
let mut chunked_file_batches =
pin!(chunked_files.chunks_timeout(512, Duration::from_secs(2)));
while let Some(chunked_files) = chunked_file_batches.next().await {
@@ -361,7 +361,7 @@ impl EmbeddingIndex {
let db_connection = self.db_connection.clone();
let db = self.db;
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut deleted_entry_ranges = pin!(deleted_entry_ranges);
let mut embedded_files = pin!(embedded_files);
loop {
@@ -397,7 +397,7 @@ impl EmbeddingIndex {
pub fn paths(&self, cx: &App) -> Task<Result<Vec<Arc<Path>>>> {
let connection = self.db_connection.clone();
let db = self.db;
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let tx = connection
.read_txn()
.context("failed to create read transaction")?;
@@ -413,7 +413,7 @@ impl EmbeddingIndex {
pub fn chunks_for_path(&self, path: Arc<Path>, cx: &App) -> Task<Result<Vec<EmbeddedChunk>>> {
let connection = self.db_connection.clone();
let db = self.db;
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let tx = connection
.read_txn()
.context("failed to create read transaction")?;
@@ -7,7 +7,9 @@ use anyhow::{anyhow, Context as _, Result};
use collections::HashMap;
use fs::Fs;
use futures::FutureExt;
-use gpui::{App, Context, Entity, EntityId, EventEmitter, Subscription, Task, WeakEntity};
+use gpui::{
+ App, AppContext as _, Context, Entity, EntityId, EventEmitter, Subscription, Task, WeakEntity,
+};
use language::LanguageRegistry;
use log;
use project::{Project, Worktree, WorktreeId};
@@ -250,7 +252,7 @@ impl ProjectIndex {
let worktree_id = index.worktree().read(cx).id();
let db_connection = index.db_connection().clone();
let db = *index.embedding_index().db();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let txn = db_connection
.read_txn()
.context("failed to create read transaction")?;
@@ -432,7 +434,7 @@ impl ProjectIndex {
let file_digest_db = summary_index.file_digest_db();
let summary_db = summary_index.summary_db();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let txn = db_connection
.read_txn()
.context("failed to create db read transaction")?;
@@ -519,8 +521,9 @@ impl ProjectIndex {
index
.read_with(&cx, |index, cx| {
- cx.background_executor()
- .spawn(index.summary_index().flush_backlog(worktree_abs_path, cx))
+ cx.background_spawn(
+ index.summary_index().flush_backlog(worktree_abs_path, cx),
+ )
})?
.await
})
@@ -42,8 +42,7 @@ impl SemanticDb {
cx: &mut AsyncApp,
) -> Result<Self> {
let db_connection = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
std::fs::create_dir_all(&db_path)?;
unsafe {
heed::EnvOpenOptions::new()
@@ -432,8 +431,7 @@ mod tests {
let worktree = search_result.worktree.read(cx);
let entry_abs_path = worktree.abs_path().join(&search_result.path);
let fs = project.read(cx).fs().clone();
- cx.background_executor()
- .spawn(async move { fs.load(&entry_abs_path).await.unwrap() })
+ cx.background_spawn(async move { fs.load(&entry_abs_path).await.unwrap() })
})
.await;
@@ -3,7 +3,7 @@ use arrayvec::ArrayString;
use fs::{Fs, MTime};
use futures::{stream::StreamExt, TryFutureExt};
use futures_batch::ChunksTimeoutStreamExt;
-use gpui::{App, Entity, Task};
+use gpui::{App, AppContext as _, Entity, Task};
use heed::{
types::{SerdeBincode, Str},
RoTxn,
@@ -254,7 +254,7 @@ impl SummaryIndex {
let db_connection = self.db_connection.clone();
let db = self.summary_db;
let (needs_summary_tx, needs_summary_rx) = channel::bounded(512);
- let task = cx.background_executor().spawn(async move {
+ let task = cx.background_spawn(async move {
let mut might_need_summary = pin!(might_need_summary);
while let Some(file) = might_need_summary.next().await {
let tx = db_connection
@@ -291,7 +291,7 @@ impl SummaryIndex {
let db_connection = self.db_connection.clone();
let digest_db = self.file_digest_db;
let backlog = Arc::clone(&self.backlog);
- let task = cx.background_executor().spawn(async move {
+ let task = cx.background_spawn(async move {
let txn = db_connection
.read_txn()
.context("failed to create read transaction")?;
@@ -368,7 +368,7 @@ impl SummaryIndex {
let db_connection = self.db_connection.clone();
let digest_db = self.file_digest_db;
let backlog = Arc::clone(&self.backlog);
- let task = cx.background_executor().spawn(async move {
+ let task = cx.background_spawn(async move {
let txn = db_connection
.read_txn()
.context("failed to create read transaction")?;
@@ -538,7 +538,7 @@ impl SummaryIndex {
.available_models(cx)
.find(|model| &model.id() == &summary_model_id)
else {
- return cx.background_executor().spawn(async move {
+ return cx.background_spawn(async move {
Err(anyhow!("Couldn't find the preferred summarization model ({:?}) in the language registry's available models", summary_model_id))
});
};
@@ -566,31 +566,30 @@ impl SummaryIndex {
let code_len = code.len();
cx.spawn(|cx| async move {
let stream = model.stream_completion(request, &cx);
- cx.background_executor()
- .spawn(async move {
- let answer: String = stream
- .await?
- .filter_map(|event| async {
- if let Ok(LanguageModelCompletionEvent::Text(text)) = event {
- Some(text)
- } else {
- None
- }
- })
- .collect()
- .await;
+ cx.background_spawn(async move {
+ let answer: String = stream
+ .await?
+ .filter_map(|event| async {
+ if let Ok(LanguageModelCompletionEvent::Text(text)) = event {
+ Some(text)
+ } else {
+ None
+ }
+ })
+ .collect()
+ .await;
- log::info!(
- "It took {:?} to summarize {:?} bytes of code.",
- start.elapsed(),
- code_len
- );
+ log::info!(
+ "It took {:?} to summarize {:?} bytes of code.",
+ start.elapsed(),
+ code_len
+ );
- log::debug!("Summary was: {:?}", &answer);
+ log::debug!("Summary was: {:?}", &answer);
- Ok(answer)
- })
- .await
+ Ok(answer)
+ })
+ .await
// TODO if summarization failed, put it back in the backlog!
})
@@ -604,7 +603,7 @@ impl SummaryIndex {
let db_connection = self.db_connection.clone();
let digest_db = self.file_digest_db;
let summary_db = self.summary_db;
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut summaries = pin!(summaries.chunks_timeout(4096, Duration::from_secs(2)));
while let Some(summaries) = summaries.next().await {
let mut txn = db_connection.write_txn()?;
@@ -650,7 +649,7 @@ impl SummaryIndex {
backlog.drain().collect()
};
- let task = cx.background_executor().spawn(async move {
+ let task = cx.background_spawn(async move {
tx.send(needs_summary).await?;
Ok(())
});
@@ -52,8 +52,7 @@ impl WorktreeIndex {
cx.spawn(|mut cx| async move {
let entries_being_indexed = Arc::new(IndexingEntrySet::new(status_tx));
let (embedding_index, summary_index) = cx
- .background_executor()
- .spawn({
+ .background_spawn({
let entries_being_indexed = Arc::clone(&entries_being_indexed);
let db_connection = db_connection.clone();
async move {
@@ -1,7 +1,7 @@
use std::time::Duration;
use db::kvp::KEY_VALUE_STORE;
-use gpui::{AnyWindowHandle, Context, Subscription, Task, WindowId};
+use gpui::{AnyWindowHandle, AppContext as _, Context, Subscription, Task, WindowId};
use util::ResultExt;
use uuid::Uuid;
@@ -88,7 +88,7 @@ impl AppSession {
fn app_will_quit(&mut self, cx: &mut Context<Self>) -> Task<()> {
if let Some(windows) = cx.window_stack() {
- cx.background_executor().spawn(store_window_stack(windows))
+ cx.background_spawn(store_window_stack(windows))
} else {
Task::ready(())
}
@@ -3,7 +3,7 @@
use std::sync::Arc;
use futures::{channel::mpsc::UnboundedSender, StreamExt};
-use gpui::App;
+use gpui::{App, AppContext};
use parking_lot::RwLock;
use serde::Deserialize;
use util::ResultExt;
@@ -33,35 +33,34 @@ impl<T: PartialEq + 'static + Sync> TrackedFile<T> {
T: for<'a> Deserialize<'a> + Default + Send,
{
let parsed_contents: Arc<RwLock<T>> = Arc::default();
- cx.background_executor()
- .spawn({
- let parsed_contents = parsed_contents.clone();
- async move {
- while let Some(new_contents) = tracker.next().await {
- if Arc::strong_count(&parsed_contents) == 1 {
- // We're no longer being observed. Stop polling.
- break;
- }
- if !new_contents.trim().is_empty() {
- let Some(new_contents) =
- serde_json_lenient::from_str::<T>(&new_contents).log_err()
- else {
- continue;
- };
- let mut contents = parsed_contents.write();
- if *contents != new_contents {
- *contents = new_contents;
- if notification_outlet.unbounded_send(()).is_err() {
- // Whoever cared about contents is not around anymore.
- break;
- }
+ cx.background_spawn({
+ let parsed_contents = parsed_contents.clone();
+ async move {
+ while let Some(new_contents) = tracker.next().await {
+ if Arc::strong_count(&parsed_contents) == 1 {
+ // We're no longer being observed. Stop polling.
+ break;
+ }
+ if !new_contents.trim().is_empty() {
+ let Some(new_contents) =
+ serde_json_lenient::from_str::<T>(&new_contents).log_err()
+ else {
+ continue;
+ };
+ let mut contents = parsed_contents.write();
+ if *contents != new_contents {
+ *contents = new_contents;
+ if notification_outlet.unbounded_send(()).is_err() {
+ // Whoever cared about contents is not around anymore.
+ break;
}
}
}
- anyhow::Ok(())
}
- })
- .detach_and_log_err(cx);
+ anyhow::Ok(())
+ }
+ })
+ .detach_and_log_err(cx);
Self { parsed_contents }
}
@@ -75,39 +74,38 @@ impl<T: PartialEq + 'static + Sync> TrackedFile<T> {
T: Default + Send,
{
let parsed_contents: Arc<RwLock<T>> = Arc::default();
- cx.background_executor()
- .spawn({
- let parsed_contents = parsed_contents.clone();
- async move {
- while let Some(new_contents) = tracker.next().await {
- if Arc::strong_count(&parsed_contents) == 1 {
- // We're no longer being observed. Stop polling.
- break;
- }
+ cx.background_spawn({
+ let parsed_contents = parsed_contents.clone();
+ async move {
+ while let Some(new_contents) = tracker.next().await {
+ if Arc::strong_count(&parsed_contents) == 1 {
+ // We're no longer being observed. Stop polling.
+ break;
+ }
- if !new_contents.trim().is_empty() {
- let Some(new_contents) =
- serde_json_lenient::from_str::<U>(&new_contents).log_err()
- else {
- continue;
- };
- let Some(new_contents) = new_contents.try_into().log_err() else {
- continue;
- };
- let mut contents = parsed_contents.write();
- if *contents != new_contents {
- *contents = new_contents;
- if notification_outlet.unbounded_send(()).is_err() {
- // Whoever cared about contents is not around anymore.
- break;
- }
+ if !new_contents.trim().is_empty() {
+ let Some(new_contents) =
+ serde_json_lenient::from_str::<U>(&new_contents).log_err()
+ else {
+ continue;
+ };
+ let Some(new_contents) = new_contents.try_into().log_err() else {
+ continue;
+ };
+ let mut contents = parsed_contents.write();
+ if *contents != new_contents {
+ *contents = new_contents;
+ if notification_outlet.unbounded_send(()).is_err() {
+ // Whoever cared about contents is not around anymore.
+ break;
}
}
}
- anyhow::Ok(())
}
- })
- .detach_and_log_err(cx);
+ anyhow::Ok(())
+ }
+ })
+ .detach_and_log_err(cx);
Self {
parsed_contents: Default::default(),
}
@@ -58,9 +58,9 @@ use std::{
use thiserror::Error;
use gpui::{
- actions, black, px, AnyWindowHandle, App, Bounds, ClipboardItem, Context, EventEmitter, Hsla,
- Keystroke, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, Point,
- Rgba, ScrollWheelEvent, SharedString, Size, Task, TouchPhase,
+ actions, black, px, AnyWindowHandle, App, AppContext as _, Bounds, ClipboardItem, Context,
+ EventEmitter, Hsla, Keystroke, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent,
+ MouseUpEvent, Pixels, Point, Rgba, ScrollWheelEvent, SharedString, Size, Task, TouchPhase,
};
use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str};
@@ -1633,7 +1633,7 @@ impl Terminal {
cx: &Context<Self>,
) -> Task<Vec<RangeInclusive<AlacPoint>>> {
let term = self.term.clone();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let term = term.lock();
all_search_matches(&term, &mut searcher).collect()
@@ -222,8 +222,7 @@ impl TerminalPanel {
mut cx: AsyncWindowContext,
) -> Result<Entity<Self>> {
let serialized_panel = cx
- .background_executor()
- .spawn(async move { KEY_VALUE_STORE.read_kvp(TERMINAL_PANEL_KEY) })
+ .background_spawn(async move { KEY_VALUE_STORE.read_kvp(TERMINAL_PANEL_KEY) })
.await
.log_err()
.flatten()
@@ -742,25 +741,24 @@ impl TerminalPanel {
))
})
.ok()?;
- cx.background_executor()
- .spawn(
- async move {
- KEY_VALUE_STORE
- .write_kvp(
- TERMINAL_PANEL_KEY.into(),
- serde_json::to_string(&SerializedTerminalPanel {
- items,
- active_item_id: None,
- height,
- width,
- })?,
- )
- .await?;
- anyhow::Ok(())
- }
- .log_err(),
- )
- .await;
+ cx.background_spawn(
+ async move {
+ KEY_VALUE_STORE
+ .write_kvp(
+ TERMINAL_PANEL_KEY.into(),
+ serde_json::to_string(&SerializedTerminalPanel {
+ items,
+ active_item_id: None,
+ height,
+ width,
+ })?,
+ )
+ .await?;
+ anyhow::Ok(())
+ }
+ .log_err(),
+ )
+ .await;
Some(())
});
}
@@ -976,7 +976,7 @@ fn possible_open_paths_metadata(
potential_paths: HashSet<PathBuf>,
cx: &mut Context<TerminalView>,
) -> Task<Vec<(PathWithPosition, Metadata)>> {
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let mut canonical_paths = HashSet::default();
for path in potential_paths {
if let Ok(canonical) = fs.canonicalize(&path).await {
@@ -1378,9 +1378,12 @@ impl Item for TerminalView {
) {
if self.terminal().read(cx).task().is_none() {
if let Some((new_id, old_id)) = workspace.database_id().zip(self.workspace_id) {
- cx.background_executor()
- .spawn(TERMINAL_DB.update_workspace_id(new_id, old_id, cx.entity_id().as_u64()))
- .detach();
+ cx.background_spawn(TERMINAL_DB.update_workspace_id(
+ new_id,
+ old_id,
+ cx.entity_id().as_u64(),
+ ))
+ .detach();
}
self.workspace_id = workspace.database_id();
}
@@ -1421,7 +1424,7 @@ impl SerializableItem for TerminalView {
}
if let Some((cwd, workspace_id)) = terminal.working_directory().zip(self.workspace_id) {
- Some(cx.background_executor().spawn(async move {
+ Some(cx.background_spawn(async move {
TERMINAL_DB
.save_working_directory(item_id, workspace_id, cwd)
.await
@@ -7,7 +7,7 @@ use editor::{
scroll::Autoscroll,
Bias, Editor, ToPoint,
};
-use gpui::{actions, impl_internal_actions, Action, App, Context, Global, Window};
+use gpui::{actions, impl_internal_actions, Action, App, AppContext as _, Context, Global, Window};
use itertools::Itertools;
use language::Point;
use multi_buffer::MultiBufferRow;
@@ -1185,8 +1185,7 @@ impl OnMatchingLines {
.clip_point(Point::new(range.end.0 + 1, 0), Bias::Left);
cx.spawn_in(window, |editor, mut cx| async move {
let new_selections = cx
- .background_executor()
- .spawn(async move {
+ .background_spawn(async move {
let mut line = String::new();
let mut new_selections = Vec::new();
let chunks = snapshot
@@ -1513,22 +1512,20 @@ impl ShellExec {
if let Some(mut stdin) = running.stdin.take() {
if let Some(snapshot) = input_snapshot {
let range = range.clone();
- cx.background_executor()
- .spawn(async move {
- for chunk in snapshot.text_for_range(range) {
- if stdin.write_all(chunk.as_bytes()).log_err().is_none() {
- return;
- }
+ cx.background_spawn(async move {
+ for chunk in snapshot.text_for_range(range) {
+ if stdin.write_all(chunk.as_bytes()).log_err().is_none() {
+ return;
}
- stdin.flush().log_err();
- })
- .detach();
+ }
+ stdin.flush().log_err();
+ })
+ .detach();
}
};
let output = cx
- .background_executor()
- .spawn(async move { running.wait_with_output() })
+ .background_spawn(async move { running.wait_with_output() })
.await;
let Some(output) = output.log_err() else {
@@ -5,7 +5,7 @@ use crate::{
use call::{RemoteVideoTrack, RemoteVideoTrackView};
use client::{proto::PeerId, User};
use gpui::{
- div, AppContext, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement,
+ div, AppContext as _, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement,
ParentElement, Render, SharedString, Styled,
};
use std::sync::Arc;
@@ -4337,8 +4337,7 @@ impl Workspace {
self.update_active_view_for_followers(window, cx);
if let Some(database_id) = self.database_id {
- cx.background_executor()
- .spawn(persistence::DB.update_timestamp(database_id))
+ cx.background_spawn(persistence::DB.update_timestamp(database_id))
.detach();
}
} else {
@@ -4626,8 +4625,7 @@ impl Workspace {
if let Ok(Some(task)) = this.update_in(cx, |workspace, window, cx| {
item.serialize(workspace, false, window, cx)
}) {
- cx.background_executor()
- .spawn(async move { task.await.log_err() })
+ cx.background_spawn(async move { task.await.log_err() })
.detach();
}
}
@@ -4965,8 +4963,7 @@ impl Workspace {
) {
self.centered_layout = !self.centered_layout;
if let Some(database_id) = self.database_id() {
- cx.background_executor()
- .spawn(DB.set_centered_layout(database_id, self.centered_layout))
+ cx.background_spawn(DB.set_centered_layout(database_id, self.centered_layout))
.detach_and_log_err(cx);
}
cx.notify();
@@ -6223,7 +6220,7 @@ fn serialize_ssh_project(
Option<SerializedWorkspace>,
)>,
> {
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let serialized_ssh_project = persistence::DB
.get_or_create_ssh_project(
connection_options.host.clone(),
@@ -791,23 +791,22 @@ impl Worktree {
// Apply updates to a separate snapshot in a background task, then
// send them to a foreground task which updates the model.
- cx.background_executor()
- .spawn(async move {
- while let Some(update) = background_updates_rx.next().await {
+ cx.background_spawn(async move {
+ while let Some(update) = background_updates_rx.next().await {
+ {
+ let mut lock = background_snapshot.lock();
+ if let Err(error) = lock
+ .0
+ .apply_remote_update(update.clone(), &settings.file_scan_inclusions)
{
- let mut lock = background_snapshot.lock();
- if let Err(error) = lock
- .0
- .apply_remote_update(update.clone(), &settings.file_scan_inclusions)
- {
- log::error!("error applying worktree update: {}", error);
- }
- lock.1.push(update);
+ log::error!("error applying worktree update: {}", error);
}
- snapshot_updated_tx.send(()).await.ok();
+ lock.1.push(update);
}
- })
- .detach();
+ snapshot_updated_tx.send(()).await.ok();
+ }
+ })
+ .detach();
// On the foreground task, update to the latest snapshot and notify
// any update observer of all updates that led to that snapshot.
@@ -991,7 +990,7 @@ impl Worktree {
Worktree::Local(this) => {
let path = Arc::from(path);
let snapshot = this.snapshot();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
if let Some(repo) = snapshot.repository_for_path(&path) {
if let Some(repo_path) = repo.relativize(&path).log_err() {
if let Some(git_repo) =
@@ -1015,7 +1014,7 @@ impl Worktree {
Worktree::Local(this) => {
let path = Arc::from(path);
let snapshot = this.snapshot();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
if let Some(repo) = snapshot.repository_for_path(&path) {
if let Some(repo_path) = repo.relativize(&path).log_err() {
if let Some(git_repo) =
@@ -1431,7 +1430,7 @@ impl LocalWorktree {
let git_hosting_provider_registry = GitHostingProviderRegistry::try_global(cx);
let settings = self.settings.clone();
let (scan_states_tx, mut scan_states_rx) = mpsc::unbounded();
- let background_scanner = cx.background_executor().spawn({
+ let background_scanner = cx.background_spawn({
let abs_path = snapshot.abs_path.as_path().to_path_buf();
let background = cx.background_executor().clone();
async move {
@@ -1668,7 +1667,7 @@ impl LocalWorktree {
let is_private = self.is_path_private(path.as_ref());
let worktree = cx.weak_entity();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
let abs_path = abs_path?;
let content = fs.load_bytes(&abs_path).await?;
@@ -1774,7 +1773,7 @@ impl LocalWorktree {
let path_excluded = self.settings.is_path_excluded(&abs_path);
let fs = self.fs.clone();
let task_abs_path = abs_path.clone();
- let write = cx.background_executor().spawn(async move {
+ let write = cx.background_spawn(async move {
if is_dir {
fs.create_dir(&task_abs_path)
.await
@@ -1838,7 +1837,7 @@ impl LocalWorktree {
return Task::ready(Err(anyhow!("invalid path {path:?}")));
};
- let write = cx.background_executor().spawn({
+ let write = cx.background_spawn({
let fs = fs.clone();
let abs_path = abs_path.clone();
async move { fs.save(&abs_path, &text, line_ending).await }
@@ -1890,7 +1889,7 @@ impl LocalWorktree {
let abs_path = self.absolutize(&entry.path);
let fs = self.fs.clone();
- let delete = cx.background_executor().spawn(async move {
+ let delete = cx.background_spawn(async move {
if entry.is_file() {
if trash {
fs.trash_file(&abs_path?, Default::default()).await?;
@@ -1964,7 +1963,7 @@ impl LocalWorktree {
let abs_path = abs_new_path.clone();
let fs = self.fs.clone();
let case_sensitive = self.fs_case_sensitive;
- let rename = cx.background_executor().spawn(async move {
+ let rename = cx.background_spawn(async move {
let abs_old_path = abs_old_path?;
let abs_new_path = abs_new_path;
@@ -2033,7 +2032,7 @@ impl LocalWorktree {
};
let abs_new_path = self.absolutize(&new_path);
let fs = self.fs.clone();
- let copy = cx.background_executor().spawn(async move {
+ let copy = cx.background_spawn(async move {
copy_recursive(
fs.as_ref(),
&abs_old_path?,
@@ -2085,27 +2084,26 @@ impl LocalWorktree {
.collect::<Vec<_>>();
cx.spawn(|this, cx| async move {
- cx.background_executor()
- .spawn(async move {
- for (source, target) in paths {
- copy_recursive(
- fs.as_ref(),
- &source,
- &target,
- fs::CopyOptions {
- overwrite: overwrite_existing_files,
- ..Default::default()
- },
- )
- .await
- .with_context(|| {
- anyhow!("Failed to copy file from {source:?} to {target:?}")
- })?;
- }
- Ok::<(), anyhow::Error>(())
- })
- .await
- .log_err();
+ cx.background_spawn(async move {
+ for (source, target) in paths {
+ copy_recursive(
+ fs.as_ref(),
+ &source,
+ &target,
+ fs::CopyOptions {
+ overwrite: overwrite_existing_files,
+ ..Default::default()
+ },
+ )
+ .await
+ .with_context(|| {
+ anyhow!("Failed to copy file from {source:?} to {target:?}")
+ })?;
+ }
+ Ok::<(), anyhow::Error>(())
+ })
+ .await
+ .log_err();
let mut refresh = cx.read_entity(
&this.upgrade().with_context(|| "Dropped worktree")?,
|this, _| {
@@ -2117,13 +2115,12 @@ impl LocalWorktree {
},
)??;
- cx.background_executor()
- .spawn(async move {
- refresh.next().await;
- Ok::<(), anyhow::Error>(())
- })
- .await
- .log_err();
+ cx.background_spawn(async move {
+ refresh.next().await;
+ Ok::<(), anyhow::Error>(())
+ })
+ .await
+ .log_err();
let this = this.upgrade().with_context(|| "Dropped worktree")?;
cx.read_entity(&this, |this, _| {
@@ -2142,7 +2139,7 @@ impl LocalWorktree {
) -> Option<Task<Result<()>>> {
let path = self.entry_for_id(entry_id)?.path.clone();
let mut refresh = self.refresh_entries_for_paths(vec![path]);
- Some(cx.background_executor().spawn(async move {
+ Some(cx.background_spawn(async move {
refresh.next().await;
Ok(())
}))
@@ -2155,7 +2152,7 @@ impl LocalWorktree {
) -> Option<Task<Result<()>>> {
let path = self.entry_for_id(entry_id).unwrap().path.clone();
let mut rx = self.add_path_prefix_to_scan(path.clone());
- Some(cx.background_executor().spawn(async move {
+ Some(cx.background_spawn(async move {
rx.next().await;
Ok(())
}))
@@ -2229,7 +2226,7 @@ impl LocalWorktree {
.ok();
let worktree_id = cx.entity_id().as_u64();
- let _maintain_remote_snapshot = cx.background_executor().spawn(async move {
+ let _maintain_remote_snapshot = cx.background_spawn(async move {
let mut is_first = true;
while let Some((snapshot, entry_changes, repo_changes)) = snapshots_rx.next().await {
let update = if is_first {
@@ -3719,16 +3716,14 @@ impl language::LocalFile for File {
let worktree = self.worktree.read(cx).as_local().unwrap();
let abs_path = worktree.absolutize(&self.path);
let fs = worktree.fs.clone();
- cx.background_executor()
- .spawn(async move { fs.load(&abs_path?).await })
+ cx.background_spawn(async move { fs.load(&abs_path?).await })
}
fn load_bytes(&self, cx: &App) -> Task<Result<Vec<u8>>> {
let worktree = self.worktree.read(cx).as_local().unwrap();
let abs_path = worktree.absolutize(&self.path);
let fs = worktree.fs.clone();
- cx.background_executor()
- .spawn(async move { fs.load_bytes(&abs_path?).await })
+ cx.background_spawn(async move { fs.load_bytes(&abs_path?).await })
}
}
@@ -11,7 +11,7 @@ use git::{
},
GITIGNORE,
};
-use gpui::{BorrowAppContext, Context, Task, TestAppContext};
+use gpui::{AppContext as _, BorrowAppContext, Context, Task, TestAppContext};
use parking_lot::Mutex;
use postage::stream::Stream;
use pretty_assertions::assert_eq;
@@ -1954,7 +1954,7 @@ fn randomly_mutate_worktree(
new_path
);
let task = worktree.rename_entry(entry.id, new_path, cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
task.await?.to_included().unwrap();
Ok(())
})
@@ -1969,7 +1969,7 @@ fn randomly_mutate_worktree(
child_path,
);
let task = worktree.create_entry(child_path, is_dir, cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
task.await?;
Ok(())
})
@@ -1977,7 +1977,7 @@ fn randomly_mutate_worktree(
log::info!("overwriting file {:?} ({})", entry.path, entry.id.0);
let task =
worktree.write_file(entry.path.clone(), "".into(), Default::default(), cx);
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
task.await?;
Ok(())
})
@@ -4,7 +4,7 @@ use backtrace::{self, Backtrace};
use chrono::Utc;
use client::{telemetry, TelemetrySettings};
use db::kvp::KEY_VALUE_STORE;
-use gpui::{App, SemanticVersion};
+use gpui::{App, AppContext as _, SemanticVersion};
use http_client::{self, HttpClient, HttpClientWithUrl, HttpRequestExt, Method};
use paths::{crashes_dir, crashes_retired_dir};
use project::Project;
@@ -205,35 +205,34 @@ pub fn init(
ssh_client.update(cx, |client, cx| {
if TelemetrySettings::get_global(cx).diagnostics {
let request = client.proto_client().request(proto::GetPanicFiles {});
- cx.background_executor()
- .spawn(async move {
- let panic_files = request.await?;
- for file in panic_files.file_contents {
- let panic: Option<Panic> = serde_json::from_str(&file)
- .log_err()
- .or_else(|| {
- file.lines()
- .next()
- .and_then(|line| serde_json::from_str(line).ok())
- })
- .unwrap_or_else(|| {
- log::error!("failed to deserialize panic file {:?}", file);
- None
- });
-
- if let Some(mut panic) = panic {
- panic.session_id = session_id.clone();
- panic.system_id = system_id.clone();
- panic.installation_id = installation_id.clone();
-
- upload_panic(&http_client, &panic_report_url, panic, &mut None)
- .await?;
- }
+ cx.background_spawn(async move {
+ let panic_files = request.await?;
+ for file in panic_files.file_contents {
+ let panic: Option<Panic> = serde_json::from_str(&file)
+ .log_err()
+ .or_else(|| {
+ file.lines()
+ .next()
+ .and_then(|line| serde_json::from_str(line).ok())
+ })
+ .unwrap_or_else(|| {
+ log::error!("failed to deserialize panic file {:?}", file);
+ None
+ });
+
+ if let Some(mut panic) = panic {
+ panic.session_id = session_id.clone();
+ panic.system_id = system_id.clone();
+ panic.installation_id = installation_id.clone();
+
+ upload_panic(&http_client, &panic_report_url, panic, &mut None)
+ .await?;
}
+ }
- anyhow::Ok(())
- })
- .detach_and_log_err(cx);
+ anyhow::Ok(())
+ })
+ .detach_and_log_err(cx);
}
})
}
@@ -450,18 +449,17 @@ fn upload_panics_and_crashes(
cx: &App,
) {
let telemetry_settings = *client::TelemetrySettings::get_global(cx);
- cx.background_executor()
- .spawn(async move {
- let most_recent_panic =
- upload_previous_panics(http.clone(), &panic_report_url, telemetry_settings)
- .await
- .log_err()
- .flatten();
- upload_previous_crashes(http, most_recent_panic, installation_id, telemetry_settings)
+ cx.background_spawn(async move {
+ let most_recent_panic =
+ upload_previous_panics(http.clone(), &panic_report_url, telemetry_settings)
.await
.log_err()
- })
- .detach()
+ .flatten();
+ upload_previous_crashes(http, most_recent_panic, installation_id, telemetry_settings)
+ .await
+ .log_err()
+ })
+ .detach()
}
/// Uploads panics via `zed.dev`.
@@ -956,7 +956,7 @@ fn install_cli(
Some(LINUX_PROMPT_DETAIL),
&["Ok"],
);
- cx.background_executor().spawn(prompt).detach();
+ cx.background_spawn(prompt).detach();
return Ok(());
}
let path = install_cli::install_cli(cx.deref())
@@ -1335,7 +1335,7 @@ fn show_markdown_app_notification<F>(
) where
F: 'static + Send + Sync + Fn(&mut Window, &mut Context<MessageNotification>),
{
- let parsed_markdown = cx.background_executor().spawn(async move {
+ let parsed_markdown = cx.background_spawn(async move {
let file_location_directory = None;
let language_registry = None;
markdown_preview::markdown_parser::parse_markdown(
@@ -3,7 +3,7 @@ use collections::HashMap;
use copilot::{Copilot, CopilotCompletionProvider};
use editor::{Editor, EditorMode};
use feature_flags::{FeatureFlagAppExt, PredictEditsFeatureFlag};
-use gpui::{AnyWindowHandle, App, AppContext, Context, Entity, WeakEntity};
+use gpui::{AnyWindowHandle, App, AppContext as _, Context, Entity, WeakEntity};
use language::language_settings::{all_language_settings, EditPredictionProvider};
use settings::SettingsStore;
use std::{cell::RefCell, rc::Rc, sync::Arc};
@@ -419,8 +419,7 @@ impl Zeta {
}
let values = cx
- .background_executor()
- .spawn({
+ .background_spawn({
let snapshot = snapshot.clone();
let path = path.clone();
async move {
@@ -813,8 +812,7 @@ and then another
let output_excerpt: Arc<str> = output_excerpt.into();
let edits: Arc<[(Range<Anchor>, String)]> = cx
- .background_executor()
- .spawn({
+ .background_spawn({
let output_excerpt = output_excerpt.clone();
let editable_range = editable_range.clone();
let snapshot = snapshot.clone();
@@ -1127,7 +1125,7 @@ impl LicenseDetectionWatcher {
.map(|file| worktree.load_file(file, cx))
.collect::<ArrayVec<_, { LICENSE_FILES_TO_CHECK.len() }>>();
- cx.background_executor().spawn(async move {
+ cx.background_spawn(async move {
for loaded_file in loaded_files.into_iter() {
let Ok(loaded_file) = loaded_file.await else {
continue;