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
|
@ -3012,7 +3012,7 @@ impl CodegenAlternative {
|
||||||
let executor = cx.background_executor().clone();
|
let executor = cx.background_executor().clone();
|
||||||
let message_id = message_id.clone();
|
let message_id = message_id.clone();
|
||||||
let line_based_stream_diff: Task<anyhow::Result<()>> =
|
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 mut response_latency = None;
|
||||||
let request_start = Instant::now();
|
let request_start = Instant::now();
|
||||||
let diff = async {
|
let diff = async {
|
||||||
|
@ -3326,8 +3326,7 @@ impl CodegenAlternative {
|
||||||
|
|
||||||
cx.spawn(|codegen, mut cx| async move {
|
cx.spawn(|codegen, mut cx| async move {
|
||||||
let (deleted_row_ranges, inserted_row_ranges) = cx
|
let (deleted_row_ranges, inserted_row_ranges) = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
let old_text = old_snapshot
|
let old_text = old_snapshot
|
||||||
.text_for_range(
|
.text_for_range(
|
||||||
Point::new(old_range.start.row, 0)
|
Point::new(old_range.start.row, 0)
|
||||||
|
|
|
@ -1149,7 +1149,7 @@ impl Codegen {
|
||||||
|
|
||||||
let (mut hunks_tx, mut hunks_rx) = mpsc::channel(1);
|
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 message_id = message_id.clone();
|
||||||
let executor = cx.background_executor().clone();
|
let executor = cx.background_executor().clone();
|
||||||
async move {
|
async move {
|
||||||
|
|
|
@ -493,7 +493,7 @@ impl CodegenAlternative {
|
||||||
let executor = cx.background_executor().clone();
|
let executor = cx.background_executor().clone();
|
||||||
let message_id = message_id.clone();
|
let message_id = message_id.clone();
|
||||||
let line_based_stream_diff: Task<anyhow::Result<()>> =
|
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 mut response_latency = None;
|
||||||
let request_start = Instant::now();
|
let request_start = Instant::now();
|
||||||
let diff = async {
|
let diff = async {
|
||||||
|
@ -807,8 +807,7 @@ impl CodegenAlternative {
|
||||||
|
|
||||||
cx.spawn(|codegen, mut cx| async move {
|
cx.spawn(|codegen, mut cx| async move {
|
||||||
let (deleted_row_ranges, inserted_row_ranges) = cx
|
let (deleted_row_ranges, inserted_row_ranges) = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
let old_text = old_snapshot
|
let old_text = old_snapshot
|
||||||
.text_for_range(
|
.text_for_range(
|
||||||
Point::new(old_range.start.row, 0)
|
Point::new(old_range.start.row, 0)
|
||||||
|
|
|
@ -208,8 +208,7 @@ impl PickerDelegate for FetchContextPickerDelegate {
|
||||||
let confirm_behavior = self.confirm_behavior;
|
let confirm_behavior = self.confirm_behavior;
|
||||||
cx.spawn_in(window, |this, mut cx| async move {
|
cx.spawn_in(window, |this, mut cx| async move {
|
||||||
let text = cx
|
let text = cx
|
||||||
.background_executor()
|
.background_spawn(Self::build_message(http_client, url.clone()))
|
||||||
.spawn(Self::build_message(http_client, url.clone()))
|
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
this.update_in(&mut cx, |this, window, cx| {
|
this.update_in(&mut cx, |this, window, cx| {
|
||||||
|
|
|
@ -123,7 +123,7 @@ impl PickerDelegate for ThreadContextPickerDelegate {
|
||||||
};
|
};
|
||||||
|
|
||||||
let executor = cx.background_executor().clone();
|
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() {
|
if query.is_empty() {
|
||||||
threads
|
threads
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use collections::{BTreeMap, HashMap, HashSet};
|
use collections::{BTreeMap, HashMap, HashSet};
|
||||||
use futures::{self, future, Future, FutureExt};
|
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 language::Buffer;
|
||||||
use project::{ProjectPath, Worktree};
|
use project::{ProjectPath, Worktree};
|
||||||
use rope::Rope;
|
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.
|
// Important to collect version at the same time as content so that staleness logic is correct.
|
||||||
let content = buffer.as_rope().clone();
|
let content = buffer.as_rope().clone();
|
||||||
let text_task = cx
|
let text_task = cx.background_spawn(async move { to_fenced_codeblock(&path, content) });
|
||||||
.background_executor()
|
|
||||||
.spawn(async move { to_fenced_codeblock(&path, content) });
|
|
||||||
(buffer_info, text_task)
|
(buffer_info, text_task)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::inline_prompt_editor::CodegenStatus;
|
use crate::inline_prompt_editor::CodegenStatus;
|
||||||
use client::telemetry::Telemetry;
|
use client::telemetry::Telemetry;
|
||||||
use futures::{channel::mpsc, SinkExt, StreamExt};
|
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_model::{LanguageModelRegistry, LanguageModelRequest};
|
||||||
use language_models::report_assistant_event;
|
use language_models::report_assistant_event;
|
||||||
use std::{sync::Arc, time::Instant};
|
use std::{sync::Arc, time::Instant};
|
||||||
|
@ -53,7 +53,7 @@ impl TerminalCodegen {
|
||||||
|
|
||||||
let (mut hunks_tx, mut hunks_rx) = mpsc::channel(1);
|
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 message_id = message_id.clone();
|
||||||
let executor = cx.background_executor().clone();
|
let executor = cx.background_executor().clone();
|
||||||
async move {
|
async move {
|
||||||
|
|
|
@ -849,7 +849,7 @@ impl AssistantContext {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
context_ops.extend(self.pending_ops.iter().cloned());
|
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;
|
let buffer_ops = buffer_ops.await;
|
||||||
context_ops.sort_unstable_by_key(|op| op.timestamp());
|
context_ops.sort_unstable_by_key(|op| op.timestamp());
|
||||||
buffer_ops
|
buffer_ops
|
||||||
|
|
|
@ -265,19 +265,18 @@ impl ContextStore {
|
||||||
local_versions.push(context.version(cx).to_proto(context_id.clone()));
|
local_versions.push(context.version(cx).to_proto(context_id.clone()));
|
||||||
let client = this.client.clone();
|
let client = this.client.clone();
|
||||||
let project_id = envelope.payload.project_id;
|
let project_id = envelope.payload.project_id;
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let operations = operations.await;
|
||||||
let operations = operations.await;
|
for operation in operations {
|
||||||
for operation in operations {
|
client.send(proto::UpdateContext {
|
||||||
client.send(proto::UpdateContext {
|
project_id,
|
||||||
project_id,
|
context_id: context_id.to_proto(),
|
||||||
context_id: context_id.to_proto(),
|
operation: Some(operation),
|
||||||
operation: Some(operation),
|
})?;
|
||||||
})?;
|
}
|
||||||
}
|
anyhow::Ok(())
|
||||||
anyhow::Ok(())
|
})
|
||||||
})
|
.detach_and_log_err(cx);
|
||||||
.detach_and_log_err(cx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,8 +400,7 @@ impl ContextStore {
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let operations = cx
|
let operations = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
context_proto
|
context_proto
|
||||||
.operations
|
.operations
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -436,7 +434,7 @@ impl ContextStore {
|
||||||
let languages = self.languages.clone();
|
let languages = self.languages.clone();
|
||||||
let project = self.project.clone();
|
let project = self.project.clone();
|
||||||
let telemetry = self.telemetry.clone();
|
let telemetry = self.telemetry.clone();
|
||||||
let load = cx.background_executor().spawn({
|
let load = cx.background_spawn({
|
||||||
let path = path.clone();
|
let path = path.clone();
|
||||||
async move {
|
async move {
|
||||||
let saved_context = fs.load(&path).await?;
|
let saved_context = fs.load(&path).await?;
|
||||||
|
@ -539,8 +537,7 @@ impl ContextStore {
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let operations = cx
|
let operations = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
context_proto
|
context_proto
|
||||||
.operations
|
.operations
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -693,7 +690,7 @@ impl ContextStore {
|
||||||
pub fn search(&self, query: String, cx: &App) -> Task<Vec<SavedContextMetadata>> {
|
pub fn search(&self, query: String, cx: &App) -> Task<Vec<SavedContextMetadata>> {
|
||||||
let metadata = self.contexts_metadata.clone();
|
let metadata = self.contexts_metadata.clone();
|
||||||
let executor = cx.background_executor().clone();
|
let executor = cx.background_executor().clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
if query.is_empty() {
|
if query.is_empty() {
|
||||||
metadata
|
metadata
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::{anyhow, Context as _, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use editor::ProposedChangesEditor;
|
use editor::ProposedChangesEditor;
|
||||||
use futures::{future, TryFutureExt as _};
|
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 language::{AutoindentMode, Buffer, BufferSnapshot};
|
||||||
use project::{Project, ProjectPath};
|
use project::{Project, ProjectPath};
|
||||||
use std::{cmp, ops::Range, path::Path, sync::Arc};
|
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 snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot())?;
|
||||||
let suggestion = cx
|
let suggestion = cx
|
||||||
.background_executor()
|
.background_spawn(async move { kind.resolve(&snapshot) })
|
||||||
.spawn(async move { kind.resolve(&snapshot) })
|
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
Ok((buffer, suggestion))
|
Ok((buffer, suggestion))
|
||||||
|
@ -547,7 +546,7 @@ impl Eq for AssistantPatch {}
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use gpui::{App, AppContext as _};
|
use gpui::App;
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::AllLanguageSettings, Language, LanguageConfig, LanguageMatcher,
|
language_settings::AllLanguageSettings, Language, LanguageConfig, LanguageMatcher,
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@ pub use assistant_slash_command::SlashCommand;
|
||||||
use assistant_slash_command::{AfterCompletion, SlashCommandLine, SlashCommandWorkingSet};
|
use assistant_slash_command::{AfterCompletion, SlashCommandLine, SlashCommandWorkingSet};
|
||||||
use editor::{CompletionProvider, Editor};
|
use editor::{CompletionProvider, Editor};
|
||||||
use fuzzy::{match_strings, StringMatchCandidate};
|
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 language::{Anchor, Buffer, CompletionDocumentation, LanguageServerId, ToPoint};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use project::CompletionIntent;
|
use project::CompletionIntent;
|
||||||
|
@ -162,7 +162,7 @@ impl SlashCommandCompletionProvider {
|
||||||
let editor = self.editor.clone();
|
let editor = self.editor.clone();
|
||||||
let workspace = self.workspace.clone();
|
let workspace = self.workspace.clone();
|
||||||
let arguments = arguments.to_vec();
|
let arguments = arguments.to_vec();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
Ok(completions
|
Ok(completions
|
||||||
.await?
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -102,8 +102,7 @@ impl PickerDelegate for SlashCommandDelegate {
|
||||||
let all_commands = self.all_commands.clone();
|
let all_commands = self.all_commands.clone();
|
||||||
cx.spawn_in(window, |this, mut cx| async move {
|
cx.spawn_in(window, |this, mut cx| async move {
|
||||||
let filtered_commands = cx
|
let filtered_commands = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
if query.is_empty() {
|
if query.is_empty() {
|
||||||
all_commands
|
all_commands
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl SlashCommand for ExtensionSlashCommand {
|
||||||
) -> Task<Result<Vec<ArgumentCompletion>>> {
|
) -> Task<Result<Vec<ArgumentCompletion>>> {
|
||||||
let command = self.command.clone();
|
let command = self.command.clone();
|
||||||
let arguments = arguments.to_owned();
|
let arguments = arguments.to_owned();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let completions = self
|
let completions = self
|
||||||
.extension
|
.extension
|
||||||
.complete_slash_command_argument(command, arguments)
|
.complete_slash_command_argument(command, arguments)
|
||||||
|
@ -135,7 +135,7 @@ impl SlashCommand for ExtensionSlashCommand {
|
||||||
) -> Task<SlashCommandResult> {
|
) -> Task<SlashCommandResult> {
|
||||||
let command = self.command.clone();
|
let command = self.command.clone();
|
||||||
let arguments = arguments.to_owned();
|
let arguments = arguments.to_owned();
|
||||||
let output = cx.background_executor().spawn(async move {
|
let output = cx.background_spawn(async move {
|
||||||
let delegate =
|
let delegate =
|
||||||
delegate.map(|delegate| Arc::new(WorktreeDelegateAdapter(delegate.clone())) as _);
|
delegate.map(|delegate| Arc::new(WorktreeDelegateAdapter(delegate.clone())) as _);
|
||||||
let output = self
|
let output = self
|
||||||
|
|
|
@ -82,7 +82,7 @@ impl SlashCommand for AutoCommand {
|
||||||
project_index.flush_summary_backlogs(cx)
|
project_index.flush_summary_backlogs(cx)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
cx.background_executor().spawn(task).await;
|
cx.background_spawn(task).await;
|
||||||
|
|
||||||
anyhow::Ok(Vec::new())
|
anyhow::Ok(Vec::new())
|
||||||
})
|
})
|
||||||
|
@ -129,7 +129,7 @@ impl SlashCommand for AutoCommand {
|
||||||
// so you don't have to write it again.
|
// so you don't have to write it again.
|
||||||
let original_prompt = argument.to_string();
|
let original_prompt = argument.to_string();
|
||||||
|
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let commands = task.await?;
|
let commands = task.await?;
|
||||||
let mut prompt = String::new();
|
let mut prompt = String::new();
|
||||||
|
|
||||||
|
@ -285,57 +285,56 @@ async fn commands_for_summaries(
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let futures = completion_streams
|
||||||
let futures = completion_streams
|
.into_iter()
|
||||||
.into_iter()
|
.enumerate()
|
||||||
.enumerate()
|
.map(|(ix, (stream, tx))| async move {
|
||||||
.map(|(ix, (stream, tx))| async move {
|
let start = std::time::Instant::now();
|
||||||
let start = std::time::Instant::now();
|
let events = stream.await?;
|
||||||
let events = stream.await?;
|
log::info!("Time taken for awaiting /await chunk stream #{ix}: {:?}", start.elapsed());
|
||||||
log::info!("Time taken for awaiting /await chunk stream #{ix}: {:?}", start.elapsed());
|
|
||||||
|
|
||||||
let completion: String = events
|
let completion: String = events
|
||||||
.filter_map(|event| async {
|
.filter_map(|event| async {
|
||||||
if let Ok(LanguageModelCompletionEvent::Text(text)) = event {
|
if let Ok(LanguageModelCompletionEvent::Text(text)) = event {
|
||||||
Some(text)
|
Some(text)
|
||||||
} else {
|
} else {
|
||||||
None
|
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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.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(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.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();
|
let duration = all_start.elapsed();
|
||||||
eprintln!("All futures completed in {:?}", duration);
|
eprintln!("All futures completed in {:?}", duration);
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
drop(tx); // Close the channel so that rx.collect() won't hang. This is safe because all futures have completed.
|
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 project = workspace.project().clone();
|
||||||
let fs = workspace.project().read(cx).fs().clone();
|
let fs = workspace.project().read(cx).fs().clone();
|
||||||
let path = Self::path_to_cargo_toml(project, cx);
|
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")?;
|
let path = path.with_context(|| "Cargo.toml not found")?;
|
||||||
Self::build_message(fs, &path).await
|
Self::build_message(fs, &path).await
|
||||||
});
|
});
|
||||||
|
|
|
@ -54,7 +54,7 @@ impl SlashCommand for DefaultSlashCommand {
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Task<SlashCommandResult> {
|
) -> Task<SlashCommandResult> {
|
||||||
let store = PromptStore::global(cx);
|
let store = PromptStore::global(cx);
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let store = store.await?;
|
let store = store.await?;
|
||||||
let prompts = store.default_prompt_metadata();
|
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 output = SlashCommandOutput::default();
|
||||||
let mut changes_detected = false;
|
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 paths = self.search_paths(query.clone(), cancellation_flag.clone(), &workspace, cx);
|
||||||
let executor = cx.background_executor().clone();
|
let executor = cx.background_executor().clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let mut matches: Vec<String> = paths
|
let mut matches: Vec<String> = paths
|
||||||
.await
|
.await
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -176,7 +176,7 @@ impl SlashCommand for DocsSlashCommand {
|
||||||
.provider()
|
.provider()
|
||||||
.ok_or_else(|| anyhow!("no docs provider specified"))
|
.ok_or_else(|| anyhow!("no docs provider specified"))
|
||||||
.and_then(|provider| IndexedDocsStore::try_global(provider, cx));
|
.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> {
|
fn build_completions(items: Vec<String>) -> Vec<ArgumentCompletion> {
|
||||||
items
|
items
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -284,7 +284,7 @@ impl SlashCommand for DocsSlashCommand {
|
||||||
|
|
||||||
let args = DocsSlashCommandArgs::parse(arguments);
|
let args = DocsSlashCommandArgs::parse(arguments);
|
||||||
let executor = cx.background_executor().clone();
|
let executor = cx.background_executor().clone();
|
||||||
let task = cx.background_executor().spawn({
|
let task = cx.background_spawn({
|
||||||
let store = args
|
let store = args
|
||||||
.provider()
|
.provider()
|
||||||
.ok_or_else(|| anyhow!("no docs provider specified"))
|
.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 http_client = workspace.read(cx).client().http_client();
|
||||||
let url = argument.to_string();
|
let url = argument.to_string();
|
||||||
|
|
||||||
let text = cx.background_executor().spawn({
|
let text = cx.background_spawn({
|
||||||
let url = url.clone();
|
let url = url.clone();
|
||||||
async move { Self::build_message(http_client, &url).await }
|
async move { Self::build_message(http_client, &url).await }
|
||||||
});
|
});
|
||||||
|
|
|
@ -156,7 +156,7 @@ impl SlashCommand for FileSlashCommand {
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
let comment_id = cx.theme().syntax().highlight_id("comment").map(HighlightId);
|
let comment_id = cx.theme().syntax().highlight_id("comment").map(HighlightId);
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
Ok(paths
|
Ok(paths
|
||||||
.await
|
.await
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -130,49 +130,48 @@ impl SlashCommand for ProjectSlashCommand {
|
||||||
|
|
||||||
let results = SemanticDb::load_results(results, &fs, &cx).await?;
|
let results = SemanticDb::load_results(results, &fs, &cx).await?;
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let mut output = "Project context:\n".to_string();
|
||||||
let mut output = "Project context:\n".to_string();
|
let mut sections = Vec::new();
|
||||||
let mut sections = Vec::new();
|
|
||||||
|
|
||||||
for (ix, query) in search_queries.into_iter().enumerate() {
|
for (ix, query) in search_queries.into_iter().enumerate() {
|
||||||
let start_ix = output.len();
|
let start_ix = output.len();
|
||||||
writeln!(&mut output, "Results for {query}:").unwrap();
|
writeln!(&mut output, "Results for {query}:").unwrap();
|
||||||
let mut has_results = false;
|
let mut has_results = false;
|
||||||
for result in &results {
|
for result in &results {
|
||||||
if result.query_index == ix {
|
if result.query_index == ix {
|
||||||
add_search_result_section(result, &mut output, &mut sections);
|
add_search_result_section(result, &mut output, &mut sections);
|
||||||
has_results = true;
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if has_results {
|
||||||
sections.push(SlashCommandOutputSection {
|
sections.push(SlashCommandOutputSection {
|
||||||
range: 0..output.len(),
|
range: start_ix..output.len(),
|
||||||
icon: IconName::Book,
|
icon: IconName::MagnifyingGlass,
|
||||||
label: "Project context".into(),
|
label: query.into(),
|
||||||
metadata: None,
|
metadata: None,
|
||||||
});
|
});
|
||||||
|
output.push('\n');
|
||||||
Ok(SlashCommandOutput {
|
} else {
|
||||||
text: output,
|
output.truncate(start_ix);
|
||||||
sections,
|
|
||||||
run_commands_in_text: true,
|
|
||||||
}
|
}
|
||||||
.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>>> {
|
) -> Task<Result<Vec<ArgumentCompletion>>> {
|
||||||
let store = PromptStore::global(cx);
|
let store = PromptStore::global(cx);
|
||||||
let query = arguments.to_owned().join(" ");
|
let query = arguments.to_owned().join(" ");
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let prompts = store.await?.search(query).await;
|
let prompts = store.await?.search(query).await;
|
||||||
Ok(prompts
|
Ok(prompts
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -77,7 +77,7 @@ impl SlashCommand for PromptSlashCommand {
|
||||||
|
|
||||||
let store = PromptStore::global(cx);
|
let store = PromptStore::global(cx);
|
||||||
let title = SharedString::from(title.clone());
|
let title = SharedString::from(title.clone());
|
||||||
let prompt = cx.background_executor().spawn({
|
let prompt = cx.background_spawn({
|
||||||
let title = title.clone();
|
let title = title.clone();
|
||||||
async move {
|
async move {
|
||||||
let store = store.await?;
|
let store = store.await?;
|
||||||
|
|
|
@ -119,8 +119,7 @@ impl SlashCommand for SearchSlashCommand {
|
||||||
let loaded_results = SemanticDb::load_results(results, &fs, &cx).await?;
|
let loaded_results = SemanticDb::load_results(results, &fs, &cx).await?;
|
||||||
|
|
||||||
let output = cx
|
let output = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
let mut text = format!("Search results for {query}:\n");
|
let mut text = format!("Search results for {query}:\n");
|
||||||
let mut sections = Vec::new();
|
let mut sections = Vec::new();
|
||||||
for loaded_result in &loaded_results {
|
for loaded_result in &loaded_results {
|
||||||
|
|
|
@ -63,56 +63,55 @@ impl SlashCommand for StreamingExampleSlashCommand {
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Task<SlashCommandResult> {
|
) -> Task<SlashCommandResult> {
|
||||||
let (events_tx, events_rx) = mpsc::unbounded();
|
let (events_tx, events_rx) = mpsc::unbounded();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
|
||||||
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
|
icon: IconName::FileRust,
|
||||||
icon: IconName::FileRust,
|
label: "Section 1".into(),
|
||||||
label: "Section 1".into(),
|
metadata: None,
|
||||||
metadata: None,
|
}))?;
|
||||||
}))?;
|
events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
|
||||||
events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
|
SlashCommandContent::Text {
|
||||||
SlashCommandContent::Text {
|
text: "Hello".into(),
|
||||||
text: "Hello".into(),
|
run_commands_in_text: false,
|
||||||
run_commands_in_text: false,
|
},
|
||||||
},
|
)))?;
|
||||||
)))?;
|
events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
|
||||||
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;
|
Timer::after(Duration::from_secs(1)).await;
|
||||||
|
|
||||||
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
|
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
|
||||||
icon: IconName::FileRust,
|
icon: IconName::StarFilled,
|
||||||
label: "Section 2".into(),
|
label: format!("Section {n}").into(),
|
||||||
metadata: None,
|
metadata: None,
|
||||||
}))?;
|
}))?;
|
||||||
events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
|
events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
|
||||||
SlashCommandContent::Text {
|
SlashCommandContent::Text {
|
||||||
text: "World".into(),
|
text: "lorem ipsum ".repeat(n).trim().into(),
|
||||||
run_commands_in_text: false,
|
run_commands_in_text: false,
|
||||||
},
|
},
|
||||||
)))?;
|
)))?;
|
||||||
events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
|
events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
|
||||||
|
}
|
||||||
|
|
||||||
for n in 1..=10 {
|
anyhow::Ok(())
|
||||||
Timer::after(Duration::from_secs(1)).await;
|
})
|
||||||
|
.detach_and_log_err(cx);
|
||||||
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);
|
|
||||||
|
|
||||||
Task::ready(Ok(events_rx.boxed()))
|
Task::ready(Ok(events_rx.boxed()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use assistant_slash_command::{
|
||||||
SlashCommandResult,
|
SlashCommandResult,
|
||||||
};
|
};
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
use gpui::{Task, WeakEntity};
|
use gpui::{AppContext as _, Task, WeakEntity};
|
||||||
use language::{BufferSnapshot, LspAdapterDelegate};
|
use language::{BufferSnapshot, LspAdapterDelegate};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{path::Path, sync::atomic::AtomicBool};
|
use std::{path::Path, sync::atomic::AtomicBool};
|
||||||
|
@ -69,7 +69,7 @@ impl SlashCommand for OutlineSlashCommand {
|
||||||
let snapshot = buffer.read(cx).snapshot();
|
let snapshot = buffer.read(cx).snapshot();
|
||||||
let path = snapshot.resolve_file_path(cx, true);
|
let path = snapshot.resolve_file_path(cx, true);
|
||||||
|
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let outline = snapshot
|
let outline = snapshot
|
||||||
.outline(None)
|
.outline(None)
|
||||||
.context("no symbols for active tab")?;
|
.context("no symbols for active tab")?;
|
||||||
|
|
|
@ -152,7 +152,7 @@ impl SlashCommand for TabSlashCommand {
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let mut output = SlashCommandOutput::default();
|
let mut output = SlashCommandOutput::default();
|
||||||
for (full_path, buffer, _) in tab_items_search.await? {
|
for (full_path, buffer, _) in tab_items_search.await? {
|
||||||
append_buffer_to_output(&buffer, full_path.as_deref(), &mut output).log_err();
|
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();
|
let background_executor = cx.background_executor().clone();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
open_buffers.sort_by_key(|(_, _, timestamp)| *timestamp);
|
||||||
open_buffers.sort_by_key(|(_, _, timestamp)| *timestamp);
|
if empty_query
|
||||||
if empty_query
|
|| queries
|
||||||
|| queries
|
.iter()
|
||||||
.iter()
|
.any(|query| query == ALL_TABS_COMPLETION_ITEM)
|
||||||
.any(|query| query == ALL_TABS_COMPLETION_ITEM)
|
{
|
||||||
{
|
return Ok(open_buffers);
|
||||||
return Ok(open_buffers);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let matched_items = if strict_match {
|
let matched_items = if strict_match {
|
||||||
let match_candidates = open_buffers
|
let match_candidates = open_buffers
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(id, (full_path, ..))| {
|
.filter_map(|(id, (full_path, ..))| {
|
||||||
let path_string = full_path.as_deref()?.to_string_lossy().to_string();
|
let path_string = full_path.as_deref()?.to_string_lossy().to_string();
|
||||||
Some((id, path_string))
|
Some((id, path_string))
|
||||||
})
|
})
|
||||||
.fold(HashMap::default(), |mut candidates, (id, path_string)| {
|
.fold(HashMap::default(), |mut candidates, (id, path_string)| {
|
||||||
candidates
|
candidates
|
||||||
.entry(path_string)
|
.entry(path_string)
|
||||||
.or_insert_with(Vec::new)
|
.or_insert_with(Vec::new)
|
||||||
.push(id);
|
.push(id);
|
||||||
candidates
|
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(),
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
join_all(file_queries)
|
queries
|
||||||
.await
|
.iter()
|
||||||
.into_iter()
|
.filter_map(|query| match_candidates.get(query))
|
||||||
.flatten()
|
.flatten()
|
||||||
.filter(|string_match| processed_matches.insert(string_match.candidate_id))
|
.copied()
|
||||||
.filter_map(|string_match| open_buffers.get(string_match.candidate_id))
|
.filter_map(|id| open_buffers.get(id))
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
};
|
} else {
|
||||||
Ok(matched_items)
|
let match_candidates = open_buffers
|
||||||
})
|
.iter()
|
||||||
.await
|
.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,
|
should_show: bool,
|
||||||
cx: &App,
|
cx: &App,
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
if should_show {
|
if should_show {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
|
@ -531,7 +531,7 @@ impl AutoUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn should_show_update_notification(&self, cx: &App) -> Task<Result<bool>> {
|
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
|
Ok(KEY_VALUE_STORE
|
||||||
.read_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?
|
.read_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?
|
||||||
.is_some())
|
.is_some())
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use futures::{channel::oneshot, future::OptionFuture};
|
use futures::{channel::oneshot, future::OptionFuture};
|
||||||
use git2::{DiffLineType as GitDiffLineType, DiffOptions as GitOptions, Patch as GitPatch};
|
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 language::{Language, LanguageRegistry};
|
||||||
use rope::Rope;
|
use rope::Rope;
|
||||||
use std::{cmp, future::Future, iter, ops::Range, sync::Arc};
|
use std::{cmp, future::Future, iter, ops::Range, sync::Arc};
|
||||||
|
@ -615,11 +615,9 @@ impl BufferDiff {
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let base_text_snapshot = cx
|
let base_text_snapshot = cx.background_spawn(OptionFuture::from(base_text_snapshot));
|
||||||
.background_executor()
|
|
||||||
.spawn(OptionFuture::from(base_text_snapshot));
|
|
||||||
|
|
||||||
let hunks = cx.background_executor().spawn({
|
let hunks = cx.background_spawn({
|
||||||
let buffer = buffer.clone();
|
let buffer = buffer.clone();
|
||||||
async move { compute_hunks(diff_base, buffer) }
|
async move { compute_hunks(diff_base, buffer) }
|
||||||
});
|
});
|
||||||
|
@ -641,7 +639,7 @@ impl BufferDiff {
|
||||||
.clone()
|
.clone()
|
||||||
.map(|buffer| buffer.as_rope().clone()),
|
.map(|buffer| buffer.as_rope().clone()),
|
||||||
);
|
);
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
BufferDiffInner {
|
BufferDiffInner {
|
||||||
hunks: compute_hunks(diff_base, buffer),
|
hunks: compute_hunks(diff_base, buffer),
|
||||||
base_text: diff_base_buffer,
|
base_text: diff_base_buffer,
|
||||||
|
@ -998,7 +996,7 @@ mod tests {
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use gpui::{AppContext as _, TestAppContext};
|
use gpui::TestAppContext;
|
||||||
use rand::{rngs::StdRng, Rng as _};
|
use rand::{rngs::StdRng, Rng as _};
|
||||||
use text::{Buffer, BufferId, Rope};
|
use text::{Buffer, BufferId, Rope};
|
||||||
use unindent::Unindent as _;
|
use unindent::Unindent as _;
|
||||||
|
|
|
@ -241,7 +241,7 @@ impl ActiveCall {
|
||||||
})
|
})
|
||||||
.shared();
|
.shared();
|
||||||
self.pending_room_creation = Some(room.clone());
|
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))?;
|
room.await.map_err(|err| anyhow!("{:?}", err))?;
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
|
@ -278,7 +278,7 @@ impl ActiveCall {
|
||||||
};
|
};
|
||||||
|
|
||||||
let client = self.client.clone();
|
let client = self.client.clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
client
|
client
|
||||||
.request(proto::CancelCall {
|
.request(proto::CancelCall {
|
||||||
room_id,
|
room_id,
|
||||||
|
|
|
@ -13,7 +13,7 @@ use client::{
|
||||||
use collections::{BTreeMap, HashMap, HashSet};
|
use collections::{BTreeMap, HashMap, HashSet};
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use futures::{FutureExt, StreamExt};
|
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;
|
use language::LanguageRegistry;
|
||||||
#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
|
#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
|
||||||
use livekit::{
|
use livekit::{
|
||||||
|
@ -255,7 +255,7 @@ impl Room {
|
||||||
fn app_will_quit(&mut self, cx: &mut Context<Self>) -> impl Future<Output = ()> {
|
fn app_will_quit(&mut self, cx: &mut Context<Self>) -> impl Future<Output = ()> {
|
||||||
let task = if self.status.is_online() {
|
let task = if self.status.is_online() {
|
||||||
let leave = self.leave_internal(cx);
|
let leave = self.leave_internal(cx);
|
||||||
Some(cx.background_executor().spawn(async move {
|
Some(cx.background_spawn(async move {
|
||||||
leave.await.log_err();
|
leave.await.log_err();
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
|
@ -322,7 +322,7 @@ impl Room {
|
||||||
self.clear_state(cx);
|
self.clear_state(cx);
|
||||||
|
|
||||||
let leave_room = self.client.request(proto::LeaveRoom {});
|
let leave_room = self.client.request(proto::LeaveRoom {});
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
leave_room.await?;
|
leave_room.await?;
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
|
@ -1248,7 +1248,7 @@ impl Room {
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
client
|
client
|
||||||
.request(proto::UpdateParticipantLocation {
|
.request(proto::UpdateParticipantLocation {
|
||||||
room_id,
|
room_id,
|
||||||
|
@ -1373,11 +1373,10 @@ impl Room {
|
||||||
match publication {
|
match publication {
|
||||||
Ok(publication) => {
|
Ok(publication) => {
|
||||||
if canceled {
|
if canceled {
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
participant.unpublish_track(&publication.sid()).await
|
||||||
participant.unpublish_track(&publication.sid()).await
|
})
|
||||||
})
|
.detach_and_log_err(cx)
|
||||||
.detach_and_log_err(cx)
|
|
||||||
} else {
|
} else {
|
||||||
if live_kit.muted_by_user || live_kit.deafened {
|
if live_kit.muted_by_user || live_kit.deafened {
|
||||||
publication.mute();
|
publication.mute();
|
||||||
|
@ -1465,11 +1464,10 @@ impl Room {
|
||||||
match publication {
|
match publication {
|
||||||
Ok(publication) => {
|
Ok(publication) => {
|
||||||
if canceled {
|
if canceled {
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
participant.unpublish_track(&publication.sid()).await
|
||||||
participant.unpublish_track(&publication.sid()).await
|
})
|
||||||
})
|
.detach()
|
||||||
.detach()
|
|
||||||
} else {
|
} else {
|
||||||
live_kit.screen_track = LocalTrack::Published {
|
live_kit.screen_track = LocalTrack::Published {
|
||||||
track_publication: publication,
|
track_publication: publication,
|
||||||
|
@ -1561,9 +1559,10 @@ impl Room {
|
||||||
{
|
{
|
||||||
let local_participant = live_kit.room.local_participant();
|
let local_participant = live_kit.room.local_participant();
|
||||||
let sid = track_publication.sid();
|
let sid = track_publication.sid();
|
||||||
cx.background_executor()
|
cx.background_spawn(
|
||||||
.spawn(async move { local_participant.unpublish_track(&sid).await })
|
async move { local_participant.unpublish_track(&sid).await },
|
||||||
.detach_and_log_err(cx);
|
)
|
||||||
|
.detach_and_log_err(cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1722,13 +1721,12 @@ impl LiveKitRoom {
|
||||||
}
|
}
|
||||||
|
|
||||||
let participant = self.room.local_participant();
|
let participant = self.room.local_participant();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
for sid in tracks_to_unpublish {
|
||||||
for sid in tracks_to_unpublish {
|
participant.unpublish_track(&sid).await.log_err();
|
||||||
participant.unpublish_track(&sid).await.log_err();
|
}
|
||||||
}
|
})
|
||||||
})
|
.detach();
|
||||||
.detach();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,7 @@ impl ActiveCall {
|
||||||
})
|
})
|
||||||
.shared();
|
.shared();
|
||||||
self.pending_room_creation = Some(room.clone());
|
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))?;
|
room.await.map_err(|err| anyhow!("{:?}", err))?;
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
|
@ -271,7 +271,7 @@ impl ActiveCall {
|
||||||
};
|
};
|
||||||
|
|
||||||
let client = self.client.clone();
|
let client = self.client.clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
client
|
client
|
||||||
.request(proto::CancelCall {
|
.request(proto::CancelCall {
|
||||||
room_id,
|
room_id,
|
||||||
|
|
|
@ -311,7 +311,7 @@ impl Room {
|
||||||
fn app_will_quit(&mut self, cx: &mut Context<Self>) -> impl Future<Output = ()> {
|
fn app_will_quit(&mut self, cx: &mut Context<Self>) -> impl Future<Output = ()> {
|
||||||
let task = if self.status.is_online() {
|
let task = if self.status.is_online() {
|
||||||
let leave = self.leave_internal(cx);
|
let leave = self.leave_internal(cx);
|
||||||
Some(cx.background_executor().spawn(async move {
|
Some(cx.background_spawn(async move {
|
||||||
leave.await.log_err();
|
leave.await.log_err();
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
|
@ -378,7 +378,7 @@ impl Room {
|
||||||
self.clear_state(cx);
|
self.clear_state(cx);
|
||||||
|
|
||||||
let leave_room = self.client.request(proto::LeaveRoom {});
|
let leave_room = self.client.request(proto::LeaveRoom {});
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
leave_room.await?;
|
leave_room.await?;
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
|
@ -1268,7 +1268,7 @@ impl Room {
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
client
|
client
|
||||||
.request(proto::UpdateParticipantLocation {
|
.request(proto::UpdateParticipantLocation {
|
||||||
room_id,
|
room_id,
|
||||||
|
@ -1385,9 +1385,7 @@ impl Room {
|
||||||
live_kit.room.unpublish_track(publication);
|
live_kit.room.unpublish_track(publication);
|
||||||
} else {
|
} else {
|
||||||
if live_kit.muted_by_user || live_kit.deafened {
|
if live_kit.muted_by_user || live_kit.deafened {
|
||||||
cx.background_executor()
|
cx.background_spawn(publication.set_mute(true)).detach();
|
||||||
.spawn(publication.set_mute(true))
|
|
||||||
.detach();
|
|
||||||
}
|
}
|
||||||
live_kit.microphone_track = LocalTrack::Published {
|
live_kit.microphone_track = LocalTrack::Published {
|
||||||
track_publication: publication,
|
track_publication: publication,
|
||||||
|
|
|
@ -514,8 +514,7 @@ impl ChannelStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { task.await.map_err(|error| anyhow!("{}", error)) })
|
||||||
.spawn(async move { task.await.map_err(|error| anyhow!("{}", error)) })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_channel_admin(&self, channel_id: ChannelId) -> bool {
|
pub fn is_channel_admin(&self, channel_id: ChannelId) -> bool {
|
||||||
|
@ -781,7 +780,7 @@ impl ChannelStore {
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
let client = self.client.clone();
|
let client = self.client.clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
client
|
client
|
||||||
.request(proto::RespondToChannelInvite {
|
.request(proto::RespondToChannelInvite {
|
||||||
channel_id: channel_id.0,
|
channel_id: channel_id.0,
|
||||||
|
@ -975,21 +974,18 @@ impl ChannelStore {
|
||||||
|
|
||||||
if let Some(operations) = operations {
|
if let Some(operations) = operations {
|
||||||
let client = this.client.clone();
|
let client = this.client.clone();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let operations = operations.await;
|
||||||
let operations = operations.await;
|
for chunk in language::proto::split_operations(operations) {
|
||||||
for chunk in
|
client
|
||||||
language::proto::split_operations(operations)
|
.send(proto::UpdateChannelBuffer {
|
||||||
{
|
channel_id: channel_id.0,
|
||||||
client
|
operations: chunk,
|
||||||
.send(proto::UpdateChannelBuffer {
|
})
|
||||||
channel_id: channel_id.0,
|
.ok();
|
||||||
operations: chunk,
|
}
|
||||||
})
|
})
|
||||||
.ok();
|
.detach();
|
||||||
}
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ use futures::{
|
||||||
channel::oneshot, future::BoxFuture, AsyncReadExt, FutureExt, SinkExt, Stream, StreamExt,
|
channel::oneshot, future::BoxFuture, AsyncReadExt, FutureExt, SinkExt, Stream, StreamExt,
|
||||||
TryFutureExt as _, TryStreamExt,
|
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 http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
|
@ -1064,7 +1064,7 @@ impl Client {
|
||||||
let rpc_url = self.rpc_url(http, release_channel);
|
let rpc_url = self.rpc_url(http, release_channel);
|
||||||
let system_id = self.telemetry.system_id();
|
let system_id = self.telemetry.system_id();
|
||||||
let metrics_id = self.telemetry.metrics_id();
|
let metrics_id = self.telemetry.metrics_id();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
use HttpOrHttps::*;
|
use HttpOrHttps::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -1743,7 +1743,7 @@ mod tests {
|
||||||
use crate::test::FakeServer;
|
use crate::test::FakeServer;
|
||||||
|
|
||||||
use clock::FakeSystemClock;
|
use clock::FakeSystemClock;
|
||||||
use gpui::{AppContext as _, BackgroundExecutor, TestAppContext};
|
use gpui::{BackgroundExecutor, TestAppContext};
|
||||||
use http_client::FakeHttpClient;
|
use http_client::FakeHttpClient;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use proto::TypedEnvelope;
|
use proto::TypedEnvelope;
|
||||||
|
@ -1806,7 +1806,7 @@ mod tests {
|
||||||
|
|
||||||
// Time out when client tries to connect.
|
// Time out when client tries to connect.
|
||||||
client.override_authenticate(move |cx| {
|
client.override_authenticate(move |cx| {
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
Ok(Credentials {
|
Ok(Credentials {
|
||||||
user_id,
|
user_id,
|
||||||
access_token: "token".into(),
|
access_token: "token".into(),
|
||||||
|
@ -1814,7 +1814,7 @@ mod tests {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
client.override_establish_connection(|_, cx| {
|
client.override_establish_connection(|_, cx| {
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
future::pending::<()>().await;
|
future::pending::<()>().await;
|
||||||
unreachable!()
|
unreachable!()
|
||||||
})
|
})
|
||||||
|
@ -1848,7 +1848,7 @@ mod tests {
|
||||||
// Time out when re-establishing the connection.
|
// Time out when re-establishing the connection.
|
||||||
server.allow_connections();
|
server.allow_connections();
|
||||||
client.override_establish_connection(|_, cx| {
|
client.override_establish_connection(|_, cx| {
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
future::pending::<()>().await;
|
future::pending::<()>().await;
|
||||||
unreachable!()
|
unreachable!()
|
||||||
})
|
})
|
||||||
|
@ -1887,7 +1887,7 @@ mod tests {
|
||||||
move |cx| {
|
move |cx| {
|
||||||
let auth_count = auth_count.clone();
|
let auth_count = auth_count.clone();
|
||||||
let dropped_auth_count = dropped_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;
|
*auth_count.lock() += 1;
|
||||||
let _drop = util::defer(move || *dropped_auth_count.lock() += 1);
|
let _drop = util::defer(move || *dropped_auth_count.lock() += 1);
|
||||||
future::pending::<()>().await;
|
future::pending::<()>().await;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use anyhow::Result;
|
||||||
use clock::SystemClock;
|
use clock::SystemClock;
|
||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
use futures::{Future, StreamExt};
|
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 http_client::{self, AsyncBody, HttpClient, HttpClientWithUrl, Method, Request};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use release_channel::ReleaseChannel;
|
use release_channel::ReleaseChannel;
|
||||||
|
@ -219,18 +219,17 @@ impl Telemetry {
|
||||||
}));
|
}));
|
||||||
Self::log_file_path();
|
Self::log_file_path();
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn({
|
||||||
.spawn({
|
let state = state.clone();
|
||||||
let state = state.clone();
|
let os_version = os_version();
|
||||||
let os_version = os_version();
|
state.lock().os_version = Some(os_version.clone());
|
||||||
state.lock().os_version = Some(os_version.clone());
|
async move {
|
||||||
async move {
|
if let Some(tempfile) = File::create(Self::log_file_path()).log_err() {
|
||||||
if let Some(tempfile) = File::create(Self::log_file_path()).log_err() {
|
state.lock().log_file = Some(tempfile);
|
||||||
state.lock().log_file = Some(tempfile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.detach();
|
})
|
||||||
|
.detach();
|
||||||
|
|
||||||
cx.observe_global::<SettingsStore>({
|
cx.observe_global::<SettingsStore>({
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
|
@ -252,17 +251,16 @@ impl Telemetry {
|
||||||
let (tx, mut rx) = mpsc::unbounded();
|
let (tx, mut rx) = mpsc::unbounded();
|
||||||
::telemetry::init(tx);
|
::telemetry::init(tx);
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn({
|
||||||
.spawn({
|
let this = Arc::downgrade(&this);
|
||||||
let this = Arc::downgrade(&this);
|
async move {
|
||||||
async move {
|
while let Some(event) = rx.next().await {
|
||||||
while let Some(event) = rx.next().await {
|
let Some(state) = this.upgrade() else { break };
|
||||||
let Some(state) = this.upgrade() else { break };
|
state.report_event(Event::Flexible(event))
|
||||||
state.report_event(Event::Flexible(event))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.detach();
|
})
|
||||||
|
.detach();
|
||||||
|
|
||||||
// We should only ever have one instance of Telemetry, leak the subscription to keep it alive
|
// 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
|
// 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());
|
Connection::in_memory(cx.background_executor().clone());
|
||||||
let (connection_id, io, incoming) =
|
let (connection_id, io, incoming) =
|
||||||
peer.add_test_connection(server_conn, cx.background_executor().clone());
|
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();
|
let mut state = state.lock();
|
||||||
state.connection_id = Some(connection_id);
|
state.connection_id = Some(connection_id);
|
||||||
|
|
|
@ -244,18 +244,17 @@ impl TestServer {
|
||||||
.await
|
.await
|
||||||
.expect("retrieving user failed")
|
.expect("retrieving user failed")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
cx.background_executor()
|
cx.background_spawn(server.handle_connection(
|
||||||
.spawn(server.handle_connection(
|
server_conn,
|
||||||
server_conn,
|
client_name,
|
||||||
client_name,
|
Principal::User(user),
|
||||||
Principal::User(user),
|
ZedVersion(SemanticVersion::new(1, 0, 0)),
|
||||||
ZedVersion(SemanticVersion::new(1, 0, 0)),
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
Some(connection_id_tx),
|
||||||
Some(connection_id_tx),
|
Executor::Deterministic(cx.background_executor().clone()),
|
||||||
Executor::Deterministic(cx.background_executor().clone()),
|
))
|
||||||
))
|
.detach();
|
||||||
.detach();
|
|
||||||
let connection_id = connection_id_rx.await.map_err(|e| {
|
let connection_id = connection_id_rx.await.map_err(|e| {
|
||||||
EstablishConnectionError::Other(anyhow!(
|
EstablishConnectionError::Other(anyhow!(
|
||||||
"{} (is server shutting down?)",
|
"{} (is server shutting down?)",
|
||||||
|
|
|
@ -201,8 +201,7 @@ impl ChatPanel {
|
||||||
) -> Task<Result<Entity<Self>>> {
|
) -> Task<Result<Entity<Self>>> {
|
||||||
cx.spawn(|mut cx| async move {
|
cx.spawn(|mut cx| async move {
|
||||||
let serialized_panel = if let Some(panel) = cx
|
let serialized_panel = if let Some(panel) = cx
|
||||||
.background_executor()
|
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(CHAT_PANEL_KEY) })
|
||||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(CHAT_PANEL_KEY) })
|
|
||||||
.await
|
.await
|
||||||
.log_err()
|
.log_err()
|
||||||
.flatten()
|
.flatten()
|
||||||
|
@ -227,7 +226,7 @@ impl ChatPanel {
|
||||||
|
|
||||||
fn serialize(&mut self, cx: &mut Context<Self>) {
|
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
self.pending_serialization = cx.background_executor().spawn(
|
self.pending_serialization = cx.background_spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
|
|
|
@ -454,8 +454,7 @@ impl MessageEditor {
|
||||||
mut cx: AsyncWindowContext,
|
mut cx: AsyncWindowContext,
|
||||||
) {
|
) {
|
||||||
let (buffer, ranges) = cx
|
let (buffer, ranges) = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
let ranges = MENTIONS_SEARCH.search(&buffer, None).await;
|
let ranges = MENTIONS_SEARCH.search(&buffer, None).await;
|
||||||
(buffer, ranges)
|
(buffer, ranges)
|
||||||
})
|
})
|
||||||
|
|
|
@ -319,8 +319,7 @@ impl CollabPanel {
|
||||||
mut cx: AsyncWindowContext,
|
mut cx: AsyncWindowContext,
|
||||||
) -> anyhow::Result<Entity<Self>> {
|
) -> anyhow::Result<Entity<Self>> {
|
||||||
let serialized_panel = cx
|
let serialized_panel = cx
|
||||||
.background_executor()
|
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
|
||||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
|
|
||||||
.await
|
.await
|
||||||
.map_err(|_| anyhow::anyhow!("Failed to read collaboration panel from key value store"))
|
.map_err(|_| anyhow::anyhow!("Failed to read collaboration panel from key value store"))
|
||||||
.log_err()
|
.log_err()
|
||||||
|
@ -351,7 +350,7 @@ impl CollabPanel {
|
||||||
fn serialize(&mut self, cx: &mut Context<Self>) {
|
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
let collapsed_channels = self.collapsed_channels.clone();
|
let collapsed_channels = self.collapsed_channels.clone();
|
||||||
self.pending_serialization = cx.background_executor().spawn(
|
self.pending_serialization = cx.background_spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
|
|
|
@ -183,8 +183,7 @@ impl NotificationPanel {
|
||||||
) -> Task<Result<Entity<Self>>> {
|
) -> Task<Result<Entity<Self>>> {
|
||||||
cx.spawn(|mut cx| async move {
|
cx.spawn(|mut cx| async move {
|
||||||
let serialized_panel = if let Some(panel) = cx
|
let serialized_panel = if let Some(panel) = cx
|
||||||
.background_executor()
|
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(NOTIFICATION_PANEL_KEY) })
|
||||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(NOTIFICATION_PANEL_KEY) })
|
|
||||||
.await
|
.await
|
||||||
.log_err()
|
.log_err()
|
||||||
.flatten()
|
.flatten()
|
||||||
|
@ -209,7 +208,7 @@ impl NotificationPanel {
|
||||||
|
|
||||||
fn serialize(&mut self, cx: &mut Context<Self>) {
|
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
self.pending_serialization = cx.background_executor().spawn(
|
self.pending_serialization = cx.background_spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
|
|
|
@ -281,7 +281,7 @@ impl PickerDelegate for CommandPaletteDelegate {
|
||||||
query = alias.to_string();
|
query = alias.to_string();
|
||||||
}
|
}
|
||||||
let (mut tx, mut rx) = postage::dispatch::channel(1);
|
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 mut commands = self.all_commands.clone();
|
||||||
let hit_counts = cx.global::<HitCounts>().clone();
|
let hit_counts = cx.global::<HitCounts>().clone();
|
||||||
let executor = cx.background_executor().clone();
|
let executor = cx.background_executor().clone();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use futures::{channel::oneshot, io::BufWriter, select, AsyncRead, AsyncWrite, FutureExt};
|
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 parking_lot::Mutex;
|
||||||
use postage::barrier;
|
use postage::barrier;
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
@ -192,7 +192,7 @@ impl Client {
|
||||||
let (stdout, stderr) = futures::join!(stdout_input_task, stderr_input_task);
|
let (stdout, stderr) = futures::join!(stdout_input_task, stderr_input_task);
|
||||||
stdout.or(stderr)
|
stdout.or(stderr)
|
||||||
});
|
});
|
||||||
let output_task = cx.background_executor().spawn({
|
let output_task = cx.background_spawn({
|
||||||
Self::handle_output(
|
Self::handle_output(
|
||||||
stdin,
|
stdin,
|
||||||
outbound_rx,
|
outbound_rx,
|
||||||
|
|
|
@ -234,8 +234,7 @@ impl RegisteredBuffer {
|
||||||
let new_snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot()).ok()?;
|
let new_snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot()).ok()?;
|
||||||
|
|
||||||
let content_changes = cx
|
let content_changes = cx
|
||||||
.background_executor()
|
.background_spawn({
|
||||||
.spawn({
|
|
||||||
let new_snapshot = new_snapshot.clone();
|
let new_snapshot = new_snapshot.clone();
|
||||||
async move {
|
async move {
|
||||||
new_snapshot
|
new_snapshot
|
||||||
|
@ -588,8 +587,7 @@ impl Copilot {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(task.map_err(|err| anyhow!("{:?}", err)))
|
||||||
.spawn(task.map_err(|err| anyhow!("{:?}", err)))
|
|
||||||
} else {
|
} else {
|
||||||
// If we're downloading, wait until download is finished
|
// If we're downloading, wait until download is finished
|
||||||
// If we're in a stuck state, display to the user
|
// 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);
|
self.update_sign_in_status(request::SignInStatus::NotSignedIn, cx);
|
||||||
if let CopilotServer::Running(RunningCopilotServer { lsp: server, .. }) = &self.server {
|
if let CopilotServer::Running(RunningCopilotServer { lsp: server, .. }) = &self.server {
|
||||||
let server = server.clone();
|
let server = server.clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
server
|
server
|
||||||
.request::<request::SignOut>(request::SignOutParams {})
|
.request::<request::SignOut>(request::SignOutParams {})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -631,7 +629,7 @@ impl Copilot {
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
|
||||||
cx.background_executor().spawn(start_task)
|
cx.background_spawn(start_task)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn language_server(&self) -> Option<&Arc<LanguageServer>> {
|
pub fn language_server(&self) -> Option<&Arc<LanguageServer>> {
|
||||||
|
@ -813,7 +811,7 @@ impl Copilot {
|
||||||
.request::<request::NotifyAccepted>(request::NotifyAcceptedParams {
|
.request::<request::NotifyAccepted>(request::NotifyAcceptedParams {
|
||||||
uuid: completion.uuid.clone(),
|
uuid: completion.uuid.clone(),
|
||||||
});
|
});
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
request.await?;
|
request.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -837,7 +835,7 @@ impl Copilot {
|
||||||
.map(|completion| completion.uuid.clone())
|
.map(|completion| completion.uuid.clone())
|
||||||
.collect(),
|
.collect(),
|
||||||
});
|
});
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
request.await?;
|
request.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -884,7 +882,7 @@ impl Copilot {
|
||||||
.map(|file| file.path().to_path_buf())
|
.map(|file| file.path().to_path_buf())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let (version, snapshot) = snapshot.await?;
|
let (version, snapshot) = snapshot.await?;
|
||||||
let result = lsp
|
let result = lsp
|
||||||
.request::<R>(request::GetCompletionsParams {
|
.request::<R>(request::GetCompletionsParams {
|
||||||
|
|
|
@ -4,7 +4,7 @@ pub mod query;
|
||||||
// Re-export
|
// Re-export
|
||||||
pub use anyhow;
|
pub use anyhow;
|
||||||
use anyhow::Context as _;
|
use anyhow::Context as _;
|
||||||
use gpui::App;
|
use gpui::{App, AppContext};
|
||||||
pub use indoc::indoc;
|
pub use indoc::indoc;
|
||||||
pub use paths::database_dir;
|
pub use paths::database_dir;
|
||||||
pub use smol;
|
pub use smol;
|
||||||
|
@ -192,8 +192,7 @@ pub fn write_and_log<F>(cx: &App, db_write: impl FnOnce() -> F + Send + 'static)
|
||||||
where
|
where
|
||||||
F: Future<Output = anyhow::Result<()>> + Send,
|
F: Future<Output = anyhow::Result<()>> + Send,
|
||||||
{
|
{
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { db_write().await.log_err() })
|
||||||
.spawn(async move { db_write().await.log_err() })
|
|
||||||
.detach()
|
.detach()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl WrapMap {
|
||||||
|
|
||||||
let text_system = cx.text_system().clone();
|
let text_system = cx.text_system().clone();
|
||||||
let (font, font_size) = self.font_with_size.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 mut line_wrapper = text_system.line_wrapper(font, font_size);
|
||||||
let tab_snapshot = new_snapshot.tab_snapshot.clone();
|
let tab_snapshot = new_snapshot.tab_snapshot.clone();
|
||||||
let range = TabPoint::zero()..tab_snapshot.max_point();
|
let range = TabPoint::zero()..tab_snapshot.max_point();
|
||||||
|
@ -255,7 +255,7 @@ impl WrapMap {
|
||||||
let mut snapshot = self.snapshot.clone();
|
let mut snapshot = self.snapshot.clone();
|
||||||
let text_system = cx.text_system().clone();
|
let text_system = cx.text_system().clone();
|
||||||
let (font, font_size) = self.font_with_size.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 edits = Patch::default();
|
||||||
let mut line_wrapper = text_system.line_wrapper(font, font_size);
|
let mut line_wrapper = text_system.line_wrapper(font, font_size);
|
||||||
for (tab_snapshot, tab_edits) in pending_edits {
|
for (tab_snapshot, tab_edits) in pending_edits {
|
||||||
|
|
|
@ -4798,7 +4798,7 @@ impl Editor {
|
||||||
let Some(matches_task) = editor
|
let Some(matches_task) = editor
|
||||||
.read_with(&mut cx, |editor, cx| {
|
.read_with(&mut cx, |editor, cx| {
|
||||||
let buffer = editor.buffer().read(cx).snapshot(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 mut ranges = Vec::new();
|
||||||
let buffer_ranges =
|
let buffer_ranges =
|
||||||
vec![buffer.anchor_before(0)..buffer.anchor_after(buffer.len())];
|
vec![buffer.anchor_before(0)..buffer.anchor_after(buffer.len())];
|
||||||
|
@ -10221,13 +10221,12 @@ impl Editor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let new_rows =
|
let new_rows =
|
||||||
cx.background_executor()
|
cx.background_spawn({
|
||||||
.spawn({
|
let snapshot = display_snapshot.clone();
|
||||||
let snapshot = display_snapshot.clone();
|
async move {
|
||||||
async move {
|
Self::fetch_runnable_ranges(&snapshot, Anchor::min()..Anchor::max())
|
||||||
Self::fetch_runnable_ranges(&snapshot, Anchor::min()..Anchor::max())
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let rows = Self::runnable_rows(project, display_snapshot, new_rows, cx.clone());
|
let rows = Self::runnable_rows(project, display_snapshot, new_rows, cx.clone());
|
||||||
|
@ -10989,7 +10988,7 @@ impl Editor {
|
||||||
HoverLink::InlayHint(lsp_location, server_id) => {
|
HoverLink::InlayHint(lsp_location, server_id) => {
|
||||||
let computation =
|
let computation =
|
||||||
self.compute_target_location(lsp_location, server_id, window, cx);
|
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?;
|
let location = computation.await?;
|
||||||
Ok(TargetTaskResult::Location(location))
|
Ok(TargetTaskResult::Location(location))
|
||||||
})
|
})
|
||||||
|
@ -15587,7 +15586,7 @@ fn snippet_completions(
|
||||||
let scope = language.map(|language| language.default_scope());
|
let scope = language.map(|language| language.default_scope());
|
||||||
let executor = cx.background_executor().clone();
|
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 classifier = CharClassifier::new(scope).for_completion(true);
|
||||||
let mut last_word = chars
|
let mut last_word = chars
|
||||||
.chars()
|
.chars()
|
||||||
|
@ -15717,7 +15716,7 @@ impl CompletionProvider for Entity<Project> {
|
||||||
self.update(cx, |project, cx| {
|
self.update(cx, |project, cx| {
|
||||||
let snippets = snippet_completions(project, buffer, buffer_position, cx);
|
let snippets = snippet_completions(project, buffer, buffer_position, cx);
|
||||||
let project_completions = project.completions(buffer, buffer_position, options, 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 mut completions = project_completions.await?;
|
||||||
let snippets_completions = snippets.await?;
|
let snippets_completions = snippets.await?;
|
||||||
completions.extend(snippets_completions);
|
completions.extend(snippets_completions);
|
||||||
|
|
|
@ -5264,8 +5264,7 @@ impl EditorElement {
|
||||||
Some(cx.spawn_in(window, |editor, mut cx| async move {
|
Some(cx.spawn_in(window, |editor, mut cx| async move {
|
||||||
let scrollbar_size = scrollbar_layout.hitbox.size;
|
let scrollbar_size = scrollbar_layout.hitbox.size;
|
||||||
let scrollbar_markers = cx
|
let scrollbar_markers = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
let max_point = snapshot.display_snapshot.buffer_snapshot.max_point();
|
let max_point = snapshot.display_snapshot.buffer_snapshot.max_point();
|
||||||
let mut marker_quads = Vec::new();
|
let mut marker_quads = Vec::new();
|
||||||
if scrollbar_settings.git_diff {
|
if scrollbar_settings.git_diff {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use git::{
|
||||||
blame::{Blame, BlameEntry},
|
blame::{Blame, BlameEntry},
|
||||||
parse_git_remote_url, GitHostingProvider, GitHostingProviderRegistry, Oid,
|
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 http_client::HttpClient;
|
||||||
use language::{markdown, Bias, Buffer, BufferSnapshot, Edit, LanguageRegistry, ParsedMarkdown};
|
use language::{markdown, Bias, Buffer, BufferSnapshot, Edit, LanguageRegistry, ParsedMarkdown};
|
||||||
use multi_buffer::RowInfo;
|
use multi_buffer::RowInfo;
|
||||||
|
@ -360,8 +360,7 @@ impl GitBlame {
|
||||||
|
|
||||||
self.task = cx.spawn(|this, mut cx| async move {
|
self.task = cx.spawn(|this, mut cx| async move {
|
||||||
let result = cx
|
let result = cx
|
||||||
.background_executor()
|
.background_spawn({
|
||||||
.spawn({
|
|
||||||
let snapshot = snapshot.clone();
|
let snapshot = snapshot.clone();
|
||||||
async move {
|
async move {
|
||||||
let Some(Blame {
|
let Some(Blame {
|
||||||
|
@ -549,7 +548,7 @@ async fn parse_markdown(text: &str, language_registry: &Arc<LanguageRegistry>) -
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use gpui::{AppContext as _, Context};
|
use gpui::Context;
|
||||||
use language::{Point, Rope};
|
use language::{Point, Rope};
|
||||||
use project::FakeFs;
|
use project::FakeFs;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
use git::diff::DiffHunkStatus;
|
use git::diff::DiffHunkStatus;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, AppContext, Corner, CursorStyle, Focusable as _, Hsla, Model, MouseButton,
|
Action, AppContext as _, Corner, CursorStyle, Focusable as _, Hsla, Model, MouseButton,
|
||||||
Subscription, Task,
|
Subscription, Task,
|
||||||
};
|
};
|
||||||
use language::{Buffer, BufferId, Point};
|
use language::{Buffer, BufferId, Point};
|
||||||
|
@ -372,7 +372,7 @@ impl Editor {
|
||||||
|
|
||||||
self.diff_map
|
self.diff_map
|
||||||
.hunk_update_tasks
|
.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(
|
pub(super) fn expand_diff_hunk(
|
||||||
|
@ -1089,10 +1089,9 @@ impl Editor {
|
||||||
.ok();
|
.ok();
|
||||||
});
|
});
|
||||||
|
|
||||||
diff_map.hunk_update_tasks.insert(
|
diff_map
|
||||||
Some(buffer_id),
|
.hunk_update_tasks
|
||||||
cx.background_executor().spawn(new_sync_task),
|
.insert(Some(buffer_id), cx.background_spawn(new_sync_task));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn go_to_subsequent_hunk(
|
fn go_to_subsequent_hunk(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{ops::Range, time::Duration};
|
use std::{ops::Range, time::Duration};
|
||||||
|
|
||||||
use collections::HashSet;
|
use collections::HashSet;
|
||||||
use gpui::{App, Context, Task, Window};
|
use gpui::{App, AppContext as _, Context, Task, Window};
|
||||||
use language::language_settings::language_settings;
|
use language::language_settings::language_settings;
|
||||||
use multi_buffer::{IndentGuide, MultiBufferRow};
|
use multi_buffer::{IndentGuide, MultiBufferRow};
|
||||||
use text::{LineIndent, Point};
|
use text::{LineIndent, Point};
|
||||||
|
@ -102,9 +102,7 @@ impl Editor {
|
||||||
|
|
||||||
let snapshot = snapshot.clone();
|
let snapshot = snapshot.clone();
|
||||||
|
|
||||||
let task = cx
|
let task = cx.background_spawn(resolve_indented_range(snapshot, cursor_row));
|
||||||
.background_executor()
|
|
||||||
.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.
|
// Try to resolve the indent in a short amount of time, otherwise move it to a background task.
|
||||||
match cx
|
match cx
|
||||||
|
@ -115,7 +113,7 @@ impl Editor {
|
||||||
Err(future) => {
|
Err(future) => {
|
||||||
state.pending_refresh =
|
state.pending_refresh =
|
||||||
Some(cx.spawn_in(window, |editor, mut cx| async move {
|
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
|
editor
|
||||||
.update(&mut cx, |editor, _| {
|
.update(&mut cx, |editor, _| {
|
||||||
editor.active_indent_guides_state.active_indent_range = result;
|
editor.active_indent_guides_state.active_indent_range = result;
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::{
|
||||||
use anyhow::Context as _;
|
use anyhow::Context as _;
|
||||||
use clock::Global;
|
use clock::Global;
|
||||||
use futures::future;
|
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 language::{language_settings::InlayHintKind, Buffer, BufferSnapshot};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use project::{InlayHint, ResolveState};
|
use project::{InlayHint, ResolveState};
|
||||||
|
@ -996,19 +996,17 @@ fn fetch_and_update_hints(
|
||||||
|
|
||||||
let background_task_buffer_snapshot = buffer_snapshot.clone();
|
let background_task_buffer_snapshot = buffer_snapshot.clone();
|
||||||
let background_fetch_range = fetch_range.clone();
|
let background_fetch_range = fetch_range.clone();
|
||||||
let new_update = cx
|
let new_update = cx.background_spawn(async move {
|
||||||
.background_executor()
|
calculate_hint_updates(
|
||||||
.spawn(async move {
|
query.excerpt_id,
|
||||||
calculate_hint_updates(
|
invalidate,
|
||||||
query.excerpt_id,
|
background_fetch_range,
|
||||||
invalidate,
|
new_hints,
|
||||||
background_fetch_range,
|
&background_task_buffer_snapshot,
|
||||||
new_hints,
|
cached_excerpt_hints,
|
||||||
&background_task_buffer_snapshot,
|
&visible_hints,
|
||||||
cached_excerpt_hints,
|
)
|
||||||
&visible_hints,
|
})
|
||||||
)
|
|
||||||
})
|
|
||||||
.await;
|
.await;
|
||||||
if let Some(new_update) = new_update {
|
if let Some(new_update) = new_update {
|
||||||
log::debug!(
|
log::debug!(
|
||||||
|
|
|
@ -1225,28 +1225,27 @@ impl SerializableItem for Editor {
|
||||||
let snapshot = buffer.read(cx).snapshot();
|
let snapshot = buffer.read(cx).snapshot();
|
||||||
|
|
||||||
Some(cx.spawn_in(window, |_this, cx| async move {
|
Some(cx.spawn_in(window, |_this, cx| async move {
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let (contents, language) = if serialize_dirty_buffers && is_dirty {
|
||||||
let (contents, language) = if serialize_dirty_buffers && is_dirty {
|
let contents = snapshot.text();
|
||||||
let contents = snapshot.text();
|
let language = snapshot.language().map(|lang| lang.name().to_string());
|
||||||
let language = snapshot.language().map(|lang| lang.name().to_string());
|
(Some(contents), language)
|
||||||
(Some(contents), language)
|
} else {
|
||||||
} else {
|
(None, None)
|
||||||
(None, None)
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let editor = SerializedEditor {
|
let editor = SerializedEditor {
|
||||||
abs_path,
|
abs_path,
|
||||||
contents,
|
contents,
|
||||||
language,
|
language,
|
||||||
mtime,
|
mtime,
|
||||||
};
|
};
|
||||||
DB.save_serialized_editor(item_id, workspace_id, editor)
|
DB.save_serialized_editor(item_id, workspace_id, editor)
|
||||||
.await
|
.await
|
||||||
.context("failed to save serialized editor")
|
.context("failed to save serialized editor")
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.context("failed to save contents of buffer")?;
|
.context("failed to save contents of buffer")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}))
|
}))
|
||||||
|
@ -1540,7 +1539,7 @@ impl SearchableItem for Editor {
|
||||||
ranges.iter().cloned().collect::<Vec<_>>()
|
ranges.iter().cloned().collect::<Vec<_>>()
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let mut ranges = Vec::new();
|
let mut ranges = Vec::new();
|
||||||
|
|
||||||
let search_within_ranges = if search_within_ranges.is_empty() {
|
let search_within_ranges = if search_within_ranges.is_empty() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::Editor;
|
use crate::Editor;
|
||||||
|
|
||||||
use gpui::{App, Task as AsyncTask, Window};
|
use gpui::{App, AppContext as _, Task as AsyncTask, Window};
|
||||||
use project::Location;
|
use project::Location;
|
||||||
use task::{TaskContext, TaskVariables, VariableName};
|
use task::{TaskContext, TaskVariables, VariableName};
|
||||||
use text::{ToOffset, ToPoint};
|
use text::{ToOffset, ToPoint};
|
||||||
|
@ -88,7 +88,6 @@ pub fn task_context(
|
||||||
};
|
};
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
let context_task = task_context_with_editor(editor, window, cx);
|
let context_task = task_context_with_editor(editor, window, cx);
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { context_task.await.unwrap_or_default() })
|
||||||
.spawn(async move { context_task.await.unwrap_or_default() })
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,10 +324,7 @@ impl ExtensionStore {
|
||||||
load_initial_extensions.await;
|
load_initial_extensions.await;
|
||||||
|
|
||||||
let mut index_changed = false;
|
let mut index_changed = false;
|
||||||
let mut debounce_timer = cx
|
let mut debounce_timer = cx.background_spawn(futures::future::pending()).fuse();
|
||||||
.background_executor()
|
|
||||||
.spawn(futures::future::pending())
|
|
||||||
.fuse();
|
|
||||||
loop {
|
loop {
|
||||||
select_biased! {
|
select_biased! {
|
||||||
_ = debounce_timer => {
|
_ = debounce_timer => {
|
||||||
|
@ -370,7 +367,7 @@ impl ExtensionStore {
|
||||||
// Watch the installed extensions directory for changes. Whenever changes are
|
// Watch the installed extensions directory for changes. Whenever changes are
|
||||||
// detected, rebuild the extension index, and load/unload any extensions that
|
// detected, rebuild the extension index, and load/unload any extensions that
|
||||||
// have been added, removed, or modified.
|
// 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 fs = this.fs.clone();
|
||||||
let reload_tx = this.reload_tx.clone();
|
let reload_tx = this.reload_tx.clone();
|
||||||
let installed_dir = this.installed_dir.clone();
|
let installed_dir = this.installed_dir.clone();
|
||||||
|
@ -886,20 +883,19 @@ impl ExtensionStore {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn({
|
||||||
.spawn({
|
let extension_source_path = extension_source_path.clone();
|
||||||
let extension_source_path = extension_source_path.clone();
|
async move {
|
||||||
async move {
|
builder
|
||||||
builder
|
.compile_extension(
|
||||||
.compile_extension(
|
&extension_source_path,
|
||||||
&extension_source_path,
|
&mut extension_manifest,
|
||||||
&mut extension_manifest,
|
CompileExtensionOptions { release: false },
|
||||||
CompileExtensionOptions { release: false },
|
)
|
||||||
)
|
.await
|
||||||
.await
|
}
|
||||||
}
|
})
|
||||||
})
|
.await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
let output_path = &extensions_dir.join(extension_id.as_ref());
|
let output_path = &extensions_dir.join(extension_id.as_ref());
|
||||||
if let Some(metadata) = fs.metadata(output_path).await? {
|
if let Some(metadata) = fs.metadata(output_path).await? {
|
||||||
|
@ -937,7 +933,7 @@ impl ExtensionStore {
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.notify();
|
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?;
|
let mut manifest = ExtensionManifest::load(fs, &path).await?;
|
||||||
builder
|
builder
|
||||||
.compile_extension(
|
.compile_extension(
|
||||||
|
@ -1192,35 +1188,33 @@ impl ExtensionStore {
|
||||||
cx.emit(Event::ExtensionsUpdated);
|
cx.emit(Event::ExtensionsUpdated);
|
||||||
|
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
cx.background_executor()
|
cx.background_spawn({
|
||||||
.spawn({
|
let fs = fs.clone();
|
||||||
let fs = fs.clone();
|
async move {
|
||||||
async move {
|
for theme_path in themes_to_add.into_iter() {
|
||||||
for theme_path in themes_to_add.into_iter() {
|
proxy
|
||||||
proxy
|
.load_user_theme(theme_path, fs.clone())
|
||||||
.load_user_theme(theme_path, fs.clone())
|
.await
|
||||||
.await
|
.log_err();
|
||||||
.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
|
proxy
|
||||||
.load_icon_theme(icon_theme_path, icons_root_path, fs.clone())
|
.load_icon_theme(icon_theme_path, icons_root_path, fs.clone())
|
||||||
.await
|
.await
|
||||||
.log_err();
|
.log_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
for snippets_path in &snippets_to_add {
|
for snippets_path in &snippets_to_add {
|
||||||
if let Some(snippets_contents) = fs.load(snippets_path).await.log_err()
|
if let Some(snippets_contents) = fs.load(snippets_path).await.log_err() {
|
||||||
{
|
proxy
|
||||||
proxy
|
.register_snippet(snippets_path, &snippets_contents)
|
||||||
.register_snippet(snippets_path, &snippets_contents)
|
.log_err();
|
||||||
.log_err();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.await;
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
let mut wasm_extensions = Vec::new();
|
let mut wasm_extensions = Vec::new();
|
||||||
for extension in extension_entries {
|
for extension in extension_entries {
|
||||||
|
@ -1304,7 +1298,7 @@ impl ExtensionStore {
|
||||||
let extensions_dir = self.installed_dir.clone();
|
let extensions_dir = self.installed_dir.clone();
|
||||||
let index_path = self.index_path.clone();
|
let index_path = self.index_path.clone();
|
||||||
let proxy = self.proxy.clone();
|
let proxy = self.proxy.clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
let mut index = ExtensionIndex::default();
|
let mut index = ExtensionIndex::default();
|
||||||
|
|
||||||
|
@ -1494,7 +1488,7 @@ impl ExtensionStore {
|
||||||
return Task::ready(Err(anyhow!("extension no longer installed")));
|
return Task::ready(Err(anyhow!("extension no longer installed")));
|
||||||
};
|
};
|
||||||
let fs = self.fs.clone();
|
let fs = self.fs.clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
const EXTENSION_TOML: &str = "extension.toml";
|
const EXTENSION_TOML: &str = "extension.toml";
|
||||||
const EXTENSION_WASM: &str = "extension.wasm";
|
const EXTENSION_WASM: &str = "extension.wasm";
|
||||||
const CONFIG_TOML: &str = "config.toml";
|
const CONFIG_TOML: &str = "config.toml";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use client::telemetry;
|
use client::telemetry;
|
||||||
use gpui::{App, Task, Window};
|
use gpui::{App, AppContext as _, Task, Window};
|
||||||
use human_bytes::human_bytes;
|
use human_bytes::human_bytes;
|
||||||
use release_channel::{AppCommitSha, AppVersion, ReleaseChannel};
|
use release_channel::{AppCommitSha, AppVersion, ReleaseChannel};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
@ -44,7 +44,7 @@ impl SystemSpecs {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let os_version = telemetry::os_version();
|
let os_version = telemetry::os_version();
|
||||||
SystemSpecs {
|
SystemSpecs {
|
||||||
app_version,
|
app_version,
|
||||||
|
|
|
@ -127,7 +127,7 @@ impl FileFinder {
|
||||||
let abs_path = abs_path?;
|
let abs_path = abs_path?;
|
||||||
if project.is_local() {
|
if project.is_local() {
|
||||||
let fs = fs.clone();
|
let fs = fs.clone();
|
||||||
Some(cx.background_executor().spawn(async move {
|
Some(cx.background_spawn(async move {
|
||||||
if fs.is_file(&abs_path).await {
|
if fs.is_file(&abs_path).await {
|
||||||
Some(FoundPath::new(project_path, Some(abs_path)))
|
Some(FoundPath::new(project_path, Some(abs_path)))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -337,7 +337,7 @@ impl GitPanel {
|
||||||
|
|
||||||
fn serialize(&mut self, cx: &mut Context<Self>) {
|
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
self.pending_serialization = cx.background_executor().spawn(
|
self.pending_serialization = cx.background_spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
|
@ -1055,8 +1055,7 @@ impl GitPanel {
|
||||||
let task = if self.has_staged_changes() {
|
let task = if self.has_staged_changes() {
|
||||||
// Repository serializes all git operations, so we can just send a commit immediately
|
// Repository serializes all git operations, so we can just send a commit immediately
|
||||||
let commit_task = active_repository.read(cx).commit(message.into(), None);
|
let commit_task = active_repository.read(cx).commit(message.into(), None);
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { commit_task.await? })
|
||||||
.spawn(async move { commit_task.await? })
|
|
||||||
} else {
|
} else {
|
||||||
let changed_files = self
|
let changed_files = self
|
||||||
.entries
|
.entries
|
||||||
|
|
|
@ -7,7 +7,7 @@ use editor::{scroll::Autoscroll, Editor, EditorEvent, ToPoint};
|
||||||
use feature_flags::FeatureFlagViewExt;
|
use feature_flags::FeatureFlagViewExt;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use gpui::{
|
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,
|
FocusHandle, Focusable, Render, Subscription, Task, WeakEntity,
|
||||||
};
|
};
|
||||||
use language::{Anchor, Buffer, Capability, OffsetRangeExt, Point};
|
use language::{Anchor, Buffer, Capability, OffsetRangeExt, Point};
|
||||||
|
|
|
@ -177,8 +177,7 @@ impl PickerDelegate for RepositorySelectorDelegate {
|
||||||
|
|
||||||
cx.spawn_in(window, |this, mut cx| async move {
|
cx.spawn_in(window, |this, mut cx| async move {
|
||||||
let filtered_repositories = cx
|
let filtered_repositories = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
if query.is_empty() {
|
if query.is_empty() {
|
||||||
all_repositories
|
all_repositories
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -252,7 +252,7 @@ impl SerializableItem for ImageView {
|
||||||
let workspace_id = workspace.database_id()?;
|
let workspace_id = workspace.database_id()?;
|
||||||
let image_path = self.image_item.read(cx).file.as_local()?.abs_path(cx);
|
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 {
|
async move {
|
||||||
IMAGE_VIEWER
|
IMAGE_VIEWER
|
||||||
.save_image_path(item_id, workspace_id, image_path)
|
.save_image_path(item_id, workspace_id, image_path)
|
||||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::Result;
|
||||||
use chrono::{Datelike, Local, NaiveTime, Timelike};
|
use chrono::{Datelike, Local, NaiveTime, Timelike};
|
||||||
use editor::scroll::Autoscroll;
|
use editor::scroll::Autoscroll;
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
use gpui::{actions, App, Context, Window};
|
use gpui::{actions, App, AppContext as _, Context, Window};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::{Settings, SettingsSources};
|
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 now = now.time();
|
||||||
let entry_heading = heading_entry(now, &settings.hour_format);
|
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)?;
|
std::fs::create_dir_all(month_dir)?;
|
||||||
OpenOptions::new()
|
OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
|
|
|
@ -940,7 +940,7 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
let text_operations = self.text.operations().clone();
|
let text_operations = self.text.operations().clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let since = since.unwrap_or_default();
|
let since = since.unwrap_or_default();
|
||||||
operations.extend(
|
operations.extend(
|
||||||
text_operations
|
text_operations
|
||||||
|
@ -1135,7 +1135,7 @@ impl Buffer {
|
||||||
let old_snapshot = self.text.snapshot();
|
let old_snapshot = self.text.snapshot();
|
||||||
let mut branch_buffer = self.text.branch();
|
let mut branch_buffer = self.text.branch();
|
||||||
let mut syntax_snapshot = self.syntax_map.lock().snapshot();
|
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 !edits.is_empty() {
|
||||||
if let Some(language) = language.clone() {
|
if let Some(language) = language.clone() {
|
||||||
syntax_snapshot.reparse(&old_snapshot, registry.clone(), language);
|
syntax_snapshot.reparse(&old_snapshot, registry.clone(), language);
|
||||||
|
@ -1499,7 +1499,7 @@ impl Buffer {
|
||||||
let mut syntax_snapshot = syntax_map.snapshot();
|
let mut syntax_snapshot = syntax_map.snapshot();
|
||||||
drop(syntax_map);
|
drop(syntax_map);
|
||||||
|
|
||||||
let parse_task = cx.background_executor().spawn({
|
let parse_task = cx.background_spawn({
|
||||||
let language = language.clone();
|
let language = language.clone();
|
||||||
let language_registry = language_registry.clone();
|
let language_registry = language_registry.clone();
|
||||||
async move {
|
async move {
|
||||||
|
@ -1578,7 +1578,7 @@ impl Buffer {
|
||||||
|
|
||||||
fn request_autoindent(&mut self, cx: &mut Context<Self>) {
|
fn request_autoindent(&mut self, cx: &mut Context<Self>) {
|
||||||
if let Some(indent_sizes) = self.compute_autoindents() {
|
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
|
match cx
|
||||||
.background_executor()
|
.background_executor()
|
||||||
.block_with_timeout(Duration::from_micros(500), indent_sizes)
|
.block_with_timeout(Duration::from_micros(500), indent_sizes)
|
||||||
|
@ -1907,7 +1907,7 @@ impl Buffer {
|
||||||
let old_text = self.as_rope().clone();
|
let old_text = self.as_rope().clone();
|
||||||
let line_ending = self.line_ending();
|
let line_ending = self.line_ending();
|
||||||
let base_version = self.version();
|
let base_version = self.version();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let ranges = trailing_whitespace_ranges(&old_text);
|
let ranges = trailing_whitespace_ranges(&old_text);
|
||||||
let empty = Arc::<str>::from("");
|
let empty = Arc::<str>::from("");
|
||||||
Diff {
|
Diff {
|
||||||
|
|
|
@ -940,6 +940,8 @@ impl LanguageRegistry {
|
||||||
binary: lsp::LanguageServerBinary,
|
binary: lsp::LanguageServerBinary,
|
||||||
cx: gpui::AsyncApp,
|
cx: gpui::AsyncApp,
|
||||||
) -> Option<lsp::LanguageServer> {
|
) -> Option<lsp::LanguageServer> {
|
||||||
|
use gpui::AppContext as _;
|
||||||
|
|
||||||
let mut state = self.state.write();
|
let mut state = self.state.write();
|
||||||
let fake_entry = state.fake_server_entries.get_mut(&name)?;
|
let fake_entry = state.fake_server_entries.get_mut(&name)?;
|
||||||
let (server, mut fake_server) = lsp::FakeLanguageServer::new(
|
let (server, mut fake_server) = lsp::FakeLanguageServer::new(
|
||||||
|
@ -956,17 +958,16 @@ impl LanguageRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
let tx = fake_entry.tx.clone();
|
let tx = fake_entry.tx.clone();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
if fake_server
|
||||||
if fake_server
|
.try_receive_notification::<lsp::notification::Initialized>()
|
||||||
.try_receive_notification::<lsp::notification::Initialized>()
|
.await
|
||||||
.await
|
.is_some()
|
||||||
.is_some()
|
{
|
||||||
{
|
tx.unbounded_send(fake_server.clone()).ok();
|
||||||
tx.unbounded_send(fake_server.clone()).ok();
|
}
|
||||||
}
|
})
|
||||||
})
|
.detach();
|
||||||
.detach();
|
|
||||||
|
|
||||||
Some(server)
|
Some(server)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@ use std::io::{Cursor, Write};
|
||||||
use crate::role::Role;
|
use crate::role::Role;
|
||||||
use crate::LanguageModelToolUse;
|
use crate::LanguageModelToolUse;
|
||||||
use base64::write::EncoderWriter;
|
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 image::{codecs::png::PngEncoder, imageops::resize, DynamicImage, ImageDecoder};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ui::{px, SharedString};
|
use ui::{px, SharedString};
|
||||||
|
@ -30,7 +32,7 @@ const ANTHROPIC_SIZE_LIMT: f32 = 1568.;
|
||||||
|
|
||||||
impl LanguageModelImage {
|
impl LanguageModelImage {
|
||||||
pub fn from_image(data: Image, cx: &mut App) -> Task<Option<Self>> {
|
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() {
|
match data.format() {
|
||||||
gpui::ImageFormat::Png
|
gpui::ImageFormat::Png
|
||||||
| gpui::ImageFormat::Jpeg
|
| gpui::ImageFormat::Jpeg
|
||||||
|
|
|
@ -228,8 +228,7 @@ impl PickerDelegate for LanguageModelPickerDelegate {
|
||||||
|
|
||||||
cx.spawn_in(window, |this, mut cx| async move {
|
cx.spawn_in(window, |this, mut cx| async move {
|
||||||
let filtered_models = cx
|
let filtered_models = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
let displayed_models = if configured_providers.is_empty() {
|
let displayed_models = if configured_providers.is_empty() {
|
||||||
all_models
|
all_models
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -252,54 +252,53 @@ pub fn count_anthropic_tokens(
|
||||||
request: LanguageModelRequest,
|
request: LanguageModelRequest,
|
||||||
cx: &App,
|
cx: &App,
|
||||||
) -> BoxFuture<'static, Result<usize>> {
|
) -> BoxFuture<'static, Result<usize>> {
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let messages = request.messages;
|
||||||
let messages = request.messages;
|
let mut tokens_from_images = 0;
|
||||||
let mut tokens_from_images = 0;
|
let mut string_messages = Vec::with_capacity(messages.len());
|
||||||
let mut string_messages = Vec::with_capacity(messages.len());
|
|
||||||
|
|
||||||
for message in messages {
|
for message in messages {
|
||||||
use language_model::MessageContent;
|
use language_model::MessageContent;
|
||||||
|
|
||||||
let mut string_contents = String::new();
|
let mut string_contents = String::new();
|
||||||
|
|
||||||
for content in message.content {
|
for content in message.content {
|
||||||
match content {
|
match content {
|
||||||
MessageContent::Text(text) => {
|
MessageContent::Text(text) => {
|
||||||
string_contents.push_str(&text);
|
string_contents.push_str(&text);
|
||||||
}
|
}
|
||||||
MessageContent::Image(image) => {
|
MessageContent::Image(image) => {
|
||||||
tokens_from_images += image.estimate_tokens();
|
tokens_from_images += image.estimate_tokens();
|
||||||
}
|
}
|
||||||
MessageContent::ToolUse(_tool_use) => {
|
MessageContent::ToolUse(_tool_use) => {
|
||||||
// TODO: Estimate token usage from tool uses.
|
// TODO: Estimate token usage from tool uses.
|
||||||
}
|
}
|
||||||
MessageContent::ToolResult(tool_result) => {
|
MessageContent::ToolResult(tool_result) => {
|
||||||
string_contents.push_str(&tool_result.content);
|
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,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tiktoken doesn't yet support these models, so we manually use the
|
if !string_contents.is_empty() {
|
||||||
// same tokenizer as GPT-4.
|
string_messages.push(tiktoken_rs::ChatCompletionRequestMessage {
|
||||||
tiktoken_rs::num_tokens_from_messages("gpt-4", &string_messages)
|
role: match message.role {
|
||||||
.map(|tokens| tokens + tokens_from_images)
|
Role::User => "user".into(),
|
||||||
})
|
Role::Assistant => "assistant".into(),
|
||||||
.boxed()
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnthropicModel {
|
impl AnthropicModel {
|
||||||
|
|
|
@ -3,7 +3,8 @@ use collections::BTreeMap;
|
||||||
use editor::{Editor, EditorElement, EditorStyle};
|
use editor::{Editor, EditorElement, EditorStyle};
|
||||||
use futures::{future::BoxFuture, stream::BoxStream, FutureExt, StreamExt};
|
use futures::{future::BoxFuture, stream::BoxStream, FutureExt, StreamExt};
|
||||||
use gpui::{
|
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 http_client::HttpClient;
|
||||||
use language_model::{
|
use language_model::{
|
||||||
|
@ -269,26 +270,25 @@ impl LanguageModel for DeepSeekLanguageModel {
|
||||||
request: LanguageModelRequest,
|
request: LanguageModelRequest,
|
||||||
cx: &App,
|
cx: &App,
|
||||||
) -> BoxFuture<'static, Result<usize>> {
|
) -> BoxFuture<'static, Result<usize>> {
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let messages = request
|
||||||
let messages = request
|
.messages
|
||||||
.messages
|
.into_iter()
|
||||||
.into_iter()
|
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
|
||||||
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
|
role: match message.role {
|
||||||
role: match message.role {
|
Role::User => "user".into(),
|
||||||
Role::User => "user".into(),
|
Role::Assistant => "assistant".into(),
|
||||||
Role::Assistant => "assistant".into(),
|
Role::System => "system".into(),
|
||||||
Role::System => "system".into(),
|
},
|
||||||
},
|
content: Some(message.string_contents()),
|
||||||
content: Some(message.string_contents()),
|
name: None,
|
||||||
name: None,
|
function_call: None,
|
||||||
function_call: None,
|
})
|
||||||
})
|
.collect::<Vec<_>>();
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
|
tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
|
||||||
})
|
})
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stream_completion(
|
fn stream_completion(
|
||||||
|
|
|
@ -330,28 +330,27 @@ pub fn count_google_tokens(
|
||||||
) -> BoxFuture<'static, Result<usize>> {
|
) -> 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.
|
// 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.
|
// So we have to use tokenizer from tiktoken_rs to count tokens.
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let messages = request
|
||||||
let messages = request
|
.messages
|
||||||
.messages
|
.into_iter()
|
||||||
.into_iter()
|
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
|
||||||
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
|
role: match message.role {
|
||||||
role: match message.role {
|
Role::User => "user".into(),
|
||||||
Role::User => "user".into(),
|
Role::Assistant => "assistant".into(),
|
||||||
Role::Assistant => "assistant".into(),
|
Role::System => "system".into(),
|
||||||
Role::System => "system".into(),
|
},
|
||||||
},
|
content: Some(message.string_contents()),
|
||||||
content: Some(message.string_contents()),
|
name: None,
|
||||||
name: None,
|
function_call: None,
|
||||||
function_call: None,
|
})
|
||||||
})
|
.collect::<Vec<_>>();
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Tiktoken doesn't yet support these models, so we manually use the
|
// Tiktoken doesn't yet support these models, so we manually use the
|
||||||
// same tokenizer as GPT-4.
|
// same tokenizer as GPT-4.
|
||||||
tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
|
tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
|
||||||
})
|
})
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConfigurationView {
|
struct ConfigurationView {
|
||||||
|
|
|
@ -281,26 +281,25 @@ impl LanguageModel for MistralLanguageModel {
|
||||||
request: LanguageModelRequest,
|
request: LanguageModelRequest,
|
||||||
cx: &App,
|
cx: &App,
|
||||||
) -> BoxFuture<'static, Result<usize>> {
|
) -> BoxFuture<'static, Result<usize>> {
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let messages = request
|
||||||
let messages = request
|
.messages
|
||||||
.messages
|
.into_iter()
|
||||||
.into_iter()
|
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
|
||||||
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
|
role: match message.role {
|
||||||
role: match message.role {
|
Role::User => "user".into(),
|
||||||
Role::User => "user".into(),
|
Role::Assistant => "assistant".into(),
|
||||||
Role::Assistant => "assistant".into(),
|
Role::System => "system".into(),
|
||||||
Role::System => "system".into(),
|
},
|
||||||
},
|
content: Some(message.string_contents()),
|
||||||
content: Some(message.string_contents()),
|
name: None,
|
||||||
name: None,
|
function_call: None,
|
||||||
function_call: None,
|
})
|
||||||
})
|
.collect::<Vec<_>>();
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
|
tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
|
||||||
})
|
})
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stream_completion(
|
fn stream_completion(
|
||||||
|
|
|
@ -343,34 +343,31 @@ pub fn count_open_ai_tokens(
|
||||||
model: open_ai::Model,
|
model: open_ai::Model,
|
||||||
cx: &App,
|
cx: &App,
|
||||||
) -> BoxFuture<'static, Result<usize>> {
|
) -> BoxFuture<'static, Result<usize>> {
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let messages = request
|
||||||
let messages = request
|
.messages
|
||||||
.messages
|
.into_iter()
|
||||||
.into_iter()
|
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
|
||||||
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
|
role: match message.role {
|
||||||
role: match message.role {
|
Role::User => "user".into(),
|
||||||
Role::User => "user".into(),
|
Role::Assistant => "assistant".into(),
|
||||||
Role::Assistant => "assistant".into(),
|
Role::System => "system".into(),
|
||||||
Role::System => "system".into(),
|
},
|
||||||
},
|
content: Some(message.string_contents()),
|
||||||
content: Some(message.string_contents()),
|
name: None,
|
||||||
name: None,
|
function_call: None,
|
||||||
function_call: None,
|
})
|
||||||
})
|
.collect::<Vec<_>>();
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
match model {
|
match model {
|
||||||
open_ai::Model::Custom { .. }
|
open_ai::Model::Custom { .. }
|
||||||
| open_ai::Model::O1Mini
|
| open_ai::Model::O1Mini
|
||||||
| open_ai::Model::O1
|
| open_ai::Model::O1
|
||||||
| open_ai::Model::O3Mini => {
|
| open_ai::Model::O3Mini => tiktoken_rs::num_tokens_from_messages("gpt-4", &messages),
|
||||||
tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
|
_ => tiktoken_rs::num_tokens_from_messages(model.id(), &messages),
|
||||||
}
|
}
|
||||||
_ => tiktoken_rs::num_tokens_from_messages(model.id(), &messages),
|
})
|
||||||
}
|
.boxed()
|
||||||
})
|
|
||||||
.boxed()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConfigurationView {
|
struct ConfigurationView {
|
||||||
|
|
|
@ -302,11 +302,10 @@ impl LivekitWindow {
|
||||||
if let Some(track) = self.screen_share_track.take() {
|
if let Some(track) = self.screen_share_track.take() {
|
||||||
self.screen_share_stream.take();
|
self.screen_share_stream.take();
|
||||||
let participant = self.room.local_participant();
|
let participant = self.room.local_participant();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
participant.unpublish_track(&track.sid()).await.unwrap();
|
||||||
participant.unpublish_track(&track.sid()).await.unwrap();
|
})
|
||||||
})
|
.detach();
|
||||||
.detach();
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
} else {
|
} else {
|
||||||
let participant = self.room.local_participant();
|
let participant = self.room.local_participant();
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use crate::track::RemoteVideoTrack;
|
use crate::track::RemoteVideoTrack;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use futures::StreamExt as _;
|
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 {
|
pub struct RemoteVideoTrackView {
|
||||||
track: RemoteVideoTrack,
|
track: RemoteVideoTrack,
|
||||||
|
|
|
@ -6,7 +6,7 @@ pub use lsp_types::*;
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use futures::{channel::oneshot, io::BufWriter, select, AsyncRead, AsyncWrite, Future, FutureExt};
|
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 notification::DidChangeWorkspaceFolders;
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use postage::{barrier, prelude::Stream};
|
use postage::{barrier, prelude::Stream};
|
||||||
|
@ -448,7 +448,7 @@ impl LanguageServer {
|
||||||
let (stdout, stderr) = futures::join!(stdout_input_task, stderr_input_task);
|
let (stdout, stderr) = futures::join!(stdout_input_task, stderr_input_task);
|
||||||
stdout.or(stderr)
|
stdout.or(stderr)
|
||||||
});
|
});
|
||||||
let output_task = cx.background_executor().spawn({
|
let output_task = cx.background_spawn({
|
||||||
Self::handle_output(
|
Self::handle_output(
|
||||||
stdin,
|
stdin,
|
||||||
outbound_rx,
|
outbound_rx,
|
||||||
|
|
|
@ -178,7 +178,7 @@ impl Markdown {
|
||||||
|
|
||||||
let text = self.source.clone();
|
let text = self.source.clone();
|
||||||
let parse_text_only = self.options.parse_links_only;
|
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 text = SharedString::from(text);
|
||||||
let events = match parse_text_only {
|
let events = match parse_text_only {
|
||||||
true => Arc::from(parse_links_only(text.as_ref())),
|
true => Arc::from(parse_links_only(text.as_ref())),
|
||||||
|
|
|
@ -383,7 +383,7 @@ impl MarkdownPreviewView {
|
||||||
(contents, file_location)
|
(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
|
parse_markdown(&contents, file_location, Some(language_registry)).await
|
||||||
});
|
});
|
||||||
let contents = parsing_task.await;
|
let contents = parsing_task.await;
|
||||||
|
|
|
@ -13,7 +13,7 @@ use buffer_diff::{
|
||||||
use clock::ReplicaId;
|
use clock::ReplicaId;
|
||||||
use collections::{BTreeMap, Bound, HashMap, HashSet};
|
use collections::{BTreeMap, Bound, HashMap, HashSet};
|
||||||
use futures::{channel::mpsc, SinkExt};
|
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 itertools::Itertools;
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::{language_settings, IndentGuideSettings, LanguageSettings},
|
language_settings::{language_settings, IndentGuideSettings, LanguageSettings},
|
||||||
|
@ -51,9 +51,6 @@ use text::{
|
||||||
use theme::SyntaxTheme;
|
use theme::SyntaxTheme;
|
||||||
use util::post_inc;
|
use util::post_inc;
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
|
||||||
use gpui::AppContext as _;
|
|
||||||
|
|
||||||
const NEWLINES: &[u8] = &[b'\n'; u8::MAX as usize];
|
const NEWLINES: &[u8] = &[b'\n'; u8::MAX as usize];
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
@ -1580,20 +1577,19 @@ impl MultiBuffer {
|
||||||
|
|
||||||
buffer_ids.push(buffer_id);
|
buffer_ids.push(buffer_id);
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn({
|
||||||
.spawn({
|
let mut excerpt_ranges_tx = excerpt_ranges_tx.clone();
|
||||||
let mut excerpt_ranges_tx = excerpt_ranges_tx.clone();
|
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
let (excerpt_ranges, counts) =
|
let (excerpt_ranges, counts) =
|
||||||
build_excerpt_ranges(&buffer_snapshot, &ranges, context_line_count);
|
build_excerpt_ranges(&buffer_snapshot, &ranges, context_line_count);
|
||||||
excerpt_ranges_tx
|
excerpt_ranges_tx
|
||||||
.send((buffer_id, buffer.clone(), ranges, excerpt_ranges, counts))
|
.send((buffer_id, buffer.clone(), ranges, excerpt_ranges, counts))
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.detach()
|
.detach()
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.spawn(move |this, mut cx| async move {
|
cx.spawn(move |this, mut cx| async move {
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl SearchState {
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
highlight_search_match_tx,
|
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 {
|
while let Ok(highlight_arguments) = highlight_search_match_rx.recv().await {
|
||||||
let needs_init = highlight_arguments.search_data.get().is_none();
|
let needs_init = highlight_arguments.search_data.get().is_none();
|
||||||
let search_data = highlight_arguments.search_data.get_or_init(|| {
|
let search_data = highlight_arguments.search_data.get_or_init(|| {
|
||||||
|
@ -681,8 +681,7 @@ impl OutlinePanel {
|
||||||
mut cx: AsyncWindowContext,
|
mut cx: AsyncWindowContext,
|
||||||
) -> anyhow::Result<Entity<Self>> {
|
) -> anyhow::Result<Entity<Self>> {
|
||||||
let serialized_panel = cx
|
let serialized_panel = cx
|
||||||
.background_executor()
|
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(OUTLINE_PANEL_KEY) })
|
||||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(OUTLINE_PANEL_KEY) })
|
|
||||||
.await
|
.await
|
||||||
.context("loading outline panel")
|
.context("loading outline panel")
|
||||||
.log_err()
|
.log_err()
|
||||||
|
@ -849,7 +848,7 @@ impl OutlinePanel {
|
||||||
fn serialize(&mut self, cx: &mut Context<Self>) {
|
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
let active = Some(self.active);
|
let active = Some(self.active);
|
||||||
self.pending_serialization = cx.background_executor().spawn(
|
self.pending_serialization = cx.background_spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
|
@ -2631,8 +2630,7 @@ impl OutlinePanel {
|
||||||
new_depth_map,
|
new_depth_map,
|
||||||
new_children_count,
|
new_children_count,
|
||||||
)) = cx
|
)) = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
let mut processed_external_buffers = HashSet::default();
|
let mut processed_external_buffers = HashSet::default();
|
||||||
let mut new_worktree_entries =
|
let mut new_worktree_entries =
|
||||||
BTreeMap::<WorktreeId, HashMap<ProjectEntryId, GitEntry>>::default();
|
BTreeMap::<WorktreeId, HashMap<ProjectEntryId, GitEntry>>::default();
|
||||||
|
@ -3224,8 +3222,7 @@ impl OutlinePanel {
|
||||||
(buffer_id, excerpt_id),
|
(buffer_id, excerpt_id),
|
||||||
cx.spawn_in(window, |outline_panel, mut cx| async move {
|
cx.spawn_in(window, |outline_panel, mut cx| async move {
|
||||||
let fetched_outlines = cx
|
let fetched_outlines = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
buffer_snapshot
|
buffer_snapshot
|
||||||
.outline_items_containing(
|
.outline_items_containing(
|
||||||
excerpt_range.context,
|
excerpt_range.context,
|
||||||
|
|
|
@ -346,7 +346,7 @@ impl RemoteBufferStore {
|
||||||
fn open_unstaged_diff(&self, buffer_id: BufferId, cx: &App) -> Task<Result<Option<String>>> {
|
fn open_unstaged_diff(&self, buffer_id: BufferId, cx: &App) -> Task<Result<Option<String>>> {
|
||||||
let project_id = self.project_id;
|
let project_id = self.project_id;
|
||||||
let client = self.upstream_client.clone();
|
let client = self.upstream_client.clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let response = client
|
let response = client
|
||||||
.request(proto::OpenUnstagedDiff {
|
.request(proto::OpenUnstagedDiff {
|
||||||
project_id,
|
project_id,
|
||||||
|
@ -366,7 +366,7 @@ impl RemoteBufferStore {
|
||||||
|
|
||||||
let project_id = self.project_id;
|
let project_id = self.project_id;
|
||||||
let client = self.upstream_client.clone();
|
let client = self.upstream_client.clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let response = client
|
let response = client
|
||||||
.request(proto::OpenUncommittedDiff {
|
.request(proto::OpenUncommittedDiff {
|
||||||
project_id,
|
project_id,
|
||||||
|
@ -402,9 +402,7 @@ impl RemoteBufferStore {
|
||||||
return Ok(buffer);
|
return Ok(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { rx.await? }).await
|
||||||
.spawn(async move { rx.await? })
|
|
||||||
.await
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,8 +841,7 @@ impl LocalBufferStore {
|
||||||
let snapshot =
|
let snapshot =
|
||||||
worktree_handle.update(&mut cx, |tree, _| tree.as_local().unwrap().snapshot())?;
|
worktree_handle.update(&mut cx, |tree, _| tree.as_local().unwrap().snapshot())?;
|
||||||
let diff_bases_changes_by_buffer = cx
|
let diff_bases_changes_by_buffer = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
diff_state_updates
|
diff_state_updates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(
|
.filter_map(
|
||||||
|
@ -1129,8 +1126,7 @@ impl LocalBufferStore {
|
||||||
cx.spawn(move |_, mut cx| async move {
|
cx.spawn(move |_, mut cx| async move {
|
||||||
let loaded = load_file.await?;
|
let loaded = load_file.await?;
|
||||||
let text_buffer = cx
|
let text_buffer = cx
|
||||||
.background_executor()
|
.background_spawn(async move { text::Buffer::new(0, buffer_id, loaded.text) })
|
||||||
.spawn(async move { text::Buffer::new(0, buffer_id, loaded.text) })
|
|
||||||
.await;
|
.await;
|
||||||
cx.insert_entity(reservation, |_| {
|
cx.insert_entity(reservation, |_| {
|
||||||
Buffer::build(text_buffer, Some(loaded.file), Capability::ReadWrite)
|
Buffer::build(text_buffer, Some(loaded.file), Capability::ReadWrite)
|
||||||
|
@ -1347,8 +1343,7 @@ impl BufferStore {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
|
||||||
.spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_unstaged_diff(
|
pub fn open_unstaged_diff(
|
||||||
|
@ -1388,8 +1383,7 @@ impl BufferStore {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
|
||||||
.spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_uncommitted_diff(
|
pub fn open_uncommitted_diff(
|
||||||
|
@ -1409,7 +1403,7 @@ impl BufferStore {
|
||||||
BufferStoreState::Local(this) => {
|
BufferStoreState::Local(this) => {
|
||||||
let committed_text = this.load_committed_text(&buffer, cx);
|
let committed_text = this.load_committed_text(&buffer, cx);
|
||||||
let staged_text = this.load_staged_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 committed_text = committed_text.await?;
|
||||||
let staged_text = staged_text.await?;
|
let staged_text = staged_text.await?;
|
||||||
let diff_bases_change = if committed_text == staged_text {
|
let diff_bases_change = if committed_text == staged_text {
|
||||||
|
@ -1445,8 +1439,7 @@ impl BufferStore {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
|
||||||
.spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn open_diff_internal(
|
async fn open_diff_internal(
|
||||||
|
@ -1587,7 +1580,7 @@ impl BufferStore {
|
||||||
anyhow::Ok(Some((repo, relative_path, content)))
|
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 {
|
let Some((repo, relative_path, content)) = blame_params? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
|
@ -2106,24 +2099,23 @@ impl BufferStore {
|
||||||
})
|
})
|
||||||
.log_err();
|
.log_err();
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(
|
||||||
.spawn(
|
async move {
|
||||||
async move {
|
let operations = operations.await;
|
||||||
let operations = operations.await;
|
for chunk in split_operations(operations) {
|
||||||
for chunk in split_operations(operations) {
|
client
|
||||||
client
|
.request(proto::UpdateBuffer {
|
||||||
.request(proto::UpdateBuffer {
|
project_id,
|
||||||
project_id,
|
buffer_id: buffer_id.into(),
|
||||||
buffer_id: buffer_id.into(),
|
operations: chunk,
|
||||||
operations: chunk,
|
})
|
||||||
})
|
.await?;
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
anyhow::Ok(())
|
|
||||||
}
|
}
|
||||||
.log_err(),
|
anyhow::Ok(())
|
||||||
)
|
}
|
||||||
.detach();
|
.log_err(),
|
||||||
|
)
|
||||||
|
.detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(response)
|
Ok(response)
|
||||||
|
@ -2558,27 +2550,26 @@ impl BufferStore {
|
||||||
|
|
||||||
if client.send(initial_state).log_err().is_some() {
|
if client.send(initial_state).log_err().is_some() {
|
||||||
let client = client.clone();
|
let client = client.clone();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let mut chunks = split_operations(operations).peekable();
|
||||||
let mut chunks = split_operations(operations).peekable();
|
while let Some(chunk) = chunks.next() {
|
||||||
while let Some(chunk) = chunks.next() {
|
let is_last = chunks.peek().is_none();
|
||||||
let is_last = chunks.peek().is_none();
|
client.send(proto::CreateBufferForPeer {
|
||||||
client.send(proto::CreateBufferForPeer {
|
project_id,
|
||||||
project_id,
|
peer_id: Some(peer_id),
|
||||||
peer_id: Some(peer_id),
|
variant: Some(proto::create_buffer_for_peer::Variant::Chunk(
|
||||||
variant: Some(proto::create_buffer_for_peer::Variant::Chunk(
|
proto::BufferChunk {
|
||||||
proto::BufferChunk {
|
buffer_id: buffer_id.into(),
|
||||||
buffer_id: buffer_id.into(),
|
operations: chunk,
|
||||||
operations: chunk,
|
is_last,
|
||||||
is_last,
|
},
|
||||||
},
|
)),
|
||||||
)),
|
})?;
|
||||||
})?;
|
}
|
||||||
}
|
anyhow::Ok(())
|
||||||
anyhow::Ok(())
|
})
|
||||||
})
|
.await
|
||||||
.await
|
.log_err();
|
||||||
.log_err();
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|
|
@ -135,8 +135,7 @@ impl ProjectEnvironment {
|
||||||
|
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
let (mut shell_env, error_message) = cx
|
let (mut shell_env, error_message) = cx
|
||||||
.background_executor()
|
.background_spawn({
|
||||||
.spawn({
|
|
||||||
let worktree_abs_path = worktree_abs_path.clone();
|
let worktree_abs_path = worktree_abs_path.clone();
|
||||||
async move {
|
async move {
|
||||||
load_worktree_shell_environment(&worktree_abs_path, &load_direnv).await
|
load_worktree_shell_environment(&worktree_abs_path, &load_direnv).await
|
||||||
|
|
|
@ -11,8 +11,8 @@ use git::{
|
||||||
status::{GitSummary, TrackedSummary},
|
status::{GitSummary, TrackedSummary},
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext, AsyncApp, Context, Entity, EventEmitter, SharedString, Subscription, Task,
|
App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, SharedString, Subscription,
|
||||||
WeakEntity,
|
Task, WeakEntity,
|
||||||
};
|
};
|
||||||
use language::{Buffer, LanguageRegistry};
|
use language::{Buffer, LanguageRegistry};
|
||||||
use rpc::proto::{git_reset, ToProto};
|
use rpc::proto::{git_reset, ToProto};
|
||||||
|
@ -242,10 +242,7 @@ impl GitStore {
|
||||||
mpsc::unbounded::<(Message, oneshot::Sender<Result<()>>)>();
|
mpsc::unbounded::<(Message, oneshot::Sender<Result<()>>)>();
|
||||||
cx.spawn(|_, cx| async move {
|
cx.spawn(|_, cx| async move {
|
||||||
while let Some((msg, respond)) = update_receiver.next().await {
|
while let Some((msg, respond)) = update_receiver.next().await {
|
||||||
let result = cx
|
let result = cx.background_spawn(Self::process_git_msg(msg)).await;
|
||||||
.background_executor()
|
|
||||||
.spawn(Self::process_git_msg(msg))
|
|
||||||
.await;
|
|
||||||
respond.send(result).ok();
|
respond.send(result).ok();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -841,15 +838,14 @@ impl Repository {
|
||||||
match self.git_repo.clone() {
|
match self.git_repo.clone() {
|
||||||
GitRepo::Local(git_repository) => {
|
GitRepo::Local(git_repository) => {
|
||||||
let commit = commit.to_string();
|
let commit = commit.to_string();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { git_repository.show(&commit) })
|
||||||
.spawn(async move { git_repository.show(&commit) })
|
|
||||||
}
|
}
|
||||||
GitRepo::Remote {
|
GitRepo::Remote {
|
||||||
project_id,
|
project_id,
|
||||||
client,
|
client,
|
||||||
worktree_id,
|
worktree_id,
|
||||||
work_directory_id,
|
work_directory_id,
|
||||||
} => cx.background_executor().spawn(async move {
|
} => cx.background_spawn(async move {
|
||||||
let resp = client
|
let resp = client
|
||||||
.request(proto::GitShow {
|
.request(proto::GitShow {
|
||||||
project_id: project_id.0,
|
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)
|
Self::wait_for_loading_image(loading_watch)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.cloned())
|
.map_err(|e| e.cloned())
|
||||||
|
|
|
@ -2144,7 +2144,7 @@ impl LocalLspStore {
|
||||||
cx: &mut Context<LspStore>,
|
cx: &mut Context<LspStore>,
|
||||||
) -> Task<Result<Vec<(Range<Anchor>, String)>>> {
|
) -> Task<Result<Vec<(Range<Anchor>, String)>>> {
|
||||||
let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
|
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 snapshot = snapshot?;
|
||||||
let mut lsp_edits = lsp_edits
|
let mut lsp_edits = lsp_edits
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -3282,16 +3282,15 @@ impl LspStore {
|
||||||
}
|
}
|
||||||
} else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
|
} else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
|
||||||
let buffer_id = buffer.read(cx).remote_id().to_proto();
|
let buffer_id = buffer.read(cx).remote_id().to_proto();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
upstream_client
|
||||||
upstream_client
|
.request(proto::RegisterBufferWithLanguageServers {
|
||||||
.request(proto::RegisterBufferWithLanguageServers {
|
project_id: upstream_project_id,
|
||||||
project_id: upstream_project_id,
|
buffer_id,
|
||||||
buffer_id,
|
})
|
||||||
})
|
.await
|
||||||
.await
|
})
|
||||||
})
|
.detach();
|
||||||
.detach();
|
|
||||||
} else {
|
} else {
|
||||||
panic!("oops!");
|
panic!("oops!");
|
||||||
}
|
}
|
||||||
|
@ -6707,7 +6706,7 @@ impl LspStore {
|
||||||
return Err(anyhow!("No language server {id}"));
|
return Err(anyhow!("No language server {id}"));
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(cx.background_executor().spawn(async move {
|
Ok(cx.background_spawn(async move {
|
||||||
let can_resolve = server
|
let can_resolve = server
|
||||||
.capabilities()
|
.capabilities()
|
||||||
.completion_provider
|
.completion_provider
|
||||||
|
@ -7375,9 +7374,7 @@ impl LspStore {
|
||||||
.map(|b| b.read(cx).remote_id().to_proto())
|
.map(|b| b.read(cx).remote_id().to_proto())
|
||||||
.collect(),
|
.collect(),
|
||||||
});
|
});
|
||||||
cx.background_executor()
|
cx.background_spawn(request).detach_and_log_err(cx);
|
||||||
.spawn(request)
|
|
||||||
.detach_and_log_err(cx);
|
|
||||||
} else {
|
} else {
|
||||||
let Some(local) = self.as_local_mut() else {
|
let Some(local) = self.as_local_mut() else {
|
||||||
return;
|
return;
|
||||||
|
@ -7406,9 +7403,7 @@ impl LspStore {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
cx.background_executor()
|
cx.background_spawn(futures::future::join_all(tasks)).await;
|
||||||
.spawn(futures::future::join_all(tasks))
|
|
||||||
.await;
|
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
for buffer in buffers {
|
for buffer in buffers {
|
||||||
this.register_buffer_with_language_servers(&buffer, true, cx);
|
this.register_buffer_with_language_servers(&buffer, true, cx);
|
||||||
|
@ -7737,9 +7732,7 @@ impl LspStore {
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
});
|
});
|
||||||
cx.background_executor()
|
cx.background_spawn(request).detach_and_log_err(cx);
|
||||||
.spawn(request)
|
|
||||||
.detach_and_log_err(cx);
|
|
||||||
} else if let Some(local) = self.as_local() {
|
} else if let Some(local) = self.as_local() {
|
||||||
let servers = buffers
|
let servers = buffers
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -7795,9 +7788,7 @@ impl LspStore {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
cx.background_executor()
|
cx.background_spawn(request).detach_and_log_err(cx);
|
||||||
.spawn(request)
|
|
||||||
.detach_and_log_err(cx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use futures::{
|
||||||
stream::FuturesUnordered,
|
stream::FuturesUnordered,
|
||||||
FutureExt,
|
FutureExt,
|
||||||
};
|
};
|
||||||
use gpui::{AsyncApp, Context, Entity, EventEmitter, Task, WeakEntity};
|
use gpui::{AppContext as _, AsyncApp, Context, Entity, EventEmitter, Task, WeakEntity};
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::{Formatter, LanguageSettings, SelectedFormatter},
|
language_settings::{Formatter, LanguageSettings, SelectedFormatter},
|
||||||
Buffer, LanguageRegistry, LocalFile,
|
Buffer, LanguageRegistry, LocalFile,
|
||||||
|
@ -121,8 +121,7 @@ impl PrettierStore {
|
||||||
let installed_prettiers = self.prettier_instances.keys().cloned().collect();
|
let installed_prettiers = self.prettier_instances.keys().cloned().collect();
|
||||||
cx.spawn(|lsp_store, mut cx| async move {
|
cx.spawn(|lsp_store, mut cx| async move {
|
||||||
match cx
|
match cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
Prettier::locate_prettier_installation(
|
Prettier::locate_prettier_installation(
|
||||||
fs.as_ref(),
|
fs.as_ref(),
|
||||||
&installed_prettiers,
|
&installed_prettiers,
|
||||||
|
@ -234,8 +233,7 @@ impl PrettierStore {
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
cx.spawn(|lsp_store, mut cx| async move {
|
cx.spawn(|lsp_store, mut cx| async move {
|
||||||
match cx
|
match cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
Prettier::locate_prettier_ignore(
|
Prettier::locate_prettier_ignore(
|
||||||
fs.as_ref(),
|
fs.as_ref(),
|
||||||
&prettier_ignores,
|
&prettier_ignores,
|
||||||
|
@ -483,31 +481,30 @@ impl PrettierStore {
|
||||||
}))
|
}))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let _: Vec<()> = future::join_all(prettiers_to_reload.into_iter().map(|(worktree_id, prettier_path, prettier_instance)| {
|
||||||
let _: Vec<()> = future::join_all(prettiers_to_reload.into_iter().map(|(worktree_id, prettier_path, prettier_instance)| {
|
async move {
|
||||||
async move {
|
if let Some(instance) = prettier_instance.prettier {
|
||||||
if let Some(instance) = prettier_instance.prettier {
|
match instance.await {
|
||||||
match instance.await {
|
Ok(prettier) => {
|
||||||
Ok(prettier) => {
|
prettier.clear_cache().log_err().await;
|
||||||
prettier.clear_cache().log_err().await;
|
},
|
||||||
},
|
Err(e) => {
|
||||||
Err(e) => {
|
match prettier_path {
|
||||||
match prettier_path {
|
Some(prettier_path) => log::error!(
|
||||||
Some(prettier_path) => log::error!(
|
"Failed to clear prettier {prettier_path:?} cache for worktree {worktree_id:?} on prettier settings update: {e:#}"
|
||||||
"Failed to clear prettier {prettier_path:?} cache for worktree {worktree_id:?} on prettier settings update: {e:#}"
|
),
|
||||||
),
|
None => log::error!(
|
||||||
None => log::error!(
|
"Failed to clear default prettier cache for worktree {worktree_id:?} on prettier settings update: {e:#}"
|
||||||
"Failed to clear default prettier cache for worktree {worktree_id:?} on prettier settings update: {e:#}"
|
),
|
||||||
),
|
}
|
||||||
}
|
},
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}
|
||||||
.await;
|
}))
|
||||||
})
|
.await;
|
||||||
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -539,7 +536,7 @@ impl PrettierStore {
|
||||||
}) {
|
}) {
|
||||||
Some(locate_from) => {
|
Some(locate_from) => {
|
||||||
let installed_prettiers = self.prettier_instances.keys().cloned().collect();
|
let installed_prettiers = self.prettier_instances.keys().cloned().collect();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
Prettier::locate_prettier_installation(
|
Prettier::locate_prettier_installation(
|
||||||
fs.as_ref(),
|
fs.as_ref(),
|
||||||
&installed_prettiers,
|
&installed_prettiers,
|
||||||
|
@ -631,13 +628,12 @@ impl PrettierStore {
|
||||||
})?;
|
})?;
|
||||||
if needs_install {
|
if needs_install {
|
||||||
let installed_plugins = new_plugins.clone();
|
let installed_plugins = new_plugins.clone();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
install_prettier_packages(fs.as_ref(), new_plugins, node).await?;
|
||||||
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 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?;
|
||||||
save_prettier_server_file(fs.as_ref()).await?;
|
anyhow::Ok(())
|
||||||
anyhow::Ok(())
|
})
|
||||||
})
|
|
||||||
.await
|
.await
|
||||||
.context("prettier & plugins install")
|
.context("prettier & plugins install")
|
||||||
.map_err(Arc::new)?;
|
.map_err(Arc::new)?;
|
||||||
|
|
|
@ -562,7 +562,7 @@ impl DirectoryLister {
|
||||||
}
|
}
|
||||||
DirectoryLister::Local(fs) => {
|
DirectoryLister::Local(fs) => {
|
||||||
let fs = fs.clone();
|
let fs = fs.clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let mut results = vec![];
|
let mut results = vec![];
|
||||||
let expanded = shellexpand::tilde(&path);
|
let expanded = shellexpand::tilde(&path);
|
||||||
let query = Path::new(expanded.as_ref());
|
let query = Path::new(expanded.as_ref());
|
||||||
|
@ -1163,13 +1163,12 @@ impl Project {
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.shutdown_processes(Some(proto::ShutdownRemoteServer {}));
|
.shutdown_processes(Some(proto::ShutdownRemoteServer {}));
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
if let Some(shutdown) = shutdown {
|
||||||
if let Some(shutdown) = shutdown {
|
shutdown.await;
|
||||||
shutdown.await;
|
}
|
||||||
}
|
})
|
||||||
})
|
.detach()
|
||||||
.detach()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match &self.client_state {
|
match &self.client_state {
|
||||||
|
@ -3138,7 +3137,7 @@ impl Project {
|
||||||
let buffer = buffer.clone();
|
let buffer = buffer.clone();
|
||||||
let query = query.clone();
|
let query = query.clone();
|
||||||
let snapshot = buffer.read_with(&cx, |buffer, _| buffer.snapshot())?;
|
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
|
let ranges = query
|
||||||
.search(&snapshot, None)
|
.search(&snapshot, None)
|
||||||
.await
|
.await
|
||||||
|
@ -3377,7 +3376,7 @@ impl Project {
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Task<Option<ResolvedPath>> {
|
) -> Task<Option<ResolvedPath>> {
|
||||||
let resolve_task = self.resolve_abs_path(path, cx);
|
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;
|
let resolved_path = resolve_task.await;
|
||||||
resolved_path.filter(|path| path.is_file())
|
resolved_path.filter(|path| path.is_file())
|
||||||
})
|
})
|
||||||
|
@ -3391,7 +3390,7 @@ impl Project {
|
||||||
if self.is_local() {
|
if self.is_local() {
|
||||||
let expanded = PathBuf::from(shellexpand::tilde(&path).into_owned());
|
let expanded = PathBuf::from(shellexpand::tilde(&path).into_owned());
|
||||||
let fs = self.fs.clone();
|
let fs = self.fs.clone();
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let path = expanded.as_path();
|
let path = expanded.as_path();
|
||||||
let metadata = fs.metadata(path).await.ok().flatten();
|
let metadata = fs.metadata(path).await.ok().flatten();
|
||||||
|
|
||||||
|
@ -3409,7 +3408,7 @@ impl Project {
|
||||||
project_id: SSH_PROJECT_ID,
|
project_id: SSH_PROJECT_ID,
|
||||||
path: request_path.to_proto(),
|
path: request_path.to_proto(),
|
||||||
});
|
});
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let response = request.await.log_err()?;
|
let response = request.await.log_err()?;
|
||||||
if response.exists {
|
if response.exists {
|
||||||
Some(ResolvedPath::AbsPath {
|
Some(ResolvedPath::AbsPath {
|
||||||
|
@ -3490,7 +3489,7 @@ impl Project {
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = session.read(cx).proto_client().request(request);
|
let response = session.read(cx).proto_client().request(request);
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let response = response.await?;
|
let response = response.await?;
|
||||||
Ok(response.entries.into_iter().map(PathBuf::from).collect())
|
Ok(response.entries.into_iter().map(PathBuf::from).collect())
|
||||||
})
|
})
|
||||||
|
@ -3906,8 +3905,7 @@ impl Project {
|
||||||
if let Some(remote_id) = this.remote_id() {
|
if let Some(remote_id) = this.remote_id() {
|
||||||
let mut payload = envelope.payload.clone();
|
let mut payload = envelope.payload.clone();
|
||||||
payload.project_id = remote_id;
|
payload.project_id = remote_id;
|
||||||
cx.background_executor()
|
cx.background_spawn(this.client.request(payload))
|
||||||
.spawn(this.client.request(payload))
|
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
}
|
}
|
||||||
this.buffer_store.clone()
|
this.buffer_store.clone()
|
||||||
|
@ -3924,8 +3922,7 @@ impl Project {
|
||||||
if let Some(ssh) = &this.ssh_client {
|
if let Some(ssh) = &this.ssh_client {
|
||||||
let mut payload = envelope.payload.clone();
|
let mut payload = envelope.payload.clone();
|
||||||
payload.project_id = SSH_PROJECT_ID;
|
payload.project_id = SSH_PROJECT_ID;
|
||||||
cx.background_executor()
|
cx.background_spawn(ssh.read(cx).proto_client().request(payload))
|
||||||
.spawn(ssh.read(cx).proto_client().request(payload))
|
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
}
|
}
|
||||||
this.buffer_store.clone()
|
this.buffer_store.clone()
|
||||||
|
@ -4146,7 +4143,7 @@ impl Project {
|
||||||
if let Some(buffer) = this.buffer_for_id(buffer_id, cx) {
|
if let Some(buffer) = this.buffer_for_id(buffer_id, cx) {
|
||||||
let operations =
|
let operations =
|
||||||
buffer.read(cx).serialize_ops(Some(remote_version), cx);
|
buffer.read(cx).serialize_ops(Some(remote_version), cx);
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let operations = operations.await;
|
let operations = operations.await;
|
||||||
for chunk in split_operations(operations) {
|
for chunk in split_operations(operations) {
|
||||||
client
|
client
|
||||||
|
@ -4169,12 +4166,11 @@ impl Project {
|
||||||
// Any incomplete buffers have open requests waiting. Request that the host sends
|
// Any incomplete buffers have open requests waiting. Request that the host sends
|
||||||
// creates these buffers for us again to unblock any waiting futures.
|
// creates these buffers for us again to unblock any waiting futures.
|
||||||
for id in incomplete_buffer_ids {
|
for id in incomplete_buffer_ids {
|
||||||
cx.background_executor()
|
cx.background_spawn(client.request(proto::OpenBufferById {
|
||||||
.spawn(client.request(proto::OpenBufferById {
|
project_id,
|
||||||
project_id,
|
id: id.into(),
|
||||||
id: id.into(),
|
}))
|
||||||
}))
|
.detach();
|
||||||
.detach();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
futures::future::join_all(send_updates_for_buffers)
|
futures::future::join_all(send_updates_for_buffers)
|
||||||
|
|
|
@ -13,7 +13,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use collections::HashMap;
|
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 language::{CachedLspAdapter, LspAdapterDelegate};
|
||||||
use lsp::LanguageServerName;
|
use lsp::LanguageServerName;
|
||||||
use path_trie::{LabelPresence, RootPathTrie, TriePath};
|
use path_trie::{LabelPresence, RootPathTrie, TriePath};
|
||||||
|
|
|
@ -15,7 +15,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use collections::{HashMap, IndexMap};
|
use collections::{HashMap, IndexMap};
|
||||||
use gpui::{App, AppContext, Entity, Subscription};
|
use gpui::{App, AppContext as _, Entity, Subscription};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::AllLanguageSettings, Attach, LanguageName, LanguageRegistry,
|
language_settings::AllLanguageSettings, Attach, LanguageName, LanguageRegistry,
|
||||||
|
|
|
@ -325,16 +325,15 @@ impl LocalToolchainStore {
|
||||||
.ok()?
|
.ok()?
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let language = registry
|
||||||
let language = registry
|
.language_for_name(language_name.as_ref())
|
||||||
.language_for_name(language_name.as_ref())
|
.await
|
||||||
.await
|
.ok()?;
|
||||||
.ok()?;
|
let toolchains = language.toolchain_lister()?;
|
||||||
let toolchains = language.toolchain_lister()?;
|
Some(toolchains.list(root.to_path_buf(), project_env).await)
|
||||||
Some(toolchains.list(root.to_path_buf(), project_env).await)
|
})
|
||||||
})
|
.await
|
||||||
.await
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub(crate) fn active_toolchain(
|
pub(crate) fn active_toolchain(
|
||||||
|
|
|
@ -13,7 +13,9 @@ use futures::{
|
||||||
FutureExt, SinkExt,
|
FutureExt, SinkExt,
|
||||||
};
|
};
|
||||||
use git::repository::Branch;
|
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 postage::oneshot;
|
||||||
use rpc::{
|
use rpc::{
|
||||||
proto::{self, FromProto, ToProto, SSH_PROJECT_ID},
|
proto::{self, FromProto, ToProto, SSH_PROJECT_ID},
|
||||||
|
@ -179,8 +181,7 @@ impl WorktreeStore {
|
||||||
Task::ready(Ok((tree, relative_path)))
|
Task::ready(Ok((tree, relative_path)))
|
||||||
} else {
|
} else {
|
||||||
let worktree = self.create_worktree(abs_path, visible, cx);
|
let worktree = self.create_worktree(abs_path, visible, cx);
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { Ok((worktree.await?, PathBuf::new())) })
|
||||||
.spawn(async move { Ok((worktree.await?, PathBuf::new())) })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,7 +680,7 @@ impl WorktreeStore {
|
||||||
let (output_tx, output_rx) = smol::channel::bounded(64);
|
let (output_tx, output_rx) = smol::channel::bounded(64);
|
||||||
let (matching_paths_tx, matching_paths_rx) = smol::channel::unbounded();
|
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 fs = fs.clone();
|
||||||
let query = query.clone();
|
let query = query.clone();
|
||||||
async move {
|
async move {
|
||||||
|
@ -696,7 +697,7 @@ impl WorktreeStore {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const MAX_CONCURRENT_FILE_SCANS: usize = 64;
|
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 fs = &fs;
|
||||||
let query = &query;
|
let query = &query;
|
||||||
executor
|
executor
|
||||||
|
@ -712,25 +713,24 @@ impl WorktreeStore {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
});
|
});
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let mut matched = 0;
|
||||||
let mut matched = 0;
|
while let Ok(mut receiver) = output_rx.recv().await {
|
||||||
while let Ok(mut receiver) = output_rx.recv().await {
|
let Some(path) = receiver.next().await else {
|
||||||
let Some(path) = receiver.next().await else {
|
continue;
|
||||||
continue;
|
};
|
||||||
};
|
let Ok(_) = matching_paths_tx.send(path).await else {
|
||||||
let Ok(_) = matching_paths_tx.send(path).await else {
|
break;
|
||||||
break;
|
};
|
||||||
};
|
matched += 1;
|
||||||
matched += 1;
|
if matched == limit {
|
||||||
if matched == limit {
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
drop(input);
|
}
|
||||||
drop(filters);
|
drop(input);
|
||||||
})
|
drop(filters);
|
||||||
.detach();
|
})
|
||||||
|
.detach();
|
||||||
matching_paths_rx
|
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 response = request.await?;
|
||||||
|
|
||||||
let branches = response
|
let branches = response
|
||||||
|
@ -1021,7 +1021,7 @@ impl WorktreeStore {
|
||||||
branch_name: new_branch,
|
branch_name: new_branch,
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
request.await?;
|
request.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|
|
@ -544,8 +544,7 @@ impl ProjectPanel {
|
||||||
mut cx: AsyncWindowContext,
|
mut cx: AsyncWindowContext,
|
||||||
) -> Result<Entity<Self>> {
|
) -> Result<Entity<Self>> {
|
||||||
let serialized_panel = cx
|
let serialized_panel = cx
|
||||||
.background_executor()
|
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) })
|
||||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) })
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| anyhow!("Failed to load project panel: {}", e))
|
.map_err(|e| anyhow!("Failed to load project panel: {}", e))
|
||||||
.log_err()
|
.log_err()
|
||||||
|
@ -627,7 +626,7 @@ impl ProjectPanel {
|
||||||
|
|
||||||
fn serialize(&mut self, cx: &mut Context<Self>) {
|
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
self.pending_serialization = cx.background_executor().spawn(
|
self.pending_serialization = cx.background_spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
.write_kvp(
|
.write_kvp(
|
||||||
|
|
|
@ -218,8 +218,7 @@ impl PickerDelegate for PromptPickerDelegate {
|
||||||
let prev_prompt_id = self.matches.get(self.selected_index).map(|mat| mat.id);
|
let prev_prompt_id = self.matches.get(self.selected_index).map(|mat| mat.id);
|
||||||
cx.spawn_in(window, |this, mut cx| async move {
|
cx.spawn_in(window, |this, mut cx| async move {
|
||||||
let (matches, selected_index) = cx
|
let (matches, selected_index) = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
let matches = search.await;
|
let matches = search.await;
|
||||||
|
|
||||||
let selected_index = prev_prompt_id
|
let selected_index = prev_prompt_id
|
||||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::Result;
|
||||||
use assets::Assets;
|
use assets::Assets;
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use gpui::{App, AssetSource};
|
use gpui::{App, AppContext as _, AssetSource};
|
||||||
use handlebars::{Handlebars, RenderError};
|
use handlebars::{Handlebars, RenderError};
|
||||||
use language::{BufferSnapshot, LanguageName, Point};
|
use language::{BufferSnapshot, LanguageName, Point};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
@ -103,103 +103,102 @@ impl PromptBuilder {
|
||||||
handlebars: Arc<Mutex<Handlebars<'static>>>,
|
handlebars: Arc<Mutex<Handlebars<'static>>>,
|
||||||
) {
|
) {
|
||||||
let templates_dir = paths::prompt_overrides_dir(params.repo_path.as_deref());
|
let templates_dir = paths::prompt_overrides_dir(params.repo_path.as_deref());
|
||||||
params.cx.background_executor()
|
params.cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let Some(parent_dir) = templates_dir.parent() else {
|
||||||
let Some(parent_dir) = templates_dir.parent() else {
|
return;
|
||||||
return;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let mut found_dir_once = false;
|
let mut found_dir_once = false;
|
||||||
loop {
|
loop {
|
||||||
// Check if the templates directory exists and handle its status
|
// 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 exists, log its presence and check if it's a symlink
|
||||||
// If it doesn't exist:
|
// If it doesn't exist:
|
||||||
// - Log that we're using built-in prompts
|
// - Log that we're using built-in prompts
|
||||||
// - Check if it's a broken symlink and log if so
|
// - Check if it's a broken symlink and log if so
|
||||||
// - Set up a watcher to detect when it's created
|
// - Set up a watcher to detect when it's created
|
||||||
// After the first check, set the `found_dir_once` flag
|
// 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.
|
// 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 dir_status = params.fs.is_dir(&templates_dir).await;
|
||||||
let symlink_status = params.fs.read_link(&templates_dir).await.ok();
|
let symlink_status = params.fs.read_link(&templates_dir).await.ok();
|
||||||
if dir_status {
|
if dir_status {
|
||||||
let mut log_message = format!("Prompt template overrides directory found at {}", templates_dir.display());
|
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 {
|
if let Some(target) = symlink_status {
|
||||||
log_message.push_str(" -> ");
|
log::info!("Symlink found pointing to {}, but target is invalid.", target.display());
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
found_dir_once = true;
|
if params.fs.is_dir(parent_dir).await {
|
||||||
|
let (mut changes, _watcher) = params.fs.watch(parent_dir, Duration::from_secs(1)).await;
|
||||||
// Initial scan of the prompt overrides directory
|
while let Some(changed_paths) = changes.next().await {
|
||||||
if let Ok(mut entries) = params.fs.read_dir(&templates_dir).await {
|
if changed_paths.iter().any(|p| &p.path == &templates_dir) {
|
||||||
while let Some(Ok(file_path)) = entries.next().await {
|
let mut log_message = format!("Prompt template overrides directory detected at {}", templates_dir.display());
|
||||||
if file_path.to_string_lossy().ends_with(".hbs") {
|
if let Ok(target) = params.fs.read_link(&templates_dir).await {
|
||||||
if let Ok(content) = params.fs.load(&file_path).await {
|
log_message.push_str(" -> ");
|
||||||
let file_name = file_path.file_stem().unwrap().to_string_lossy();
|
log_message.push_str(&target.display().to_string());
|
||||||
log::debug!("Registering prompt template override: {}", file_name);
|
|
||||||
handlebars.lock().register_template_string(&file_name, content).log_err();
|
|
||||||
}
|
}
|
||||||
}
|
log::info!("{}.", log_message);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for event in changed_paths {
|
} else {
|
||||||
if event.path.starts_with(&templates_dir) && event.path.extension().map_or(false, |ext| ext == "hbs") {
|
return;
|
||||||
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();
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drop(watcher);
|
|
||||||
drop(parent_watcher);
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(watcher);
|
||||||
|
drop(parent_watcher);
|
||||||
|
}
|
||||||
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ use futures::{
|
||||||
select, select_biased, AsyncReadExt as _, Future, FutureExt as _, StreamExt as _,
|
select, select_biased, AsyncReadExt as _, Future, FutureExt as _, StreamExt as _,
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext, AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Global,
|
App, AppContext as _, AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Global,
|
||||||
SemanticVersion, Task, WeakEntity,
|
SemanticVersion, Task, WeakEntity,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
@ -1158,12 +1158,11 @@ impl SshRemoteClient {
|
||||||
c.connections.insert(
|
c.connections.insert(
|
||||||
opts.clone(),
|
opts.clone(),
|
||||||
ConnectionPoolEntry::Connecting(
|
ConnectionPoolEntry::Connecting(
|
||||||
cx.background_executor()
|
cx.background_spawn({
|
||||||
.spawn({
|
let connection = connection.clone();
|
||||||
let connection = connection.clone();
|
async move { Ok(connection.clone()) }
|
||||||
async move { Ok(connection.clone()) }
|
})
|
||||||
})
|
.shared(),
|
||||||
.shared(),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
@ -1358,7 +1357,7 @@ impl RemoteConnection for SshRemoteConnection {
|
||||||
))
|
))
|
||||||
.output();
|
.output();
|
||||||
|
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
let output = output.await?;
|
let output = output.await?;
|
||||||
|
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
|
@ -1679,14 +1678,14 @@ impl SshRemoteConnection {
|
||||||
let mut stderr_buffer = Vec::new();
|
let mut stderr_buffer = Vec::new();
|
||||||
let mut stderr_offset = 0;
|
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 {
|
while let Some(outgoing) = outgoing_rx.next().await {
|
||||||
write_message(&mut child_stdin, &mut stdin_buffer, outgoing).await?;
|
write_message(&mut child_stdin, &mut stdin_buffer, outgoing).await?;
|
||||||
}
|
}
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
let stdout_task = cx.background_executor().spawn({
|
let stdout_task = cx.background_spawn({
|
||||||
let mut connection_activity_tx = connection_activity_tx.clone();
|
let mut connection_activity_tx = connection_activity_tx.clone();
|
||||||
async move {
|
async move {
|
||||||
loop {
|
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 {
|
loop {
|
||||||
stderr_buffer.resize(stderr_offset + 1024, 0);
|
stderr_buffer.resize(stderr_offset + 1024, 0);
|
||||||
|
|
||||||
|
@ -2449,7 +2448,7 @@ mod fake {
|
||||||
},
|
},
|
||||||
select_biased, FutureExt, SinkExt, StreamExt,
|
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 release_channel::ReleaseChannel;
|
||||||
use rpc::proto::Envelope;
|
use rpc::proto::Envelope;
|
||||||
|
|
||||||
|
@ -2533,7 +2532,7 @@ mod fake {
|
||||||
&self.server_cx.get(cx),
|
&self.server_cx.get(cx),
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
select_biased! {
|
select_biased! {
|
||||||
server_to_client = server_outgoing_rx.next().fuse() => {
|
server_to_client = server_outgoing_rx.next().fuse() => {
|
||||||
|
|
|
@ -240,8 +240,7 @@ impl HeadlessProject {
|
||||||
operation,
|
operation,
|
||||||
is_local: true,
|
is_local: true,
|
||||||
} => cx
|
} => cx
|
||||||
.background_executor()
|
.background_spawn(self.session.request(proto::UpdateBuffer {
|
||||||
.spawn(self.session.request(proto::UpdateBuffer {
|
|
||||||
project_id: SSH_PROJECT_ID,
|
project_id: SSH_PROJECT_ID,
|
||||||
buffer_id: buffer.read(cx).remote_id().to_proto(),
|
buffer_id: buffer.read(cx).remote_id().to_proto(),
|
||||||
operations: vec![serialize_operation(operation)],
|
operations: vec![serialize_operation(operation)],
|
||||||
|
@ -302,15 +301,14 @@ impl HeadlessProject {
|
||||||
message: prompt.message.clone(),
|
message: prompt.message.clone(),
|
||||||
});
|
});
|
||||||
let prompt = prompt.clone();
|
let prompt = prompt.clone();
|
||||||
cx.background_executor()
|
cx.background_spawn(async move {
|
||||||
.spawn(async move {
|
let response = request.await?;
|
||||||
let response = request.await?;
|
if let Some(action_response) = response.action_response {
|
||||||
if let Some(action_response) = response.action_response {
|
prompt.respond(action_response as usize).await;
|
||||||
prompt.respond(action_response as usize).await;
|
}
|
||||||
}
|
anyhow::Ok(())
|
||||||
anyhow::Ok(())
|
})
|
||||||
})
|
.detach();
|
||||||
.detach();
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,7 +311,7 @@ fn start_server(
|
||||||
let mut output_buffer = Vec::new();
|
let mut output_buffer = Vec::new();
|
||||||
|
|
||||||
let (mut stdin_msg_tx, mut stdin_msg_rx) = mpsc::unbounded::<Envelope>();
|
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 {
|
while let Ok(msg) = read_message(&mut stdin_stream, &mut input_buffer).await {
|
||||||
if let Err(_) = stdin_msg_tx.send(msg).await {
|
if let Err(_) = stdin_msg_tx.send(msg).await {
|
||||||
break;
|
break;
|
||||||
|
@ -487,8 +487,7 @@ pub fn execute_run(
|
||||||
|
|
||||||
handle_panic_requests(&project, &session);
|
handle_panic_requests(&project, &session);
|
||||||
|
|
||||||
cx.background_executor()
|
cx.background_spawn(async move { cleanup_old_binaries() })
|
||||||
.spawn(async move { cleanup_old_binaries() })
|
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
mem::forget(project);
|
mem::forget(project);
|
||||||
|
|
|
@ -5,7 +5,7 @@ use futures::{
|
||||||
stream::{SelectAll, StreamExt},
|
stream::{SelectAll, StreamExt},
|
||||||
AsyncBufReadExt as _, SinkExt as _,
|
AsyncBufReadExt as _, SinkExt as _,
|
||||||
};
|
};
|
||||||
use gpui::{App, Entity, EntityId, Task, Window};
|
use gpui::{App, AppContext as _, Entity, EntityId, Task, Window};
|
||||||
use jupyter_protocol::{
|
use jupyter_protocol::{
|
||||||
connection_info::{ConnectionInfo, Transport},
|
connection_info::{ConnectionInfo, Transport},
|
||||||
ExecutionState, JupyterKernelspec, JupyterMessage, JupyterMessageContent, KernelInfoReply,
|
ExecutionState, JupyterKernelspec, JupyterMessage, JupyterMessageContent, KernelInfoReply,
|
||||||
|
@ -211,7 +211,7 @@ impl NativeRunningKernel {
|
||||||
futures::channel::mpsc::channel(100);
|
futures::channel::mpsc::channel(100);
|
||||||
let (mut shell_request_tx, mut shell_request_rx) = 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 {
|
async move {
|
||||||
while let Some(message) = request_rx.next().await {
|
while let Some(message) = request_rx.next().await {
|
||||||
match message.content {
|
match message.content {
|
||||||
|
@ -229,7 +229,7 @@ impl NativeRunningKernel {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let shell_task = cx.background_executor().spawn({
|
let shell_task = cx.background_spawn({
|
||||||
async move {
|
async move {
|
||||||
while let Some(message) = shell_request_rx.next().await {
|
while let Some(message) = shell_request_rx.next().await {
|
||||||
shell_socket.send(message).await.ok();
|
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 {
|
async move {
|
||||||
while let Some(message) = control_request_rx.next().await {
|
while let Some(message) = control_request_rx.next().await {
|
||||||
control_socket.send(message).await.ok();
|
control_socket.send(message).await.ok();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use futures::{channel::mpsc, SinkExt as _};
|
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 http_client::{AsyncBody, HttpClient, Request};
|
||||||
use jupyter_protocol::{ExecutionState, JupyterKernelspec, JupyterMessage, KernelInfoReply};
|
use jupyter_protocol::{ExecutionState, JupyterKernelspec, JupyterMessage, KernelInfoReply};
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ impl RemoteRunningKernel {
|
||||||
let (request_tx, mut request_rx) =
|
let (request_tx, mut request_rx) =
|
||||||
futures::channel::mpsc::channel::<JupyterMessage>(100);
|
futures::channel::mpsc::channel::<JupyterMessage>(100);
|
||||||
|
|
||||||
let routing_task = cx.background_executor().spawn({
|
let routing_task = cx.background_spawn({
|
||||||
async move {
|
async move {
|
||||||
while let Some(message) = request_rx.next().await {
|
while let Some(message) = request_rx.next().await {
|
||||||
w.send(message).await.ok();
|
w.send(message).await.ok();
|
||||||
|
|
|
@ -134,8 +134,7 @@ impl Cell {
|
||||||
|
|
||||||
cx.spawn_in(window, |this, mut cx| async move {
|
cx.spawn_in(window, |this, mut cx| async move {
|
||||||
let parsed_markdown = cx
|
let parsed_markdown = cx
|
||||||
.background_executor()
|
.background_spawn(async move {
|
||||||
.spawn(async move {
|
|
||||||
parse_markdown(&source, None, Some(languages)).await
|
parse_markdown(&source, None, Some(languages)).await
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
|
@ -19,9 +19,8 @@ impl MarkdownView {
|
||||||
pub fn from(text: String, cx: &mut Context<Self>) -> Self {
|
pub fn from(text: String, cx: &mut Context<Self>) -> Self {
|
||||||
let task = cx.spawn(|markdown_view, mut cx| {
|
let task = cx.spawn(|markdown_view, mut cx| {
|
||||||
let text = text.clone();
|
let text = text.clone();
|
||||||
let parsed = cx
|
let parsed =
|
||||||
.background_executor()
|
cx.background_spawn(async move { parse_markdown(&text, None, None).await });
|
||||||
.spawn(async move { parse_markdown(&text, None, None).await });
|
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
let content = parsed.await;
|
let content = parsed.await;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue