Skip to content

Commit 3ea30a7

Browse files
P1n3appl3cole-millerConradIrwin
authored andcommitted
Parse env vars and args from debug launch editor (zed-industries#30538)
Release Notes: - debugger: allow setting env vars and arguments on the launch command. --------- Co-authored-by: Cole Miller <m@cole-miller.net> Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
1 parent a4f6fa9 commit 3ea30a7

File tree

11 files changed

+53
-13
lines changed

11 files changed

+53
-13
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/dap_adapters/src/codelldb.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ impl CodeLldbDebugAdapter {
4242
if !launch.args.is_empty() {
4343
map.insert("args".into(), launch.args.clone().into());
4444
}
45-
45+
if !launch.env.is_empty() {
46+
map.insert("env".into(), launch.env_json());
47+
}
4648
if let Some(stop_on_entry) = config.stop_on_entry {
4749
map.insert("stopOnEntry".into(), stop_on_entry.into());
4850
}

crates/dap_adapters/src/gdb.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ impl GdbDebugAdapter {
3535
map.insert("args".into(), launch.args.clone().into());
3636
}
3737

38+
if !launch.env.is_empty() {
39+
map.insert("env".into(), launch.env_json());
40+
}
41+
3842
if let Some(stop_on_entry) = config.stop_on_entry {
3943
map.insert(
4044
"stopAtBeginningOfMainSubprogram".into(),

crates/dap_adapters/src/go.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ impl GoDebugAdapter {
1919
dap::DebugRequest::Launch(launch_config) => json!({
2020
"program": launch_config.program,
2121
"cwd": launch_config.cwd,
22-
"args": launch_config.args
22+
"args": launch_config.args,
23+
"env": launch_config.env_json()
2324
}),
2425
};
2526

crates/dap_adapters/src/javascript.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ impl JsDebugAdapter {
3636
if !launch.args.is_empty() {
3737
map.insert("args".into(), launch.args.clone().into());
3838
}
39+
if !launch.env.is_empty() {
40+
map.insert("env".into(), launch.env_json());
41+
}
3942

4043
if let Some(stop_on_entry) = config.stop_on_entry {
4144
map.insert("stopOnEntry".into(), stop_on_entry.into());

crates/dap_adapters/src/php.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ impl PhpDebugAdapter {
2929
"program": launch_config.program,
3030
"cwd": launch_config.cwd,
3131
"args": launch_config.args,
32+
"env": launch_config.env_json(),
3233
"stopOnEntry": config.stop_on_entry.unwrap_or_default(),
3334
}),
3435
request: config.request.to_dap(),

crates/dap_adapters/src/python.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ impl PythonDebugAdapter {
3232
DebugRequest::Launch(launch) => {
3333
map.insert("program".into(), launch.program.clone().into());
3434
map.insert("args".into(), launch.args.clone().into());
35+
if !launch.env.is_empty() {
36+
map.insert("env".into(), launch.env_json());
37+
}
3538

3639
if let Some(stop_on_entry) = config.stop_on_entry {
3740
map.insert("stopOnEntry".into(), stop_on_entry.into());

crates/dap_adapters/src/ruby.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl DebugAdapter for RubyDebugAdapter {
6262
let tcp_connection = definition.tcp_connection.clone().unwrap_or_default();
6363
let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
6464

65-
let DebugRequest::Launch(mut launch) = definition.request.clone() else {
65+
let DebugRequest::Launch(launch) = definition.request.clone() else {
6666
anyhow::bail!("rdbg does not yet support attaching");
6767
};
6868

@@ -71,12 +71,6 @@ impl DebugAdapter for RubyDebugAdapter {
7171
format!("--port={}", port),
7272
format!("--host={}", host),
7373
];
74-
if launch.args.is_empty() {
75-
let program = launch.program.clone();
76-
let mut split = program.split(" ");
77-
launch.program = split.next().unwrap().to_string();
78-
launch.args = split.map(|s| s.to_string()).collect();
79-
}
8074
if delegate.which(launch.program.as_ref()).is_some() {
8175
arguments.push("--command".to_string())
8276
}

crates/debugger_ui/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ rpc.workspace = true
5151
serde.workspace = true
5252
serde_json.workspace = true
5353
settings.workspace = true
54+
shlex.workspace = true
5455
sysinfo.workspace = true
5556
task.workspace = true
5657
tasks_ui.workspace = true

crates/debugger_ui/src/new_session_modal.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use collections::FxHashMap;
12
use std::{
23
borrow::Cow,
34
ops::Not,
@@ -595,7 +596,7 @@ impl CustomMode {
595596

596597
let program = cx.new(|cx| Editor::single_line(window, cx));
597598
program.update(cx, |this, cx| {
598-
this.set_placeholder_text("Program path", cx);
599+
this.set_placeholder_text("Run", cx);
599600

600601
if let Some(past_program) = past_program {
601602
this.set_text(past_program, window, cx);
@@ -617,11 +618,29 @@ impl CustomMode {
617618

618619
pub(super) fn debug_request(&self, cx: &App) -> task::LaunchRequest {
619620
let path = self.cwd.read(cx).text(cx);
621+
let command = self.program.read(cx).text(cx);
622+
let mut args = shlex::split(&command).into_iter().flatten().peekable();
623+
let mut env = FxHashMap::default();
624+
while args.peek().is_some_and(|arg| arg.contains('=')) {
625+
let arg = args.next().unwrap();
626+
let (lhs, rhs) = arg.split_once('=').unwrap();
627+
env.insert(lhs.to_string(), rhs.to_string());
628+
}
629+
630+
let program = if let Some(program) = args.next() {
631+
program
632+
} else {
633+
env = FxHashMap::default();
634+
command
635+
};
636+
637+
let args = args.collect::<Vec<_>>();
638+
620639
task::LaunchRequest {
621-
program: self.program.read(cx).text(cx),
640+
program,
622641
cwd: path.is_empty().not().then(|| PathBuf::from(path)),
623-
args: Default::default(),
624-
env: Default::default(),
642+
args,
643+
env,
625644
}
626645
}
627646

crates/task/src/debug_format.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ pub struct LaunchRequest {
9393
pub env: FxHashMap<String, String>,
9494
}
9595

96+
impl LaunchRequest {
97+
pub fn env_json(&self) -> serde_json::Value {
98+
serde_json::Value::Object(
99+
self.env
100+
.iter()
101+
.map(|(k, v)| (k.clone(), v.to_owned().into()))
102+
.collect::<serde_json::Map<String, serde_json::Value>>(),
103+
)
104+
}
105+
}
106+
96107
/// Represents the type that will determine which request to call on the debug adapter
97108
#[derive(Deserialize, Serialize, PartialEq, Eq, JsonSchema, Clone, Debug)]
98109
#[serde(rename_all = "lowercase", untagged)]

0 commit comments

Comments
 (0)