summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-08-19 02:24:53 +0000
committerBlaž Hrastnik2021-08-20 04:51:38 +0000
commit94a1951d40d26f4f535bdb5aab5668c84fdd95ae (patch)
treef0cfbfca98cbddbb3388f935671eaee00343b53a
parent8759dc7e3389a6215f6a28e3e89e4a4912aca3c4 (diff)
Work towards a breakpoint UI
-rw-r--r--helix-dap/src/client.rs5
-rw-r--r--helix-term/src/application.rs6
-rw-r--r--helix-term/src/commands.rs42
-rw-r--r--helix-term/src/keymap.rs3
-rw-r--r--helix-term/src/ui/editor.rs20
-rw-r--r--helix-view/src/document.rs2
-rw-r--r--helix-view/src/editor.rs6
7 files changed, 69 insertions, 15 deletions
diff --git a/helix-dap/src/client.rs b/helix-dap/src/client.rs
index 487022cf..84704b96 100644
--- a/helix-dap/src/client.rs
+++ b/helix-dap/src/client.rs
@@ -33,6 +33,9 @@ pub struct Client {
request_counter: AtomicU64,
capabilities: Option<DebuggerCapabilities>,
awaited_events: Arc<Mutex<HashMap<String, Sender<Event>>>>,
+
+ //
+ pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>,
}
impl Client {
@@ -51,6 +54,8 @@ impl Client {
request_counter: AtomicU64::new(0),
capabilities: None,
awaited_events: Arc::new(Mutex::new(HashMap::default())),
+ //
+ breakpoints: HashMap::new(),
};
tokio::spawn(Self::recv(Arc::clone(&client.awaited_events), server_rx));
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index 59072a09..42b9bcde 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -245,11 +245,7 @@ impl Application {
}
}
- pub async fn handle_debugger_message(
- &mut self,
- call: (),
- server_id: usize,
- ) {
+ pub async fn handle_debugger_message(&mut self, call: ()) {
//
}
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index bcab85c4..ddbf1cb5 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -302,6 +302,7 @@ impl Command {
surround_delete, "Surround delete",
select_textobject_around, "Select around object",
select_textobject_inner, "Select inside object",
+ toggle_breakpoint, "Toggle breakpoint",
suspend, "Suspend"
);
}
@@ -1913,25 +1914,21 @@ mod cmd {
// look up config for filetype
// if multiple available, open picker
- log::error!("1");
-
let client = Client::tcp_process("dlv", vec!["dap"], "-l 127.0.0.1:{}", 0);
let mut client = block_on(client)?;
- log::error!("2");
let request = client.initialize("go".to_owned());
let _ = block_on(request)?;
- log::error!("3");
let mut args = HashMap::new();
args.insert("mode", "debug");
- args.insert("program", "main");
+ args.insert("program", "main.go");
let request = client.launch(to_value(args)?);
let _ = block_on(request)?;
log::error!("4");
- doc.debugger = Some(client);
+ cx.editor.debugger = Some(client);
Ok(())
}
@@ -4282,3 +4279,36 @@ fn suspend(_cx: &mut Context) {
#[cfg(not(windows))]
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);
+ }
+ }
+}
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index 57bcb321..05b75c5d 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -485,6 +485,9 @@ impl Default for Keymaps {
"s" => symbol_picker,
"a" => code_action,
"'" => last_picker,
+ "d" => { "Debug"
+ "b" => toggle_breakpoint,
+ },
"w" => { "Window"
"C-w" | "w" => rotate_view,
"C-h" | "h" => hsplit,
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index b0e6de3e..074f322e 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -71,6 +71,7 @@ impl EditorView {
is_focused: bool,
loader: &syntax::Loader,
config: &helix_view::editor::Config,
+ debugger: Option<&helix_dap::Client>,
) {
let inner = view.inner_area();
let area = view.area;
@@ -87,7 +88,9 @@ impl EditorView {
};
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 {
Self::render_focused_view_elements(view, doc, inner, theme, surface);
@@ -409,6 +412,7 @@ impl EditorView {
theme: &Theme,
is_focused: bool,
config: &helix_view::editor::Config,
+ debugger: Option<&helix_dap::Client>,
) {
let text = doc.text().slice(..);
let last_line = view.last_line(doc);
@@ -438,6 +442,10 @@ impl EditorView {
.map(|range| range.cursor_line(text))
.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() {
use helix_core::diagnostic::Severity;
if let Some(diagnostic) = doc.diagnostics().iter().find(|d| d.line == line) {
@@ -457,6 +465,14 @@ impl EditorView {
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 {
" ~".into()
} else {
@@ -1007,6 +1023,7 @@ impl Component for EditorView {
for (view, is_focused) in cx.editor.tree.views() {
let doc = cx.editor.document(view.doc).unwrap();
let loader = &cx.editor.syn_loader;
+ let debugger = cx.editor.debugger.as_ref();
self.render_view(
doc,
view,
@@ -1016,6 +1033,7 @@ impl Component for EditorView {
is_focused,
loader,
&cx.editor.config,
+ debugger,
);
}
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index 3e8ed21c..ff0c8bf4 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -100,7 +100,6 @@ pub struct Document {
diagnostics: Vec<Diagnostic>,
language_server: Option<Arc<helix_lsp::Client>>,
- pub debugger: Option<helix_dap::Client>,
}
use std::fmt;
@@ -426,7 +425,6 @@ impl Document {
history: Cell::new(History::default()),
last_saved_revision: 0,
language_server: None,
- debugger: None,
line_ending: DEFAULT_LINE_ENDING,
}
}
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 7b9f34fc..1fae59be 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -73,7 +73,10 @@ pub struct Editor {
pub registers: Registers,
pub theme: Theme,
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 syn_loader: Arc<syntax::Loader>,
@@ -111,6 +114,7 @@ impl Editor {
selected_register: RegisterSelection::default(),
theme: themes.default(),
language_servers,
+ debugger: None,
debuggers: SelectAll::new(),
syn_loader: config_loader,
theme_loader: themes,