commit view: Fix layout shift while loading commit (#44548)
Fixes a few cases where the commit view would layout shift as the diff loaded. This was caused by: - Adding the commit message buffer after all the diff files - Using the gutter dimensions from the last frame for the avatar spacing Release Notes: - commit view: Fix layout shift while loading commit --------- Co-authored-by: MrSubidubi <dev@bahn.sh>
This commit is contained in:
co-authored by
MrSubidubi
parent
dd431631b4
commit
21f7e6a9e6
+190
-154
@@ -108,7 +108,7 @@ use gpui::{
|
||||
DispatchPhase, Edges, Entity, EntityInputHandler, EventEmitter, FocusHandle, FocusOutEvent,
|
||||
Focusable, FontId, FontWeight, Global, HighlightStyle, Hsla, KeyContext, Modifiers,
|
||||
MouseButton, MouseDownEvent, MouseMoveEvent, PaintQuad, ParentElement, Pixels, Render,
|
||||
ScrollHandle, SharedString, Size, Stateful, Styled, Subscription, Task, TextStyle,
|
||||
ScrollHandle, SharedString, Size, Stateful, Styled, Subscription, Task, TextRun, TextStyle,
|
||||
TextStyleRefinement, UTF16Selection, UnderlineStyle, UniformListScrollHandle, WeakEntity,
|
||||
WeakFocusHandle, Window, div, point, prelude::*, pulsating_between, px, relative, size,
|
||||
};
|
||||
@@ -575,7 +575,7 @@ impl Default for EditorStyle {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_inlay_hints_style(cx: &mut App) -> HighlightStyle {
|
||||
pub fn make_inlay_hints_style(cx: &App) -> HighlightStyle {
|
||||
let show_background = language_settings::language_settings(None, None, cx)
|
||||
.inlay_hints
|
||||
.show_background;
|
||||
@@ -598,7 +598,7 @@ pub fn make_inlay_hints_style(cx: &mut App) -> HighlightStyle {
|
||||
style
|
||||
}
|
||||
|
||||
pub fn make_suggestion_styles(cx: &mut App) -> EditPredictionStyles {
|
||||
pub fn make_suggestion_styles(cx: &App) -> EditPredictionStyles {
|
||||
EditPredictionStyles {
|
||||
insertion: HighlightStyle {
|
||||
color: Some(cx.theme().status().predictive),
|
||||
@@ -1249,6 +1249,7 @@ impl NextScrollCursorCenterTopBottom {
|
||||
pub struct EditorSnapshot {
|
||||
pub mode: EditorMode,
|
||||
show_gutter: bool,
|
||||
offset_content: bool,
|
||||
show_line_numbers: Option<bool>,
|
||||
show_git_diff_gutter: Option<bool>,
|
||||
show_code_actions: Option<bool>,
|
||||
@@ -1825,7 +1826,11 @@ impl Editor {
|
||||
Editor::new_internal(mode, buffer, project, None, window, cx)
|
||||
}
|
||||
|
||||
pub fn sticky_headers(&self, cx: &App) -> Option<Vec<OutlineItem<Anchor>>> {
|
||||
pub fn sticky_headers(
|
||||
&self,
|
||||
style: &EditorStyle,
|
||||
cx: &App,
|
||||
) -> Option<Vec<OutlineItem<Anchor>>> {
|
||||
let multi_buffer = self.buffer().read(cx);
|
||||
let multi_buffer_snapshot = multi_buffer.snapshot(cx);
|
||||
let multi_buffer_visible_start = self
|
||||
@@ -1843,7 +1848,7 @@ impl Editor {
|
||||
.outline_items_containing(
|
||||
Point::new(start_row, 0)..Point::new(end_row, 0),
|
||||
true,
|
||||
self.style().map(|style| style.syntax.as_ref()),
|
||||
Some(style.syntax.as_ref()),
|
||||
)
|
||||
.into_iter()
|
||||
.map(|outline_item| OutlineItem {
|
||||
@@ -2935,6 +2940,7 @@ impl Editor {
|
||||
EditorSnapshot {
|
||||
mode: self.mode.clone(),
|
||||
show_gutter: self.show_gutter,
|
||||
offset_content: self.offset_content,
|
||||
show_line_numbers: self.show_line_numbers,
|
||||
show_git_diff_gutter: self.show_git_diff_gutter,
|
||||
show_code_actions: self.show_code_actions,
|
||||
@@ -6895,7 +6901,7 @@ impl Editor {
|
||||
};
|
||||
|
||||
let anchor = self.selections.newest_anchor().head();
|
||||
let position = self.to_pixel_point(anchor, &snapshot, window);
|
||||
let position = self.to_pixel_point(anchor, &snapshot, window, cx);
|
||||
if let (Some(position), Some(last_bounds)) = (position, self.last_bounds) {
|
||||
self.show_blame_popover(
|
||||
buffer,
|
||||
@@ -9208,7 +9214,8 @@ impl Editor {
|
||||
|
||||
let size = element.layout_as_root(AvailableSpace::min_size(), window, cx);
|
||||
|
||||
let line_origin = self.display_to_pixel_point(target_line_end, editor_snapshot, window)?;
|
||||
let line_origin =
|
||||
self.display_to_pixel_point(target_line_end, editor_snapshot, window, cx)?;
|
||||
|
||||
let start_point = content_origin - point(scroll_pixel_position.x.into(), Pixels::ZERO);
|
||||
let mut origin = start_point
|
||||
@@ -9950,8 +9957,7 @@ impl Editor {
|
||||
}
|
||||
|
||||
pub fn render_context_menu(
|
||||
&self,
|
||||
style: &EditorStyle,
|
||||
&mut self,
|
||||
max_height_in_lines: u32,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
@@ -9961,7 +9967,9 @@ impl Editor {
|
||||
if !menu.visible() {
|
||||
return None;
|
||||
};
|
||||
Some(menu.render(style, max_height_in_lines, window, cx))
|
||||
self.style
|
||||
.as_ref()
|
||||
.map(|style| menu.render(style, max_height_in_lines, window, cx))
|
||||
}
|
||||
|
||||
fn render_context_menu_aside(
|
||||
@@ -20364,8 +20372,11 @@ impl Editor {
|
||||
self.style = Some(style);
|
||||
}
|
||||
|
||||
pub fn style(&self) -> Option<&EditorStyle> {
|
||||
self.style.as_ref()
|
||||
pub fn style(&mut self, cx: &App) -> &EditorStyle {
|
||||
if self.style.is_none() {
|
||||
self.style = Some(self.create_style(cx));
|
||||
}
|
||||
self.style.as_ref().unwrap()
|
||||
}
|
||||
|
||||
// Called by the element. This method is not designed to be called outside of the editor
|
||||
@@ -22989,22 +23000,24 @@ impl Editor {
|
||||
}
|
||||
|
||||
pub fn to_pixel_point(
|
||||
&self,
|
||||
&mut self,
|
||||
source: multi_buffer::Anchor,
|
||||
editor_snapshot: &EditorSnapshot,
|
||||
window: &mut Window,
|
||||
cx: &App,
|
||||
) -> Option<gpui::Point<Pixels>> {
|
||||
let source_point = source.to_display_point(editor_snapshot);
|
||||
self.display_to_pixel_point(source_point, editor_snapshot, window)
|
||||
self.display_to_pixel_point(source_point, editor_snapshot, window, cx)
|
||||
}
|
||||
|
||||
pub fn display_to_pixel_point(
|
||||
&self,
|
||||
&mut self,
|
||||
source: DisplayPoint,
|
||||
editor_snapshot: &EditorSnapshot,
|
||||
window: &mut Window,
|
||||
cx: &App,
|
||||
) -> Option<gpui::Point<Pixels>> {
|
||||
let line_height = self.style()?.text.line_height_in_pixels(window.rem_size());
|
||||
let line_height = self.style(cx).text.line_height_in_pixels(window.rem_size());
|
||||
let text_layout_details = self.text_layout_details(window);
|
||||
let scroll_top = text_layout_details
|
||||
.scroll_anchor
|
||||
@@ -23068,10 +23081,6 @@ impl Editor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn last_gutter_dimensions(&self) -> &GutterDimensions {
|
||||
&self.gutter_dimensions
|
||||
}
|
||||
|
||||
pub fn wait_for_diff_to_load(&self) -> Option<Shared<Task<()>>> {
|
||||
self.load_diff_task.clone()
|
||||
}
|
||||
@@ -23171,6 +23180,57 @@ impl Editor {
|
||||
// skip any LSP updates for it.
|
||||
self.active_diagnostics == ActiveDiagnostic::All || !self.mode().is_full()
|
||||
}
|
||||
|
||||
fn create_style(&self, cx: &App) -> EditorStyle {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
|
||||
let mut text_style = match self.mode {
|
||||
EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle {
|
||||
color: cx.theme().colors().editor_foreground,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings.ui_font.features.clone(),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: rems(0.875).into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
line_height: relative(settings.buffer_line_height.value()),
|
||||
..Default::default()
|
||||
},
|
||||
EditorMode::Full { .. } | EditorMode::Minimap { .. } => TextStyle {
|
||||
color: cx.theme().colors().editor_foreground,
|
||||
font_family: settings.buffer_font.family.clone(),
|
||||
font_features: settings.buffer_font.features.clone(),
|
||||
font_fallbacks: settings.buffer_font.fallbacks.clone(),
|
||||
font_size: settings.buffer_font_size(cx).into(),
|
||||
font_weight: settings.buffer_font.weight,
|
||||
line_height: relative(settings.buffer_line_height.value()),
|
||||
..Default::default()
|
||||
},
|
||||
};
|
||||
if let Some(text_style_refinement) = &self.text_style_refinement {
|
||||
text_style.refine(text_style_refinement)
|
||||
}
|
||||
|
||||
let background = match self.mode {
|
||||
EditorMode::SingleLine => cx.theme().system().transparent,
|
||||
EditorMode::AutoHeight { .. } => cx.theme().system().transparent,
|
||||
EditorMode::Full { .. } => cx.theme().colors().editor_background,
|
||||
EditorMode::Minimap { .. } => cx.theme().colors().editor_background.opacity(0.7),
|
||||
};
|
||||
|
||||
EditorStyle {
|
||||
background,
|
||||
border: cx.theme().colors().border,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
scrollbar_width: EditorElement::SCROLLBAR_WIDTH,
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
status: cx.theme().status().clone(),
|
||||
inlay_hints_style: make_inlay_hints_style(cx),
|
||||
edit_prediction_styles: make_suggestion_styles(cx),
|
||||
unnecessary_code_fade: settings.unnecessary_code_fade,
|
||||
show_underlines: self.diagnostics_enabled(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn edit_for_markdown_paste<'a>(
|
||||
@@ -24698,94 +24758,98 @@ impl EditorSnapshot {
|
||||
self.scroll_anchor.scroll_position(&self.display_snapshot)
|
||||
}
|
||||
|
||||
fn gutter_dimensions(
|
||||
pub fn gutter_dimensions(
|
||||
&self,
|
||||
font_id: FontId,
|
||||
font_size: Pixels,
|
||||
max_line_number_width: Pixels,
|
||||
style: &EditorStyle,
|
||||
window: &mut Window,
|
||||
cx: &App,
|
||||
) -> Option<GutterDimensions> {
|
||||
if !self.show_gutter {
|
||||
return None;
|
||||
) -> GutterDimensions {
|
||||
if self.show_gutter
|
||||
&& let Some(ch_width) = cx.text_system().ch_width(font_id, font_size).log_err()
|
||||
&& let Some(ch_advance) = cx.text_system().ch_advance(font_id, font_size).log_err()
|
||||
{
|
||||
let show_git_gutter = self.show_git_diff_gutter.unwrap_or_else(|| {
|
||||
matches!(
|
||||
ProjectSettings::get_global(cx).git.git_gutter,
|
||||
GitGutterSetting::TrackedFiles
|
||||
)
|
||||
});
|
||||
let gutter_settings = EditorSettings::get_global(cx).gutter;
|
||||
let show_line_numbers = self
|
||||
.show_line_numbers
|
||||
.unwrap_or(gutter_settings.line_numbers);
|
||||
let line_gutter_width = if show_line_numbers {
|
||||
// Avoid flicker-like gutter resizes when the line number gains another digit by
|
||||
// only resizing the gutter on files with > 10**min_line_number_digits lines.
|
||||
let min_width_for_number_on_gutter =
|
||||
ch_advance * gutter_settings.min_line_number_digits as f32;
|
||||
self.max_line_number_width(style, window)
|
||||
.max(min_width_for_number_on_gutter)
|
||||
} else {
|
||||
0.0.into()
|
||||
};
|
||||
|
||||
let show_runnables = self.show_runnables.unwrap_or(gutter_settings.runnables);
|
||||
let show_breakpoints = self.show_breakpoints.unwrap_or(gutter_settings.breakpoints);
|
||||
|
||||
let git_blame_entries_width =
|
||||
self.git_blame_gutter_max_author_length
|
||||
.map(|max_author_length| {
|
||||
let renderer = cx.global::<GlobalBlameRenderer>().0.clone();
|
||||
const MAX_RELATIVE_TIMESTAMP: &str = "60 minutes ago";
|
||||
|
||||
/// The number of characters to dedicate to gaps and margins.
|
||||
const SPACING_WIDTH: usize = 4;
|
||||
|
||||
let max_char_count = max_author_length.min(renderer.max_author_length())
|
||||
+ ::git::SHORT_SHA_LENGTH
|
||||
+ MAX_RELATIVE_TIMESTAMP.len()
|
||||
+ SPACING_WIDTH;
|
||||
|
||||
ch_advance * max_char_count
|
||||
});
|
||||
|
||||
let is_singleton = self.buffer_snapshot().is_singleton();
|
||||
|
||||
let mut left_padding = git_blame_entries_width.unwrap_or(Pixels::ZERO);
|
||||
left_padding += if !is_singleton {
|
||||
ch_width * 4.0
|
||||
} else if show_runnables || show_breakpoints {
|
||||
ch_width * 3.0
|
||||
} else if show_git_gutter && show_line_numbers {
|
||||
ch_width * 2.0
|
||||
} else if show_git_gutter || show_line_numbers {
|
||||
ch_width
|
||||
} else {
|
||||
px(0.)
|
||||
};
|
||||
|
||||
let shows_folds = is_singleton && gutter_settings.folds;
|
||||
|
||||
let right_padding = if shows_folds && show_line_numbers {
|
||||
ch_width * 4.0
|
||||
} else if shows_folds || (!is_singleton && show_line_numbers) {
|
||||
ch_width * 3.0
|
||||
} else if show_line_numbers {
|
||||
ch_width
|
||||
} else {
|
||||
px(0.)
|
||||
};
|
||||
|
||||
GutterDimensions {
|
||||
left_padding,
|
||||
right_padding,
|
||||
width: line_gutter_width + left_padding + right_padding,
|
||||
margin: GutterDimensions::default_gutter_margin(font_id, font_size, cx),
|
||||
git_blame_entries_width,
|
||||
}
|
||||
} else if self.offset_content {
|
||||
GutterDimensions::default_with_margin(font_id, font_size, cx)
|
||||
} else {
|
||||
GutterDimensions::default()
|
||||
}
|
||||
|
||||
let ch_width = cx.text_system().ch_width(font_id, font_size).log_err()?;
|
||||
let ch_advance = cx.text_system().ch_advance(font_id, font_size).log_err()?;
|
||||
|
||||
let show_git_gutter = self.show_git_diff_gutter.unwrap_or_else(|| {
|
||||
matches!(
|
||||
ProjectSettings::get_global(cx).git.git_gutter,
|
||||
GitGutterSetting::TrackedFiles
|
||||
)
|
||||
});
|
||||
let gutter_settings = EditorSettings::get_global(cx).gutter;
|
||||
let show_line_numbers = self
|
||||
.show_line_numbers
|
||||
.unwrap_or(gutter_settings.line_numbers);
|
||||
let line_gutter_width = if show_line_numbers {
|
||||
// Avoid flicker-like gutter resizes when the line number gains another digit by
|
||||
// only resizing the gutter on files with > 10**min_line_number_digits lines.
|
||||
let min_width_for_number_on_gutter =
|
||||
ch_advance * gutter_settings.min_line_number_digits as f32;
|
||||
max_line_number_width.max(min_width_for_number_on_gutter)
|
||||
} else {
|
||||
0.0.into()
|
||||
};
|
||||
|
||||
let show_runnables = self.show_runnables.unwrap_or(gutter_settings.runnables);
|
||||
let show_breakpoints = self.show_breakpoints.unwrap_or(gutter_settings.breakpoints);
|
||||
|
||||
let git_blame_entries_width =
|
||||
self.git_blame_gutter_max_author_length
|
||||
.map(|max_author_length| {
|
||||
let renderer = cx.global::<GlobalBlameRenderer>().0.clone();
|
||||
const MAX_RELATIVE_TIMESTAMP: &str = "60 minutes ago";
|
||||
|
||||
/// The number of characters to dedicate to gaps and margins.
|
||||
const SPACING_WIDTH: usize = 4;
|
||||
|
||||
let max_char_count = max_author_length.min(renderer.max_author_length())
|
||||
+ ::git::SHORT_SHA_LENGTH
|
||||
+ MAX_RELATIVE_TIMESTAMP.len()
|
||||
+ SPACING_WIDTH;
|
||||
|
||||
ch_advance * max_char_count
|
||||
});
|
||||
|
||||
let is_singleton = self.buffer_snapshot().is_singleton();
|
||||
|
||||
let mut left_padding = git_blame_entries_width.unwrap_or(Pixels::ZERO);
|
||||
left_padding += if !is_singleton {
|
||||
ch_width * 4.0
|
||||
} else if show_runnables || show_breakpoints {
|
||||
ch_width * 3.0
|
||||
} else if show_git_gutter && show_line_numbers {
|
||||
ch_width * 2.0
|
||||
} else if show_git_gutter || show_line_numbers {
|
||||
ch_width
|
||||
} else {
|
||||
px(0.)
|
||||
};
|
||||
|
||||
let shows_folds = is_singleton && gutter_settings.folds;
|
||||
|
||||
let right_padding = if shows_folds && show_line_numbers {
|
||||
ch_width * 4.0
|
||||
} else if shows_folds || (!is_singleton && show_line_numbers) {
|
||||
ch_width * 3.0
|
||||
} else if show_line_numbers {
|
||||
ch_width
|
||||
} else {
|
||||
px(0.)
|
||||
};
|
||||
|
||||
Some(GutterDimensions {
|
||||
left_padding,
|
||||
right_padding,
|
||||
width: line_gutter_width + left_padding + right_padding,
|
||||
margin: GutterDimensions::default_gutter_margin(font_id, font_size, cx),
|
||||
git_blame_entries_width,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn render_crease_toggle(
|
||||
@@ -24868,6 +24932,28 @@ impl EditorSnapshot {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn max_line_number_width(&self, style: &EditorStyle, window: &mut Window) -> Pixels {
|
||||
let digit_count = self.widest_line_number().ilog10() + 1;
|
||||
column_pixels(style, digit_count as usize, window)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn column_pixels(style: &EditorStyle, column: usize, window: &Window) -> Pixels {
|
||||
let font_size = style.text.font_size.to_pixels(window.rem_size());
|
||||
let layout = window.text_system().shape_line(
|
||||
SharedString::from(" ".repeat(column)),
|
||||
font_size,
|
||||
&[TextRun {
|
||||
len: column,
|
||||
font: style.text.font(),
|
||||
color: Hsla::default(),
|
||||
..Default::default()
|
||||
}],
|
||||
None,
|
||||
);
|
||||
|
||||
layout.width
|
||||
}
|
||||
|
||||
impl Deref for EditorSnapshot {
|
||||
@@ -24948,57 +25034,7 @@ impl Focusable for Editor {
|
||||
|
||||
impl Render for Editor {
|
||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
|
||||
let mut text_style = match self.mode {
|
||||
EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle {
|
||||
color: cx.theme().colors().editor_foreground,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings.ui_font.features.clone(),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: rems(0.875).into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
line_height: relative(settings.buffer_line_height.value()),
|
||||
..Default::default()
|
||||
},
|
||||
EditorMode::Full { .. } | EditorMode::Minimap { .. } => TextStyle {
|
||||
color: cx.theme().colors().editor_foreground,
|
||||
font_family: settings.buffer_font.family.clone(),
|
||||
font_features: settings.buffer_font.features.clone(),
|
||||
font_fallbacks: settings.buffer_font.fallbacks.clone(),
|
||||
font_size: settings.buffer_font_size(cx).into(),
|
||||
font_weight: settings.buffer_font.weight,
|
||||
line_height: relative(settings.buffer_line_height.value()),
|
||||
..Default::default()
|
||||
},
|
||||
};
|
||||
if let Some(text_style_refinement) = &self.text_style_refinement {
|
||||
text_style.refine(text_style_refinement)
|
||||
}
|
||||
|
||||
let background = match self.mode {
|
||||
EditorMode::SingleLine => cx.theme().system().transparent,
|
||||
EditorMode::AutoHeight { .. } => cx.theme().system().transparent,
|
||||
EditorMode::Full { .. } => cx.theme().colors().editor_background,
|
||||
EditorMode::Minimap { .. } => cx.theme().colors().editor_background.opacity(0.7),
|
||||
};
|
||||
|
||||
EditorElement::new(
|
||||
&cx.entity(),
|
||||
EditorStyle {
|
||||
background,
|
||||
border: cx.theme().colors().border,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
scrollbar_width: EditorElement::SCROLLBAR_WIDTH,
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
status: cx.theme().status().clone(),
|
||||
inlay_hints_style: make_inlay_hints_style(cx),
|
||||
edit_prediction_styles: make_suggestion_styles(cx),
|
||||
unnecessary_code_fade: ThemeSettings::get_global(cx).unnecessary_code_fade,
|
||||
show_underlines: self.diagnostics_enabled(),
|
||||
},
|
||||
)
|
||||
EditorElement::new(&cx.entity(), self.create_style(cx))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2218,10 +2218,9 @@ async fn test_move_start_of_paragraph_end_of_paragraph(cx: &mut TestAppContext)
|
||||
init_test(cx, |_| {});
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
|
||||
let line_height = cx.editor(|editor, window, _| {
|
||||
let line_height = cx.update_editor(|editor, window, cx| {
|
||||
editor
|
||||
.style()
|
||||
.unwrap()
|
||||
.style(cx)
|
||||
.text
|
||||
.line_height_in_pixels(window.rem_size())
|
||||
});
|
||||
@@ -2334,10 +2333,9 @@ async fn test_move_start_of_paragraph_end_of_paragraph(cx: &mut TestAppContext)
|
||||
async fn test_scroll_page_up_page_down(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
let line_height = cx.editor(|editor, window, _| {
|
||||
let line_height = cx.update_editor(|editor, window, cx| {
|
||||
editor
|
||||
.style()
|
||||
.unwrap()
|
||||
.style(cx)
|
||||
.text
|
||||
.line_height_in_pixels(window.rem_size())
|
||||
});
|
||||
@@ -2400,8 +2398,7 @@ async fn test_autoscroll(cx: &mut TestAppContext) {
|
||||
let line_height = cx.update_editor(|editor, window, cx| {
|
||||
editor.set_vertical_scroll_margin(2, cx);
|
||||
editor
|
||||
.style()
|
||||
.unwrap()
|
||||
.style(cx)
|
||||
.text
|
||||
.line_height_in_pixels(window.rem_size())
|
||||
});
|
||||
@@ -2480,10 +2477,9 @@ async fn test_move_page_up_page_down(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
|
||||
let line_height = cx.editor(|editor, window, _cx| {
|
||||
let line_height = cx.update_editor(|editor, window, cx| {
|
||||
editor
|
||||
.style()
|
||||
.unwrap()
|
||||
.style(cx)
|
||||
.text
|
||||
.line_height_in_pixels(window.rem_size())
|
||||
});
|
||||
@@ -28311,7 +28307,8 @@ async fn test_sticky_scroll(cx: &mut TestAppContext) {
|
||||
let mut sticky_headers = |offset: ScrollOffset| {
|
||||
cx.update_editor(|e, window, cx| {
|
||||
e.scroll(gpui::Point { x: 0., y: offset }, None, window, cx);
|
||||
EditorElement::sticky_headers(&e, &e.snapshot(window, cx), cx)
|
||||
let style = e.style(cx).clone();
|
||||
EditorElement::sticky_headers(&e, &e.snapshot(window, cx), &style, cx)
|
||||
.into_iter()
|
||||
.map(
|
||||
|StickyHeader {
|
||||
@@ -28365,10 +28362,9 @@ async fn test_scroll_by_clicking_sticky_header(cx: &mut TestAppContext) {
|
||||
});
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
|
||||
let line_height = cx.editor(|editor, window, _cx| {
|
||||
let line_height = cx.update_editor(|editor, window, cx| {
|
||||
editor
|
||||
.style()
|
||||
.unwrap()
|
||||
.style(cx)
|
||||
.text
|
||||
.line_height_in_pixels(window.rem_size())
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::{
|
||||
SelectedTextHighlight, Selection, SelectionDragState, SelectionEffects, SizingBehavior,
|
||||
SoftWrap, StickyHeaderExcerpt, ToPoint, ToggleFold, ToggleFoldAll,
|
||||
code_context_menus::{CodeActionsMenu, MENU_ASIDE_MAX_WIDTH, MENU_ASIDE_MIN_WIDTH, MENU_GAP},
|
||||
column_pixels,
|
||||
display_map::{
|
||||
Block, BlockContext, BlockStyle, ChunkRendererId, DisplaySnapshot, EditorMargins,
|
||||
HighlightKey, HighlightedChunk, ToDisplayPoint,
|
||||
@@ -2269,7 +2270,8 @@ impl EditorElement {
|
||||
};
|
||||
|
||||
let padding = ProjectSettings::get_global(cx).diagnostics.inline.padding as f32 * em_width;
|
||||
let min_x = self.column_pixels(
|
||||
let min_x = column_pixels(
|
||||
&self.style,
|
||||
ProjectSettings::get_global(cx)
|
||||
.diagnostics
|
||||
.inline
|
||||
@@ -2572,7 +2574,8 @@ impl EditorElement {
|
||||
|
||||
let padded_line_end = line_end + padding;
|
||||
|
||||
let min_column_in_pixels = self.column_pixels(
|
||||
let min_column_in_pixels = column_pixels(
|
||||
&self.style,
|
||||
ProjectSettings::get_global(cx).git.inline_blame.min_column as usize,
|
||||
window,
|
||||
);
|
||||
@@ -2796,7 +2799,7 @@ impl EditorElement {
|
||||
.enumerate()
|
||||
.filter_map(|(i, indent_guide)| {
|
||||
let single_indent_width =
|
||||
self.column_pixels(indent_guide.tab_size as usize, window);
|
||||
column_pixels(&self.style, indent_guide.tab_size as usize, window);
|
||||
let total_width = single_indent_width * indent_guide.depth as f32;
|
||||
let start_x = Pixels::from(
|
||||
ScrollOffset::from(content_origin.x + total_width)
|
||||
@@ -2853,7 +2856,7 @@ impl EditorElement {
|
||||
.wrap_guides(cx)
|
||||
.into_iter()
|
||||
.flat_map(|(guide, active)| {
|
||||
let wrap_position = self.column_pixels(guide, window);
|
||||
let wrap_position = column_pixels(&self.style, guide, window);
|
||||
let wrap_guide_x = wrap_position + horizontal_offset;
|
||||
let display_wrap_guide = wrap_guide_x >= content_origin
|
||||
&& wrap_guide_x <= hitbox.bounds.right() - vertical_scrollbar_width;
|
||||
@@ -4619,6 +4622,7 @@ impl EditorElement {
|
||||
gutter_dimensions: &GutterDimensions,
|
||||
gutter_hitbox: &Hitbox,
|
||||
text_hitbox: &Hitbox,
|
||||
style: &EditorStyle,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Option<StickyHeaders> {
|
||||
@@ -4626,7 +4630,7 @@ impl EditorElement {
|
||||
.show_line_numbers
|
||||
.unwrap_or_else(|| EditorSettings::get_global(cx).gutter.line_numbers);
|
||||
|
||||
let rows = Self::sticky_headers(self.editor.read(cx), snapshot, cx);
|
||||
let rows = Self::sticky_headers(self.editor.read(cx), snapshot, style, cx);
|
||||
|
||||
let mut lines = Vec::<StickyHeaderLine>::new();
|
||||
|
||||
@@ -4685,6 +4689,7 @@ impl EditorElement {
|
||||
pub(crate) fn sticky_headers(
|
||||
editor: &Editor,
|
||||
snapshot: &EditorSnapshot,
|
||||
style: &EditorStyle,
|
||||
cx: &App,
|
||||
) -> Vec<StickyHeader> {
|
||||
let scroll_top = snapshot.scroll_position().y;
|
||||
@@ -4692,7 +4697,7 @@ impl EditorElement {
|
||||
let mut end_rows = Vec::<DisplayRow>::new();
|
||||
let mut rows = Vec::<StickyHeader>::new();
|
||||
|
||||
let items = editor.sticky_headers(cx).unwrap_or_default();
|
||||
let items = editor.sticky_headers(style, cx).unwrap_or_default();
|
||||
|
||||
for item in items {
|
||||
let start_point = item.range.start.to_point(snapshot.buffer_snapshot());
|
||||
@@ -5255,7 +5260,7 @@ impl EditorElement {
|
||||
) -> Option<AnyElement> {
|
||||
let max_height_in_lines = ((height - POPOVER_Y_PADDING) / line_height).floor() as u32;
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.render_context_menu(&self.style, max_height_in_lines, window, cx)
|
||||
editor.render_context_menu(max_height_in_lines, window, cx)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5282,16 +5287,18 @@ impl EditorElement {
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Option<AnyElement> {
|
||||
let position = self.editor.update(cx, |editor, _cx| {
|
||||
let position = self.editor.update(cx, |editor, cx| {
|
||||
let visible_start_point = editor.display_to_pixel_point(
|
||||
DisplayPoint::new(visible_range.start, 0),
|
||||
editor_snapshot,
|
||||
window,
|
||||
cx,
|
||||
)?;
|
||||
let visible_end_point = editor.display_to_pixel_point(
|
||||
DisplayPoint::new(visible_range.end, 0),
|
||||
editor_snapshot,
|
||||
window,
|
||||
cx,
|
||||
)?;
|
||||
|
||||
let mouse_context_menu = editor.mouse_context_menu.as_ref()?;
|
||||
@@ -5299,7 +5306,8 @@ impl EditorElement {
|
||||
MenuPosition::PinnedToScreen(point) => (None, point),
|
||||
MenuPosition::PinnedToEditor { source, offset } => {
|
||||
let source_display_point = source.to_display_point(editor_snapshot);
|
||||
let source_point = editor.to_pixel_point(source, editor_snapshot, window)?;
|
||||
let source_point =
|
||||
editor.to_pixel_point(source, editor_snapshot, window, cx)?;
|
||||
let position = content_origin + source_point + offset;
|
||||
(Some(source_display_point), position)
|
||||
}
|
||||
@@ -7773,29 +7781,6 @@ impl EditorElement {
|
||||
});
|
||||
}
|
||||
|
||||
fn column_pixels(&self, column: usize, window: &Window) -> Pixels {
|
||||
let style = &self.style;
|
||||
let font_size = style.text.font_size.to_pixels(window.rem_size());
|
||||
let layout = window.text_system().shape_line(
|
||||
SharedString::from(" ".repeat(column)),
|
||||
font_size,
|
||||
&[TextRun {
|
||||
len: column,
|
||||
font: style.text.font(),
|
||||
color: Hsla::default(),
|
||||
..Default::default()
|
||||
}],
|
||||
None,
|
||||
);
|
||||
|
||||
layout.width
|
||||
}
|
||||
|
||||
fn max_line_number_width(&self, snapshot: &EditorSnapshot, window: &mut Window) -> Pixels {
|
||||
let digit_count = snapshot.widest_line_number().ilog10() + 1;
|
||||
self.column_pixels(digit_count as usize, window)
|
||||
}
|
||||
|
||||
fn shape_line_number(
|
||||
&self,
|
||||
text: SharedString,
|
||||
@@ -8943,8 +8928,6 @@ impl Element for EditorElement {
|
||||
max_lines,
|
||||
} => {
|
||||
let editor_handle = cx.entity();
|
||||
let max_line_number_width =
|
||||
self.max_line_number_width(&editor.snapshot(window, cx), window);
|
||||
window.request_measured_layout(
|
||||
Style::default(),
|
||||
move |known_dimensions, available_space, window, cx| {
|
||||
@@ -8954,7 +8937,6 @@ impl Element for EditorElement {
|
||||
editor,
|
||||
min_lines,
|
||||
max_lines,
|
||||
max_line_number_width,
|
||||
known_dimensions,
|
||||
available_space.width,
|
||||
window,
|
||||
@@ -9041,15 +9023,10 @@ impl Element for EditorElement {
|
||||
.gutter_dimensions(
|
||||
font_id,
|
||||
font_size,
|
||||
self.max_line_number_width(&snapshot, window),
|
||||
style,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.or_else(|| {
|
||||
self.editor.read(cx).offset_content.then(|| {
|
||||
GutterDimensions::default_with_margin(font_id, font_size, cx)
|
||||
})
|
||||
})
|
||||
.unwrap_or_default();
|
||||
);
|
||||
let text_width = bounds.size.width - gutter_dimensions.width;
|
||||
|
||||
let settings = EditorSettings::get_global(cx);
|
||||
@@ -9740,6 +9717,7 @@ impl Element for EditorElement {
|
||||
&gutter_dimensions,
|
||||
&gutter_hitbox,
|
||||
&text_hitbox,
|
||||
&style,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
@@ -11456,7 +11434,6 @@ fn compute_auto_height_layout(
|
||||
editor: &mut Editor,
|
||||
min_lines: usize,
|
||||
max_lines: Option<usize>,
|
||||
max_line_number_width: Pixels,
|
||||
known_dimensions: Size<Option<Pixels>>,
|
||||
available_width: AvailableSpace,
|
||||
window: &mut Window,
|
||||
@@ -11480,14 +11457,7 @@ fn compute_auto_height_layout(
|
||||
let em_width = window.text_system().em_width(font_id, font_size).unwrap();
|
||||
|
||||
let mut snapshot = editor.snapshot(window, cx);
|
||||
let gutter_dimensions = snapshot
|
||||
.gutter_dimensions(font_id, font_size, max_line_number_width, cx)
|
||||
.or_else(|| {
|
||||
editor
|
||||
.offset_content
|
||||
.then(|| GutterDimensions::default_with_margin(font_id, font_size, cx))
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let gutter_dimensions = snapshot.gutter_dimensions(font_id, font_size, style, window, cx);
|
||||
|
||||
editor.gutter_dimensions = gutter_dimensions;
|
||||
let text_width = width - gutter_dimensions.width;
|
||||
@@ -11550,7 +11520,7 @@ mod tests {
|
||||
});
|
||||
let cx = &mut VisualTestContext::from_window(*window, cx);
|
||||
let editor = window.root(cx).unwrap();
|
||||
let style = cx.update(|_, cx| editor.read(cx).style().unwrap().clone());
|
||||
let style = cx.update(|_, cx| editor.update(cx, |editor, cx| editor.style(cx).clone()));
|
||||
|
||||
for x in 1..=100 {
|
||||
let (_, state) = cx.draw(
|
||||
@@ -11578,7 +11548,7 @@ mod tests {
|
||||
});
|
||||
let cx = &mut VisualTestContext::from_window(*window, cx);
|
||||
let editor = window.root(cx).unwrap();
|
||||
let style = cx.update(|_, cx| editor.read(cx).style().unwrap().clone());
|
||||
let style = cx.update(|_, cx| editor.update(cx, |editor, cx| editor.style(cx).clone()));
|
||||
|
||||
for x in 1..=100 {
|
||||
let (_, state) = cx.draw(
|
||||
@@ -11603,7 +11573,7 @@ mod tests {
|
||||
});
|
||||
|
||||
let editor = window.root(cx).unwrap();
|
||||
let style = cx.update(|cx| editor.read(cx).style().unwrap().clone());
|
||||
let style = editor.update(cx, |editor, cx| editor.style(cx).clone());
|
||||
let line_height = window
|
||||
.update(cx, |_, window, _| {
|
||||
style.text.line_height_in_pixels(window.rem_size())
|
||||
@@ -11751,7 +11721,7 @@ mod tests {
|
||||
});
|
||||
|
||||
let editor = window.root(cx).unwrap();
|
||||
let style = cx.update(|cx| editor.read(cx).style().unwrap().clone());
|
||||
let style = editor.update(cx, |editor, cx| editor.style(cx).clone());
|
||||
let line_height = window
|
||||
.update(cx, |_, window, _| {
|
||||
style.text.line_height_in_pixels(window.rem_size())
|
||||
@@ -11878,7 +11848,7 @@ mod tests {
|
||||
});
|
||||
let cx = &mut VisualTestContext::from_window(*window, cx);
|
||||
let editor = window.root(cx).unwrap();
|
||||
let style = cx.update(|_, cx| editor.read(cx).style().unwrap().clone());
|
||||
let style = cx.update(|_, cx| editor.update(cx, |editor, cx| editor.style(cx).clone()));
|
||||
|
||||
window
|
||||
.update(cx, |editor, window, cx| {
|
||||
@@ -11949,7 +11919,7 @@ mod tests {
|
||||
});
|
||||
let cx = &mut VisualTestContext::from_window(*window, cx);
|
||||
let editor = window.root(cx).unwrap();
|
||||
let style = cx.update(|_, cx| editor.read(cx).style().unwrap().clone());
|
||||
let style = cx.update(|_, cx| editor.update(cx, |editor, cx| editor.style(cx).clone()));
|
||||
window
|
||||
.update(cx, |editor, window, cx| {
|
||||
editor.set_placeholder_text("hello", window, cx);
|
||||
@@ -12189,7 +12159,7 @@ mod tests {
|
||||
let cx = &mut VisualTestContext::from_window(*window, cx);
|
||||
let editor = window.root(cx).unwrap();
|
||||
|
||||
let style = cx.update(|_, cx| editor.read(cx).style().unwrap().clone());
|
||||
let style = editor.update(cx, |editor, cx| editor.style(cx).clone());
|
||||
window
|
||||
.update(cx, |editor, _, cx| {
|
||||
editor.set_soft_wrap_mode(language_settings::SoftWrap::EditorWidth, cx);
|
||||
|
||||
@@ -59,7 +59,7 @@ impl MouseContextMenu {
|
||||
x: editor.gutter_dimensions.width,
|
||||
y: Pixels::ZERO,
|
||||
};
|
||||
let source_position = editor.to_pixel_point(source, &editor_snapshot, window)?;
|
||||
let source_position = editor.to_pixel_point(source, &editor_snapshot, window, cx)?;
|
||||
let menu_position = MenuPosition::PinnedToEditor {
|
||||
source,
|
||||
offset: position - (source_position + content_origin),
|
||||
|
||||
@@ -283,8 +283,7 @@ impl EditorTestContext {
|
||||
.head();
|
||||
let pixel_position = editor.pixel_position_of_newest_cursor.unwrap();
|
||||
let line_height = editor
|
||||
.style()
|
||||
.unwrap()
|
||||
.style(cx)
|
||||
.text
|
||||
.line_height_in_pixels(window.rem_size());
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use anyhow::{Context as _, Result};
|
||||
use buffer_diff::{BufferDiff, BufferDiffSnapshot};
|
||||
use editor::display_map::{BlockPlacement, BlockProperties, BlockStyle};
|
||||
use editor::{
|
||||
Editor, EditorEvent, ExcerptId, ExcerptRange, MultiBuffer, multibuffer_context_lines,
|
||||
};
|
||||
use editor::{Editor, EditorEvent, ExcerptRange, MultiBuffer, multibuffer_context_lines};
|
||||
use git::repository::{CommitDetails, CommitDiff, RepoPath};
|
||||
use git::{GitHostingProviderRegistry, GitRemote, parse_git_remote_url};
|
||||
use gpui::{
|
||||
@@ -13,7 +11,7 @@ use gpui::{
|
||||
};
|
||||
use language::{
|
||||
Anchor, Buffer, Capability, DiskState, File, LanguageRegistry, LineEnding, OffsetRangeExt as _,
|
||||
ReplicaId, Rope, TextBuffer,
|
||||
Point, ReplicaId, Rope, TextBuffer,
|
||||
};
|
||||
use multi_buffer::PathKey;
|
||||
use project::{Project, WorktreeId, git_store::Repository};
|
||||
@@ -70,6 +68,7 @@ struct GitBlob {
|
||||
display_name: Arc<str>,
|
||||
}
|
||||
|
||||
const COMMIT_MESSAGE_SORT_PREFIX: u64 = 0;
|
||||
const FILE_NAMESPACE_SORT_PREFIX: u64 = 1;
|
||||
|
||||
impl CommitView {
|
||||
@@ -147,6 +146,32 @@ impl CommitView {
|
||||
) -> Self {
|
||||
let language_registry = project.read(cx).languages().clone();
|
||||
let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadOnly));
|
||||
|
||||
let message_buffer = cx.new(|cx| {
|
||||
let mut buffer = Buffer::local(commit.message.clone(), cx);
|
||||
buffer.set_capability(Capability::ReadOnly, cx);
|
||||
buffer
|
||||
});
|
||||
|
||||
multibuffer.update(cx, |multibuffer, cx| {
|
||||
let snapshot = message_buffer.read(cx).snapshot();
|
||||
let full_range = Point::zero()..snapshot.max_point();
|
||||
let range = ExcerptRange {
|
||||
context: full_range.clone(),
|
||||
primary: full_range,
|
||||
};
|
||||
multibuffer.set_excerpt_ranges_for_path(
|
||||
PathKey::with_sort_prefix(
|
||||
COMMIT_MESSAGE_SORT_PREFIX,
|
||||
RelPath::unix("commit message").unwrap().into(),
|
||||
),
|
||||
message_buffer.clone(),
|
||||
&snapshot,
|
||||
vec![range],
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
let editor = cx.new(|cx| {
|
||||
let mut editor =
|
||||
Editor::for_multibuffer(multibuffer.clone(), Some(project.clone()), window, cx);
|
||||
@@ -154,9 +179,38 @@ impl CommitView {
|
||||
editor.disable_inline_diagnostics();
|
||||
editor.set_show_breakpoints(false, cx);
|
||||
editor.set_expand_all_diff_hunks(cx);
|
||||
editor.disable_header_for_buffer(message_buffer.read(cx).remote_id(), cx);
|
||||
editor.disable_indent_guides_for_buffer(message_buffer.read(cx).remote_id(), cx);
|
||||
|
||||
editor.insert_blocks(
|
||||
[BlockProperties {
|
||||
placement: BlockPlacement::Above(editor::Anchor::min()),
|
||||
height: Some(1),
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| gpui::Empty.into_any_element()),
|
||||
priority: 0,
|
||||
}]
|
||||
.into_iter()
|
||||
.chain(
|
||||
editor
|
||||
.buffer()
|
||||
.read(cx)
|
||||
.buffer_anchor_to_anchor(&message_buffer, Anchor::MAX, cx)
|
||||
.map(|anchor| BlockProperties {
|
||||
placement: BlockPlacement::Below(anchor),
|
||||
height: Some(1),
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| gpui::Empty.into_any_element()),
|
||||
priority: 0,
|
||||
}),
|
||||
),
|
||||
None,
|
||||
cx,
|
||||
);
|
||||
|
||||
editor
|
||||
});
|
||||
|
||||
let commit_sha = Arc::<str>::from(commit.sha.as_ref());
|
||||
|
||||
let first_worktree_id = project
|
||||
@@ -166,7 +220,6 @@ impl CommitView {
|
||||
.map(|worktree| worktree.read(cx).id());
|
||||
|
||||
let repository_clone = repository.clone();
|
||||
let commit_message = commit.message.clone();
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
for file in commit_diff.files {
|
||||
@@ -228,59 +281,6 @@ impl CommitView {
|
||||
})?;
|
||||
}
|
||||
|
||||
let message_buffer = cx.new(|cx| {
|
||||
let mut buffer = Buffer::local(commit_message, cx);
|
||||
buffer.set_capability(Capability::ReadOnly, cx);
|
||||
buffer
|
||||
})?;
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
this.multibuffer.update(cx, |multibuffer, cx| {
|
||||
let range = ExcerptRange {
|
||||
context: Anchor::MIN..Anchor::MAX,
|
||||
primary: Anchor::MIN..Anchor::MAX,
|
||||
};
|
||||
multibuffer.insert_excerpts_after(
|
||||
ExcerptId::min(),
|
||||
message_buffer.clone(),
|
||||
[range],
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
this.editor.update(cx, |editor, cx| {
|
||||
editor.disable_header_for_buffer(message_buffer.read(cx).remote_id(), cx);
|
||||
editor
|
||||
.disable_indent_guides_for_buffer(message_buffer.read(cx).remote_id(), cx);
|
||||
|
||||
editor.insert_blocks(
|
||||
[BlockProperties {
|
||||
placement: BlockPlacement::Above(editor::Anchor::min()),
|
||||
height: Some(1),
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| gpui::Empty.into_any_element()),
|
||||
priority: 0,
|
||||
}]
|
||||
.into_iter()
|
||||
.chain(
|
||||
editor
|
||||
.buffer()
|
||||
.read(cx)
|
||||
.buffer_anchor_to_anchor(&message_buffer, Anchor::MAX, cx)
|
||||
.map(|anchor| BlockProperties {
|
||||
placement: BlockPlacement::Below(anchor),
|
||||
height: Some(1),
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| gpui::Empty.into_any_element()),
|
||||
priority: 0,
|
||||
}),
|
||||
),
|
||||
None,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
})?;
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach();
|
||||
@@ -417,12 +417,23 @@ impl CommitView {
|
||||
None
|
||||
};
|
||||
|
||||
let gutter_width = self.editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let style = editor.style(cx);
|
||||
let font_id = window.text_system().resolve_font(&style.text.font());
|
||||
let font_size = style.text.font_size.to_pixels(window.rem_size());
|
||||
snapshot
|
||||
.gutter_dimensions(font_id, font_size, style, window, cx)
|
||||
.full_width()
|
||||
});
|
||||
|
||||
h_flex()
|
||||
.border_b_1()
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
.w_full()
|
||||
.child(
|
||||
h_flex()
|
||||
.w(self.editor.read(cx).last_gutter_dimensions().full_width())
|
||||
.w(gutter_width)
|
||||
.justify_center()
|
||||
.child(self.render_commit_avatar(&commit.sha, rems_from_px(48.), window, cx)),
|
||||
)
|
||||
@@ -1011,7 +1022,9 @@ impl Render for CommitView {
|
||||
.size_full()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.child(self.render_header(window, cx))
|
||||
.child(div().flex_grow().child(self.editor.clone()))
|
||||
.when(!self.editor.read(cx).is_empty(cx), |this| {
|
||||
this.child(div().flex_grow().child(self.editor.clone()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -294,11 +294,10 @@ mod test {
|
||||
async fn test_scroll(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
let (line_height, visible_line_count) = cx.editor(|editor, window, _cx| {
|
||||
let (line_height, visible_line_count) = cx.update_editor(|editor, window, cx| {
|
||||
(
|
||||
editor
|
||||
.style()
|
||||
.unwrap()
|
||||
.style(cx)
|
||||
.text
|
||||
.line_height_in_pixels(window.rem_size()),
|
||||
editor.visible_line_count().unwrap(),
|
||||
|
||||
@@ -2399,7 +2399,7 @@ async fn test_clipping_on_mode_change(cx: &mut gpui::TestAppContext) {
|
||||
.end;
|
||||
editor.last_bounds().unwrap().origin
|
||||
+ editor
|
||||
.display_to_pixel_point(current_head, &snapshot, window)
|
||||
.display_to_pixel_point(current_head, &snapshot, window, cx)
|
||||
.unwrap()
|
||||
});
|
||||
pixel_position.x += px(100.);
|
||||
|
||||
@@ -304,11 +304,10 @@ impl NeovimBackedTestContext {
|
||||
self.neovim.set_option(&format!("scrolloff={}", 3)).await;
|
||||
// +2 to account for the vim command UI at the bottom.
|
||||
self.neovim.set_option(&format!("lines={}", rows + 2)).await;
|
||||
let (line_height, visible_line_count) = self.editor(|editor, window, _cx| {
|
||||
let (line_height, visible_line_count) = self.update_editor(|editor, window, cx| {
|
||||
(
|
||||
editor
|
||||
.style()
|
||||
.unwrap()
|
||||
.style(cx)
|
||||
.text
|
||||
.line_height_in_pixels(window.rem_size()),
|
||||
editor.visible_line_count().unwrap(),
|
||||
|
||||
@@ -174,17 +174,13 @@ impl Render for QuickActionBar {
|
||||
.as_ref()
|
||||
.is_some_and(|menu| matches!(menu.origin(), ContextMenuOrigin::QuickActionBar))
|
||||
};
|
||||
let code_action_element = if is_deployed {
|
||||
editor.update(cx, |editor, cx| {
|
||||
if let Some(style) = editor.style() {
|
||||
editor.render_context_menu(style, MAX_CODE_ACTION_MENU_LINES, window, cx)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
let code_action_element = is_deployed
|
||||
.then(|| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.render_context_menu(MAX_CODE_ACTION_MENU_LINES, window, cx)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
.flatten();
|
||||
v_flex()
|
||||
.child(
|
||||
IconButton::new("toggle_code_actions_icon", IconName::BoltOutlined)
|
||||
|
||||
Reference in New Issue
Block a user