From 56882b97e57618fe2d68d210abc2d5a5afc20152 Mon Sep 17 00:00:00 2001 From: faysou Date: Wed, 8 Apr 2026 02:13:38 +0100 Subject: [PATCH] feat: support Cursor editor as debug session option (#5205) * feat: support Cursor editor as debug session option * fmt --------- Co-authored-by: Jonathan Kelley --- packages/cli/src/build/builder.rs | 25 ++++++++++++++++++++----- packages/cli/src/cli/config.rs | 8 +++++++- packages/cli/src/logging.rs | 3 +++ packages/cli/src/settings.rs | 18 ++++++++++++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/packages/cli/src/build/builder.rs b/packages/cli/src/build/builder.rs index 34f9816f8..0f22668e6 100644 --- a/packages/cli/src/build/builder.rs +++ b/packages/cli/src/build/builder.rs @@ -1611,6 +1611,21 @@ impl AppBuilder { } pub(crate) async fn open_debugger(&mut self, server: &WebServer) -> Result<()> { + // Get the preferred editor from workspace settings, defaulting to VS Code + use crate::settings::SupportedEditor; + let preferred_editor = self + .build + .workspace + .settings + .preferred_editor + .unwrap_or(SupportedEditor::Vscode); + + // Map the editor to its binary and URL scheme + let (editor_binary, url_scheme) = match preferred_editor { + SupportedEditor::Vscode => ("code", "vscode"), + SupportedEditor::Cursor => ("cursor", "cursor"), + }; + let url = match self.build.bundle { BundleFormat::MacOS | BundleFormat::Windows @@ -1622,7 +1637,7 @@ impl AppBuilder { }; format!( - "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{pid}}}" + "{url_scheme}://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{pid}}}" ) } @@ -1637,7 +1652,7 @@ impl AppBuilder { Some(base_path) => format!("/{}", base_path.trim_matches('/')), None => "".to_owned(), }; - format!("vscode://DioxusLabs.dioxus/debugger?uri={protocol}://{address}{base_path}") + format!("{url_scheme}://DioxusLabs.dioxus/debugger?uri={protocol}://{address}{base_path}") } BundleFormat::Ios => { @@ -1647,7 +1662,7 @@ impl AppBuilder { }; format!( - "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{pid}}}" + "{url_scheme}://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{pid}}}" ) } @@ -1742,7 +1757,7 @@ impl AppBuilder { let program_path = self.build.main_exe(); format!( - r#"vscode://vadimcn.vscode-lldb/launch/config?{{ + r#"{url_scheme}://vadimcn.vscode-lldb/launch/config?{{ 'name':'Attach to Android', 'type':'lldb', 'request':'attach', @@ -1769,7 +1784,7 @@ impl AppBuilder { tracing::info!("Opening debugger for [{}]: {url}", self.build.bundle); - _ = tokio::process::Command::new("code") + _ = tokio::process::Command::new(editor_binary) .arg("--open-url") .arg(url) .spawn(); diff --git a/packages/cli/src/cli/config.rs b/packages/cli/src/cli/config.rs index 18d9d909e..70c84c9a7 100644 --- a/packages/cli/src/cli/config.rs +++ b/packages/cli/src/cli/config.rs @@ -1,5 +1,5 @@ use super::*; -use crate::{CliSettings, TraceSrc, Workspace}; +use crate::{settings::SupportedEditor, CliSettings, TraceSrc, Workspace}; /// Dioxus config file controls #[derive(Clone, Debug, Deserialize, Subcommand)] @@ -46,6 +46,8 @@ pub(crate) enum Setting { WSLFilePollInterval { value: u16 }, /// Disable the built-in telemetry for the CLI DisableTelemetry { value: BoolValue }, + /// Set the preferred editor for debug sessions + PreferredEditor { value: SupportedEditor }, } impl Display for Setting { @@ -56,6 +58,7 @@ impl Display for Setting { Self::AlwaysOnTop { value: _ } => write!(f, "always-on-top"), Self::WSLFilePollInterval { value: _ } => write!(f, "wsl-file-poll-interval"), Self::DisableTelemetry { value: _ } => write!(f, "disable-telemetry"), + Self::PreferredEditor { value: _ } => write!(f, "preferred-editor"), } } } @@ -122,6 +125,9 @@ impl Config { Setting::DisableTelemetry { value } => { settings.disable_telemetry = Some(value.into()); } + Setting::PreferredEditor { value } => { + settings.preferred_editor = Some(value); + } })?; tracing::info!(dx_src = ?TraceSrc::Dev, "🚩 CLI setting `{setting}` has been set."); } diff --git a/packages/cli/src/logging.rs b/packages/cli/src/logging.rs index 8a2f649b5..21d999556 100644 --- a/packages/cli/src/logging.rs +++ b/packages/cli/src/logging.rs @@ -882,6 +882,9 @@ impl TraceController { Setting::AlwaysOnTop { value } => json!({ "value": value }), Setting::WSLFilePollInterval { value } => json!({ "value": value }), Setting::DisableTelemetry { value } => json!({ "value": value }), + Setting::PreferredEditor { value } => { + json!({ "value": format!("{:?}", value) }) + } }, ), }, diff --git a/packages/cli/src/settings.rs b/packages/cli/src/settings.rs index 8d4a7c908..7dc5103b0 100644 --- a/packages/cli/src/settings.rs +++ b/packages/cli/src/settings.rs @@ -5,6 +5,22 @@ use std::sync::LazyLock; use std::{fs, path::PathBuf, sync::Arc}; use tracing::{error, trace, warn}; +/// Supported editors for debug sessions +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, clap::ValueEnum)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum SupportedEditor { + /// Visual Studio Code + Vscode, + /// Cursor editor + Cursor, +} + +impl Default for SupportedEditor { + fn default() -> Self { + SupportedEditor::Vscode + } +} + /// Describes cli settings from project or global level. /// The order of priority goes: /// 1. CLI Flags/Arguments @@ -29,6 +45,8 @@ pub(crate) struct CliSettings { pub(crate) ignore_version_update: Option, /// Disable telemetry pub(crate) disable_telemetry: Option, + /// Preferred editor for debug sessions + pub(crate) preferred_editor: Option, } impl CliSettings {