Add stack pointer display when stopped

pull/574/head
Dmitry Sharshakov 3 years ago
parent 738e8a4dd3
commit 6458edecfd
No known key found for this signature in database
GPG Key ID: 471FD32E15FD8473

@ -36,6 +36,8 @@ pub struct Client {
// //
pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>, pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>,
// TODO: multiple threads support
pub stack_pointer: Option<StackFrame>,
} }
impl Client { impl Client {
@ -56,6 +58,7 @@ impl Client {
awaited_events: Arc::new(Mutex::new(HashMap::default())), awaited_events: Arc::new(Mutex::new(HashMap::default())),
// //
breakpoints: HashMap::new(), breakpoints: HashMap::new(),
stack_pointer: None,
}; };
tokio::spawn(Self::recv(Arc::clone(&client.awaited_events), server_rx)); tokio::spawn(Self::recv(Arc::clone(&client.awaited_events), server_rx));

@ -24,6 +24,7 @@ use helix_lsp::{
}; };
use insert::*; use insert::*;
use movement::Movement; use movement::Movement;
use tokio::sync::{mpsc::Receiver, Mutex};
use crate::{ use crate::{
compositor::{self, Component, Compositor}, compositor::{self, Component, Compositor},
@ -32,8 +33,8 @@ use crate::{
use crate::job::{self, Job, Jobs}; use crate::job::{self, Job, Jobs};
use futures_util::FutureExt; use futures_util::FutureExt;
use std::num::NonZeroUsize;
use std::{collections::HashMap, fmt, future::Future}; use std::{collections::HashMap, fmt, future::Future};
use std::{num::NonZeroUsize, sync::Arc};
use std::{ use std::{
borrow::Cow, borrow::Cow,
@ -4267,11 +4268,34 @@ fn dap_start(cx: &mut Context) {
let request = debugger.launch(to_value(args).unwrap()); let request = debugger.launch(to_value(args).unwrap());
let _ = block_on(request).unwrap(); let _ = block_on(request).unwrap();
// TODO: either await "initialized" or buffer commands until event is received let stopped = block_on(debugger.listen_for_event("stopped".to_owned()));
let debugger = Arc::new(Mutex::new(debugger));
tokio::spawn(dap_listen_stopped(stopped, Arc::clone(&debugger)));
// TODO: either await "initialized" or buffer commands until event is received
cx.editor.debugger = Some(debugger); cx.editor.debugger = Some(debugger);
} }
async fn dap_listen_stopped(
mut stopped: Receiver<helix_dap::Event>,
debugger: Arc<Mutex<helix_dap::Client>>,
) {
loop {
stopped.recv().await;
let mut dbg = debugger.lock().await;
let main = dbg
.threads()
.await
.ok()
.and_then(|threads| threads.get(0).and_then(|x| Some(x.clone())));
if let Some(main) = main {
let (a, _) = dbg.stack_trace(main.id).await.unwrap();
dbg.stack_pointer = a.get(0).and_then(|x| Some(x.clone()));
}
}
}
fn dap_toggle_breakpoint(cx: &mut Context) { fn dap_toggle_breakpoint(cx: &mut Context) {
use helix_lsp::block_on; use helix_lsp::block_on;
@ -4297,6 +4321,7 @@ fn dap_toggle_breakpoint(cx: &mut Context) {
// we shouldn't really allow editing while debug is running though // we shouldn't really allow editing while debug is running though
if let Some(debugger) = &mut cx.editor.debugger { if let Some(debugger) = &mut cx.editor.debugger {
let mut debugger = block_on(debugger.lock());
let breakpoints = debugger.breakpoints.entry(path.clone()).or_default(); let breakpoints = debugger.breakpoints.entry(path.clone()).or_default();
if let Some(pos) = breakpoints.iter().position(|b| b.line == breakpoint.line) { if let Some(pos) = breakpoints.iter().position(|b| b.line == breakpoint.line) {
breakpoints.remove(pos); breakpoints.remove(pos);
@ -4315,6 +4340,7 @@ fn dap_run(cx: &mut Context) {
use helix_lsp::block_on; use helix_lsp::block_on;
if let Some(debugger) = &mut cx.editor.debugger { if let Some(debugger) = &mut cx.editor.debugger {
let mut debugger = block_on(debugger.lock());
let request = debugger.configuration_done(); let request = debugger.configuration_done();
let _ = block_on(request).unwrap(); let _ = block_on(request).unwrap();
} }

@ -15,6 +15,7 @@ use helix_core::{
unicode::width::UnicodeWidthStr, unicode::width::UnicodeWidthStr,
LineEnding, Position, Range, Selection, LineEnding, Position, Range, Selection,
}; };
use helix_dap::{SourceBreakpoint, StackFrame};
use helix_view::{ use helix_view::{
document::Mode, document::Mode,
editor::LineNumber, editor::LineNumber,
@ -24,7 +25,8 @@ use helix_view::{
keyboard::{KeyCode, KeyModifiers}, keyboard::{KeyCode, KeyModifiers},
Document, Editor, Theme, View, Document, Editor, Theme, View,
}; };
use std::borrow::Cow; use std::{borrow::Cow, sync::Arc};
use tokio::sync::Mutex;
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;
@ -71,7 +73,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>, debugger: Option<Arc<Mutex<helix_dap::Client>>>,
) { ) {
let inner = view.inner_area(); let inner = view.inner_area();
let area = view.area; let area = view.area;
@ -412,8 +414,9 @@ 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>, debugger: Option<Arc<Mutex<helix_dap::Client>>>,
) { ) {
use helix_lsp::block_on;
let text = doc.text().slice(..); let text = doc.text().slice(..);
let last_line = view.last_line(doc); let last_line = view.last_line(doc);
@ -442,9 +445,15 @@ impl EditorView {
.map(|range| range.cursor_line(text)) .map(|range| range.cursor_line(text))
.collect(); .collect();
let breakpoints = doc let mut breakpoints: Option<Vec<SourceBreakpoint>> = None;
.path() let mut stack_pointer: Option<StackFrame> = None;
.and_then(|path| debugger.and_then(|debugger| debugger.breakpoints.get(path))); if let Some(debugger) = debugger {
if let Some(path) = doc.path() {
let dbg = block_on(debugger.lock());
breakpoints = dbg.breakpoints.get(path).and_then(|bps| Some(bps.clone()));
stack_pointer = dbg.stack_pointer.clone()
}
}
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;
@ -465,12 +474,23 @@ impl EditorView {
let selected = cursors.contains(&line); let selected = cursors.contains(&line);
if let Some(_breakpoint) = breakpoints.and_then(|breakpoints| { if let Some(bps) = breakpoints.as_ref() {
breakpoints if let Some(_) = bps.iter().find(|breakpoint| breakpoint.line == line) {
.iter() surface.set_stringn(viewport.x, viewport.y + i as u16, "▲", 1, warning);
.find(|breakpoint| breakpoint.line == line) }
}) { }
surface.set_stringn(viewport.x, viewport.y + i as u16, "▲", 1, warning);
if let Some(sp) = stack_pointer.as_ref() {
if let Some(src) = sp.source.as_ref() {
if doc
.path()
.and_then(|path| Some(src.path == Some(path.clone())))
.unwrap_or(false)
&& sp.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 {
@ -1023,7 +1043,10 @@ 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(); let mut dbg: Option<Arc<Mutex<helix_dap::Client>>> = None;
if let Some(debugger) = &cx.editor.debugger {
dbg = Some(Arc::clone(&debugger));
}
self.render_view( self.render_view(
doc, doc,
view, view,
@ -1033,7 +1056,7 @@ impl Component for EditorView {
is_focused, is_focused,
loader, loader,
&cx.editor.config, &cx.editor.config,
debugger, dbg,
); );
} }

@ -8,6 +8,7 @@ use crate::{
use futures_util::future; use futures_util::future;
use futures_util::stream::select_all::SelectAll; use futures_util::stream::select_all::SelectAll;
use tokio::sync::Mutex;
use tokio_stream::wrappers::UnboundedReceiverStream; use tokio_stream::wrappers::UnboundedReceiverStream;
use std::{ use std::{
@ -74,7 +75,7 @@ pub struct Editor {
pub theme: Theme, pub theme: Theme,
pub language_servers: helix_lsp::Registry, pub language_servers: helix_lsp::Registry,
pub debugger: Option<helix_dap::Client>, pub debugger: Option<Arc<Mutex<helix_dap::Client>>>,
pub debuggers: SelectAll<UnboundedReceiverStream<helix_dap::Payload>>, pub debuggers: SelectAll<UnboundedReceiverStream<helix_dap::Payload>>,
pub clipboard_provider: Box<dyn ClipboardProvider>, pub clipboard_provider: Box<dyn ClipboardProvider>,

Loading…
Cancel
Save