diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index b4efca5779e4c829c2a42fe98e1d1b2880fc8acc..dfcdf109e61764d8ce8c2e7bf24a1cc451ae9e31 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -211,6 +211,7 @@ pub(crate) const SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT: Duration = Duration: pub(crate) const EDIT_PREDICTION_KEY_CONTEXT: &str = "edit_prediction"; pub(crate) const EDIT_PREDICTION_CONFLICT_KEY_CONTEXT: &str = "edit_prediction_conflict"; +pub(crate) const MIN_LINE_NUMBER_DIGITS: u32 = 4; const COLUMNAR_SELECTION_MODIFIERS: Modifiers = Modifiers { alt: true, @@ -17618,7 +17619,7 @@ impl EditorSnapshot { .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 and only resize the gutter on files with N*10^5 lines. - let min_width_for_number_on_gutter = em_advance * 4.0; + let min_width_for_number_on_gutter = em_advance * MIN_LINE_NUMBER_DIGITS as f32; max_line_number_width.max(min_width_for_number_on_gutter) } else { 0.0.into() @@ -17647,8 +17648,12 @@ impl EditorSnapshot { em_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 show_code_actions || show_runnables { + left_padding += if !is_singleton { + em_width * 4.0 + } else if show_code_actions || show_runnables { em_width * 3.0 } else if show_git_gutter && show_line_numbers { em_width * 2.0 @@ -17658,9 +17663,11 @@ impl EditorSnapshot { px(0.) }; - let right_padding = if gutter_settings.folds && show_line_numbers { + let shows_folds = is_singleton && gutter_settings.folds; + + let right_padding = if shows_folds && show_line_numbers { em_width * 4.0 - } else if gutter_settings.folds { + } else if shows_folds || (!is_singleton && show_line_numbers) { em_width * 3.0 } else if show_line_numbers { em_width diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 2ae8fc5cb25610afd014ac00bba7fd6775bc8637..9abdaca114cd5b6ed83097100658d0717261081c 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -23,7 +23,7 @@ use crate::{ InlineCompletion, JumpData, LineDown, LineHighlight, LineUp, OpenExcerpts, PageDown, PageUp, Point, RowExt, RowRangeExt, SelectPhase, SelectedTextHighlight, Selection, SoftWrap, StickyHeaderExcerpt, ToPoint, ToggleFold, COLUMNAR_SELECTION_MODIFIERS, CURSORS_VISIBLE_FOR, - FILE_HEADER_HEIGHT, GIT_BLAME_MAX_AUTHOR_CHARS_DISPLAYED, MAX_LINE_LEN, + FILE_HEADER_HEIGHT, GIT_BLAME_MAX_AUTHOR_CHARS_DISPLAYED, MAX_LINE_LEN, MIN_LINE_NUMBER_DIGITS, MULTI_BUFFER_EXCERPT_HEADER_HEIGHT, }; use buffer_diff::{DiffHunkStatus, DiffHunkStatusKind}; @@ -2119,9 +2119,11 @@ impl EditorElement { }) } - fn layout_excerpt_gutter( + fn layout_expand_toggles( &self, gutter_hitbox: &Hitbox, + gutter_dimensions: GutterDimensions, + em_width: Pixels, line_height: Pixels, scroll_position: gpui::Point, buffer_rows: &[RowInfo], @@ -2130,19 +2132,17 @@ impl EditorElement { ) -> Vec)>> { let editor_font_size = self.style.text.font_size.to_pixels(window.rem_size()) * 1.2; - let icon_size = editor_font_size.round(); - let button_h_padding = ((icon_size - px(1.0)) / 2.0).round() - px(2.0); - let scroll_top = scroll_position.y * line_height; - let max_line_number_length = 1 + self + let max_line_number_length = self .editor .read(cx) .buffer() .read(cx) .snapshot(cx) .widest_line_number() - .ilog10(); + .ilog10() + + 1; let elements = buffer_rows .into_iter() @@ -2159,20 +2159,27 @@ impl EditorElement { ExpandExcerptDirection::UpAndDown => IconName::ExpandVertical, }; + let git_gutter_width = Self::gutter_strip_width(line_height); + let available_width = gutter_dimensions.left_padding - git_gutter_width; + let editor = self.editor.clone(); - let is_wide = max_line_number_length > 3 + let is_wide = max_line_number_length >= MIN_LINE_NUMBER_DIGITS && row_info .buffer_row - .is_some_and(|row| (row + 1).ilog10() + 1 == max_line_number_length); + .is_some_and(|row| (row + 1).ilog10() + 1 == max_line_number_length) + || gutter_dimensions.right_padding == px(0.); + + let width = if is_wide { + available_width - px(2.) + } else { + available_width + em_width - px(2.) + }; let toggle = IconButton::new(("expand", ix), icon_name) .icon_color(Color::Custom(cx.theme().colors().editor_line_number)) .selected_icon_color(Color::Custom(cx.theme().colors().editor_foreground)) .icon_size(IconSize::Custom(rems(editor_font_size / window.rem_size()))) - .width((icon_size + button_h_padding * 2).into()) - .when(is_wide, |el| { - el.width((icon_size + button_h_padding).into()) - }) + .width(width.into()) .on_click(move |_, _, cx| { editor.update(cx, |editor, cx| { editor.expand_excerpt(excerpt_id, direction, cx); @@ -2185,7 +2192,7 @@ impl EditorElement { .into_any_element(); let position = point( - px(1.), + git_gutter_width + px(1.), ix as f32 * line_height - (scroll_top % line_height) + px(1.), ); let origin = gutter_hitbox.origin + position; @@ -2709,7 +2716,7 @@ impl EditorElement { for_excerpt: &ExcerptInfo, is_folded: bool, is_selected: bool, - _is_sticky: bool, + is_sticky: bool, jump_data: JumpData, window: &mut Window, cx: &mut App, @@ -2744,8 +2751,7 @@ impl EditorElement { let colors = cx.theme().colors(); div() - .px_2() - .pt_2() + .p_1() .w_full() .h(FILE_HEADER_HEIGHT as f32 * window.line_height()) .child( @@ -2756,7 +2762,7 @@ impl EditorElement { .pl_0p5() .pr_5() .rounded_sm() - // .when(is_sticky, |el| el.shadow_md()) + .when(is_sticky, |el| el.shadow_md()) .border_1() .map(|div| { let border_color = if is_selected @@ -2784,7 +2790,7 @@ impl EditorElement { ButtonLike::new("toggle-buffer-fold") .style(ui::ButtonStyle::Transparent) .size(ButtonSize::Large) - .width(px(30.).into()) + .width(px(24.).into()) .children(toggle_chevron_icon) .tooltip({ let focus_handle = focus_handle.clone(); @@ -4413,6 +4419,10 @@ impl EditorElement { }); } + fn gutter_strip_width(line_height: Pixels) -> Pixels { + (0.275 * line_height).floor() + } + fn diff_hunk_bounds( snapshot: &EditorSnapshot, line_height: Pixels, @@ -4421,7 +4431,7 @@ impl EditorElement { ) -> Bounds { let scroll_position = snapshot.scroll_position(); let scroll_top = scroll_position.y * line_height; - let gutter_strip_width = (0.275 * line_height).floor(); + let gutter_strip_width = Self::gutter_strip_width(line_height); match hunk { DisplayDiffHunk::Folded { display_row, .. } => { @@ -6887,8 +6897,10 @@ impl Element for EditorElement { let mut expand_toggles = window.with_element_namespace("expand_toggles", |window| { - self.layout_excerpt_gutter( + self.layout_expand_toggles( &gutter_hitbox, + gutter_dimensions, + em_width, line_height, scroll_position, &row_infos,