Use ch-width (0
) instead of em-width (m
) for gutter width calculation (#32548)
Closes #21860 Release Notes: - Added `ch_width` and `ch_advance` function alongside their `em_*` counterparts - Use `ch_*` version to calculate gutter layouts - Update a stale comment from changes in #31959 The ch units refer to the width of the number `0` whereas em is the width of `m` and the actual font size (e.g. 16px means 16 px width of `m`). This change has no effect for monospaced fonts but can be drastic for proportional ones as seen below for "Zed Plex Sans" with a `"min_line_number_width" = 4`. <img width="726" alt="Screenshot 2025-06-11 at 15 47 35" src="https://github.com/user-attachments/assets/aa73f4d4-32bc-42cf-a9f6-7e25fee68c9a" />
This commit is contained in:
parent
f428d54b74
commit
242af863f5
2 changed files with 27 additions and 12 deletions
|
@ -21565,8 +21565,8 @@ impl EditorSnapshot {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let em_width = cx.text_system().em_width(font_id, font_size).log_err()?;
|
let ch_width = cx.text_system().ch_width(font_id, font_size).log_err()?;
|
||||||
let em_advance = cx.text_system().em_advance(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(|| {
|
let show_git_gutter = self.show_git_diff_gutter.unwrap_or_else(|| {
|
||||||
matches!(
|
matches!(
|
||||||
|
@ -21579,9 +21579,10 @@ impl EditorSnapshot {
|
||||||
.show_line_numbers
|
.show_line_numbers
|
||||||
.unwrap_or(gutter_settings.line_numbers);
|
.unwrap_or(gutter_settings.line_numbers);
|
||||||
let line_gutter_width = if show_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.
|
// 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 =
|
let min_width_for_number_on_gutter =
|
||||||
em_advance * gutter_settings.min_line_number_digits as f32;
|
ch_advance * gutter_settings.min_line_number_digits as f32;
|
||||||
max_line_number_width.max(min_width_for_number_on_gutter)
|
max_line_number_width.max(min_width_for_number_on_gutter)
|
||||||
} else {
|
} else {
|
||||||
0.0.into()
|
0.0.into()
|
||||||
|
@ -21604,20 +21605,20 @@ impl EditorSnapshot {
|
||||||
+ MAX_RELATIVE_TIMESTAMP.len()
|
+ MAX_RELATIVE_TIMESTAMP.len()
|
||||||
+ SPACING_WIDTH;
|
+ SPACING_WIDTH;
|
||||||
|
|
||||||
em_advance * max_char_count
|
ch_advance * max_char_count
|
||||||
});
|
});
|
||||||
|
|
||||||
let is_singleton = self.buffer_snapshot.is_singleton();
|
let is_singleton = self.buffer_snapshot.is_singleton();
|
||||||
|
|
||||||
let mut left_padding = git_blame_entries_width.unwrap_or(Pixels::ZERO);
|
let mut left_padding = git_blame_entries_width.unwrap_or(Pixels::ZERO);
|
||||||
left_padding += if !is_singleton {
|
left_padding += if !is_singleton {
|
||||||
em_width * 4.0
|
ch_width * 4.0
|
||||||
} else if show_runnables || show_breakpoints {
|
} else if show_runnables || show_breakpoints {
|
||||||
em_width * 3.0
|
ch_width * 3.0
|
||||||
} else if show_git_gutter && show_line_numbers {
|
} else if show_git_gutter && show_line_numbers {
|
||||||
em_width * 2.0
|
ch_width * 2.0
|
||||||
} else if show_git_gutter || show_line_numbers {
|
} else if show_git_gutter || show_line_numbers {
|
||||||
em_width
|
ch_width
|
||||||
} else {
|
} else {
|
||||||
px(0.)
|
px(0.)
|
||||||
};
|
};
|
||||||
|
@ -21625,11 +21626,11 @@ impl EditorSnapshot {
|
||||||
let shows_folds = is_singleton && gutter_settings.folds;
|
let shows_folds = is_singleton && gutter_settings.folds;
|
||||||
|
|
||||||
let right_padding = if shows_folds && show_line_numbers {
|
let right_padding = if shows_folds && show_line_numbers {
|
||||||
em_width * 4.0
|
ch_width * 4.0
|
||||||
} else if shows_folds || (!is_singleton && show_line_numbers) {
|
} else if shows_folds || (!is_singleton && show_line_numbers) {
|
||||||
em_width * 3.0
|
ch_width * 3.0
|
||||||
} else if show_line_numbers {
|
} else if show_line_numbers {
|
||||||
em_width
|
ch_width
|
||||||
} else {
|
} else {
|
||||||
px(0.)
|
px(0.)
|
||||||
};
|
};
|
||||||
|
|
|
@ -209,6 +209,20 @@ impl TextSystem {
|
||||||
Ok(self.advance(font_id, font_size, 'm')?.width)
|
Ok(self.advance(font_id, font_size, 'm')?.width)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the width of an `ch`.
|
||||||
|
///
|
||||||
|
/// Uses the width of the `0` character in the given font and size.
|
||||||
|
pub fn ch_width(&self, font_id: FontId, font_size: Pixels) -> Result<Pixels> {
|
||||||
|
Ok(self.typographic_bounds(font_id, font_size, '0')?.size.width)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the advance width of an `ch`.
|
||||||
|
///
|
||||||
|
/// Uses the advance width of the `0` character in the given font and size.
|
||||||
|
pub fn ch_advance(&self, font_id: FontId, font_size: Pixels) -> Result<Pixels> {
|
||||||
|
Ok(self.advance(font_id, font_size, '0')?.width)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the number of font size units per 'em square',
|
/// Get the number of font size units per 'em square',
|
||||||
/// Per MDN: "an abstract square whose height is the intended distance between
|
/// Per MDN: "an abstract square whose height is the intended distance between
|
||||||
/// lines of type in the same type size"
|
/// lines of type in the same type size"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue