@@ -2,7 +2,7 @@ use std::fmt::Write;
3use crate::{
3use crate::{
4 editor::GutterType,
4 editor::GutterType,
5− graphics::{Color, Style, UnderlineStyle},
5+ graphics::{Style, UnderlineStyle},
6 Document, Editor, Theme, View,
6 Document, Editor, Theme, View,
@@ -245,9 +245,9 @@ pub fn breakpoints<'doc>(
245 theme: &Theme,
245 theme: &Theme,
246 _is_focused: bool,
246 _is_focused: bool,
247) -> GutterFn<'doc> {
247) -> GutterFn<'doc> {
248− let warning = theme.get("warning");
249 let error = theme.get("error");
248 let error = theme.get("error");
250 let info = theme.get("info");
249 let info = theme.get("info");
250+ let breakpoint_style = theme.get("ui.debug.breakpoint");
252 let breakpoints = doc.path().and_then(|path| editor.breakpoints.get(path));
252 let breakpoints = doc.path().and_then(|path| editor.breakpoints.get(path));
@@ -265,30 +265,52 @@ pub fn breakpoints<'doc>(
266 .find(|breakpoint| breakpoint.line == line)?;
266 .find(|breakpoint| breakpoint.line == line)?;
268− let mut style = if breakpoint.condition.is_some() && breakpoint.log_message.is_some() {
268+ let style = if breakpoint.condition.is_some() && breakpoint.log_message.is_some() {
269 error.underline_style(UnderlineStyle::Line)
269 error.underline_style(UnderlineStyle::Line)
270 } else if breakpoint.condition.is_some() {
270 } else if breakpoint.condition.is_some() {
272 } else if breakpoint.log_message.is_some() {
272 } else if breakpoint.log_message.is_some() {
275− warning
275+ breakpoint_style
278− if !breakpoint.verified {
278+ let sym = if breakpoint.verified { "●" } else { "◯" };
279− // Faded colors
279+ write!(out, "{}", sym).unwrap();
280− style = if let Some(Color::Rgb(r, g, b)) = style.fg {
280+ Some(style)
281− style.fg(Color::Rgb(
281+ },
282− ((r as f32) * 0.4).floor() as u8,
282+ )
283− ((g as f32) * 0.4).floor() as u8,
283+}
284− ((b as f32) * 0.4).floor() as u8,
284+
285− ))
285+fn execution_pause_indicator<'doc>(
286− } else {
286+ editor: &'doc Editor,
287− style.fg(Color::Gray)
287+ doc: &'doc Document,
288− }
288+ theme: &Theme,
290+) -> GutterFn<'doc> {
291+ let style = theme.get("ui.debug.active");
292+ let current_stack_frame = editor.current_stack_frame();
293+ let frame_line = current_stack_frame.map(|frame| frame.line - 1);
294+ let frame_source_path = current_stack_frame.map(|frame| {
298+ .and_then(|source| source.path.as_ref())
300+ let should_display_for_current_doc =
301+ doc.path().is_some() && frame_source_path.unwrap_or(None) == doc.path();
304+ move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| {
305+ if !first_visual_line
307+ || line != frame_line?
308+ || !should_display_for_current_doc
291− let sym = if breakpoint.verified { "▲" } else { "⊚" };
313+ let sym = "▶";
292 write!(out, "{}", sym).unwrap();
314 write!(out, "{}", sym).unwrap();
293 Some(style)
315 Some(style)
@@ -304,9 +326,11 @@ pub fn diagnostics_or_breakpoints<'doc>(
304) -> GutterFn<'doc> {
326) -> GutterFn<'doc> {
305 let mut diagnostics = diagnostic(editor, doc, view, theme, is_focused);
327 let mut diagnostics = diagnostic(editor, doc, view, theme, is_focused);
306 let mut breakpoints = breakpoints(editor, doc, view, theme, is_focused);
328 let mut breakpoints = breakpoints(editor, doc, view, theme, is_focused);
329+ let mut execution_pause_indicator = execution_pause_indicator(editor, doc, theme, is_focused);
308 Box::new(move |line, selected, first_visual_line: bool, out| {
331 Box::new(move |line, selected, first_visual_line: bool, out| {
332+ execution_pause_indicator(line, selected, first_visual_line, out)
309− breakpoints(line, selected, first_visual_line, out)
333+ .or_else(|| breakpoints(line, selected, first_visual_line, out))
310 .or_else(|| diagnostics(line, selected, first_visual_line, out))
334 .or_else(|| diagnostics(line, selected, first_visual_line, out))