Detailed changes
@@ -22,17 +22,16 @@ impl CodeLldbDebugAdapter {
async fn request_args(
&self,
delegate: &Arc<dyn DapDelegate>,
- task_definition: &DebugTaskDefinition,
+ mut configuration: Value,
+ label: &str,
) -> Result<dap::StartDebuggingRequestArguments> {
- // CodeLLDB uses `name` for a terminal label.
- let mut configuration = task_definition.config.clone();
-
let obj = configuration
.as_object_mut()
.context("CodeLLDB is not a valid json object")?;
+ // CodeLLDB uses `name` for a terminal label.
obj.entry("name")
- .or_insert(Value::String(String::from(task_definition.label.as_ref())));
+ .or_insert(Value::String(String::from(label)));
obj.entry("cwd")
.or_insert(delegate.worktree_root_path().to_string_lossy().into());
@@ -361,17 +360,31 @@ impl DebugAdapter for CodeLldbDebugAdapter {
self.path_to_codelldb.set(path.clone()).ok();
command = Some(path);
};
-
+ let mut json_config = config.config.clone();
Ok(DebugAdapterBinary {
command: Some(command.unwrap()),
cwd: Some(delegate.worktree_root_path().to_path_buf()),
arguments: user_args.unwrap_or_else(|| {
- vec![
- "--settings".into(),
- json!({"sourceLanguages": ["cpp", "rust"]}).to_string(),
- ]
+ if let Some(config) = json_config.as_object_mut()
+ && let Some(source_languages) = config.get("sourceLanguages").filter(|value| {
+ value
+ .as_array()
+ .map_or(false, |array| array.iter().all(Value::is_string))
+ })
+ {
+ let ret = vec![
+ "--settings".into(),
+ json!({"sourceLanguages": source_languages}).to_string(),
+ ];
+ config.remove("sourceLanguages");
+ ret
+ } else {
+ vec![]
+ }
}),
- request_args: self.request_args(delegate, &config).await?,
+ request_args: self
+ .request_args(delegate, json_config, &config.label)
+ .await?,
envs: HashMap::default(),
connection: None,
})
@@ -434,9 +434,14 @@ impl LogStore {
fn clean_sessions(&mut self, cx: &mut Context<Self>) {
self.projects.values_mut().for_each(|project| {
- project
- .debug_sessions
- .retain(|_, session| !session.is_terminated);
+ let mut allowed_terminated_sessions = 10u32;
+ project.debug_sessions.retain(|_, session| {
+ if !session.is_terminated {
+ return true;
+ }
+ allowed_terminated_sessions = allowed_terminated_sessions.saturating_sub(1);
+ allowed_terminated_sessions > 0
+ });
});
cx.notify();
@@ -900,7 +900,7 @@ impl RunningState {
let config_is_valid = request_type.is_ok();
-
+ let mut extra_config = Value::Null;
let build_output = if let Some(build) = build {
let (task_template, locator_name) = match build {
BuildTaskDefinition::Template {
@@ -930,6 +930,7 @@ impl RunningState {
};
let locator_name = if let Some(locator_name) = locator_name {
+ extra_config = config.clone();
debug_assert!(!config_is_valid);
Some(locator_name)
} else if !config_is_valid {
@@ -945,6 +946,7 @@ impl RunningState {
});
if let Ok(t) = task {
t.await.and_then(|scenario| {
+ extra_config = scenario.config;
match scenario.build {
Some(BuildTaskDefinition::Template {
locator_name, ..
@@ -1008,13 +1010,13 @@ impl RunningState {
if !exit_status.success() {
anyhow::bail!("Build failed");
}
- Some((task.resolved.clone(), locator_name))
+ Some((task.resolved.clone(), locator_name, extra_config))
} else {
None
};
if config_is_valid {
- } else if let Some((task, locator_name)) = build_output {
+ } else if let Some((task, locator_name, extra_config)) = build_output {
let locator_name =
locator_name.with_context(|| {
format!("Could not find a valid locator for a build task and configure is invalid with error: {}", request_type.err()
@@ -1039,6 +1041,8 @@ impl RunningState {
.with_context(|| anyhow!("{}: is not a valid adapter name", &adapter))?.config_from_zed_format(zed_config)
.await?;
config = scenario.config;
+ util::merge_non_null_json_value_into(extra_config, &mut config);
+
Self::substitute_variables_in_config(&mut config, &task_context);
} else {
let Err(e) = request_type else {
@@ -2,7 +2,7 @@ use anyhow::{Context as _, Result};
use async_trait::async_trait;
use dap::{DapLocator, DebugRequest, adapters::DebugAdapterName};
use gpui::SharedString;
-use serde_json::Value;
+use serde_json::{Value, json};
use smol::{
io::AsyncReadExt,
process::{Command, Stdio},
@@ -76,6 +76,13 @@ impl DapLocator for CargoLocator {
_ => {}
}
+ let config = if adapter.as_ref() == "CodeLLDB" {
+ json!({
+ "sourceLanguages": ["rust"]
+ })
+ } else {
+ Value::Null
+ };
Some(DebugScenario {
adapter: adapter.0.clone(),
label: resolved_label.to_string().into(),
@@ -83,7 +90,7 @@ impl DapLocator for CargoLocator {
task_template,
locator_name: Some(self.name()),
}),
- config: serde_json::Value::Null,
+ config,
tcp_connection: None,
})
}
@@ -1479,6 +1479,28 @@ impl Session {
}
Events::Capabilities(event) => {
self.capabilities = self.capabilities.merge(event.capabilities);
+
+ // The adapter might've enabled new exception breakpoints (or disabled existing ones).
+ let recent_filters = self
+ .capabilities
+ .exception_breakpoint_filters
+ .iter()
+ .flatten()
+ .map(|filter| (filter.filter.clone(), filter.clone()))
+ .collect::<BTreeMap<_, _>>();
+ for filter in recent_filters.values() {
+ let default = filter.default.unwrap_or_default();
+ self.exception_breakpoints
+ .entry(filter.filter.clone())
+ .or_insert_with(|| (filter.clone(), default));
+ }
+ self.exception_breakpoints
+ .retain(|k, _| recent_filters.contains_key(k));
+ if self.is_started() {
+ self.send_exception_breakpoints(cx);
+ }
+
+ // Remove the ones that no longer exist.
cx.notify();
}
Events::Memory(_) => {}
@@ -214,6 +214,8 @@ requirements.txt
#### Rust/C++/C
+> For CodeLLDB, you might want to set `sourceLanguages` in your launch configuration based on the source code language.
+
##### Using pre-built binary
```json
@@ -222,7 +224,7 @@ requirements.txt
"label": "Debug native binary",
"program": "$ZED_WORKTREE_ROOT/build/binary",
"request": "launch",
- "adapter": "CodeLLDB" // GDB is available on non arm macs as well as linux
+ "adapter": "CodeLLDB" // GDB is available on non-ARM Macs as well as Linux
}
]
```
@@ -239,7 +241,23 @@ requirements.txt
},
"program": "$ZED_WORKTREE_ROOT/target/debug/binary",
"request": "launch",
- "adapter": "CodeLLDB" // GDB is available on non arm macs as well as linux
+ "adapter": "CodeLLDB" // GDB is available on non-ARM Macs as well as Linux
+ }
+]
+```
+
+##### Automatically locate a debug target based on build command
+
+```json
+[
+ {
+ "label": "Build & Debug native binary",
+ "adapter": "CodeLLDB" // GDB is available on non-ARM Macs as well as Linux
+ // Zed can infer the path to a debuggee based on the build command
+ "build": {
+ "command": "cargo",
+ "args": ["build"]
+ },
}
]
```