cx.background_executor().spawn(...)
-> cx.background_spawn(...)
(#25103)
Done automatically with > ast-grep -p '$A.background_executor().spawn($B)' -r '$A.background_spawn($B)' --update-all --globs "\!crates/gpui" Followed by: * `cargo fmt` * Unexpected need to remove some trailing whitespace. * Manually adding imports of `gpui::{AppContext as _}` which provides `background_spawn` * Added `AppContext as _` to existing use of `AppContext` Release Notes: - N/A
This commit is contained in:
parent
f606b0641e
commit
b1872e3afd
120 changed files with 1146 additions and 1267 deletions
|
@ -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());
|
||||
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
|
||||
);
|
||||
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();
|
||||
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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
});
|
||||
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue