debugger: Allow users to include PickProcessId in debug tasks and resolve Pid (#42913)
Closes #33286 This PR adds support for Zed's `$ZED_PICK_PID` command in debug configurations, which allows users to select a process to attach to at debug time. When this variable is present in a debug configuration, Zed automatically opens a process picker modal. Follow up for this will be integrating this variable in the task system instead of just the debug configuration system. Release Notes: - Added `$ZED_PICK_PID` variable for debug configurations, allowing users to select which process to attach the debugger to at runtime --------- Co-authored-by: Remco Smits <djsmits12@gmail.com>
This commit is contained in:
co-authored by
Remco Smits
parent
e033829ef2
commit
56401fc99c
+24
-1
@@ -173,6 +173,9 @@ pub enum VariableName {
|
||||
SelectedText,
|
||||
/// The symbol selected by the symbol tagging system, specifically the @run capture in a runnables.scm
|
||||
RunnableSymbol,
|
||||
/// Open a Picker to select a process ID to use in place
|
||||
/// Can only be used to debug configurations
|
||||
PickProcessId,
|
||||
/// Custom variable, provided by the plugin or other external source.
|
||||
/// Will be printed with `CUSTOM_` prefix to avoid potential conflicts with other variables.
|
||||
Custom(Cow<'static, str>),
|
||||
@@ -240,6 +243,7 @@ impl std::fmt::Display for VariableName {
|
||||
Self::Column => write!(f, "{ZED_VARIABLE_NAME_PREFIX}COLUMN"),
|
||||
Self::SelectedText => write!(f, "{ZED_VARIABLE_NAME_PREFIX}SELECTED_TEXT"),
|
||||
Self::RunnableSymbol => write!(f, "{ZED_VARIABLE_NAME_PREFIX}RUNNABLE_SYMBOL"),
|
||||
Self::PickProcessId => write!(f, "{ZED_VARIABLE_NAME_PREFIX}PICK_PID"),
|
||||
Self::Custom(s) => write!(
|
||||
f,
|
||||
"{ZED_VARIABLE_NAME_PREFIX}{ZED_CUSTOM_VARIABLE_NAME_PREFIX}{s}"
|
||||
@@ -346,15 +350,28 @@ pub fn shell_to_proto(shell: Shell) -> proto::Shell {
|
||||
}
|
||||
|
||||
type VsCodeEnvVariable = String;
|
||||
type VsCodeCommand = String;
|
||||
type ZedEnvVariable = String;
|
||||
|
||||
struct EnvVariableReplacer {
|
||||
variables: HashMap<VsCodeEnvVariable, ZedEnvVariable>,
|
||||
commands: HashMap<VsCodeCommand, ZedEnvVariable>,
|
||||
}
|
||||
|
||||
impl EnvVariableReplacer {
|
||||
fn new(variables: HashMap<VsCodeEnvVariable, ZedEnvVariable>) -> Self {
|
||||
Self { variables }
|
||||
Self {
|
||||
variables,
|
||||
commands: HashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn with_commands(
|
||||
mut self,
|
||||
commands: impl IntoIterator<Item = (VsCodeCommand, ZedEnvVariable)>,
|
||||
) -> Self {
|
||||
self.commands = commands.into_iter().collect();
|
||||
self
|
||||
}
|
||||
|
||||
fn replace_value(&self, input: serde_json::Value) -> serde_json::Value {
|
||||
@@ -380,7 +397,13 @@ impl EnvVariableReplacer {
|
||||
if left == "env" && !right.is_empty() {
|
||||
let variable_name = &right[1..];
|
||||
return Some(format!("${{{variable_name}}}"));
|
||||
} else if left == "command" && !right.is_empty() {
|
||||
let command_name = &right[1..];
|
||||
if let Some(replacement_command) = self.commands.get(command_name) {
|
||||
return Some(format!("${{{replacement_command}}}"));
|
||||
}
|
||||
}
|
||||
|
||||
let (variable_name, default) = (left, right);
|
||||
let append_previous_default = |ret: &mut String| {
|
||||
if !default.is_empty() {
|
||||
|
||||
@@ -68,7 +68,11 @@ impl TryFrom<VsCodeDebugTaskFile> for DebugTaskFile {
|
||||
VariableName::RelativeFile.to_string(),
|
||||
),
|
||||
("file".to_owned(), VariableName::File.to_string()),
|
||||
]));
|
||||
]))
|
||||
.with_commands([(
|
||||
"pickMyProcess".to_owned(),
|
||||
VariableName::PickProcessId.to_string(),
|
||||
)]);
|
||||
let templates = file
|
||||
.configurations
|
||||
.into_iter()
|
||||
@@ -96,7 +100,7 @@ fn task_type_to_adapter_name(task_type: &str) -> String {
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{DebugScenario, DebugTaskFile};
|
||||
use crate::{DebugScenario, DebugTaskFile, VariableName};
|
||||
|
||||
use super::VsCodeDebugTaskFile;
|
||||
|
||||
@@ -152,4 +156,39 @@ mod tests {
|
||||
}])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_command_pickmyprocess_replacement() {
|
||||
let raw = r#"
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Attach to Process",
|
||||
"request": "attach",
|
||||
"type": "cppdbg",
|
||||
"processId": "${command:pickMyProcess}"
|
||||
}
|
||||
]
|
||||
}
|
||||
"#;
|
||||
let parsed: VsCodeDebugTaskFile =
|
||||
serde_json_lenient::from_str(raw).expect("deserializing launch.json");
|
||||
let zed = DebugTaskFile::try_from(parsed).expect("converting to Zed debug templates");
|
||||
|
||||
let expected_placeholder = format!("${{{}}}", VariableName::PickProcessId);
|
||||
pretty_assertions::assert_eq!(
|
||||
zed,
|
||||
DebugTaskFile(vec![DebugScenario {
|
||||
label: "Attach to Process".into(),
|
||||
adapter: "CodeLLDB".into(),
|
||||
config: json!({
|
||||
"request": "attach",
|
||||
"processId": expected_placeholder,
|
||||
}),
|
||||
tcp_connection: None,
|
||||
build: None
|
||||
}])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user