Skip to content

Commit bda88b1

Browse files
committed
feat(debug): highlight current line
Add new theme highlight keys, for setting the colour of the breakpoint character and the current line at which execution has been paused at. The two new keys are `ui.highlight.frameline` and `ui.debug.breakpoint`. Highlight according to those keys, both the line at which debugging is paused at and the breakpoint indicator. Add an indicator for the current line at which execution is paused at, themed by the `ui.debug.active` theme scope. Update various themes to showcase how the new functionality works. Better icons are dependent on #2869, and as such will be handled in the future, once it lands. Closes: #5952 Signed-off-by: Filip Dutescu <[email protected]>
1 parent ce1fb9e commit bda88b1

File tree

16 files changed

+155
-112
lines changed

16 files changed

+155
-112
lines changed

book/src/themes.md

Lines changed: 56 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -261,58 +261,61 @@ These scopes are used for theming the editor interface:
261261
- `hover` - for hover popup UI
262262

263263

264-
| Key | Notes |
265-
| --- | --- |
266-
| `ui.background` | |
267-
| `ui.background.separator` | Picker separator below input line |
268-
| `ui.cursor` | |
269-
| `ui.cursor.normal` | |
270-
| `ui.cursor.insert` | |
271-
| `ui.cursor.select` | |
272-
| `ui.cursor.match` | Matching bracket etc. |
273-
| `ui.cursor.primary` | Cursor with primary selection |
274-
| `ui.cursor.primary.normal` | |
275-
| `ui.cursor.primary.insert` | |
276-
| `ui.cursor.primary.select` | |
277-
| `ui.gutter` | Gutter |
278-
| `ui.gutter.selected` | Gutter for the line the cursor is on |
279-
| `ui.linenr` | Line numbers |
280-
| `ui.linenr.selected` | Line number for the line the cursor is on |
281-
| `ui.statusline` | Statusline |
282-
| `ui.statusline.inactive` | Statusline (unfocused document) |
283-
| `ui.statusline.normal` | Statusline mode during normal mode ([only if `editor.color-modes` is enabled][editor-section]) |
284-
| `ui.statusline.insert` | Statusline mode during insert mode ([only if `editor.color-modes` is enabled][editor-section]) |
285-
| `ui.statusline.select` | Statusline mode during select mode ([only if `editor.color-modes` is enabled][editor-section]) |
286-
| `ui.statusline.separator` | Separator character in statusline |
287-
| `ui.popup` | Documentation popups (e.g. Space + k) |
288-
| `ui.popup.info` | Prompt for multiple key options |
289-
| `ui.window` | Borderlines separating splits |
290-
| `ui.help` | Description box for commands |
291-
| `ui.text` | Command prompts, popup text, etc. |
292-
| `ui.text.focus` | |
293-
| `ui.text.inactive` | Same as `ui.text` but when the text is inactive (e.g. suggestions) |
294-
| `ui.text.info` | The key: command text in `ui.popup.info` boxes |
295-
| `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][editor-section]) |
296-
| `ui.virtual.whitespace` | Visible whitespace characters |
297-
| `ui.virtual.indent-guide` | Vertical indent width guides |
298-
| `ui.virtual.wrap` | Soft-wrap indicator (see the [`editor.soft-wrap` config][editor-section]) |
299-
| `ui.menu` | Code and command completion menus |
300-
| `ui.menu.selected` | Selected autocomplete item |
301-
| `ui.menu.scroll` | `fg` sets thumb color, `bg` sets track color of scrollbar |
302-
| `ui.selection` | For selections in the editing area |
303-
| `ui.selection.primary` | |
304-
| `ui.cursorline.primary` | The line of the primary cursor ([if cursorline is enabled][editor-section]) |
305-
| `ui.cursorline.secondary` | The lines of any other cursors ([if cursorline is enabled][editor-section]) |
306-
| `ui.cursorcolumn.primary` | The column of the primary cursor ([if cursorcolumn is enabled][editor-section]) |
307-
| `ui.cursorcolumn.secondary` | The columns of any other cursors ([if cursorcolumn is enabled][editor-section]) |
308-
| `warning` | Diagnostics warning (gutter) |
309-
| `error` | Diagnostics error (gutter) |
310-
| `info` | Diagnostics info (gutter) |
311-
| `hint` | Diagnostics hint (gutter) |
312-
| `diagnostic` | Diagnostics fallback style (editing area) |
313-
| `diagnostic.hint` | Diagnostics hint (editing area) |
314-
| `diagnostic.info` | Diagnostics info (editing area) |
315-
| `diagnostic.warning` | Diagnostics warning (editing area) |
316-
| `diagnostic.error` | Diagnostics error (editing area) |
264+
| Key | Notes |
265+
| --- | --- |
266+
| `ui.background` | |
267+
| `ui.background.separator` | Picker separator below input line |
268+
| `ui.cursor` | |
269+
| `ui.cursor.normal` | |
270+
| `ui.cursor.insert` | |
271+
| `ui.cursor.select` | |
272+
| `ui.cursor.match` | Matching bracket etc. |
273+
| `ui.cursor.primary` | Cursor with primary selection |
274+
| `ui.cursor.primary.normal` | |
275+
| `ui.cursor.primary.insert` | |
276+
| `ui.cursor.primary.select` | |
277+
| `ui.debug.breakpoint` | Color of the breakpoint indicator, found in the gutter |
278+
| `ui.debug.active` | Color of the indicator for the line at which debugging execution is paused at, found in the gutter |
279+
| `ui.gutter` | Gutter |
280+
| `ui.gutter.selected` | Gutter for the line the cursor is on |
281+
| `ui.highlight.frameline` | Color on the line at which debugging execution is paused at |
282+
| `ui.linenr` | Line numbers |
283+
| `ui.linenr.selected` | Line number for the line the cursor is on |
284+
| `ui.statusline` | Statusline |
285+
| `ui.statusline.inactive` | Statusline (unfocused document) |
286+
| `ui.statusline.normal` | Statusline mode during normal mode ([only if `editor.color-modes` is enabled][editor-section]) |
287+
| `ui.statusline.insert` | Statusline mode during insert mode ([only if `editor.color-modes` is enabled][editor-section]) |
288+
| `ui.statusline.select` | Statusline mode during select mode ([only if `editor.color-modes` is enabled][editor-section]) |
289+
| `ui.statusline.separator` | Separator character in statusline |
290+
| `ui.popup` | Documentation popups (e.g. Space + k) |
291+
| `ui.popup.info` | Prompt for multiple key options |
292+
| `ui.window` | Borderlines separating splits |
293+
| `ui.help` | Description box for commands |
294+
| `ui.text` | Command prompts, popup text, etc. |
295+
| `ui.text.focus` | |
296+
| `ui.text.inactive` | Same as `ui.text` but when the text is inactive (e.g. suggestions) |
297+
| `ui.text.info` | The key: command text in `ui.popup.info` boxes |
298+
| `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][editor-section]) |
299+
| `ui.virtual.whitespace` | Visible whitespace characters |
300+
| `ui.virtual.indent-guide` | Vertical indent width guides |
301+
| `ui.virtual.wrap` | Soft-wrap indicator (see the [`editor.soft-wrap` config][editor-section]) |
302+
| `ui.menu` | Code and command completion menus |
303+
| `ui.menu.selected` | Selected autocomplete item |
304+
| `ui.menu.scroll` | `fg` sets thumb color, `bg` sets track color of scrollbar |
305+
| `ui.selection` | For selections in the editing area |
306+
| `ui.selection.primary` | |
307+
| `ui.cursorline.primary` | The line of the primary cursor ([if cursorline is enabled][editor-section]) |
308+
| `ui.cursorline.secondary` | The lines of any other cursors ([if cursorline is enabled][editor-section]) |
309+
| `ui.cursorcolumn.primary` | The column of the primary cursor ([if cursorcolumn is enabled][editor-section]) |
310+
| `ui.cursorcolumn.secondary` | The columns of any other cursors ([if cursorcolumn is enabled][editor-section]) |
311+
| `warning` | Diagnostics warning (gutter) |
312+
| `error` | Diagnostics error (gutter) |
313+
| `info` | Diagnostics info (gutter) |
314+
| `hint` | Diagnostics hint (gutter) |
315+
| `diagnostic` | Diagnostics fallback style (editing area) |
316+
| `diagnostic.hint` | Diagnostics hint (editing area) |
317+
| `diagnostic.info` | Diagnostics info (editing area) |
318+
| `diagnostic.warning` | Diagnostics warning (editing area) |
319+
| `diagnostic.error` | Diagnostics error (editing area) |
317320

318321
[editor-section]: ./configuration.md#editor-section

helix-dap/src/client.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,4 +512,10 @@ impl Client {
512512

513513
self.call::<requests::SetExceptionBreakpoints>(args)
514514
}
515+
516+
pub fn current_stack_frame(&self) -> Option<&StackFrame> {
517+
self.stack_frames
518+
.get(&self.thread_id?)?
519+
.get(self.active_frame?)
520+
}
515521
}

helix-term/src/ui/editor.rs

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -92,40 +92,6 @@ impl EditorView {
9292
let mut line_decorations: Vec<Box<dyn LineDecoration>> = Vec::new();
9393
let mut translated_positions: Vec<TranslatedPosition> = Vec::new();
9494

95-
// DAP: Highlight current stack frame position
96-
let stack_frame = editor.debugger.as_ref().and_then(|debugger| {
97-
if let (Some(frame), Some(thread_id)) = (debugger.active_frame, debugger.thread_id) {
98-
debugger
99-
.stack_frames
100-
.get(&thread_id)
101-
.and_then(|bt| bt.get(frame))
102-
} else {
103-
None
104-
}
105-
});
106-
if let Some(frame) = stack_frame {
107-
if doc.path().is_some()
108-
&& frame
109-
.source
110-
.as_ref()
111-
.and_then(|source| source.path.as_ref())
112-
== doc.path()
113-
{
114-
let line = frame.line - 1; // convert to 0-indexing
115-
let style = theme.get("ui.highlight");
116-
let line_decoration = move |renderer: &mut TextRenderer, pos: LinePos| {
117-
if pos.doc_line != line {
118-
return;
119-
}
120-
renderer
121-
.surface
122-
.set_style(Rect::new(area.x, pos.visual_line, area.width, 1), style);
123-
};
124-
125-
line_decorations.push(Box::new(line_decoration));
126-
}
127-
}
128-
12995
if is_focused && config.cursorline {
13096
line_decorations.push(Self::cursorline_decorator(doc, view, theme))
13197
}
@@ -134,6 +100,23 @@ impl EditorView {
134100
Self::highlight_cursorcolumn(doc, view, surface, theme, inner, &text_annotations);
135101
}
136102

103+
// Set DAP highlights, if needed.
104+
if let Some(frame) = editor.current_stack_frame() {
105+
let dap_line = frame.line.saturating_sub(1) as usize;
106+
let style = theme.get("ui.highlight.frameline");
107+
let line_decoration = move |renderer: &mut TextRenderer, pos: LinePos| {
108+
if pos.doc_line != dap_line {
109+
return;
110+
}
111+
renderer.surface.set_style(
112+
Rect::new(inner.x, inner.y + pos.visual_line, inner.width, 1),
113+
style,
114+
);
115+
};
116+
117+
line_decorations.push(Box::new(line_decoration));
118+
}
119+
137120
let mut highlights =
138121
Self::doc_syntax_highlights(doc, view.offset.anchor, inner.height, theme);
139122
let overlay_highlights = Self::overlay_syntax_highlights(
@@ -421,6 +404,7 @@ impl EditorView {
421404
let primary_selection_scope = theme
422405
.find_scope_index_exact("ui.selection.primary")
423406
.unwrap_or(selection_scope);
407+
424408
let base_cursor_scope = theme
425409
.find_scope_index_exact("ui.cursor")
426410
.unwrap_or(selection_scope);

helix-view/src/editor.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
view::ViewPosition,
1111
Align, Document, DocumentId, View, ViewId,
1212
};
13+
use dap::StackFrame;
1314
use helix_vcs::DiffProviderRegistry;
1415

1516
use futures_util::stream::select_all::SelectAll;
@@ -1630,6 +1631,12 @@ impl Editor {
16301631
doc.restore_cursor = false;
16311632
}
16321633
}
1634+
1635+
pub fn current_stack_frame(&self) -> Option<&StackFrame> {
1636+
self.debugger
1637+
.as_ref()
1638+
.and_then(|debugger| debugger.current_stack_frame())
1639+
}
16331640
}
16341641

16351642
fn try_restore_indent(doc: &mut Document, view: &mut View) {

0 commit comments

Comments
 (0)