@@ -16,11 +16,11 @@ use helix_core::{
1616 unicode::width::UnicodeWidthStr,
1717 LineEnding, Position, Range, Selection,
1818};
19−use helix_dap::{SourceBreakpoint, StackFrame};
19+use helix_dap::{Breakpoint, SourceBreakpoint, StackFrame};
2020use helix_view::{
2121 document::Mode,
2222 editor::LineNumber,
23− graphics::{CursorKind, Modifier, Rect, Style},
23+ graphics::{Color, CursorKind, Modifier, Rect, Style},
2424 info::Info,
2525 input::KeyEvent,
2626 keyboard::{KeyCode, KeyModifiers},
@@ -76,7 +76,8 @@ impl EditorView {
7676 loader: &syntax::Loader,
7777 config: &helix_view::editor::Config,
7878 debugger: &Option<helix_dap::Client>,
79− breakpoints: &HashMap<PathBuf, Vec<helix_dap::SourceBreakpoint>>,
79+ all_breakpoints: &HashMap<PathBuf, Vec<SourceBreakpoint>>,
80+ dbg_breakpoints: &Option<Vec<Breakpoint>>,
8081 ) {
8182 let inner = view.inner_area();
8283 let area = view.area;
@@ -102,7 +103,8 @@ impl EditorView {
102103 is_focused,
103104 config,
104105 debugger,
105− breakpoints,
106+ all_breakpoints,
107+ dbg_breakpoints,
106108 );
107109
108110 if is_focused {
@@ -122,7 +124,7 @@ impl EditorView {
122124 }
123125 }
124126
125− self.render_diagnostics(doc, view, inner, surface, theme, breakpoints);
127+ self.render_diagnostics(doc, view, inner, surface, theme, all_breakpoints);
126128
127129 let statusline_area = view
128130 .area
@@ -426,7 +428,8 @@ impl EditorView {
426428 is_focused: bool,
427429 config: &helix_view::editor::Config,
428430 debugger: &Option<helix_dap::Client>,
429− all_breakpoints: &HashMap<PathBuf, Vec<helix_dap::SourceBreakpoint>>,
431+ all_breakpoints: &HashMap<PathBuf, Vec<SourceBreakpoint>>,
432+ dbg_breakpoints: &Option<Vec<Breakpoint>>,
430433 ) {
431434 let text = doc.text().slice(..);
432435 let last_line = view.last_line(doc);
@@ -500,10 +503,35 @@ impl EditorView {
500503
501504 let selected = cursors.contains(&line);
502505
503− if let Some(bps) = breakpoints.as_ref() {
504− if let Some(breakpoint) = bps.iter().find(|breakpoint| breakpoint.line - 1 == line)
506+ if let Some(user) = breakpoints.as_ref() {
507+ let debugger_breakpoint = if let Some(debugger) = dbg_breakpoints.as_ref() {
508+ debugger.iter().find(|breakpoint| {
509+ if breakpoint.source.is_some()
510+ && doc.path().is_some()
511+ && breakpoint.source.as_ref().unwrap().path == doc.path().cloned()
512+ {
513+ match (breakpoint.line, breakpoint.end_line) {
514+ #[allow(clippy::int_plus_one)]
515+ (Some(l), Some(el)) => l - 1 <= line && line <= el - 1,
516+ (Some(l), None) => l - 1 == line,
517+ _ => false,
518+ }
519+ } else {
520+ false
521+ }
522+ })
523+ } else {
524+ None
525+ };
526+
527+ if let Some(breakpoint) = user.iter().find(|breakpoint| breakpoint.line - 1 == line)
505528 {
506− let style =
529+ let unverified = match dbg_breakpoints {
530+ Some(_) => debugger_breakpoint.map(|b| !b.verified).unwrap_or(true),
531+ // We cannot mark breakpoint as unverified unless we have a debugger
532+ None => false,
533+ };
534+ let mut style =
507535 if breakpoint.condition.is_some() && breakpoint.log_message.is_some() {
508536 error.add_modifier(Modifier::UNDERLINED)
509537 } else if breakpoint.condition.is_some() {
@@ -513,7 +541,26 @@ impl EditorView {
513541 } else {
514542 warning
515543 };
544+ if unverified {
545+ // Faded colors
546+ style = if let Some(Color::Rgb(r, g, b)) = style.fg {
547+ style.fg(Color::Rgb(
548+ ((r as f32) * 0.4).floor() as u8,
549+ ((g as f32) * 0.4).floor() as u8,
550+ ((b as f32) * 0.4).floor() as u8,
551+ ))
552+ } else {
553+ style.fg(Color::Gray)
554+ }
555+ };
516556 surface.set_stringn(viewport.x, viewport.y + i as u16, "▲", 1, style);
557+ } else if let Some(breakpoint) = debugger_breakpoint {
558+ let style = if breakpoint.verified {
559+ info
560+ } else {
561+ info.fg(Color::Gray)
562+ };
563+ surface.set_stringn(viewport.x, viewport.y + i as u16, "⊚", 1, style);
517564 }
518565 }
519566
@@ -563,7 +610,7 @@ impl EditorView {
563610 viewport: Rect,
564611 surface: &mut Surface,
565612 theme: &Theme,
566− all_breakpoints: &HashMap<PathBuf, Vec<helix_dap::SourceBreakpoint>>,
613+ all_breakpoints: &HashMap<PathBuf, Vec<SourceBreakpoint>>,
567614 ) {
568615 use helix_core::diagnostic::Severity;
569616 use tui::{
@@ -602,8 +649,8 @@ impl EditorView {
602649 }
603650
604651 if let Some(path) = doc.path() {
652+ let line = doc.text().char_to_line(cursor);
605653 if let Some(breakpoints) = all_breakpoints.get(path) {
606− let line = doc.text().char_to_line(cursor);
607654 if let Some(breakpoint) = breakpoints
608655 .iter()
609656 .find(|breakpoint| breakpoint.line - 1 == line)
@@ -1272,6 +1319,7 @@ impl Component for EditorView {
12721319 for (view, is_focused) in cx.editor.tree.views() {
12731320 let doc = cx.editor.document(view.doc).unwrap();
12741321 let loader = &cx.editor.syn_loader;
1322+ let dbg_breakpoints = cx.editor.debugger.as_ref().map(|d| d.breakpoints.clone());
12751323 self.render_view(
12761324 doc,
12771325 view,
@@ -1283,6 +1331,7 @@ impl Component for EditorView {
12831331 &cx.editor.config,
12841332 &cx.editor.debugger,
12851333 &cx.editor.breakpoints,
1334+ &dbg_breakpoints,
12861335 );
12871336 }
12881337