From 3b0ec750ff7348c60a60164ca54237c5b4acd694 Mon Sep 17 00:00:00 2001 From: Dmitry Sharshakov Date: Sun, 5 Sep 2021 08:14:17 +0300 Subject: [PATCH] Support editing breakpoint condition with right click --- helix-term/src/commands/dap.rs | 138 ++++++++++++++++++--------------- helix-term/src/ui/editor.rs | 25 ++++++ 2 files changed, 100 insertions(+), 63 deletions(-) diff --git a/helix-term/src/commands/dap.rs b/helix-term/src/commands/dap.rs index ffb1aa9f..e72b4700 100644 --- a/helix-term/src/commands/dap.rs +++ b/helix-term/src/commands/dap.rs @@ -1,6 +1,8 @@ use super::{align_view, Align, Context, Editor}; use crate::{ commands, + compositor::Compositor, + job::Callback, ui::{FilePicker, Picker, Prompt, PromptEvent}, }; use helix_core::Selection; @@ -479,69 +481,79 @@ pub fn dap_terminate(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) { - let condition = bp.condition.clone(); - let prompt = Prompt::new( - "condition: ".into(), - None, - |_input: &str| Vec::new(), - move |cx: &mut crate::compositor::Context, input: &str, event: PromptEvent| { - if event != PromptEvent::Validate { - return; - } - - let (_, doc) = current!(cx.editor); - let path = match doc.path() { - Some(path) => path.to_path_buf(), - None => { - cx.editor - .set_status("Can't edit breakpoint: document has no path".to_owned()); - return; - } - }; - - let breakpoints = cx.editor.breakpoints.entry(path.clone()).or_default(); - breakpoints.remove(pos); - bp.condition = match input { - "" => None, - input => Some(input.to_owned()), - }; - breakpoints.push(bp.clone()); - - if let Some(debugger) = &mut cx.editor.debugger { - // TODO: handle capabilities correctly again, by filterin breakpoints when emitting - // if breakpoint.condition.is_some() - // && !debugger - // .caps - // .as_ref() - // .unwrap() - // .supports_conditional_breakpoints - // .unwrap_or_default() - // { - // bail!( - // "Can't edit breakpoint: debugger does not support conditional breakpoints" - // ) - // } - // if breakpoint.log_message.is_some() - // && !debugger - // .caps - // .as_ref() - // .unwrap() - // .supports_log_points - // .unwrap_or_default() - // { - // bail!("Can't edit breakpoint: debugger does not support logpoints") - // } - let request = debugger.set_breakpoints(path, breakpoints.clone()); - if let Err(e) = block_on(request) { - cx.editor - .set_status(format!("Failed to set breakpoints: {:?}", e)) - } - } - }, - condition, - ); - - cx.push_layer(Box::new(prompt)); + let callback = Box::pin(async move { + let call: Callback = + Box::new(move |_editor: &mut Editor, compositor: &mut Compositor| { + let condition = bp.condition.clone(); + let prompt = Prompt::new( + "condition: ".into(), + None, + |_input: &str| Vec::new(), + move |cx: &mut crate::compositor::Context, + input: &str, + event: PromptEvent| { + if event != PromptEvent::Validate { + return; + } + + let (_, doc) = current!(cx.editor); + let path = match doc.path() { + Some(path) => path.to_path_buf(), + None => { + cx.editor.set_status( + "Can't edit breakpoint: document has no path".to_owned(), + ); + return; + } + }; + + let breakpoints = + cx.editor.breakpoints.entry(path.clone()).or_default(); + breakpoints.remove(pos); + bp.condition = match input { + "" => None, + input => Some(input.to_owned()), + }; + breakpoints.push(bp.clone()); + + if let Some(debugger) = &mut cx.editor.debugger { + // TODO: handle capabilities correctly again, by filterin breakpoints when emitting + // if breakpoint.condition.is_some() + // && !debugger + // .caps + // .as_ref() + // .unwrap() + // .supports_conditional_breakpoints + // .unwrap_or_default() + // { + // bail!( + // "Can't edit breakpoint: debugger does not support conditional breakpoints" + // ) + // } + // if breakpoint.log_message.is_some() + // && !debugger + // .caps + // .as_ref() + // .unwrap() + // .supports_log_points + // .unwrap_or_default() + // { + // bail!("Can't edit breakpoint: debugger does not support logpoints") + // } + let request = debugger.set_breakpoints(path, breakpoints.clone()); + if let Err(e) = block_on(request) { + cx.editor + .set_status(format!("Failed to set breakpoints: {:?}", e)) + } + } + }, + condition, + ); + compositor.push(Box::new(prompt)); + }); + Ok(call) + }); + cx.jobs.callback(callback); } } diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 4681f400..20fdd152 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1073,6 +1073,31 @@ impl EditorView { EventResult::Consumed(None) } + MouseEvent { + kind: MouseEventKind::Up(MouseButton::Right), + row, + column, + .. + } => { + let result = cxt.editor.tree.views().find_map(|(view, _focus)| { + view.gutter_coords_at_screen_coords(row, column) + .map(|coords| (coords.0, coords.1, view.id)) + }); + + if let Some((line, _, view_id)) = result { + cxt.editor.tree.focus = view_id; + + let doc = &mut cxt.editor.documents[cxt.editor.tree.get(view_id).doc]; + if let Ok(pos) = doc.text().try_line_to_char(line) { + doc.set_selection(view_id, Selection::point(pos)); + commands::Command::dap_edit_condition.execute(cxt); + + return EventResult::Consumed(None); + } + } + EventResult::Ignored + } + MouseEvent { kind: MouseEventKind::Up(MouseButton::Middle), row,