debugger: Fix the JavaScript debug terminal scenario (#33924)

There were a couple of things preventing this from working:

- our hack to stop the node REPL from appearing broke in recent versions
of the JS DAP that started passing `--experimental-network-inspection`
by default
- we had lost the ability to create a debug terminal without specifying
a program

This PR fixes those issues. We also fixed environment variables from the
**runInTerminal** request not getting passed to the spawned program.

Release Notes:

- Debugger: Fix RunInTerminal not working for JavaScript debugger.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
This commit is contained in:
Remco Smits 2025-07-06 01:48:55 +02:00 committed by GitHub
parent 66e45818af
commit 01295aa687
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 108 additions and 73 deletions

View file

@ -149,17 +149,23 @@ impl ShellBuilder {
}
}
/// Returns the program and arguments to run this task in a shell.
pub fn build(mut self, task_command: String, task_args: &Vec<String>) -> (String, Vec<String>) {
let combined_command = task_args
.into_iter()
.fold(task_command, |mut command, arg| {
command.push(' ');
command.push_str(&self.kind.to_shell_variable(arg));
command
});
pub fn build(
mut self,
task_command: Option<String>,
task_args: &Vec<String>,
) -> (String, Vec<String>) {
if let Some(task_command) = task_command {
let combined_command = task_args
.into_iter()
.fold(task_command, |mut command, arg| {
command.push(' ');
command.push_str(&self.kind.to_shell_variable(arg));
command
});
self.args
.extend(self.kind.args_for_shell(self.interactive, combined_command));
self.args
.extend(self.kind.args_for_shell(self.interactive, combined_command));
}
(self.program, self.args)
}

View file

@ -46,7 +46,7 @@ pub struct SpawnInTerminal {
/// Human readable name of the terminal tab.
pub label: String,
/// Executable command to spawn.
pub command: String,
pub command: Option<String>,
/// Arguments to the command, potentially unsubstituted,
/// to let the shell that spawns the command to do the substitution, if needed.
pub args: Vec<String>,

View file

@ -255,7 +255,7 @@ impl TaskTemplate {
command_label
},
),
command,
command: Some(command),
args: self.args.clone(),
env,
use_new_terminal: self.use_new_terminal,
@ -635,7 +635,7 @@ mod tests {
"Human-readable label should have long substitutions trimmed"
);
assert_eq!(
spawn_in_terminal.command,
spawn_in_terminal.command.clone().unwrap(),
format!("echo test_file {long_value}"),
"Command should be substituted with variables and those should not be shortened"
);
@ -652,7 +652,7 @@ mod tests {
spawn_in_terminal.command_label,
format!(
"{} arg1 test_selected_text arg2 5678 arg3 {long_value}",
spawn_in_terminal.command
spawn_in_terminal.command.clone().unwrap()
),
"Command label args should be substituted with variables and those should not be shortened"
);
@ -711,7 +711,7 @@ mod tests {
assert_substituted_variables(&resolved_task, Vec::new());
let resolved = resolved_task.resolved;
assert_eq!(resolved.label, task.label);
assert_eq!(resolved.command, task.command);
assert_eq!(resolved.command, Some(task.command));
assert_eq!(resolved.args, task.args);
}