dap: Modify breakpoints in place with no cloning

imgbot
Blaž Hrastnik 3 years ago
parent 3b3c396ca4
commit 5f329a22c4

@ -391,6 +391,7 @@ fn debug_parameter_prompt(
} }
pub fn dap_toggle_breakpoint(cx: &mut Context) { pub fn dap_toggle_breakpoint(cx: &mut Context) {
// TODO: accept line instead of current selection
let (view, doc) = current!(cx.editor); let (view, doc) = current!(cx.editor);
let text = doc.text().slice(..); let text = doc.text().slice(..);
let pos = doc.selection(view.id).primary().cursor(text); let pos = doc.selection(view.id).primary().cursor(text);
@ -413,6 +414,7 @@ pub fn dap_toggle_breakpoint(cx: &mut Context) {
// we shouldn't really allow editing while debug is running though // we shouldn't really allow editing while debug is running though
let breakpoints = cx.editor.breakpoints.entry(path.clone()).or_default(); let breakpoints = cx.editor.breakpoints.entry(path.clone()).or_default();
// TODO: always keep breakpoints sorted and use binary search
if let Some(pos) = breakpoints.iter().position(|b| b.line == breakpoint.line) { if let Some(pos) = breakpoints.iter().position(|b| b.line == breakpoint.line) {
breakpoints.remove(pos); breakpoints.remove(pos);
} else { } else {
@ -629,12 +631,14 @@ pub fn dap_disable_exceptions(cx: &mut Context) {
} }
} }
// TODO: both edit condition and edit log need to be stable: we might get new breakpoints from the debugger which can change offsets
// we also might be editing a breakpoint in a document that's no longer focused
pub fn dap_edit_condition(cx: &mut Context) { pub fn dap_edit_condition(cx: &mut Context) {
if let Some((pos, mut bp)) = commands::cmd::get_breakpoint_at_current_line(cx.editor) { if let Some((pos, breakpoint)) = commands::cmd::get_breakpoint_at_current_line(cx.editor) {
let callback = Box::pin(async move { let callback = Box::pin(async move {
let call: Callback = let call: Callback =
Box::new(move |_editor: &mut Editor, compositor: &mut Compositor| { Box::new(move |_editor: &mut Editor, compositor: &mut Compositor| {
let condition = bp.condition.clone(); let condition = breakpoint.condition;
let prompt = Prompt::new( let prompt = Prompt::new(
"condition: ".into(), "condition: ".into(),
None, None,
@ -657,14 +661,11 @@ pub fn dap_edit_condition(cx: &mut Context) {
} }
}; };
let breakpoints = let breakpoints = &mut cx.editor.breakpoints.get_mut(path).unwrap();
cx.editor.breakpoints.entry(path.clone()).or_default(); breakpoints[pos].condition = match input {
breakpoints.remove(pos);
bp.condition = match input {
"" => None, "" => None,
input => Some(input.to_owned()), input => Some(input.to_owned()),
}; };
breakpoints.push(bp.clone());
if let Some(debugger) = &mut cx.editor.debugger { if let Some(debugger) = &mut cx.editor.debugger {
// TODO: handle capabilities correctly again, by filterin breakpoints when emitting // TODO: handle capabilities correctly again, by filterin breakpoints when emitting
@ -709,11 +710,11 @@ pub fn dap_edit_condition(cx: &mut Context) {
} }
pub fn dap_edit_log(cx: &mut Context) { pub fn dap_edit_log(cx: &mut Context) {
if let Some((pos, mut bp)) = commands::cmd::get_breakpoint_at_current_line(cx.editor) { if let Some((pos, breakpoint)) = commands::cmd::get_breakpoint_at_current_line(cx.editor) {
let callback = Box::pin(async move { let callback = Box::pin(async move {
let call: Callback = let call: Callback =
Box::new(move |_editor: &mut Editor, compositor: &mut Compositor| { Box::new(move |_editor: &mut Editor, compositor: &mut Compositor| {
let log_message = bp.log_message.clone(); let log_message = breakpoint.log_message;
let prompt = Prompt::new( let prompt = Prompt::new(
"log message: ".into(), "log message: ".into(),
None, None,
@ -736,14 +737,11 @@ pub fn dap_edit_log(cx: &mut Context) {
} }
}; };
let breakpoints = let breakpoints = &mut cx.editor.breakpoints.get_mut(path).unwrap();
cx.editor.breakpoints.entry(path.clone()).or_default(); breakpoints[pos].log_message = match input {
breakpoints.remove(pos);
bp.log_message = match input {
"" => None, "" => None,
input => Some(input.to_owned()), input => Some(input.to_owned()),
}; };
breakpoints.push(bp.clone());
if let Some(debugger) = &mut cx.editor.debugger { if let Some(debugger) = &mut cx.editor.debugger {
// TODO: handle capabilities correctly again, by filterin breakpoints when emitting // TODO: handle capabilities correctly again, by filterin breakpoints when emitting

@ -978,17 +978,17 @@ impl EditorView {
let result = editor.tree.views().find_map(|(view, _focus)| { let result = editor.tree.views().find_map(|(view, _focus)| {
view.gutter_coords_at_screen_coords(row, column) view.gutter_coords_at_screen_coords(row, column)
.map(|coords| (coords.0, coords.1, view.id)) .map(|coords| (coords, view.id))
}); });
if let Some((line, _, view_id)) = result { if let Some((coords, view_id)) = result {
editor.tree.focus = view_id; editor.tree.focus = view_id;
let doc = editor let doc = editor
.documents .documents
.get_mut(&editor.tree.get(view_id).doc) .get_mut(&editor.tree.get(view_id).doc)
.unwrap(); .unwrap();
if let Ok(pos) = doc.text().try_line_to_char(line) { if let Ok(pos) = doc.text().try_line_to_char(coords.row) {
doc.set_selection(view_id, Selection::point(pos)); doc.set_selection(view_id, Selection::point(pos));
commands::dap_toggle_breakpoint(cxt); commands::dap_toggle_breakpoint(cxt);
@ -1080,10 +1080,10 @@ impl EditorView {
} => { } => {
let result = cxt.editor.tree.views().find_map(|(view, _focus)| { let result = cxt.editor.tree.views().find_map(|(view, _focus)| {
view.gutter_coords_at_screen_coords(row, column) view.gutter_coords_at_screen_coords(row, column)
.map(|coords| (coords.0, coords.1, view.id)) .map(|coords| (coords, view.id))
}); });
if let Some((line, _, view_id)) = result { if let Some((coords, view_id)) = result {
cxt.editor.tree.focus = view_id; cxt.editor.tree.focus = view_id;
let doc = cxt let doc = cxt
@ -1091,7 +1091,7 @@ impl EditorView {
.documents .documents
.get_mut(&cxt.editor.tree.get(view_id).doc) .get_mut(&cxt.editor.tree.get(view_id).doc)
.unwrap(); .unwrap();
if let Ok(pos) = doc.text().try_line_to_char(line) { if let Ok(pos) = doc.text().try_line_to_char(coords.row) {
doc.set_selection(view_id, Selection::point(pos)); doc.set_selection(view_id, Selection::point(pos));
if modifiers == crossterm::event::KeyModifiers::ALT { if modifiers == crossterm::event::KeyModifiers::ALT {
commands::Command::dap_edit_log.execute(cxt); commands::Command::dap_edit_log.execute(cxt);

@ -253,7 +253,7 @@ impl View {
/// Translates screen coordinates into coordinates on the gutter of the view. /// Translates screen coordinates into coordinates on the gutter of the view.
/// Returns a tuple of usize typed line and column numbers starting with 0. /// Returns a tuple of usize typed line and column numbers starting with 0.
/// Returns None if coordinates are not on the gutter. /// Returns None if coordinates are not on the gutter.
pub fn gutter_coords_at_screen_coords(&self, row: u16, column: u16) -> Option<(usize, usize)> { pub fn gutter_coords_at_screen_coords(&self, row: u16, column: u16) -> Option<Position> {
// 1 for status // 1 for status
if row < self.area.top() || row >= self.area.bottom() { if row < self.area.top() || row >= self.area.bottom() {
return None; return None;
@ -263,7 +263,7 @@ impl View {
return None; return None;
} }
Some(( Some(Position::new(
(row - self.area.top()) as usize, (row - self.area.top()) as usize,
(column - self.area.left()) as usize, (column - self.area.left()) as usize,
)) ))

Loading…
Cancel
Save