Draw gutter highlights and indicators on top of blocks (#13142)

This ensures that the gutter progress in the inline assistant is
contiguous.

Release Notes:

- N/A
This commit is contained in:
Antonio Scandurra 2024-06-17 15:34:05 +02:00 committed by GitHub
parent 78091fa91e
commit 6322351f00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 73 additions and 64 deletions

View File

@ -335,24 +335,32 @@ impl InlineAssistant {
let buffer = editor.read(cx).buffer().read(cx).snapshot(cx);
let assist_range = assist.codegen.read(cx).range().to_offset(&buffer);
let editor = editor.read(cx);
if let Some(decorations) = assist.editor_decorations.as_ref() {
if editor.selections.count() == 1 {
let selection = editor.selections.newest::<usize>(cx);
if assist_range.contains(&selection.start) && assist_range.contains(&selection.end)
{
decorations.prompt_editor.update(cx, |prompt_editor, cx| {
prompt_editor.editor.update(cx, |editor, cx| {
editor.select_all(&SelectAll, cx);
editor.focus(cx);
let propagate = editor.update(cx, |editor, cx| {
if let Some(decorations) = assist.editor_decorations.as_ref() {
if editor.selections.count() == 1 {
let selection = editor.selections.newest::<usize>(cx);
if assist_range.contains(&selection.start)
&& assist_range.contains(&selection.end)
{
editor.change_selections(Some(Autoscroll::newest()), cx, |selections| {
selections.select_ranges([assist_range.start..assist_range.start]);
});
});
return;
decorations.prompt_editor.update(cx, |prompt_editor, cx| {
prompt_editor.editor.update(cx, |prompt_editor, cx| {
prompt_editor.select_all(&SelectAll, cx);
prompt_editor.focus(cx);
});
});
return false;
}
}
}
}
true
});
cx.propagate();
if propagate {
cx.propagate();
}
}
fn handle_editor_event(

View File

@ -2497,6 +2497,7 @@ impl Editor {
cx: &mut ViewContext<Self>,
) {
if !self.focus_handle.is_focused(cx) {
self.last_focused_descendant = None;
cx.focus(&self.focus_handle);
}
@ -2564,6 +2565,7 @@ impl Editor {
cx: &mut ViewContext<Self>,
) {
if !self.focus_handle.is_focused(cx) {
self.last_focused_descendant = None;
cx.focus(&self.focus_handle);
}

View File

@ -2810,38 +2810,12 @@ impl EditorElement {
}
}
fn paint_gutter(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
fn paint_line_numbers(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) {
let line_height = layout.position_map.line_height;
let scroll_position = layout.position_map.snapshot.scroll_position();
let scroll_top = scroll_position.y * line_height;
cx.set_cursor_style(CursorStyle::Arrow, &layout.gutter_hitbox);
for (_, hunk_hitbox) in &layout.display_hunks {
if let Some(hunk_hitbox) = hunk_hitbox {
cx.set_cursor_style(CursorStyle::PointingHand, hunk_hitbox);
}
}
let show_git_gutter = layout
.position_map
.snapshot
.show_git_diff_gutter
.unwrap_or_else(|| {
matches!(
ProjectSettings::get_global(cx).git.git_gutter,
Some(GitGutterSetting::TrackedFiles)
)
});
if show_git_gutter {
Self::paint_diff_hunks(layout.gutter_hitbox.bounds, layout, cx)
}
self.paint_gutter_highlights(layout, cx);
if layout.blamed_display_rows.is_some() {
self.paint_blamed_display_rows(layout, cx);
}
for (ix, line) in layout.line_numbers.iter().enumerate() {
if let Some(line) = line {
@ -2856,29 +2830,9 @@ impl EditorElement {
line.paint(line_origin, line_height, cx).log_err();
}
}
cx.paint_layer(layout.gutter_hitbox.bounds, |cx| {
cx.with_element_namespace("gutter_fold_toggles", |cx| {
for fold_indicator in layout.gutter_fold_toggles.iter_mut().flatten() {
fold_indicator.paint(cx);
}
});
for test_indicators in layout.test_indicators.iter_mut() {
test_indicators.paint(cx);
}
if let Some(indicator) = layout.code_actions_indicator.as_mut() {
indicator.paint(cx);
}
});
}
fn paint_diff_hunks(
gutter_bounds: Bounds<Pixels>,
layout: &EditorLayout,
cx: &mut WindowContext,
) {
fn paint_diff_hunks(layout: &EditorLayout, cx: &mut WindowContext) {
if layout.display_hunks.is_empty() {
return;
}
@ -2891,7 +2845,7 @@ impl EditorElement {
let hunk_bounds = Self::diff_hunk_bounds(
&layout.position_map.snapshot,
line_height,
gutter_bounds,
layout.gutter_hitbox.bounds,
&hunk,
);
Some((
@ -3008,7 +2962,45 @@ impl EditorElement {
}
}
fn paint_gutter_indicators(&self, layout: &mut EditorLayout, cx: &mut WindowContext) {
cx.paint_layer(layout.gutter_hitbox.bounds, |cx| {
cx.with_element_namespace("gutter_fold_toggles", |cx| {
for fold_indicator in layout.gutter_fold_toggles.iter_mut().flatten() {
fold_indicator.paint(cx);
}
});
for test_indicators in layout.test_indicators.iter_mut() {
test_indicators.paint(cx);
}
if let Some(indicator) = layout.code_actions_indicator.as_mut() {
indicator.paint(cx);
}
});
}
fn paint_gutter_highlights(&self, layout: &EditorLayout, cx: &mut WindowContext) {
for (_, hunk_hitbox) in &layout.display_hunks {
if let Some(hunk_hitbox) = hunk_hitbox {
cx.set_cursor_style(CursorStyle::PointingHand, hunk_hitbox);
}
}
let show_git_gutter = layout
.position_map
.snapshot
.show_git_diff_gutter
.unwrap_or_else(|| {
matches!(
ProjectSettings::get_global(cx).git.git_gutter,
Some(GitGutterSetting::TrackedFiles)
)
});
if show_git_gutter {
Self::paint_diff_hunks(layout, cx)
}
let highlight_width = 0.275 * layout.position_map.line_height;
let highlight_corner_radii = Corners::all(0.05 * layout.position_map.line_height);
cx.paint_layer(layout.gutter_hitbox.bounds, |cx| {
@ -5112,8 +5104,10 @@ impl Element for EditorElement {
self.paint_mouse_listeners(layout, hovered_hunk, cx);
self.paint_background(layout, cx);
self.paint_indent_guides(layout, cx);
if layout.gutter_hitbox.size.width > Pixels::ZERO {
self.paint_gutter(layout, cx)
self.paint_blamed_display_rows(layout, cx);
self.paint_line_numbers(layout, cx);
}
self.paint_text(layout, cx);
@ -5124,6 +5118,11 @@ impl Element for EditorElement {
});
}
if layout.gutter_hitbox.size.width > Pixels::ZERO {
self.paint_gutter_highlights(layout, cx);
self.paint_gutter_indicators(layout, cx);
}
self.paint_scrollbar(layout, cx);
self.paint_mouse_context_menu(layout, cx);
});