mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-23 18:06:18 +04:00
Add command for editing breakpoint condition
This commit is contained in:
parent
e36fc57fff
commit
1befbd076c
@ -317,6 +317,7 @@ pub fn doc(&self) -> &'static str {
|
|||||||
dap_next, "Step to next",
|
dap_next, "Step to next",
|
||||||
dap_variables, "List variables",
|
dap_variables, "List variables",
|
||||||
dap_terminate, "End debug session",
|
dap_terminate, "End debug session",
|
||||||
|
dap_edit_condition, "Edit condition of the breakpoint on the current line",
|
||||||
dap_switch_thread, "Switch current thread",
|
dap_switch_thread, "Switch current thread",
|
||||||
dap_switch_stack_frame, "Switch stack frame",
|
dap_switch_stack_frame, "Switch stack frame",
|
||||||
shell_pipe, "Pipe selections through shell command",
|
shell_pipe, "Pipe selections through shell command",
|
||||||
@ -1979,10 +1980,10 @@ fn debug_eval(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_breakpoint_at_current_line(
|
pub fn get_breakpoint_at_current_line(
|
||||||
cx: &mut compositor::Context,
|
editor: &mut Editor,
|
||||||
) -> Option<(usize, SourceBreakpoint)> {
|
) -> Option<(usize, SourceBreakpoint)> {
|
||||||
let (view, doc) = current!(cx.editor);
|
let (view, doc) = current!(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);
|
||||||
@ -1992,12 +1993,9 @@ fn get_breakpoint_at_current_line(
|
|||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
let vec = vec![];
|
let vec = vec![];
|
||||||
let breakpoints = cx.editor.breakpoints.get(&path.clone()).unwrap_or(&vec);
|
let breakpoints = editor.breakpoints.get(&path).unwrap_or(&vec);
|
||||||
let i = breakpoints.iter().position(|b| b.line == line);
|
let i = breakpoints.iter().position(|b| b.line == line);
|
||||||
match i {
|
i.map(|i| (i, breakpoints.get(i).unwrap().clone()))
|
||||||
Some(i) => Some((i, breakpoints.get(i).unwrap().clone())),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edit_breakpoint_impl(
|
fn edit_breakpoint_impl(
|
||||||
@ -2015,7 +2013,7 @@ fn edit_breakpoint_impl(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some((pos, mut bp)) = get_breakpoint_at_current_line(cx) {
|
if let Some((pos, mut bp)) = get_breakpoint_at_current_line(cx.editor) {
|
||||||
let breakpoints = cx.editor.breakpoints.entry(path.clone()).or_default();
|
let breakpoints = cx.editor.breakpoints.entry(path.clone()).or_default();
|
||||||
breakpoints.remove(pos);
|
breakpoints.remove(pos);
|
||||||
|
|
||||||
@ -2481,6 +2479,7 @@ fn command_mode(cx: &mut Context) {
|
|||||||
.set_error(format!("no such command: '{}'", parts[0]));
|
.set_error(format!("no such command: '{}'", parts[0]));
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
prompt.doc_fn = Box::new(|input: &str| {
|
prompt.doc_fn = Box::new(|input: &str| {
|
||||||
let part = input.split(' ').next().unwrap_or_default();
|
let part = input.split(' ').next().unwrap_or_default();
|
||||||
@ -4584,6 +4583,7 @@ fn shell_keep_pipe(cx: &mut Context) {
|
|||||||
let index = index.unwrap_or_else(|| ranges.len() - 1);
|
let index = index.unwrap_or_else(|| ranges.len() - 1);
|
||||||
doc.set_selection(view.id, Selection::new(ranges, index));
|
doc.set_selection(view.id, Selection::new(ranges, index));
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.push_layer(Box::new(prompt));
|
cx.push_layer(Box::new(prompt));
|
||||||
@ -4683,6 +4683,7 @@ fn shell(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {
|
|||||||
doc.append_changes_to_history(view.id);
|
doc.append_changes_to_history(view.id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.push_layer(Box::new(prompt));
|
cx.push_layer(Box::new(prompt));
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use super::{align_view, Align, Context, Editor};
|
use super::{align_view, Align, Context, Editor};
|
||||||
use crate::ui::{FilePicker, Picker};
|
use crate::{
|
||||||
|
commands,
|
||||||
|
ui::{FilePicker, Picker, Prompt, PromptEvent},
|
||||||
|
};
|
||||||
use helix_core::Selection;
|
use helix_core::Selection;
|
||||||
use helix_dap::{self as dap, Client};
|
use helix_dap::{self as dap, Client};
|
||||||
use helix_lsp::block_on;
|
use helix_lsp::block_on;
|
||||||
@ -474,6 +477,74 @@ pub fn dap_terminate(cx: &mut Context) {
|
|||||||
cx.editor.debugger = None;
|
cx.editor.debugger = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dap_switch_thread(cx: &mut Context) {
|
pub fn dap_switch_thread(cx: &mut Context) {
|
||||||
thread_picker(cx, |editor, thread| {
|
thread_picker(cx, |editor, thread| {
|
||||||
block_on(select_thread_id(editor, thread.id, true));
|
block_on(select_thread_id(editor, thread.id, true));
|
||||||
|
@ -497,6 +497,7 @@ fn default() -> Keymaps {
|
|||||||
"n" => dap_next,
|
"n" => dap_next,
|
||||||
"v" => dap_variables,
|
"v" => dap_variables,
|
||||||
"t" => dap_terminate,
|
"t" => dap_terminate,
|
||||||
|
"C-c" => dap_edit_condition,
|
||||||
"s" => { "Switch"
|
"s" => { "Switch"
|
||||||
"t" => dap_switch_thread,
|
"t" => dap_switch_thread,
|
||||||
"f" => dap_switch_stack_frame,
|
"f" => dap_switch_stack_frame,
|
||||||
|
@ -795,6 +795,7 @@ fn debug_parameter_prompt(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ pub fn regex_prompt(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,6 +208,7 @@ pub fn new(
|
|||||||
|_editor: &mut Context, _pattern: &str, _event: PromptEvent| {
|
|_editor: &mut Context, _pattern: &str, _event: PromptEvent| {
|
||||||
//
|
//
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut picker = Self {
|
let mut picker = Self {
|
||||||
|
@ -59,10 +59,11 @@ pub fn new(
|
|||||||
history_register: Option<char>,
|
history_register: Option<char>,
|
||||||
mut completion_fn: impl FnMut(&str) -> Vec<Completion> + 'static,
|
mut completion_fn: impl FnMut(&str) -> Vec<Completion> + 'static,
|
||||||
callback_fn: impl FnMut(&mut Context, &str, PromptEvent) + 'static,
|
callback_fn: impl FnMut(&mut Context, &str, PromptEvent) + 'static,
|
||||||
|
line: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
prompt,
|
prompt,
|
||||||
line: String::new(),
|
line: line.unwrap_or_default(),
|
||||||
cursor: 0,
|
cursor: 0,
|
||||||
completion: completion_fn(""),
|
completion: completion_fn(""),
|
||||||
selection: None,
|
selection: None,
|
||||||
|
Loading…
Reference in New Issue
Block a user