Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(debug): highlight current line #5957

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions book/src/themes.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,11 @@ These scopes are used for theming the editor interface:
| `ui.cursor.primary.normal` | |
| `ui.cursor.primary.insert` | |
| `ui.cursor.primary.select` | |
| `ui.debug.breakpoint` | Breakpoint indicator, found in the gutter |
| `ui.debug.active` | Indicator for the line at which debugging execution is paused at, found in the gutter |
| `ui.gutter` | Gutter |
| `ui.gutter.selected` | Gutter for the line the cursor is on |
| `ui.highlight.frameline` | Line at which debugging execution is paused at |
| `ui.linenr` | Line numbers |
| `ui.linenr.selected` | Line number for the line the cursor is on |
| `ui.statusline` | Statusline |
Expand Down
6 changes: 6 additions & 0 deletions helix-dap/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,4 +512,10 @@ impl Client {

self.call::<requests::SetExceptionBreakpoints>(args)
}

pub fn current_stack_frame(&self) -> Option<&StackFrame> {
self.stack_frames
.get(&self.thread_id?)?
.get(self.active_frame?)
}
}
52 changes: 18 additions & 34 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,40 +93,6 @@ impl EditorView {
let mut line_decorations: Vec<Box<dyn LineDecoration>> = Vec::new();
let mut translated_positions: Vec<TranslatedPosition> = Vec::new();

// DAP: Highlight current stack frame position
let stack_frame = editor.debugger.as_ref().and_then(|debugger| {
if let (Some(frame), Some(thread_id)) = (debugger.active_frame, debugger.thread_id) {
debugger
.stack_frames
.get(&thread_id)
.and_then(|bt| bt.get(frame))
} else {
None
}
});
if let Some(frame) = stack_frame {
if doc.path().is_some()
&& frame
.source
.as_ref()
.and_then(|source| source.path.as_ref())
== doc.path()
{
let line = frame.line - 1; // convert to 0-indexing
let style = theme.get("ui.highlight");
let line_decoration = move |renderer: &mut TextRenderer, pos: LinePos| {
if pos.doc_line != line {
return;
}
renderer
.surface
.set_style(Rect::new(area.x, pos.visual_line, area.width, 1), style);
};

line_decorations.push(Box::new(line_decoration));
}
}

if is_focused && config.cursorline {
line_decorations.push(Self::cursorline_decorator(doc, view, theme))
}
Expand All @@ -135,6 +101,23 @@ impl EditorView {
Self::highlight_cursorcolumn(doc, view, surface, theme, inner, &text_annotations);
}

// Set DAP highlights, if needed.
if let Some(frame) = editor.current_stack_frame() {
let dap_line = frame.line.saturating_sub(1) as usize;
let style = theme.get("ui.highlight.frameline");
let line_decoration = move |renderer: &mut TextRenderer, pos: LinePos| {
if pos.doc_line != dap_line {
return;
}
renderer.surface.set_style(
Rect::new(inner.x, inner.y + pos.visual_line, inner.width, 1),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a reference for other reviews:

Adding inner,.y is correct here, the fact that it was missing before was a regression from #5420

style,
);
};

line_decorations.push(Box::new(line_decoration));
}

let mut highlights =
Self::doc_syntax_highlights(doc, view.offset.anchor, inner.height, theme);
let overlay_highlights = Self::overlay_syntax_highlights(
Expand Down Expand Up @@ -422,6 +405,7 @@ impl EditorView {
let primary_selection_scope = theme
.find_scope_index_exact("ui.selection.primary")
.unwrap_or(selection_scope);

let base_cursor_scope = theme
.find_scope_index_exact("ui.cursor")
.unwrap_or(selection_scope);
Expand Down
7 changes: 7 additions & 0 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
view::ViewPosition,
Align, Document, DocumentId, View, ViewId,
};
use dap::StackFrame;
use helix_vcs::DiffProviderRegistry;

use futures_util::stream::select_all::SelectAll;
Expand Down Expand Up @@ -1657,6 +1658,12 @@ impl Editor {
doc.restore_cursor = false;
}
}

pub fn current_stack_frame(&self) -> Option<&StackFrame> {
self.debugger
.as_ref()
.and_then(|debugger| debugger.current_stack_frame())
}
}

fn try_restore_indent(doc: &mut Document, view: &mut View) {
Expand Down
60 changes: 42 additions & 18 deletions helix-view/src/gutter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt::Write;

use crate::{
editor::GutterType,
graphics::{Color, Style, UnderlineStyle},
graphics::{Style, UnderlineStyle},
Document, Editor, Theme, View,
};

Expand Down Expand Up @@ -245,9 +245,9 @@ pub fn breakpoints<'doc>(
theme: &Theme,
_is_focused: bool,
) -> GutterFn<'doc> {
let warning = theme.get("warning");
let error = theme.get("error");
let info = theme.get("info");
let breakpoint_style = theme.get("ui.debug.breakpoint");

let breakpoints = doc.path().and_then(|path| editor.breakpoints.get(path));

Expand All @@ -265,30 +265,52 @@ pub fn breakpoints<'doc>(
.iter()
.find(|breakpoint| breakpoint.line == line)?;

let mut style = if breakpoint.condition.is_some() && breakpoint.log_message.is_some() {
let style = if breakpoint.condition.is_some() && breakpoint.log_message.is_some() {
error.underline_style(UnderlineStyle::Line)
} else if breakpoint.condition.is_some() {
error
} else if breakpoint.log_message.is_some() {
info
} else {
warning
breakpoint_style
};

if !breakpoint.verified {
// Faded colors
style = if let Some(Color::Rgb(r, g, b)) = style.fg {
style.fg(Color::Rgb(
((r as f32) * 0.4).floor() as u8,
((g as f32) * 0.4).floor() as u8,
((b as f32) * 0.4).floor() as u8,
))
} else {
style.fg(Color::Gray)
}
};
let sym = if breakpoint.verified { "●" } else { "◯" };
write!(out, "{}", sym).unwrap();
Some(style)
},
)
}

fn execution_pause_indicator<'doc>(
editor: &'doc Editor,
doc: &'doc Document,
theme: &Theme,
is_focused: bool,
) -> GutterFn<'doc> {
let style = theme.get("ui.debug.active");
let current_stack_frame = editor.current_stack_frame();
let frame_line = current_stack_frame.map(|frame| frame.line - 1);
let frame_source_path = current_stack_frame.map(|frame| {
frame
.source
.as_ref()
.and_then(|source| source.path.as_ref())
});
let should_display_for_current_doc =
doc.path().is_some() && frame_source_path.unwrap_or(None) == doc.path();

Box::new(
move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| {
if !first_visual_line
|| !is_focused
|| line != frame_line?
|| !should_display_for_current_doc
{
return None;
}

let sym = if breakpoint.verified { "▲" } else { "⊚" };
let sym = "▶";
write!(out, "{}", sym).unwrap();
Some(style)
},
Expand All @@ -304,9 +326,11 @@ pub fn diagnostics_or_breakpoints<'doc>(
) -> GutterFn<'doc> {
let mut diagnostics = diagnostic(editor, doc, view, theme, is_focused);
let mut breakpoints = breakpoints(editor, doc, view, theme, is_focused);
let mut execution_pause_indicator = execution_pause_indicator(editor, doc, theme, is_focused);

Box::new(move |line, selected, first_visual_line: bool, out| {
breakpoints(line, selected, first_visual_line, out)
execution_pause_indicator(line, selected, first_visual_line, out)
.or_else(|| breakpoints(line, selected, first_visual_line, out))
.or_else(|| diagnostics(line, selected, first_visual_line, out))
})
}
Expand Down
2 changes: 2 additions & 0 deletions runtime/themes/acme.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"ui.virtual.ruler" = { bg = "acme_bar_bg" }
"ui.cursor.match" = {bg="acme_bar_bg"}
"ui.cursor" = {bg="cursor", fg="white"}
"ui.debug" = {fg="orange"}
"ui.highlight.frameline" = {bg="#da8581"}
"string" = "red"
"comment" = "green"
"ui.help" = {fg="black", bg="acme_bg"}
Expand Down
2 changes: 2 additions & 0 deletions runtime/themes/autumn.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
"ui.cursor.primary" = { fg = "my_white", modifiers = ["reversed"] }
"ui.cursorline.primary" = { bg = "my_black" }
"ui.cursorline.secondary" = { bg = "my_black" }
"ui.highlight.frameline" = { bg = "#8b6904" }
"ui.debug" = { fg = "my_yellow1", bg = "my_gray0" }
"ui.text" = "my_white"
"operator" = "my_white"
"ui.text.focus" = "my_white"
Expand Down
2 changes: 2 additions & 0 deletions runtime/themes/ayu_dark.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
"diagnostic.error"= { underline = { color = "red", style="curl"} }
"ui.bufferline" = { fg = "gray", bg = "background" }
"ui.bufferline.active" = { fg = "foreground", bg = "dark_gray" }
"ui.debug" = { fg = "orange", bg = "background" }
"ui.highlight.frameline" = { bg = "#0067a3" }

"special" = "orange"

Expand Down
2 changes: 2 additions & 0 deletions runtime/themes/ayu_light.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
"diagnostic.error"= { underline = { color = "red", style = "curl" } }
"ui.bufferline" = { fg = "gray", bg = "background" }
"ui.bufferline.active" = { fg = "foreground", bg = "dark_gray" }
"ui.debug" = { fg = "orange", bg = "background" }
"ui.highlight.frameline" = { bg = "#cfe0f2" }

"special" = "orange"

Expand Down
2 changes: 2 additions & 0 deletions runtime/themes/ayu_mirage.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
"diagnostic.error"= { underline = { color = "red", style = "curl" } }
"ui.bufferline" = { fg = "gray", bg = "background" }
"ui.bufferline.active" = { fg = "foreground", bg = "dark_gray" }
"ui.debug" = { fg = "orange", bg = "background" }
"ui.highlight.frameline" = { bg = "#0067a3" }

"special" = "orange"

Expand Down
2 changes: 2 additions & 0 deletions runtime/themes/dracula.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
"ui.cursor.primary" = { fg = "background", bg = "cyan", modifiers = ["dim"] }
"ui.cursorline.primary" = { bg = "background_dark" }
"ui.help" = { fg = "foreground", bg = "background_dark" }
"ui.debug" = { fg = "red" }
"ui.highlight.frameline" = { fg = "black", bg = "red" }
"ui.linenr" = { fg = "comment" }
"ui.linenr.selected" = { fg = "foreground" }
"ui.menu" = { fg = "foreground", bg = "background_dark" }
Expand Down
2 changes: 2 additions & 0 deletions runtime/themes/dracula_at_night.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
"ui.cursor.match" = { fg = "green", modifiers = ["underlined"] }
"ui.cursor.primary" = { fg = "background", bg = "cyan", modifiers = ["dim"] }
"ui.help" = { fg = "foreground", bg = "background_dark" }
"ui.debug" = { fg = "red" }
"ui.highlight.frameline" = { fg = "black", bg = "red" }
"ui.linenr" = { fg = "comment" }
"ui.linenr.selected" = { fg = "foreground" }
"ui.menu" = { fg = "foreground", bg = "background_dark" }
Expand Down
3 changes: 3 additions & 0 deletions runtime/themes/onedark.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"ui.cursorline.primary" = { bg = "light-black" }

"ui.highlight" = { bg = "gray" }
"ui.highlight.frameline" = { bg = "#97202a" }

"ui.linenr" = { fg = "linenr" }
"ui.linenr.selected" = { fg = "white" }
Expand All @@ -84,6 +85,8 @@
"ui.menu.selected" = { fg = "black", bg = "blue" }
"ui.menu.scroll" = { fg = "white", bg = "light-gray" }

"ui.debug" = { fg = "red" }

[palette]

yellow = "#E5C07B"
Expand Down
2 changes: 2 additions & 0 deletions runtime/themes/onedarker.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
"ui.text.focus" = { fg = "white", bg = "light-black", modifiers = ["bold"] }

"ui.help" = { fg = "white", bg = "gray" }
"ui.debug" = { fg = "red" }
"ui.highlight.frameline" = { bg = "#97202a" }
"ui.popup" = { bg = "gray" }
"ui.window" = { fg = "gray" }
"ui.menu" = { fg = "white", bg = "gray" }
Expand Down
4 changes: 3 additions & 1 deletion theme.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ label = "honey"
"ui.cursor" = { modifiers = ["reversed"] }
"ui.cursorline.primary" = { bg = "bossanova" }
"ui.highlight" = { bg = "bossanova" }

"ui.highlight.frameline" = { bg = "#634450" }
"ui.debug" = { fg = "#634450" }
"ui.debug.breakpoint" = { fg = "apricot" }
"ui.menu" = { fg = "lavender", bg = "revolver" }
"ui.menu.selected" = { fg = "revolver", bg = "white" }
"ui.menu.scroll" = { fg = "lavender", bg = "comet" }
Expand Down