Work towards a breakpoint UI
This commit is contained in:
parent
8759dc7e33
commit
94a1951d40
7 changed files with 69 additions and 15 deletions
|
@ -33,6 +33,9 @@ pub struct Client {
|
||||||
request_counter: AtomicU64,
|
request_counter: AtomicU64,
|
||||||
capabilities: Option<DebuggerCapabilities>,
|
capabilities: Option<DebuggerCapabilities>,
|
||||||
awaited_events: Arc<Mutex<HashMap<String, Sender<Event>>>>,
|
awaited_events: Arc<Mutex<HashMap<String, Sender<Event>>>>,
|
||||||
|
|
||||||
|
//
|
||||||
|
pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
|
@ -51,6 +54,8 @@ impl Client {
|
||||||
request_counter: AtomicU64::new(0),
|
request_counter: AtomicU64::new(0),
|
||||||
capabilities: None,
|
capabilities: None,
|
||||||
awaited_events: Arc::new(Mutex::new(HashMap::default())),
|
awaited_events: Arc::new(Mutex::new(HashMap::default())),
|
||||||
|
//
|
||||||
|
breakpoints: HashMap::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
tokio::spawn(Self::recv(Arc::clone(&client.awaited_events), server_rx));
|
tokio::spawn(Self::recv(Arc::clone(&client.awaited_events), server_rx));
|
||||||
|
|
|
@ -245,11 +245,7 @@ impl Application {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_debugger_message(
|
pub async fn handle_debugger_message(&mut self, call: ()) {
|
||||||
&mut self,
|
|
||||||
call: (),
|
|
||||||
server_id: usize,
|
|
||||||
) {
|
|
||||||
|
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,6 +302,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",
|
||||||
|
toggle_breakpoint, "Toggle breakpoint",
|
||||||
suspend, "Suspend"
|
suspend, "Suspend"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1913,25 +1914,21 @@ mod cmd {
|
||||||
// look up config for filetype
|
// look up config for filetype
|
||||||
// if multiple available, open picker
|
// if multiple available, open picker
|
||||||
|
|
||||||
log::error!("1");
|
|
||||||
|
|
||||||
let client = Client::tcp_process("dlv", vec!["dap"], "-l 127.0.0.1:{}", 0);
|
let client = Client::tcp_process("dlv", vec!["dap"], "-l 127.0.0.1:{}", 0);
|
||||||
let mut client = block_on(client)?;
|
let mut client = block_on(client)?;
|
||||||
log::error!("2");
|
|
||||||
|
|
||||||
let request = client.initialize("go".to_owned());
|
let request = client.initialize("go".to_owned());
|
||||||
let _ = block_on(request)?;
|
let _ = block_on(request)?;
|
||||||
log::error!("3");
|
|
||||||
|
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("mode", "debug");
|
args.insert("mode", "debug");
|
||||||
args.insert("program", "main");
|
args.insert("program", "main.go");
|
||||||
|
|
||||||
let request = client.launch(to_value(args)?);
|
let request = client.launch(to_value(args)?);
|
||||||
let _ = block_on(request)?;
|
let _ = block_on(request)?;
|
||||||
|
|
||||||
log::error!("4");
|
log::error!("4");
|
||||||
doc.debugger = Some(client);
|
cx.editor.debugger = Some(client);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4282,3 +4279,36 @@ fn suspend(_cx: &mut Context) {
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
signal_hook::low_level::raise(signal_hook::consts::signal::SIGTSTP).unwrap();
|
signal_hook::low_level::raise(signal_hook::consts::signal::SIGTSTP).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DAP
|
||||||
|
fn toggle_breakpoint(cx: &mut Context) {
|
||||||
|
let (view, doc) = current!(cx.editor);
|
||||||
|
let text = doc.text().slice(..);
|
||||||
|
let pos = doc.selection(view.id).primary().cursor(text);
|
||||||
|
|
||||||
|
let breakpoint = helix_dap::SourceBreakpoint {
|
||||||
|
line: text.char_to_line(pos),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = match doc.path() {
|
||||||
|
Some(path) => path.to_path_buf(),
|
||||||
|
None => {
|
||||||
|
cx.editor
|
||||||
|
.set_error("Can't set breakpoint: document has no path".to_string());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: need to map breakpoints over edits and update them?
|
||||||
|
// we shouldn't really allow editing while debug is running though
|
||||||
|
|
||||||
|
if let Some(debugger) = &mut cx.editor.debugger {
|
||||||
|
let breakpoints = debugger.breakpoints.entry(path).or_default();
|
||||||
|
if let Some(pos) = breakpoints.iter().position(|b| b.line == breakpoint.line) {
|
||||||
|
breakpoints.remove(pos);
|
||||||
|
} else {
|
||||||
|
breakpoints.push(breakpoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -485,6 +485,9 @@ impl Default for Keymaps {
|
||||||
"s" => symbol_picker,
|
"s" => symbol_picker,
|
||||||
"a" => code_action,
|
"a" => code_action,
|
||||||
"'" => last_picker,
|
"'" => last_picker,
|
||||||
|
"d" => { "Debug"
|
||||||
|
"b" => toggle_breakpoint,
|
||||||
|
},
|
||||||
"w" => { "Window"
|
"w" => { "Window"
|
||||||
"C-w" | "w" => rotate_view,
|
"C-w" | "w" => rotate_view,
|
||||||
"C-h" | "h" => hsplit,
|
"C-h" | "h" => hsplit,
|
||||||
|
|
|
@ -71,6 +71,7 @@ impl EditorView {
|
||||||
is_focused: bool,
|
is_focused: bool,
|
||||||
loader: &syntax::Loader,
|
loader: &syntax::Loader,
|
||||||
config: &helix_view::editor::Config,
|
config: &helix_view::editor::Config,
|
||||||
|
debugger: Option<&helix_dap::Client>,
|
||||||
) {
|
) {
|
||||||
let inner = view.inner_area();
|
let inner = view.inner_area();
|
||||||
let area = view.area;
|
let area = view.area;
|
||||||
|
@ -87,7 +88,9 @@ impl EditorView {
|
||||||
};
|
};
|
||||||
|
|
||||||
Self::render_text_highlights(doc, view.offset, inner, surface, theme, highlights);
|
Self::render_text_highlights(doc, view.offset, inner, surface, theme, highlights);
|
||||||
Self::render_gutter(doc, view, view.area, surface, theme, is_focused, config);
|
Self::render_gutter(
|
||||||
|
doc, view, view.area, surface, theme, is_focused, config, debugger,
|
||||||
|
);
|
||||||
|
|
||||||
if is_focused {
|
if is_focused {
|
||||||
Self::render_focused_view_elements(view, doc, inner, theme, surface);
|
Self::render_focused_view_elements(view, doc, inner, theme, surface);
|
||||||
|
@ -409,6 +412,7 @@ impl EditorView {
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
is_focused: bool,
|
is_focused: bool,
|
||||||
config: &helix_view::editor::Config,
|
config: &helix_view::editor::Config,
|
||||||
|
debugger: Option<&helix_dap::Client>,
|
||||||
) {
|
) {
|
||||||
let text = doc.text().slice(..);
|
let text = doc.text().slice(..);
|
||||||
let last_line = view.last_line(doc);
|
let last_line = view.last_line(doc);
|
||||||
|
@ -438,6 +442,10 @@ impl EditorView {
|
||||||
.map(|range| range.cursor_line(text))
|
.map(|range| range.cursor_line(text))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let breakpoints = doc
|
||||||
|
.path()
|
||||||
|
.and_then(|path| debugger.and_then(|debugger| debugger.breakpoints.get(path)));
|
||||||
|
|
||||||
for (i, line) in (view.offset.row..(last_line + 1)).enumerate() {
|
for (i, line) in (view.offset.row..(last_line + 1)).enumerate() {
|
||||||
use helix_core::diagnostic::Severity;
|
use helix_core::diagnostic::Severity;
|
||||||
if let Some(diagnostic) = doc.diagnostics().iter().find(|d| d.line == line) {
|
if let Some(diagnostic) = doc.diagnostics().iter().find(|d| d.line == line) {
|
||||||
|
@ -457,6 +465,14 @@ impl EditorView {
|
||||||
|
|
||||||
let selected = cursors.contains(&line);
|
let selected = cursors.contains(&line);
|
||||||
|
|
||||||
|
if let Some(breakpoint) = breakpoints.and_then(|breakpoints| {
|
||||||
|
breakpoints
|
||||||
|
.iter()
|
||||||
|
.find(|breakpoint| breakpoint.line == line)
|
||||||
|
}) {
|
||||||
|
surface.set_stringn(viewport.x, viewport.y + i as u16, "▲", 1, warning);
|
||||||
|
}
|
||||||
|
|
||||||
let text = if line == last_line && !draw_last {
|
let text = if line == last_line && !draw_last {
|
||||||
" ~".into()
|
" ~".into()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1007,6 +1023,7 @@ impl Component for EditorView {
|
||||||
for (view, is_focused) in cx.editor.tree.views() {
|
for (view, is_focused) in cx.editor.tree.views() {
|
||||||
let doc = cx.editor.document(view.doc).unwrap();
|
let doc = cx.editor.document(view.doc).unwrap();
|
||||||
let loader = &cx.editor.syn_loader;
|
let loader = &cx.editor.syn_loader;
|
||||||
|
let debugger = cx.editor.debugger.as_ref();
|
||||||
self.render_view(
|
self.render_view(
|
||||||
doc,
|
doc,
|
||||||
view,
|
view,
|
||||||
|
@ -1016,6 +1033,7 @@ impl Component for EditorView {
|
||||||
is_focused,
|
is_focused,
|
||||||
loader,
|
loader,
|
||||||
&cx.editor.config,
|
&cx.editor.config,
|
||||||
|
debugger,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,6 @@ pub struct Document {
|
||||||
|
|
||||||
diagnostics: Vec<Diagnostic>,
|
diagnostics: Vec<Diagnostic>,
|
||||||
language_server: Option<Arc<helix_lsp::Client>>,
|
language_server: Option<Arc<helix_lsp::Client>>,
|
||||||
pub debugger: Option<helix_dap::Client>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -426,7 +425,6 @@ impl Document {
|
||||||
history: Cell::new(History::default()),
|
history: Cell::new(History::default()),
|
||||||
last_saved_revision: 0,
|
last_saved_revision: 0,
|
||||||
language_server: None,
|
language_server: None,
|
||||||
debugger: None,
|
|
||||||
line_ending: DEFAULT_LINE_ENDING,
|
line_ending: DEFAULT_LINE_ENDING,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,10 @@ pub struct Editor {
|
||||||
pub registers: Registers,
|
pub registers: Registers,
|
||||||
pub theme: Theme,
|
pub theme: Theme,
|
||||||
pub language_servers: helix_lsp::Registry,
|
pub language_servers: helix_lsp::Registry,
|
||||||
pub debuggers: SelectAll<UnboundedReceiverStream<(usize, helix_dap::Payload)>>,
|
|
||||||
|
pub debugger: Option<helix_dap::Client>,
|
||||||
|
pub debuggers: SelectAll<UnboundedReceiverStream<helix_dap::Payload>>,
|
||||||
|
|
||||||
pub clipboard_provider: Box<dyn ClipboardProvider>,
|
pub clipboard_provider: Box<dyn ClipboardProvider>,
|
||||||
|
|
||||||
pub syn_loader: Arc<syntax::Loader>,
|
pub syn_loader: Arc<syntax::Loader>,
|
||||||
|
@ -111,6 +114,7 @@ impl Editor {
|
||||||
selected_register: RegisterSelection::default(),
|
selected_register: RegisterSelection::default(),
|
||||||
theme: themes.default(),
|
theme: themes.default(),
|
||||||
language_servers,
|
language_servers,
|
||||||
|
debugger: None,
|
||||||
debuggers: SelectAll::new(),
|
debuggers: SelectAll::new(),
|
||||||
syn_loader: config_loader,
|
syn_loader: config_loader,
|
||||||
theme_loader: themes,
|
theme_loader: themes,
|
||||||
|
|
Loading…
Add table
Reference in a new issue