debugger: Support passing custom arguments to debug adapters (#33251)
Custom arguments replace any arguments that we normally pass to the DAP. For interpreted languages, they are passed to the interpreter after the DAP path or module. They can be combined with a custom binary, or you can omit `dap.binary` and just customize the arguments to the DAPs we download. This doesn't take care of updating the extension API to support custom arguments. Release Notes: - debugger: Implemented support for passing custom arguments to a debug adapter binary using the `dap.args` setting. - debugger: Fixed not being able to use the `dap` setting in `.zed/settings.json`.
This commit is contained in:
parent
a067c16c82
commit
c9bd409732
11 changed files with 154 additions and 54 deletions
|
@ -344,6 +344,7 @@ pub trait DebugAdapter: 'static + Send + Sync {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
config: &DebugTaskDefinition,
|
config: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<PathBuf>,
|
user_installed_path: Option<PathBuf>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
cx: &mut AsyncApp,
|
cx: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary>;
|
) -> Result<DebugAdapterBinary>;
|
||||||
|
|
||||||
|
@ -434,6 +435,7 @@ impl DebugAdapter for FakeAdapter {
|
||||||
_: &Arc<dyn DapDelegate>,
|
_: &Arc<dyn DapDelegate>,
|
||||||
task_definition: &DebugTaskDefinition,
|
task_definition: &DebugTaskDefinition,
|
||||||
_: Option<PathBuf>,
|
_: Option<PathBuf>,
|
||||||
|
_: Option<Vec<String>>,
|
||||||
_: &mut AsyncApp,
|
_: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
Ok(DebugAdapterBinary {
|
Ok(DebugAdapterBinary {
|
||||||
|
|
|
@ -329,6 +329,7 @@ impl DebugAdapter for CodeLldbDebugAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
config: &DebugTaskDefinition,
|
config: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<PathBuf>,
|
user_installed_path: Option<PathBuf>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
_: &mut AsyncApp,
|
_: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
let mut command = user_installed_path
|
let mut command = user_installed_path
|
||||||
|
@ -364,10 +365,12 @@ impl DebugAdapter for CodeLldbDebugAdapter {
|
||||||
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: vec![
|
arguments: user_args.unwrap_or_else(|| {
|
||||||
"--settings".into(),
|
vec![
|
||||||
json!({"sourceLanguages": ["cpp", "rust"]}).to_string(),
|
"--settings".into(),
|
||||||
],
|
json!({"sourceLanguages": ["cpp", "rust"]}).to_string(),
|
||||||
|
]
|
||||||
|
}),
|
||||||
request_args: self.request_args(delegate, &config).await?,
|
request_args: self.request_args(delegate, &config).await?,
|
||||||
envs: HashMap::default(),
|
envs: HashMap::default(),
|
||||||
connection: None,
|
connection: None,
|
||||||
|
|
|
@ -159,6 +159,7 @@ impl DebugAdapter for GdbDebugAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
config: &DebugTaskDefinition,
|
config: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<std::path::PathBuf>,
|
user_installed_path: Option<std::path::PathBuf>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
_: &mut AsyncApp,
|
_: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
let user_setting_path = user_installed_path
|
let user_setting_path = user_installed_path
|
||||||
|
@ -186,7 +187,7 @@ impl DebugAdapter for GdbDebugAdapter {
|
||||||
|
|
||||||
Ok(DebugAdapterBinary {
|
Ok(DebugAdapterBinary {
|
||||||
command: Some(gdb_path),
|
command: Some(gdb_path),
|
||||||
arguments: vec!["-i=dap".into()],
|
arguments: user_args.unwrap_or_else(|| vec!["-i=dap".into()]),
|
||||||
envs: HashMap::default(),
|
envs: HashMap::default(),
|
||||||
cwd: Some(delegate.worktree_root_path().to_path_buf()),
|
cwd: Some(delegate.worktree_root_path().to_path_buf()),
|
||||||
connection: None,
|
connection: None,
|
||||||
|
|
|
@ -399,6 +399,7 @@ impl DebugAdapter for GoDebugAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
task_definition: &DebugTaskDefinition,
|
task_definition: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<PathBuf>,
|
user_installed_path: Option<PathBuf>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
_cx: &mut AsyncApp,
|
_cx: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
let adapter_path = paths::debug_adapters_dir().join(&Self::ADAPTER_NAME);
|
let adapter_path = paths::debug_adapters_dir().join(&Self::ADAPTER_NAME);
|
||||||
|
@ -470,7 +471,10 @@ impl DebugAdapter for GoDebugAdapter {
|
||||||
crate::configure_tcp_connection(TcpArgumentsTemplate::default()).await?;
|
crate::configure_tcp_connection(TcpArgumentsTemplate::default()).await?;
|
||||||
command = Some(minidelve_path.to_string_lossy().into_owned());
|
command = Some(minidelve_path.to_string_lossy().into_owned());
|
||||||
connection = None;
|
connection = None;
|
||||||
arguments = if cfg!(windows) {
|
arguments = if let Some(mut args) = user_args {
|
||||||
|
args.insert(0, delve_path);
|
||||||
|
args
|
||||||
|
} else if cfg!(windows) {
|
||||||
vec![
|
vec![
|
||||||
delve_path,
|
delve_path,
|
||||||
"dap".into(),
|
"dap".into(),
|
||||||
|
|
|
@ -50,6 +50,7 @@ impl JsDebugAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
task_definition: &DebugTaskDefinition,
|
task_definition: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<PathBuf>,
|
user_installed_path: Option<PathBuf>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
_: &mut AsyncApp,
|
_: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
let adapter_path = if let Some(user_installed_path) = user_installed_path {
|
let adapter_path = if let Some(user_installed_path) = user_installed_path {
|
||||||
|
@ -109,6 +110,26 @@ impl JsDebugAdapter {
|
||||||
.or_insert(true.into());
|
.or_insert(true.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let arguments = if let Some(mut args) = user_args {
|
||||||
|
args.insert(
|
||||||
|
0,
|
||||||
|
adapter_path
|
||||||
|
.join(Self::ADAPTER_PATH)
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
args
|
||||||
|
} else {
|
||||||
|
vec![
|
||||||
|
adapter_path
|
||||||
|
.join(Self::ADAPTER_PATH)
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
port.to_string(),
|
||||||
|
host.to_string(),
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
Ok(DebugAdapterBinary {
|
Ok(DebugAdapterBinary {
|
||||||
command: Some(
|
command: Some(
|
||||||
delegate
|
delegate
|
||||||
|
@ -118,14 +139,7 @@ impl JsDebugAdapter {
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.into_owned(),
|
.into_owned(),
|
||||||
),
|
),
|
||||||
arguments: vec![
|
arguments,
|
||||||
adapter_path
|
|
||||||
.join(Self::ADAPTER_PATH)
|
|
||||||
.to_string_lossy()
|
|
||||||
.to_string(),
|
|
||||||
port.to_string(),
|
|
||||||
host.to_string(),
|
|
||||||
],
|
|
||||||
cwd: Some(delegate.worktree_root_path().to_path_buf()),
|
cwd: Some(delegate.worktree_root_path().to_path_buf()),
|
||||||
envs: HashMap::default(),
|
envs: HashMap::default(),
|
||||||
connection: Some(adapters::TcpArguments {
|
connection: Some(adapters::TcpArguments {
|
||||||
|
@ -464,6 +478,7 @@ impl DebugAdapter for JsDebugAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
config: &DebugTaskDefinition,
|
config: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<PathBuf>,
|
user_installed_path: Option<PathBuf>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
cx: &mut AsyncApp,
|
cx: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
if self.checked.set(()).is_ok() {
|
if self.checked.set(()).is_ok() {
|
||||||
|
@ -481,7 +496,7 @@ impl DebugAdapter for JsDebugAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.get_installed_binary(delegate, &config, user_installed_path, cx)
|
self.get_installed_binary(delegate, &config, user_installed_path, user_args, cx)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ impl PhpDebugAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
task_definition: &DebugTaskDefinition,
|
task_definition: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<PathBuf>,
|
user_installed_path: Option<PathBuf>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
_: &mut AsyncApp,
|
_: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
let adapter_path = if let Some(user_installed_path) = user_installed_path {
|
let adapter_path = if let Some(user_installed_path) = user_installed_path {
|
||||||
|
@ -77,6 +78,25 @@ impl PhpDebugAdapter {
|
||||||
.or_insert_with(|| delegate.worktree_root_path().to_string_lossy().into());
|
.or_insert_with(|| delegate.worktree_root_path().to_string_lossy().into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let arguments = if let Some(mut args) = user_args {
|
||||||
|
args.insert(
|
||||||
|
0,
|
||||||
|
adapter_path
|
||||||
|
.join(Self::ADAPTER_PATH)
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
args
|
||||||
|
} else {
|
||||||
|
vec![
|
||||||
|
adapter_path
|
||||||
|
.join(Self::ADAPTER_PATH)
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
format!("--server={}", port),
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
Ok(DebugAdapterBinary {
|
Ok(DebugAdapterBinary {
|
||||||
command: Some(
|
command: Some(
|
||||||
delegate
|
delegate
|
||||||
|
@ -86,13 +106,7 @@ impl PhpDebugAdapter {
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.into_owned(),
|
.into_owned(),
|
||||||
),
|
),
|
||||||
arguments: vec![
|
arguments,
|
||||||
adapter_path
|
|
||||||
.join(Self::ADAPTER_PATH)
|
|
||||||
.to_string_lossy()
|
|
||||||
.to_string(),
|
|
||||||
format!("--server={}", port),
|
|
||||||
],
|
|
||||||
connection: Some(TcpArguments {
|
connection: Some(TcpArguments {
|
||||||
port,
|
port,
|
||||||
host,
|
host,
|
||||||
|
@ -326,6 +340,7 @@ impl DebugAdapter for PhpDebugAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
task_definition: &DebugTaskDefinition,
|
task_definition: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<PathBuf>,
|
user_installed_path: Option<PathBuf>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
cx: &mut AsyncApp,
|
cx: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
if self.checked.set(()).is_ok() {
|
if self.checked.set(()).is_ok() {
|
||||||
|
@ -341,7 +356,13 @@ impl DebugAdapter for PhpDebugAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.get_installed_binary(delegate, &task_definition, user_installed_path, cx)
|
self.get_installed_binary(
|
||||||
.await
|
delegate,
|
||||||
|
&task_definition,
|
||||||
|
user_installed_path,
|
||||||
|
user_args,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,29 +32,23 @@ impl PythonDebugAdapter {
|
||||||
host: &Ipv4Addr,
|
host: &Ipv4Addr,
|
||||||
port: u16,
|
port: u16,
|
||||||
user_installed_path: Option<&Path>,
|
user_installed_path: Option<&Path>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
installed_in_venv: bool,
|
installed_in_venv: bool,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
if let Some(user_installed_path) = user_installed_path {
|
let mut args = if let Some(user_installed_path) = user_installed_path {
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Using user-installed debugpy adapter from: {}",
|
"Using user-installed debugpy adapter from: {}",
|
||||||
user_installed_path.display()
|
user_installed_path.display()
|
||||||
);
|
);
|
||||||
Ok(vec![
|
vec![
|
||||||
user_installed_path
|
user_installed_path
|
||||||
.join(Self::ADAPTER_PATH)
|
.join(Self::ADAPTER_PATH)
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
format!("--host={}", host),
|
]
|
||||||
format!("--port={}", port),
|
|
||||||
])
|
|
||||||
} else if installed_in_venv {
|
} else if installed_in_venv {
|
||||||
log::debug!("Using venv-installed debugpy");
|
log::debug!("Using venv-installed debugpy");
|
||||||
Ok(vec![
|
vec!["-m".to_string(), "debugpy.adapter".to_string()]
|
||||||
"-m".to_string(),
|
|
||||||
"debugpy.adapter".to_string(),
|
|
||||||
format!("--host={}", host),
|
|
||||||
format!("--port={}", port),
|
|
||||||
])
|
|
||||||
} else {
|
} else {
|
||||||
let adapter_path = paths::debug_adapters_dir().join(Self::DEBUG_ADAPTER_NAME.as_ref());
|
let adapter_path = paths::debug_adapters_dir().join(Self::DEBUG_ADAPTER_NAME.as_ref());
|
||||||
let file_name_prefix = format!("{}_", Self::ADAPTER_NAME);
|
let file_name_prefix = format!("{}_", Self::ADAPTER_NAME);
|
||||||
|
@ -70,15 +64,20 @@ impl PythonDebugAdapter {
|
||||||
"Using GitHub-downloaded debugpy adapter from: {}",
|
"Using GitHub-downloaded debugpy adapter from: {}",
|
||||||
debugpy_dir.display()
|
debugpy_dir.display()
|
||||||
);
|
);
|
||||||
Ok(vec![
|
vec![
|
||||||
debugpy_dir
|
debugpy_dir
|
||||||
.join(Self::ADAPTER_PATH)
|
.join(Self::ADAPTER_PATH)
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
format!("--host={}", host),
|
]
|
||||||
format!("--port={}", port),
|
};
|
||||||
])
|
|
||||||
}
|
args.extend(if let Some(args) = user_args {
|
||||||
|
args
|
||||||
|
} else {
|
||||||
|
vec![format!("--host={}", host), format!("--port={}", port)]
|
||||||
|
});
|
||||||
|
Ok(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn request_args(
|
async fn request_args(
|
||||||
|
@ -151,6 +150,7 @@ impl PythonDebugAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
config: &DebugTaskDefinition,
|
config: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<PathBuf>,
|
user_installed_path: Option<PathBuf>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
toolchain: Option<Toolchain>,
|
toolchain: Option<Toolchain>,
|
||||||
installed_in_venv: bool,
|
installed_in_venv: bool,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
|
@ -182,6 +182,7 @@ impl PythonDebugAdapter {
|
||||||
&host,
|
&host,
|
||||||
port,
|
port,
|
||||||
user_installed_path.as_deref(),
|
user_installed_path.as_deref(),
|
||||||
|
user_args,
|
||||||
installed_in_venv,
|
installed_in_venv,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -595,6 +596,7 @@ impl DebugAdapter for PythonDebugAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
config: &DebugTaskDefinition,
|
config: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<PathBuf>,
|
user_installed_path: Option<PathBuf>,
|
||||||
|
user_args: Option<Vec<String>>,
|
||||||
cx: &mut AsyncApp,
|
cx: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
if let Some(local_path) = &user_installed_path {
|
if let Some(local_path) = &user_installed_path {
|
||||||
|
@ -603,7 +605,14 @@ impl DebugAdapter for PythonDebugAdapter {
|
||||||
local_path.display()
|
local_path.display()
|
||||||
);
|
);
|
||||||
return self
|
return self
|
||||||
.get_installed_binary(delegate, &config, Some(local_path.clone()), None, false)
|
.get_installed_binary(
|
||||||
|
delegate,
|
||||||
|
&config,
|
||||||
|
Some(local_path.clone()),
|
||||||
|
user_args,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,6 +639,7 @@ impl DebugAdapter for PythonDebugAdapter {
|
||||||
delegate,
|
delegate,
|
||||||
&config,
|
&config,
|
||||||
None,
|
None,
|
||||||
|
user_args,
|
||||||
Some(toolchain.clone()),
|
Some(toolchain.clone()),
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
|
@ -647,7 +657,7 @@ impl DebugAdapter for PythonDebugAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.get_installed_binary(delegate, &config, None, toolchain, false)
|
self.get_installed_binary(delegate, &config, None, user_args, toolchain, false)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -682,15 +692,21 @@ mod tests {
|
||||||
|
|
||||||
// Case 1: User-defined debugpy path (highest precedence)
|
// Case 1: User-defined debugpy path (highest precedence)
|
||||||
let user_path = PathBuf::from("/custom/path/to/debugpy");
|
let user_path = PathBuf::from("/custom/path/to/debugpy");
|
||||||
let user_args =
|
let user_args = PythonDebugAdapter::generate_debugpy_arguments(
|
||||||
PythonDebugAdapter::generate_debugpy_arguments(&host, port, Some(&user_path), false)
|
&host,
|
||||||
.await
|
port,
|
||||||
.unwrap();
|
Some(&user_path),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// Case 2: Venv-installed debugpy (uses -m debugpy.adapter)
|
// Case 2: Venv-installed debugpy (uses -m debugpy.adapter)
|
||||||
let venv_args = PythonDebugAdapter::generate_debugpy_arguments(&host, port, None, true)
|
let venv_args =
|
||||||
.await
|
PythonDebugAdapter::generate_debugpy_arguments(&host, port, None, None, true)
|
||||||
.unwrap();
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert!(user_args[0].ends_with("src/debugpy/adapter"));
|
assert!(user_args[0].ends_with("src/debugpy/adapter"));
|
||||||
assert_eq!(user_args[1], "--host=127.0.0.1");
|
assert_eq!(user_args[1], "--host=127.0.0.1");
|
||||||
|
@ -701,6 +717,33 @@ mod tests {
|
||||||
assert_eq!(venv_args[2], "--host=127.0.0.1");
|
assert_eq!(venv_args[2], "--host=127.0.0.1");
|
||||||
assert_eq!(venv_args[3], "--port=5678");
|
assert_eq!(venv_args[3], "--port=5678");
|
||||||
|
|
||||||
|
// The same cases, with arguments overridden by the user
|
||||||
|
let user_args = PythonDebugAdapter::generate_debugpy_arguments(
|
||||||
|
&host,
|
||||||
|
port,
|
||||||
|
Some(&user_path),
|
||||||
|
Some(vec!["foo".into()]),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let venv_args = PythonDebugAdapter::generate_debugpy_arguments(
|
||||||
|
&host,
|
||||||
|
port,
|
||||||
|
None,
|
||||||
|
Some(vec!["foo".into()]),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert!(user_args[0].ends_with("src/debugpy/adapter"));
|
||||||
|
assert_eq!(user_args[1], "foo");
|
||||||
|
|
||||||
|
assert_eq!(venv_args[0], "-m");
|
||||||
|
assert_eq!(venv_args[1], "debugpy.adapter");
|
||||||
|
assert_eq!(venv_args[2], "foo");
|
||||||
|
|
||||||
// Note: Case 3 (GitHub-downloaded debugpy) is not tested since this requires mocking the Github API.
|
// Note: Case 3 (GitHub-downloaded debugpy) is not tested since this requires mocking the Github API.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ impl DebugAdapter for RubyDebugAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
definition: &DebugTaskDefinition,
|
definition: &DebugTaskDefinition,
|
||||||
_user_installed_path: Option<PathBuf>,
|
_user_installed_path: Option<PathBuf>,
|
||||||
|
_user_args: Option<Vec<String>>,
|
||||||
_cx: &mut AsyncApp,
|
_cx: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
let adapter_path = paths::debug_adapters_dir().join(self.name().as_ref());
|
let adapter_path = paths::debug_adapters_dir().join(self.name().as_ref());
|
||||||
|
|
|
@ -88,6 +88,8 @@ impl DebugAdapter for ExtensionDapAdapter {
|
||||||
delegate: &Arc<dyn DapDelegate>,
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
config: &DebugTaskDefinition,
|
config: &DebugTaskDefinition,
|
||||||
user_installed_path: Option<PathBuf>,
|
user_installed_path: Option<PathBuf>,
|
||||||
|
// TODO support user args in the extension API
|
||||||
|
_user_args: Option<Vec<String>>,
|
||||||
_cx: &mut AsyncApp,
|
_cx: &mut AsyncApp,
|
||||||
) -> Result<DebugAdapterBinary> {
|
) -> Result<DebugAdapterBinary> {
|
||||||
self.extension
|
self.extension
|
||||||
|
|
|
@ -40,7 +40,7 @@ use rpc::{
|
||||||
AnyProtoClient, TypedEnvelope,
|
AnyProtoClient, TypedEnvelope,
|
||||||
proto::{self},
|
proto::{self},
|
||||||
};
|
};
|
||||||
use settings::{Settings, WorktreeId};
|
use settings::{Settings, SettingsLocation, WorktreeId};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
|
@ -190,17 +190,23 @@ impl DapStore {
|
||||||
return Task::ready(Err(anyhow!("Failed to find a debug adapter")));
|
return Task::ready(Err(anyhow!("Failed to find a debug adapter")));
|
||||||
};
|
};
|
||||||
|
|
||||||
let user_installed_path = ProjectSettings::get_global(cx)
|
let settings_location = SettingsLocation {
|
||||||
|
worktree_id: worktree.read(cx).id(),
|
||||||
|
path: Path::new(""),
|
||||||
|
};
|
||||||
|
let dap_settings = ProjectSettings::get(Some(settings_location), cx)
|
||||||
.dap
|
.dap
|
||||||
.get(&adapter.name())
|
.get(&adapter.name());
|
||||||
.and_then(|s| s.binary.as_ref().map(PathBuf::from));
|
let user_installed_path =
|
||||||
|
dap_settings.and_then(|s| s.binary.as_ref().map(PathBuf::from));
|
||||||
|
let user_args = dap_settings.map(|s| s.args.clone());
|
||||||
|
|
||||||
let delegate = self.delegate(&worktree, console, cx);
|
let delegate = self.delegate(&worktree, console, cx);
|
||||||
let cwd: Arc<Path> = worktree.read(cx).abs_path().as_ref().into();
|
let cwd: Arc<Path> = worktree.read(cx).abs_path().as_ref().into();
|
||||||
|
|
||||||
cx.spawn(async move |this, cx| {
|
cx.spawn(async move |this, cx| {
|
||||||
let mut binary = adapter
|
let mut binary = adapter
|
||||||
.get_binary(&delegate, &definition, user_installed_path, cx)
|
.get_binary(&delegate, &definition, user_installed_path, user_args, cx)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let env = this
|
let env = this
|
||||||
|
|
|
@ -82,6 +82,8 @@ pub struct ProjectSettings {
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct DapSettings {
|
pub struct DapSettings {
|
||||||
pub binary: Option<String>,
|
pub binary: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub args: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
|
#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue