Make stepping granularity configurable (#33)

This commit also changes the default granularity to line, before this was statement but most editors have line as the default.
This commit is contained in:
Remco Smits
2024-09-01 11:44:32 +02:00
committed by GitHub
parent 4cf735bd93
commit 83cc452465
4 changed files with 50 additions and 53 deletions

View File

@@ -1031,7 +1031,7 @@
"ssh_connections": null,
"debugger": {
// Save breakpoints across different Zed sessions
"stepping_granularity": "line",
"save_breakpoints": true,
"button": true
},

View File

@@ -476,16 +476,12 @@ impl DebugAdapterClient {
self.request::<Continue>(ContinueArguments {
thread_id,
single_thread: if supports_single_thread_execution_requests {
Some(true)
} else {
None
},
single_thread: supports_single_thread_execution_requests.then(|| true),
})
.await
}
pub async fn step_over(&self, thread_id: u64) -> Result<()> {
pub async fn step_over(&self, thread_id: u64, granularity: SteppingGranularity) -> Result<()> {
let capabilities = self.capabilities();
let supports_single_thread_execution_requests = capabilities
@@ -497,21 +493,13 @@ impl DebugAdapterClient {
self.request::<Next>(NextArguments {
thread_id,
granularity: if supports_stepping_granularity {
Some(SteppingGranularity::Statement)
} else {
None
},
single_thread: if supports_single_thread_execution_requests {
Some(true)
} else {
None
},
granularity: supports_stepping_granularity.then(|| granularity),
single_thread: supports_single_thread_execution_requests.then(|| true),
})
.await
}
pub async fn step_in(&self, thread_id: u64) -> Result<()> {
pub async fn step_in(&self, thread_id: u64, granularity: SteppingGranularity) -> Result<()> {
let capabilities = self.capabilities();
let supports_single_thread_execution_requests = capabilities
@@ -524,21 +512,13 @@ impl DebugAdapterClient {
self.request::<StepIn>(StepInArguments {
thread_id,
target_id: None,
granularity: if supports_stepping_granularity {
Some(SteppingGranularity::Statement)
} else {
None
},
single_thread: if supports_single_thread_execution_requests {
Some(true)
} else {
None
},
granularity: supports_stepping_granularity.then(|| granularity),
single_thread: supports_single_thread_execution_requests.then(|| true),
})
.await
}
pub async fn step_out(&self, thread_id: u64) -> Result<()> {
pub async fn step_out(&self, thread_id: u64, granularity: SteppingGranularity) -> Result<()> {
let capabilities = self.capabilities();
let supports_single_thread_execution_requests = capabilities
@@ -550,21 +530,13 @@ impl DebugAdapterClient {
self.request::<StepOut>(StepOutArguments {
thread_id,
granularity: if supports_stepping_granularity {
Some(SteppingGranularity::Statement)
} else {
None
},
single_thread: if supports_single_thread_execution_requests {
Some(true)
} else {
None
},
granularity: supports_stepping_granularity.then(|| granularity),
single_thread: supports_single_thread_execution_requests.then(|| true),
})
.await
}
pub async fn step_back(&self, thread_id: u64) -> Result<()> {
pub async fn step_back(&self, thread_id: u64, granularity: SteppingGranularity) -> Result<()> {
let capabilities = self.capabilities();
let supports_single_thread_execution_requests = capabilities
@@ -576,16 +548,8 @@ impl DebugAdapterClient {
self.request::<StepBack>(StepBackArguments {
thread_id,
granularity: if supports_stepping_granularity {
Some(SteppingGranularity::Statement)
} else {
None
},
single_thread: if supports_single_thread_execution_requests {
Some(true)
} else {
None
},
granularity: supports_stepping_granularity.then(|| granularity),
single_thread: supports_single_thread_execution_requests.then(|| true),
})
.await
}

View File

@@ -6,6 +6,10 @@ use settings::{Settings, SettingsSources};
#[derive(Serialize, Deserialize, JsonSchema, Clone, Copy)]
#[serde(default)]
pub struct DebuggerSettings {
/// Determines the stepping granularity.
///
/// Default: line
pub stepping_granularity: SteppingGranularity,
/// Whether the breakpoints should be reused across Zed sessions.
///
/// Default: true
@@ -16,11 +20,35 @@ pub struct DebuggerSettings {
pub button: bool,
}
#[derive(Serialize, Deserialize, JsonSchema, Clone, Copy, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum SteppingGranularity {
/// The step should allow the program to run until the current statement has finished executing.
/// The meaning of a statement is determined by the adapter and it may be considered equivalent to a line.
/// For example 'for(int i = 0; i < 10; i++)' could be considered to have 3 statements 'int i = 0', 'i < 10', and 'i++'.
Statement,
/// The step should allow the program to run until the current source line has executed.
Line,
/// The step should allow one instruction to execute (e.g. one x86 instruction).
Instruction,
}
impl Default for DebuggerSettings {
fn default() -> Self {
Self {
button: true,
save_breakpoints: true,
stepping_granularity: SteppingGranularity::Line,
}
}
}
impl DebuggerSettings {
pub fn stepping_granularity(&self) -> dap_types::SteppingGranularity {
match &self.stepping_granularity {
SteppingGranularity::Statement => dap_types::SteppingGranularity::Statement,
SteppingGranularity::Line => dap_types::SteppingGranularity::Line,
SteppingGranularity::Instruction => dap_types::SteppingGranularity::Instruction,
}
}
}

View File

@@ -4,6 +4,7 @@ use crate::variable_list::VariableList;
use anyhow::Result;
use dap::client::{DebugAdapterClient, DebugAdapterClientId, ThreadState, ThreadStatus};
use dap::debugger_settings::DebuggerSettings;
use dap::{
OutputEvent, OutputEventCategory, Scope, StackFrame, StoppedEvent, ThreadEvent, Variable,
};
@@ -13,6 +14,7 @@ use gpui::{
FocusableView, ListState, Subscription, View, WeakView,
};
use serde::Deserialize;
use settings::Settings;
use std::sync::Arc;
use ui::WindowContext;
use ui::{prelude::*, Tooltip};
@@ -441,9 +443,10 @@ impl DebugPanelItem {
let client = self.client.clone();
let thread_id = self.thread_id;
let previous_status = self.current_thread_state().status;
let granularity = DebuggerSettings::get_global(cx).stepping_granularity();
cx.spawn(|this, cx| async move {
client.step_over(thread_id).await?;
client.step_over(thread_id, granularity).await?;
Self::update_thread_state(this, previous_status, None, cx)
})
@@ -454,9 +457,10 @@ impl DebugPanelItem {
let client = self.client.clone();
let thread_id = self.thread_id;
let previous_status = self.current_thread_state().status;
let granularity = DebuggerSettings::get_global(cx).stepping_granularity();
cx.spawn(|this, cx| async move {
client.step_in(thread_id).await?;
client.step_in(thread_id, granularity).await?;
Self::update_thread_state(this, previous_status, None, cx)
})
@@ -467,9 +471,10 @@ impl DebugPanelItem {
let client = self.client.clone();
let thread_id = self.thread_id;
let previous_status = self.current_thread_state().status;
let granularity = DebuggerSettings::get_global(cx).stepping_granularity();
cx.spawn(|this, cx| async move {
client.step_out(thread_id).await?;
client.step_out(thread_id, granularity).await?;
Self::update_thread_state(this, previous_status, None, cx)
})