New way of starting debug sessions

imgbot
Dmitry Sharshakov 3 years ago
parent 5e4da09be2
commit 8df6739759
No known key found for this signature in database
GPG Key ID: 471FD32E15FD8473

@ -304,6 +304,7 @@ impl Command {
surround_delete, "Surround delete", surround_delete, "Surround delete",
select_textobject_around, "Select around object", select_textobject_around, "Select around object",
select_textobject_inner, "Select inside object", select_textobject_inner, "Select inside object",
dap_launch, "Launch debug target",
dap_toggle_breakpoint, "Toggle breakpoint", dap_toggle_breakpoint, "Toggle breakpoint",
dap_run, "Begin program execution", dap_run, "Begin program execution",
dap_continue, "Continue program execution", dap_continue, "Continue program execution",
@ -4491,7 +4492,7 @@ fn suspend(_cx: &mut Context) {
} }
// DAP // DAP
fn dap_start_impl( pub fn dap_start_impl(
editor: &mut Editor, editor: &mut Editor,
name: Option<&str>, name: Option<&str>,
socket: Option<std::net::SocketAddr>, socket: Option<std::net::SocketAddr>,
@ -4596,6 +4597,41 @@ fn dap_start_impl(
editor.debugger_events.push(stream); editor.debugger_events.push(stream);
} }
fn dap_launch(cx: &mut Context) {
if cx.editor.debugger.is_some() {
cx.editor
.set_error("Can't start debug: debugger is running".to_string());
return;
}
let (_, doc) = current!(cx.editor);
let path = match doc.path() {
Some(path) => path.to_path_buf(),
None => {
cx.editor
.set_error("Can't start debug: document has no path".to_string());
return;
}
};
let config = cx
.editor
.syn_loader
.language_config_for_file_name(&path)
.and_then(|x| x.debugger.clone());
let config = match config {
Some(c) => c,
None => {
cx.editor.set_error(
"Can't start debug: no debug adapter available for language".to_string(),
);
return;
}
};
cx.editor.debug_config_picker = Some(config.templates.iter().map(|t| t.name.clone()).collect());
}
fn dap_toggle_breakpoint(cx: &mut Context) { fn dap_toggle_breakpoint(cx: &mut Context) {
use helix_lsp::block_on; use helix_lsp::block_on;

@ -486,6 +486,7 @@ impl Default for Keymaps {
"a" => code_action, "a" => code_action,
"'" => last_picker, "'" => last_picker,
"d" => { "Debug" "d" => { "Debug"
"s" => dap_launch,
"b" => dap_toggle_breakpoint, "b" => dap_toggle_breakpoint,
"r" => dap_run, "r" => dap_run,
"c" => dap_continue, "c" => dap_continue,

@ -30,6 +30,8 @@ use std::borrow::Cow;
use crossterm::event::{Event, MouseButton, MouseEvent, MouseEventKind}; use crossterm::event::{Event, MouseButton, MouseEvent, MouseEventKind};
use tui::buffer::Buffer as Surface; use tui::buffer::Buffer as Surface;
use super::{Prompt, PromptEvent};
pub struct EditorView { pub struct EditorView {
keymaps: Keymaps, keymaps: Keymaps,
on_next_key: Option<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>, on_next_key: Option<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>,
@ -712,6 +714,45 @@ impl EditorView {
) -> Option<KeymapResult> { ) -> Option<KeymapResult> {
self.autoinfo = None; self.autoinfo = None;
if let Some(picker) = cxt.editor.debug_config_picker.clone() {
match event {
KeyEvent {
code: KeyCode::Esc, ..
} => {}
KeyEvent {
code: KeyCode::Char(char),
..
} => {
let name = match picker.iter().find(|t| t.starts_with(char)) {
Some(n) => n.clone(),
None => return None,
};
let prompt = Prompt::new(
"arg:".to_owned(),
None,
|_input: &str| Vec::new(), // this is fine because Vec::new() doesn't allocate
move |cx: &mut crate::compositor::Context,
input: &str,
event: PromptEvent| {
if event != PromptEvent::Validate {
return;
}
commands::dap_start_impl(
cx.editor,
Some(&name),
None,
Some(vec![input]),
);
},
);
cxt.push_layer(Box::new(prompt));
}
_ => return None,
}
cxt.editor.debug_config_picker = None;
return None;
}
if cxt.editor.variables.is_some() { if cxt.editor.variables.is_some() {
match event { match event {
KeyEvent { KeyEvent {
@ -735,6 +776,7 @@ impl EditorView {
} }
return None; return None;
} }
match self.keymaps.get_mut(&mode).unwrap().get(event) { match self.keymaps.get_mut(&mode).unwrap().get(event) {
KeymapResult::Matched(command) => command.execute(cxt), KeymapResult::Matched(command) => command.execute(cxt),
KeymapResult::Pending(node) => self.autoinfo = Some(node.into()), KeymapResult::Pending(node) => self.autoinfo = Some(node.into()),
@ -1137,6 +1179,26 @@ impl Component for EditorView {
info.render(area, surface, cx); info.render(area, surface, cx);
} }
if let Some(ref configs) = cx.editor.debug_config_picker {
let mut text = String::new();
let mut height = 0;
let mut max_len = 20;
for line in configs {
max_len = max_len.max(line.len() as u16 + 2);
height += 1;
text.push_str(&format!("{} {}\n", line.chars().next().unwrap(), line));
}
let mut info = Info {
height: 20.min(height + 1),
width: 70.min(max_len),
title: "Debug targets".to_owned(),
text: text + "Exit Esc",
};
info.render(area, surface, cx);
}
if let Some(ref mut info) = self.autoinfo { if let Some(ref mut info) = self.autoinfo {
info.render(area, surface, cx); info.render(area, surface, cx);
} }

@ -76,6 +76,7 @@ pub struct Editor {
pub debugger: Option<helix_dap::Client>, pub debugger: Option<helix_dap::Client>,
pub debugger_events: SelectAll<UnboundedReceiverStream<helix_dap::Payload>>, pub debugger_events: SelectAll<UnboundedReceiverStream<helix_dap::Payload>>,
pub debug_config_picker: Option<Vec<String>>,
pub variables: Option<Vec<String>>, pub variables: Option<Vec<String>>,
pub variables_page: usize, pub variables_page: usize,
@ -118,6 +119,7 @@ impl Editor {
language_servers, language_servers,
debugger: None, debugger: None,
debugger_events: SelectAll::new(), debugger_events: SelectAll::new(),
debug_config_picker: None,
variables: None, variables: None,
variables_page: 0, variables_page: 0,
syn_loader: config_loader, syn_loader: config_loader,

Loading…
Cancel
Save