editor: typewriter centering keys on view and line heights; a placement resets the editor's centering too
CI / platforms (windows-latest) (push) Failing after 8s
CI / site (push) Successful in 22s
CI / crate (push) Failing after 12m26s
CI / platforms (ubuntu-24.04) (push) Canceled after 0s

This commit is contained in:
ZacharyZhang-NY committed 2026-10-12 09:28:47 -04:00
1 parent cf9cc1971c
commit 7ed4ea8323
4 files changed
+70 -6

No files matched your search

+4
View File
@@ -160,6 +160,10 @@ impl MarkdownDocument {
self.top = None;
// The view moved: center again.
self.centered = None;
self.editor.update(cx, |editor, cx| {
editor.centered = None;
cx.notify();
});
cx.notify();
}
+60
View File
@@ -280,3 +280,63 @@ fn switching_to_visual_centers_the_caret_block(cx: &mut TestAppContext) {
let off = off_middle(&document, 50, cx);
assert!(off < px(4.0), "{off:?} from the middle");
}
/// How far line 100 sits from mid-view.
fn source_off(
document: &gpui::Entity<super::MarkdownDocument>,
cx: &mut gpui::VisualTestContext,
) -> gpui::Pixels {
let drawn = cx.debug_bounds("editor-line-100").expect("line drawn");
let editor = document.read_with(cx, |document, _| document.editor().clone());
let middle = editor.read_with(cx, |editor, _| {
editor.metrics.top + editor.metrics.height / 2.0
});
(drawn.center().y - middle).abs()
}
/// Typewriter source, caret on line 100.
fn source_at_100(
cx: &mut TestAppContext,
) -> (
gpui::Entity<super::MarkdownDocument>,
&mut gpui::VisualTestContext,
) {
let (document, cx) = open(&long(), MarkdownMode::Source, cx);
document.update(cx, |document, cx| {
document.set_look(typewriter(), cx);
document.set_caret(100, 0, cx);
});
frames(cx);
(document, cx)
}
#[gpui::test]
fn a_mode_round_trip_centers_the_source_line(cx: &mut TestAppContext) {
let (document, cx) = source_at_100(cx);
for mode in [MarkdownMode::Visual, MarkdownMode::Source] {
document.update_in(cx, |document, window, cx| {
document.set_mode(mode, window, cx)
});
frames(cx);
}
let off = source_off(&document, cx);
assert!(off < px(4.0), "{off:?} from the middle");
}
#[gpui::test]
fn revealing_the_caret_line_keeps_it_centered(cx: &mut TestAppContext) {
let (document, cx) = source_at_100(cx);
document.update_in(cx, |document, window, cx| document.reveal(100, window, cx));
frames(cx);
let off = source_off(&document, cx);
assert!(off < px(4.0), "{off:?} from the middle");
}
#[gpui::test]
fn a_small_resize_centers_the_source_line(cx: &mut TestAppContext) {
let (document, cx) = source_at_100(cx);
cx.simulate_resize(gpui::size(px(1000.0), px(1070.0)));
frames(cx);
let off = source_off(&document, cx);
assert!(off < px(4.0), "{off:?} from the middle");
}
+2 -2
View File
@@ -122,8 +122,8 @@ pub struct CodeEditor {
/// The text before an input method's composition began, while it runs.
pub(crate) composing: Option<Snapshot>,
pub(crate) metrics: Metrics,
/// The caret row typewriter scrolling last centered.
pub(crate) centered: Option<usize>,
/// The caret row, view and line heights last centered.
pub(crate) centered: Option<(usize, Pixels, Pixels)>,
/// Typewriter room rows at each end.
pub(crate) pad: usize,
pub(crate) dragging: bool,
+4 -4
View File
@@ -272,11 +272,11 @@ impl Render for CodeEditor {
self.metrics.advance = advance;
self.metrics.line = line;
// Typewriter: the caret's row centers as it moves.
let row = self.primary_row();
if self.options.typewriter && self.centered != Some(row) {
let centered = (self.primary_row(), self.metrics.height, line);
if self.options.typewriter && self.centered != Some(centered) {
self.scroll
.scroll_to_item_strict(row, ScrollStrategy::Center);
self.centered = Some(row);
.scroll_to_item_strict(centered.0, ScrollStrategy::Center);
self.centered = Some(centered);
}
let sticky = if self.options.sticky {
self.sticky(cx)