debugger: Do not include Rust in default value for sourceLanguages
(CodeLLDB config) (#33670)
- **debugger: Update exception breakpoints list on capability update** - **Do not prefill codelldb sourcelanguages by default** Release Notes: - debugger: CodeLLDB no longer enables pretty-printers for Rust by default. This fixes pretty-printers for C++. This is a breaking change for user-defined debug scenarios from debug.json; in order to enable Rust pretty printing when using CodeLLDB, add `"sourceLanguages": ["rust"]` to your debug configuration. This change does not affect scenarios automatically inferred by Zed. --------- Co-authored-by: Anthony Eid <anthony@zed.dev>
This commit is contained in:
parent
bff5d85ff4
commit
2caa19214b
6 changed files with 90 additions and 21 deletions
|
@ -22,17 +22,16 @@ impl CodeLldbDebugAdapter {
|
||||||
async fn request_args(
|
async fn request_args(
|
||||||
&self,
|
&self,
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
task_definition: &DebugTaskDefinition,
|
mut configuration: Value,
|
||||||
|
label: &str,
|
||||||
) -> Result<dap::StartDebuggingRequestArguments> {
|
) -> Result<dap::StartDebuggingRequestArguments> {
|
||||||
// CodeLLDB uses `name` for a terminal label.
|
|
||||||
let mut configuration = task_definition.config.clone();
|
|
||||||
|
|
||||||
let obj = configuration
|
let obj = configuration
|
||||||
.as_object_mut()
|
.as_object_mut()
|
||||||
.context("CodeLLDB is not a valid json object")?;
|
.context("CodeLLDB is not a valid json object")?;
|
||||||
|
|
||||||
|
// CodeLLDB uses `name` for a terminal label.
|
||||||
obj.entry("name")
|
obj.entry("name")
|
||||||
.or_insert(Value::String(String::from(task_definition.label.as_ref())));
|
.or_insert(Value::String(String::from(label)));
|
||||||
|
|
||||||
obj.entry("cwd")
|
obj.entry("cwd")
|
||||||
.or_insert(delegate.worktree_root_path().to_string_lossy().into());
|
.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();
|
self.path_to_codelldb.set(path.clone()).ok();
|
||||||
command = Some(path);
|
command = Some(path);
|
||||||
};
|
};
|
||||||
|
let mut json_config = config.config.clone();
|
||||||
Ok(DebugAdapterBinary {
|
Ok(DebugAdapterBinary {
|
||||||
command: Some(command.unwrap()),
|
command: Some(command.unwrap()),
|
||||||
cwd: Some(delegate.worktree_root_path().to_path_buf()),
|
cwd: Some(delegate.worktree_root_path().to_path_buf()),
|
||||||
arguments: user_args.unwrap_or_else(|| {
|
arguments: user_args.unwrap_or_else(|| {
|
||||||
vec![
|
if let Some(config) = json_config.as_object_mut()
|
||||||
"--settings".into(),
|
&& let Some(source_languages) = config.get("sourceLanguages").filter(|value| {
|
||||||
json!({"sourceLanguages": ["cpp", "rust"]}).to_string(),
|
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(),
|
envs: HashMap::default(),
|
||||||
connection: None,
|
connection: None,
|
||||||
})
|
})
|
||||||
|
|
|
@ -434,9 +434,14 @@ impl LogStore {
|
||||||
|
|
||||||
fn clean_sessions(&mut self, cx: &mut Context<Self>) {
|
fn clean_sessions(&mut self, cx: &mut Context<Self>) {
|
||||||
self.projects.values_mut().for_each(|project| {
|
self.projects.values_mut().for_each(|project| {
|
||||||
project
|
let mut allowed_terminated_sessions = 10u32;
|
||||||
.debug_sessions
|
project.debug_sessions.retain(|_, session| {
|
||||||
.retain(|_, session| !session.is_terminated);
|
if !session.is_terminated {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
allowed_terminated_sessions = allowed_terminated_sessions.saturating_sub(1);
|
||||||
|
allowed_terminated_sessions > 0
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
|
|
@ -900,7 +900,7 @@ impl RunningState {
|
||||||
|
|
||||||
|
|
||||||
let config_is_valid = request_type.is_ok();
|
let config_is_valid = request_type.is_ok();
|
||||||
|
let mut extra_config = Value::Null;
|
||||||
let build_output = if let Some(build) = build {
|
let build_output = if let Some(build) = build {
|
||||||
let (task_template, locator_name) = match build {
|
let (task_template, locator_name) = match build {
|
||||||
BuildTaskDefinition::Template {
|
BuildTaskDefinition::Template {
|
||||||
|
@ -930,6 +930,7 @@ impl RunningState {
|
||||||
};
|
};
|
||||||
|
|
||||||
let locator_name = if let Some(locator_name) = locator_name {
|
let locator_name = if let Some(locator_name) = locator_name {
|
||||||
|
extra_config = config.clone();
|
||||||
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 {
|
||||||
|
@ -945,6 +946,7 @@ impl RunningState {
|
||||||
});
|
});
|
||||||
if let Ok(t) = task {
|
if let Ok(t) = task {
|
||||||
t.await.and_then(|scenario| {
|
t.await.and_then(|scenario| {
|
||||||
|
extra_config = scenario.config;
|
||||||
match scenario.build {
|
match scenario.build {
|
||||||
Some(BuildTaskDefinition::Template {
|
Some(BuildTaskDefinition::Template {
|
||||||
locator_name, ..
|
locator_name, ..
|
||||||
|
@ -1008,13 +1010,13 @@ impl RunningState {
|
||||||
if !exit_status.success() {
|
if !exit_status.success() {
|
||||||
anyhow::bail!("Build failed");
|
anyhow::bail!("Build failed");
|
||||||
}
|
}
|
||||||
Some((task.resolved.clone(), locator_name))
|
Some((task.resolved.clone(), locator_name, extra_config))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
if config_is_valid {
|
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 =
|
let locator_name =
|
||||||
locator_name.with_context(|| {
|
locator_name.with_context(|| {
|
||||||
format!("Could not find a valid locator for a build task and configure is invalid with error: {}", request_type.err()
|
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)
|
.with_context(|| anyhow!("{}: is not a valid adapter name", &adapter))?.config_from_zed_format(zed_config)
|
||||||
.await?;
|
.await?;
|
||||||
config = scenario.config;
|
config = scenario.config;
|
||||||
|
util::merge_non_null_json_value_into(extra_config, &mut config);
|
||||||
|
|
||||||
Self::substitute_variables_in_config(&mut config, &task_context);
|
Self::substitute_variables_in_config(&mut config, &task_context);
|
||||||
} else {
|
} else {
|
||||||
let Err(e) = request_type else {
|
let Err(e) = request_type else {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::{Context as _, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use dap::{DapLocator, DebugRequest, adapters::DebugAdapterName};
|
use dap::{DapLocator, DebugRequest, adapters::DebugAdapterName};
|
||||||
use gpui::SharedString;
|
use gpui::SharedString;
|
||||||
use serde_json::Value;
|
use serde_json::{Value, json};
|
||||||
use smol::{
|
use smol::{
|
||||||
io::AsyncReadExt,
|
io::AsyncReadExt,
|
||||||
process::{Command, Stdio},
|
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 {
|
Some(DebugScenario {
|
||||||
adapter: adapter.0.clone(),
|
adapter: adapter.0.clone(),
|
||||||
label: resolved_label.to_string().into(),
|
label: resolved_label.to_string().into(),
|
||||||
|
@ -83,7 +90,7 @@ impl DapLocator for CargoLocator {
|
||||||
task_template,
|
task_template,
|
||||||
locator_name: Some(self.name()),
|
locator_name: Some(self.name()),
|
||||||
}),
|
}),
|
||||||
config: serde_json::Value::Null,
|
config,
|
||||||
tcp_connection: None,
|
tcp_connection: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1479,6 +1479,28 @@ impl Session {
|
||||||
}
|
}
|
||||||
Events::Capabilities(event) => {
|
Events::Capabilities(event) => {
|
||||||
self.capabilities = self.capabilities.merge(event.capabilities);
|
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();
|
cx.notify();
|
||||||
}
|
}
|
||||||
Events::Memory(_) => {}
|
Events::Memory(_) => {}
|
||||||
|
|
|
@ -214,6 +214,8 @@ requirements.txt
|
||||||
|
|
||||||
#### Rust/C++/C
|
#### 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
|
##### Using pre-built binary
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
@ -222,7 +224,7 @@ requirements.txt
|
||||||
"label": "Debug native binary",
|
"label": "Debug native binary",
|
||||||
"program": "$ZED_WORKTREE_ROOT/build/binary",
|
"program": "$ZED_WORKTREE_ROOT/build/binary",
|
||||||
"request": "launch",
|
"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",
|
"program": "$ZED_WORKTREE_ROOT/target/debug/binary",
|
||||||
"request": "launch",
|
"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"]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue