debugger: Mark DapLocator::create_scenario as an async function (#32680)
Paves way for locators in extensions. Release Notes: - N/A
This commit is contained in:
parent
2c491d3a66
commit
d5b8c21a75
10 changed files with 290 additions and 218 deletions
|
@ -19,11 +19,11 @@ use std::{collections::BTreeMap, sync::Arc};
|
||||||
pub trait DapLocator: Send + Sync {
|
pub trait DapLocator: Send + Sync {
|
||||||
fn name(&self) -> SharedString;
|
fn name(&self) -> SharedString;
|
||||||
/// Determines whether this locator can generate debug target for given task.
|
/// Determines whether this locator can generate debug target for given task.
|
||||||
fn create_scenario(
|
async fn create_scenario(
|
||||||
&self,
|
&self,
|
||||||
build_config: &TaskTemplate,
|
build_config: &TaskTemplate,
|
||||||
resolved_label: &str,
|
resolved_label: &str,
|
||||||
adapter: DebugAdapterName,
|
adapter: &DebugAdapterName,
|
||||||
) -> Option<DebugScenario>;
|
) -> Option<DebugScenario>;
|
||||||
|
|
||||||
async fn run(&self, build_config: SpawnInTerminal) -> Result<DebugRequest>;
|
async fn run(&self, build_config: SpawnInTerminal) -> Result<DebugRequest>;
|
||||||
|
|
|
@ -17,7 +17,7 @@ use fuzzy::{StringMatch, StringMatchCandidate};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, App, AppContext, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable,
|
Action, App, AppContext, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable,
|
||||||
HighlightStyle, InteractiveText, KeyContext, PromptButton, PromptLevel, Render, StyledText,
|
HighlightStyle, InteractiveText, KeyContext, PromptButton, PromptLevel, Render, StyledText,
|
||||||
Subscription, TextStyle, UnderlineStyle, WeakEntity,
|
Subscription, Task, TextStyle, UnderlineStyle, WeakEntity,
|
||||||
};
|
};
|
||||||
use itertools::Itertools as _;
|
use itertools::Itertools as _;
|
||||||
use picker::{Picker, PickerDelegate, highlighted_match_with_paths::HighlightedMatch};
|
use picker::{Picker, PickerDelegate, highlighted_match_with_paths::HighlightedMatch};
|
||||||
|
@ -201,20 +201,24 @@ impl NewProcessModal {
|
||||||
})?
|
})?
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
debug_picker
|
if let Ok(task) = debug_picker.update(cx, |picker, cx| {
|
||||||
.update_in(cx, |picker, window, cx| {
|
picker.delegate.tasks_loaded(
|
||||||
picker.delegate.tasks_loaded(
|
task_contexts.clone(),
|
||||||
task_contexts.clone(),
|
languages,
|
||||||
languages,
|
lsp_tasks.clone(),
|
||||||
lsp_tasks.clone(),
|
current_resolved_tasks.clone(),
|
||||||
current_resolved_tasks.clone(),
|
add_current_language_tasks,
|
||||||
add_current_language_tasks,
|
cx,
|
||||||
cx,
|
)
|
||||||
);
|
}) {
|
||||||
picker.refresh(window, cx);
|
task.await;
|
||||||
cx.notify();
|
debug_picker
|
||||||
})
|
.update_in(cx, |picker, window, cx| {
|
||||||
.ok();
|
picker.refresh(window, cx);
|
||||||
|
cx.notify();
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(active_cwd) = task_contexts
|
if let Some(active_cwd) = task_contexts
|
||||||
.active_context()
|
.active_context()
|
||||||
|
@ -1143,61 +1147,67 @@ impl DebugDelegate {
|
||||||
current_resolved_tasks: Vec<(TaskSourceKind, task::ResolvedTask)>,
|
current_resolved_tasks: Vec<(TaskSourceKind, task::ResolvedTask)>,
|
||||||
add_current_language_tasks: bool,
|
add_current_language_tasks: bool,
|
||||||
cx: &mut Context<Picker<Self>>,
|
cx: &mut Context<Picker<Self>>,
|
||||||
) {
|
) -> Task<()> {
|
||||||
self.task_contexts = Some(task_contexts.clone());
|
self.task_contexts = Some(task_contexts.clone());
|
||||||
|
let task = self.task_store.update(cx, |task_store, cx| {
|
||||||
let (recent, scenarios) = self
|
task_store.task_inventory().map(|inventory| {
|
||||||
.task_store
|
inventory.update(cx, |inventory, cx| {
|
||||||
.update(cx, |task_store, cx| {
|
inventory.list_debug_scenarios(
|
||||||
task_store.task_inventory().map(|inventory| {
|
&task_contexts,
|
||||||
inventory.update(cx, |inventory, cx| {
|
lsp_tasks,
|
||||||
inventory.list_debug_scenarios(
|
current_resolved_tasks,
|
||||||
&task_contexts,
|
add_current_language_tasks,
|
||||||
lsp_tasks,
|
cx,
|
||||||
current_resolved_tasks,
|
)
|
||||||
add_current_language_tasks,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
if !recent.is_empty() {
|
|
||||||
self.last_used_candidate_index = Some(recent.len() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let dap_registry = cx.global::<DapRegistry>();
|
|
||||||
let hide_vscode = scenarios.iter().any(|(kind, _)| match kind {
|
|
||||||
TaskSourceKind::Worktree {
|
|
||||||
id: _,
|
|
||||||
directory_in_worktree: dir,
|
|
||||||
id_base: _,
|
|
||||||
} => dir.ends_with(".zed"),
|
|
||||||
_ => false,
|
|
||||||
});
|
});
|
||||||
|
cx.spawn(async move |this, cx| {
|
||||||
|
let (recent, scenarios) = if let Some(task) = task {
|
||||||
|
task.await
|
||||||
|
} else {
|
||||||
|
(Vec::new(), Vec::new())
|
||||||
|
};
|
||||||
|
|
||||||
self.candidates = recent
|
this.update(cx, |this, cx| {
|
||||||
.into_iter()
|
if !recent.is_empty() {
|
||||||
.map(|scenario| Self::get_scenario_kind(&languages, &dap_registry, scenario))
|
this.delegate.last_used_candidate_index = Some(recent.len() - 1);
|
||||||
.chain(
|
}
|
||||||
scenarios
|
|
||||||
|
let dap_registry = cx.global::<DapRegistry>();
|
||||||
|
let hide_vscode = scenarios.iter().any(|(kind, _)| match kind {
|
||||||
|
TaskSourceKind::Worktree {
|
||||||
|
id: _,
|
||||||
|
directory_in_worktree: dir,
|
||||||
|
id_base: _,
|
||||||
|
} => dir.ends_with(".zed"),
|
||||||
|
_ => false,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.delegate.candidates = recent
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(kind, _)| match kind {
|
.map(|scenario| Self::get_scenario_kind(&languages, &dap_registry, scenario))
|
||||||
TaskSourceKind::Worktree {
|
.chain(
|
||||||
id: _,
|
scenarios
|
||||||
directory_in_worktree: dir,
|
.into_iter()
|
||||||
id_base: _,
|
.filter(|(kind, _)| match kind {
|
||||||
} => !(hide_vscode && dir.ends_with(".vscode")),
|
TaskSourceKind::Worktree {
|
||||||
_ => true,
|
id: _,
|
||||||
})
|
directory_in_worktree: dir,
|
||||||
.map(|(kind, scenario)| {
|
id_base: _,
|
||||||
let (language, scenario) =
|
} => !(hide_vscode && dir.ends_with(".vscode")),
|
||||||
Self::get_scenario_kind(&languages, &dap_registry, scenario);
|
_ => true,
|
||||||
(language.or(Some(kind)), scenario)
|
})
|
||||||
}),
|
.map(|(kind, scenario)| {
|
||||||
)
|
let (language, scenario) =
|
||||||
.collect();
|
Self::get_scenario_kind(&languages, &dap_registry, scenario);
|
||||||
|
(language.or(Some(kind)), scenario)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.collect();
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1355,24 +1365,44 @@ impl PickerDelegate for DebugDelegate {
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(debug_scenario) = cx
|
let locators = cx.global::<DapRegistry>().locators();
|
||||||
.global::<DapRegistry>()
|
cx.spawn_in(window, async move |this, cx| {
|
||||||
.locators()
|
let Some(debug_scenario) = cx
|
||||||
.iter()
|
.background_spawn(async move {
|
||||||
.find_map(|locator| locator.1.create_scenario(&task, "one-off", adapter.clone()))
|
for locator in locators {
|
||||||
else {
|
if let Some(scenario) =
|
||||||
return;
|
locator.1.create_scenario(&task, "one-off", &adapter).await
|
||||||
};
|
{
|
||||||
|
return Some(scenario);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
send_telemetry(&debug_scenario, TelemetrySpawnLocation::ScenarioList, cx);
|
this.update_in(cx, |this, window, cx| {
|
||||||
|
send_telemetry(&debug_scenario, TelemetrySpawnLocation::ScenarioList, cx);
|
||||||
self.debug_panel
|
this.delegate
|
||||||
.update(cx, |panel, cx| {
|
.debug_panel
|
||||||
panel.start_session(debug_scenario, task_context, None, worktree_id, window, cx);
|
.update(cx, |panel, cx| {
|
||||||
|
panel.start_session(
|
||||||
|
debug_scenario,
|
||||||
|
task_context,
|
||||||
|
None,
|
||||||
|
worktree_id,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
cx.emit(DismissEvent);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
})
|
||||||
cx.emit(DismissEvent);
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm(&mut self, _: bool, window: &mut Window, cx: &mut Context<picker::Picker<Self>>) {
|
fn confirm(&mut self, _: bool, window: &mut Window, cx: &mut Context<picker::Picker<Self>>) {
|
||||||
|
|
|
@ -855,7 +855,7 @@ impl RunningState {
|
||||||
debug_assert!(!config_is_valid);
|
debug_assert!(!config_is_valid);
|
||||||
Some(locator_name)
|
Some(locator_name)
|
||||||
} else if !config_is_valid {
|
} else if !config_is_valid {
|
||||||
dap_store
|
let task = dap_store
|
||||||
.update(cx, |this, cx| {
|
.update(cx, |this, cx| {
|
||||||
this.debug_scenario_for_build_task(
|
this.debug_scenario_for_build_task(
|
||||||
task.original_task().clone(),
|
task.original_task().clone(),
|
||||||
|
@ -863,17 +863,21 @@ impl RunningState {
|
||||||
task.display_label().to_owned().into(),
|
task.display_label().to_owned().into(),
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
.and_then(|scenario| {
|
|
||||||
match scenario.build {
|
});
|
||||||
Some(BuildTaskDefinition::Template {
|
if let Ok(t) = task {
|
||||||
locator_name, ..
|
t.await.and_then(|scenario| {
|
||||||
}) => locator_name,
|
match scenario.build {
|
||||||
_ => None,
|
Some(BuildTaskDefinition::Template {
|
||||||
}
|
locator_name, ..
|
||||||
})
|
}) => locator_name,
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.ok()
|
} else {
|
||||||
.flatten()
|
None
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
|
@ -5801,9 +5801,11 @@ impl Editor {
|
||||||
tasks.column,
|
tasks.column,
|
||||||
)),
|
)),
|
||||||
});
|
});
|
||||||
let debug_scenarios = editor.update(cx, |editor, cx| {
|
let debug_scenarios = editor
|
||||||
editor.debug_scenarios(&resolved_tasks, &buffer, cx)
|
.update(cx, |editor, cx| {
|
||||||
})?;
|
editor.debug_scenarios(&resolved_tasks, &buffer, cx)
|
||||||
|
})?
|
||||||
|
.await;
|
||||||
anyhow::Ok((resolved_tasks, debug_scenarios, task_context))
|
anyhow::Ok((resolved_tasks, debug_scenarios, task_context))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -5859,7 +5861,7 @@ impl Editor {
|
||||||
resolved_tasks: &Option<ResolvedTasks>,
|
resolved_tasks: &Option<ResolvedTasks>,
|
||||||
buffer: &Entity<Buffer>,
|
buffer: &Entity<Buffer>,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Vec<task::DebugScenario> {
|
) -> Task<Vec<task::DebugScenario>> {
|
||||||
if cx.has_flag::<DebuggerFeatureFlag>() {
|
if cx.has_flag::<DebuggerFeatureFlag>() {
|
||||||
maybe!({
|
maybe!({
|
||||||
let project = self.project.as_ref()?;
|
let project = self.project.as_ref()?;
|
||||||
|
@ -5877,21 +5879,27 @@ impl Editor {
|
||||||
|
|
||||||
dap_store.update(cx, |dap_store, cx| {
|
dap_store.update(cx, |dap_store, cx| {
|
||||||
for (_, task) in &resolved_tasks.templates {
|
for (_, task) in &resolved_tasks.templates {
|
||||||
if let Some(scenario) = dap_store.debug_scenario_for_build_task(
|
let maybe_scenario = dap_store.debug_scenario_for_build_task(
|
||||||
task.original_task().clone(),
|
task.original_task().clone(),
|
||||||
debug_adapter.clone().into(),
|
debug_adapter.clone().into(),
|
||||||
task.display_label().to_owned().into(),
|
task.display_label().to_owned().into(),
|
||||||
cx,
|
cx,
|
||||||
) {
|
);
|
||||||
scenarios.push(scenario);
|
scenarios.push(maybe_scenario);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Some(scenarios)
|
Some(cx.background_spawn(async move {
|
||||||
|
let scenarios = futures::future::join_all(scenarios)
|
||||||
|
.await
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
scenarios
|
||||||
|
}))
|
||||||
})
|
})
|
||||||
.unwrap_or_default()
|
.unwrap_or_else(|| Task::ready(vec![]))
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
Task::ready(vec![])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -287,11 +287,17 @@ impl DapStore {
|
||||||
adapter: DebugAdapterName,
|
adapter: DebugAdapterName,
|
||||||
label: SharedString,
|
label: SharedString,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Option<DebugScenario> {
|
) -> Task<Option<DebugScenario>> {
|
||||||
DapRegistry::global(cx)
|
let locators = DapRegistry::global(cx).locators();
|
||||||
.locators()
|
|
||||||
.values()
|
cx.background_spawn(async move {
|
||||||
.find_map(|locator| locator.create_scenario(&build, &label, adapter.clone()))
|
for locator in locators.values() {
|
||||||
|
if let Some(scenario) = locator.create_scenario(&build, &label, &adapter).await {
|
||||||
|
return Some(scenario);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_debug_locator(
|
pub fn run_debug_locator(
|
||||||
|
|
|
@ -41,11 +41,11 @@ impl DapLocator for CargoLocator {
|
||||||
fn name(&self) -> SharedString {
|
fn name(&self) -> SharedString {
|
||||||
SharedString::new_static("rust-cargo-locator")
|
SharedString::new_static("rust-cargo-locator")
|
||||||
}
|
}
|
||||||
fn create_scenario(
|
async fn create_scenario(
|
||||||
&self,
|
&self,
|
||||||
build_config: &TaskTemplate,
|
build_config: &TaskTemplate,
|
||||||
resolved_label: &str,
|
resolved_label: &str,
|
||||||
adapter: DebugAdapterName,
|
adapter: &DebugAdapterName,
|
||||||
) -> Option<DebugScenario> {
|
) -> Option<DebugScenario> {
|
||||||
if build_config.command != "cargo" {
|
if build_config.command != "cargo" {
|
||||||
return None;
|
return None;
|
||||||
|
@ -77,7 +77,7 @@ impl DapLocator for CargoLocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(DebugScenario {
|
Some(DebugScenario {
|
||||||
adapter: adapter.0,
|
adapter: adapter.0.clone(),
|
||||||
label: resolved_label.to_string().into(),
|
label: resolved_label.to_string().into(),
|
||||||
build: Some(BuildTaskDefinition::Template {
|
build: Some(BuildTaskDefinition::Template {
|
||||||
task_template,
|
task_template,
|
||||||
|
|
|
@ -89,11 +89,11 @@ impl DapLocator for GoLocator {
|
||||||
SharedString::new_static("go-debug-locator")
|
SharedString::new_static("go-debug-locator")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_scenario(
|
async fn create_scenario(
|
||||||
&self,
|
&self,
|
||||||
build_config: &TaskTemplate,
|
build_config: &TaskTemplate,
|
||||||
resolved_label: &str,
|
resolved_label: &str,
|
||||||
adapter: DebugAdapterName,
|
adapter: &DebugAdapterName,
|
||||||
) -> Option<DebugScenario> {
|
) -> Option<DebugScenario> {
|
||||||
if build_config.command != "go" {
|
if build_config.command != "go" {
|
||||||
return None;
|
return None;
|
||||||
|
@ -170,7 +170,7 @@ impl DapLocator for GoLocator {
|
||||||
|
|
||||||
Some(DebugScenario {
|
Some(DebugScenario {
|
||||||
label: resolved_label.to_string().into(),
|
label: resolved_label.to_string().into(),
|
||||||
adapter: adapter.0,
|
adapter: adapter.0.clone(),
|
||||||
build: None,
|
build: None,
|
||||||
config: config,
|
config: config,
|
||||||
tcp_connection: None,
|
tcp_connection: None,
|
||||||
|
@ -214,7 +214,7 @@ impl DapLocator for GoLocator {
|
||||||
|
|
||||||
Some(DebugScenario {
|
Some(DebugScenario {
|
||||||
label: resolved_label.to_string().into(),
|
label: resolved_label.to_string().into(),
|
||||||
adapter: adapter.0,
|
adapter: adapter.0.clone(),
|
||||||
build: None,
|
build: None,
|
||||||
config,
|
config,
|
||||||
tcp_connection: None,
|
tcp_connection: None,
|
||||||
|
@ -232,10 +232,11 @@ impl DapLocator for GoLocator {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use gpui::TestAppContext;
|
||||||
use task::{HideStrategy, RevealStrategy, RevealTarget, Shell, TaskTemplate};
|
use task::{HideStrategy, RevealStrategy, RevealTarget, Shell, TaskTemplate};
|
||||||
|
|
||||||
#[test]
|
#[gpui::test]
|
||||||
fn test_create_scenario_for_go_build() {
|
async fn test_create_scenario_for_go_build(_: &mut TestAppContext) {
|
||||||
let locator = GoLocator;
|
let locator = GoLocator;
|
||||||
let task = TaskTemplate {
|
let task = TaskTemplate {
|
||||||
label: "go build".into(),
|
label: "go build".into(),
|
||||||
|
@ -254,14 +255,15 @@ mod tests {
|
||||||
show_command: true,
|
show_command: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let scenario =
|
let scenario = locator
|
||||||
locator.create_scenario(&task, "test label", DebugAdapterName("Delve".into()));
|
.create_scenario(&task, "test label", &DebugAdapterName("Delve".into()))
|
||||||
|
.await;
|
||||||
|
|
||||||
assert!(scenario.is_none());
|
assert!(scenario.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[gpui::test]
|
||||||
fn test_skip_non_go_commands_with_non_delve_adapter() {
|
async fn test_skip_non_go_commands_with_non_delve_adapter(_: &mut TestAppContext) {
|
||||||
let locator = GoLocator;
|
let locator = GoLocator;
|
||||||
let task = TaskTemplate {
|
let task = TaskTemplate {
|
||||||
label: "cargo build".into(),
|
label: "cargo build".into(),
|
||||||
|
@ -280,19 +282,22 @@ mod tests {
|
||||||
show_command: true,
|
show_command: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let scenario = locator.create_scenario(
|
let scenario = locator
|
||||||
&task,
|
.create_scenario(
|
||||||
"test label",
|
&task,
|
||||||
DebugAdapterName("SomeOtherAdapter".into()),
|
"test label",
|
||||||
);
|
&DebugAdapterName("SomeOtherAdapter".into()),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert!(scenario.is_none());
|
assert!(scenario.is_none());
|
||||||
|
|
||||||
let scenario =
|
let scenario = locator
|
||||||
locator.create_scenario(&task, "test label", DebugAdapterName("Delve".into()));
|
.create_scenario(&task, "test label", &DebugAdapterName("Delve".into()))
|
||||||
|
.await;
|
||||||
assert!(scenario.is_none());
|
assert!(scenario.is_none());
|
||||||
}
|
}
|
||||||
#[test]
|
#[gpui::test]
|
||||||
fn test_go_locator_run() {
|
async fn test_go_locator_run(_: &mut TestAppContext) {
|
||||||
let locator = GoLocator;
|
let locator = GoLocator;
|
||||||
let delve = DebugAdapterName("Delve".into());
|
let delve = DebugAdapterName("Delve".into());
|
||||||
|
|
||||||
|
@ -319,7 +324,8 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
let scenario = locator
|
let scenario = locator
|
||||||
.create_scenario(&task, "test run label", delve)
|
.create_scenario(&task, "test run label", &delve)
|
||||||
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let config: DelveLaunchRequest = serde_json::from_value(scenario.config).unwrap();
|
let config: DelveLaunchRequest = serde_json::from_value(scenario.config).unwrap();
|
||||||
|
@ -350,8 +356,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[gpui::test]
|
||||||
fn test_go_locator_test() {
|
async fn test_go_locator_test(_: &mut TestAppContext) {
|
||||||
let locator = GoLocator;
|
let locator = GoLocator;
|
||||||
let delve = DebugAdapterName("Delve".into());
|
let delve = DebugAdapterName("Delve".into());
|
||||||
|
|
||||||
|
@ -370,7 +376,8 @@ mod tests {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let result = locator
|
let result = locator
|
||||||
.create_scenario(&task_with_tags, "", delve.clone())
|
.create_scenario(&task_with_tags, "", &delve)
|
||||||
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let config: DelveLaunchRequest = serde_json::from_value(result.config).unwrap();
|
let config: DelveLaunchRequest = serde_json::from_value(result.config).unwrap();
|
||||||
|
@ -393,8 +400,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[gpui::test]
|
||||||
fn test_skip_unsupported_go_commands() {
|
async fn test_skip_unsupported_go_commands(_: &mut TestAppContext) {
|
||||||
let locator = GoLocator;
|
let locator = GoLocator;
|
||||||
let task = TaskTemplate {
|
let task = TaskTemplate {
|
||||||
label: "go clean".into(),
|
label: "go clean".into(),
|
||||||
|
@ -413,8 +420,9 @@ mod tests {
|
||||||
show_command: true,
|
show_command: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let scenario =
|
let scenario = locator
|
||||||
locator.create_scenario(&task, "test label", DebugAdapterName("Delve".into()));
|
.create_scenario(&task, "test label", &DebugAdapterName("Delve".into()))
|
||||||
|
.await;
|
||||||
assert!(scenario.is_none());
|
assert!(scenario.is_none());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,11 @@ impl DapLocator for NodeLocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether this locator can generate debug target for given task.
|
/// Determines whether this locator can generate debug target for given task.
|
||||||
fn create_scenario(
|
async fn create_scenario(
|
||||||
&self,
|
&self,
|
||||||
build_config: &TaskTemplate,
|
build_config: &TaskTemplate,
|
||||||
resolved_label: &str,
|
resolved_label: &str,
|
||||||
adapter: DebugAdapterName,
|
adapter: &DebugAdapterName,
|
||||||
) -> Option<DebugScenario> {
|
) -> Option<DebugScenario> {
|
||||||
if adapter.0.as_ref() != "JavaScript" {
|
if adapter.0.as_ref() != "JavaScript" {
|
||||||
return None;
|
return None;
|
||||||
|
@ -68,7 +68,7 @@ impl DapLocator for NodeLocator {
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(DebugScenario {
|
Some(DebugScenario {
|
||||||
adapter: adapter.0,
|
adapter: adapter.0.clone(),
|
||||||
label: resolved_label.to_string().into(),
|
label: resolved_label.to_string().into(),
|
||||||
build: None,
|
build: None,
|
||||||
config,
|
config,
|
||||||
|
|
|
@ -16,11 +16,11 @@ impl DapLocator for PythonLocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether this locator can generate debug target for given task.
|
/// Determines whether this locator can generate debug target for given task.
|
||||||
fn create_scenario(
|
async fn create_scenario(
|
||||||
&self,
|
&self,
|
||||||
build_config: &TaskTemplate,
|
build_config: &TaskTemplate,
|
||||||
resolved_label: &str,
|
resolved_label: &str,
|
||||||
adapter: DebugAdapterName,
|
adapter: &DebugAdapterName,
|
||||||
) -> Option<DebugScenario> {
|
) -> Option<DebugScenario> {
|
||||||
if adapter.0.as_ref() != "Debugpy" {
|
if adapter.0.as_ref() != "Debugpy" {
|
||||||
return None;
|
return None;
|
||||||
|
@ -92,7 +92,7 @@ impl DapLocator for PythonLocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(DebugScenario {
|
Some(DebugScenario {
|
||||||
adapter: adapter.0,
|
adapter: adapter.0.clone(),
|
||||||
label: resolved_label.to_string().into(),
|
label: resolved_label.to_string().into(),
|
||||||
build: None,
|
build: None,
|
||||||
config,
|
config,
|
||||||
|
|
|
@ -265,7 +265,7 @@ impl Inventory {
|
||||||
current_resolved_tasks: Vec<(TaskSourceKind, task::ResolvedTask)>,
|
current_resolved_tasks: Vec<(TaskSourceKind, task::ResolvedTask)>,
|
||||||
add_current_language_tasks: bool,
|
add_current_language_tasks: bool,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> (Vec<DebugScenario>, Vec<(TaskSourceKind, DebugScenario)>) {
|
) -> Task<(Vec<DebugScenario>, Vec<(TaskSourceKind, DebugScenario)>)> {
|
||||||
let mut scenarios = Vec::new();
|
let mut scenarios = Vec::new();
|
||||||
|
|
||||||
if let Some(worktree_id) = task_contexts
|
if let Some(worktree_id) = task_contexts
|
||||||
|
@ -279,9 +279,13 @@ impl Inventory {
|
||||||
}
|
}
|
||||||
scenarios.extend(self.global_debug_scenarios_from_settings());
|
scenarios.extend(self.global_debug_scenarios_from_settings());
|
||||||
|
|
||||||
if let Some(location) = task_contexts.location() {
|
let last_scheduled_scenarios = self.last_scheduled_scenarios.iter().cloned().collect();
|
||||||
let file = location.buffer.read(cx).file();
|
|
||||||
let language = location.buffer.read(cx).language();
|
let adapter = task_contexts.location().and_then(|location| {
|
||||||
|
let (file, language) = {
|
||||||
|
let buffer = location.buffer.read(cx);
|
||||||
|
(buffer.file(), buffer.language())
|
||||||
|
};
|
||||||
let language_name = language.as_ref().map(|l| l.name());
|
let language_name = language.as_ref().map(|l| l.name());
|
||||||
let adapter = language_settings(language_name, file, cx)
|
let adapter = language_settings(language_name, file, cx)
|
||||||
.debuggers
|
.debuggers
|
||||||
|
@ -290,7 +294,10 @@ impl Inventory {
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
language.and_then(|l| l.config().debuggers.first().map(SharedString::from))
|
language.and_then(|l| l.config().debuggers.first().map(SharedString::from))
|
||||||
});
|
});
|
||||||
if let Some(adapter) = adapter {
|
adapter.map(|adapter| (adapter, DapRegistry::global(cx).locators()))
|
||||||
|
});
|
||||||
|
cx.background_spawn(async move {
|
||||||
|
if let Some((adapter, locators)) = adapter {
|
||||||
for (kind, task) in
|
for (kind, task) in
|
||||||
lsp_tasks
|
lsp_tasks
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -299,28 +306,21 @@ impl Inventory {
|
||||||
|| !matches!(kind, TaskSourceKind::Language { .. })
|
|| !matches!(kind, TaskSourceKind::Language { .. })
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
if let Some(scenario) =
|
let adapter = adapter.clone().into();
|
||||||
DapRegistry::global(cx)
|
|
||||||
.locators()
|
for locator in locators.values() {
|
||||||
.values()
|
if let Some(scenario) = locator
|
||||||
.find_map(|locator| {
|
.create_scenario(&task.original_task(), &task.display_label(), &adapter)
|
||||||
locator.create_scenario(
|
.await
|
||||||
&task.original_task().clone(),
|
{
|
||||||
&task.display_label(),
|
scenarios.push((kind, scenario));
|
||||||
adapter.clone().into(),
|
break;
|
||||||
)
|
}
|
||||||
})
|
|
||||||
{
|
|
||||||
scenarios.push((kind, scenario));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
(last_scheduled_scenarios, scenarios)
|
||||||
|
})
|
||||||
(
|
|
||||||
self.last_scheduled_scenarios.iter().cloned().collect(),
|
|
||||||
scenarios,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn task_template_by_label(
|
pub fn task_template_by_label(
|
||||||
|
@ -1275,7 +1275,7 @@ mod tests {
|
||||||
init_test(cx);
|
init_test(cx);
|
||||||
let fs = FakeFs::new(cx.executor());
|
let fs = FakeFs::new(cx.executor());
|
||||||
let inventory = cx.update(|cx| Inventory::new(fs, cx));
|
let inventory = cx.update(|cx| Inventory::new(fs, cx));
|
||||||
inventory.update(cx, |inventory, cx| {
|
inventory.update(cx, |inventory, _| {
|
||||||
inventory
|
inventory
|
||||||
.update_file_based_scenarios(
|
.update_file_based_scenarios(
|
||||||
TaskSettingsLocation::Global(Path::new("")),
|
TaskSettingsLocation::Global(Path::new("")),
|
||||||
|
@ -1291,31 +1291,40 @@ mod tests {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
let (_, scenario) = inventory
|
let (_, scenario) = inventory
|
||||||
.list_debug_scenarios(&TaskContexts::default(), vec![], vec![], false, cx)
|
.update(cx, |this, cx| {
|
||||||
.1
|
this.list_debug_scenarios(&TaskContexts::default(), vec![], vec![], false, cx)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.1
|
||||||
|
.first()
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
inventory.update(cx, |this, _| {
|
||||||
|
this.scenario_scheduled(scenario.clone());
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inventory
|
||||||
|
.update(cx, |this, cx| {
|
||||||
|
this.list_debug_scenarios(&TaskContexts::default(), vec![], vec![], false, cx)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.0
|
||||||
.first()
|
.first()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone(),
|
||||||
|
scenario
|
||||||
|
);
|
||||||
|
|
||||||
inventory.scenario_scheduled(scenario.clone());
|
inventory.update(cx, |this, _| {
|
||||||
|
this.update_file_based_scenarios(
|
||||||
assert_eq!(
|
TaskSettingsLocation::Global(Path::new("")),
|
||||||
inventory
|
Some(
|
||||||
.list_debug_scenarios(&TaskContexts::default(), vec![], vec![], false, cx)
|
r#"
|
||||||
.0
|
|
||||||
.first()
|
|
||||||
.unwrap()
|
|
||||||
.clone(),
|
|
||||||
scenario
|
|
||||||
);
|
|
||||||
|
|
||||||
inventory
|
|
||||||
.update_file_based_scenarios(
|
|
||||||
TaskSettingsLocation::Global(Path::new("")),
|
|
||||||
Some(
|
|
||||||
r#"
|
|
||||||
[{
|
[{
|
||||||
"label": "test scenario",
|
"label": "test scenario",
|
||||||
"adapter": "Delve",
|
"adapter": "Delve",
|
||||||
|
@ -1323,25 +1332,29 @@ mod tests {
|
||||||
"program": "wowzer",
|
"program": "wowzer",
|
||||||
}]
|
}]
|
||||||
"#,
|
"#,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
});
|
||||||
assert_eq!(
|
|
||||||
inventory
|
|
||||||
.list_debug_scenarios(&TaskContexts::default(), vec![], vec![], false, cx)
|
|
||||||
.0
|
|
||||||
.first()
|
|
||||||
.unwrap()
|
|
||||||
.adapter,
|
|
||||||
"Delve",
|
|
||||||
);
|
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
inventory
|
inventory
|
||||||
.update_file_based_scenarios(
|
.update(cx, |this, cx| {
|
||||||
TaskSettingsLocation::Global(Path::new("")),
|
this.list_debug_scenarios(&TaskContexts::default(), vec![], vec![], false, cx)
|
||||||
Some(
|
})
|
||||||
r#"
|
.await
|
||||||
|
.0
|
||||||
|
.first()
|
||||||
|
.unwrap()
|
||||||
|
.adapter,
|
||||||
|
"Delve",
|
||||||
|
);
|
||||||
|
|
||||||
|
inventory.update(cx, |this, _| {
|
||||||
|
this.update_file_based_scenarios(
|
||||||
|
TaskSettingsLocation::Global(Path::new("")),
|
||||||
|
Some(
|
||||||
|
r#"
|
||||||
[{
|
[{
|
||||||
"label": "testing scenario",
|
"label": "testing scenario",
|
||||||
"adapter": "Delve",
|
"adapter": "Delve",
|
||||||
|
@ -1349,18 +1362,21 @@ mod tests {
|
||||||
"program": "wowzer",
|
"program": "wowzer",
|
||||||
}]
|
}]
|
||||||
"#,
|
"#,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
inventory
|
|
||||||
.list_debug_scenarios(&TaskContexts::default(), vec![], vec![], false, cx)
|
|
||||||
.0
|
|
||||||
.first(),
|
|
||||||
None
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inventory
|
||||||
|
.update(cx, |this, cx| {
|
||||||
|
this.list_debug_scenarios(&TaskContexts::default(), vec![], vec![], false, cx)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.0
|
||||||
|
.first(),
|
||||||
|
None
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue