editor: typewriter room as rows, so drawing and text queries share one origin; a placement resets centering
CI / platforms (windows-latest) (push) Failing after 8s
CI / site (push) Successful in 22s
CI / crate (push) Failing after 10m53s
CI / platforms (ubuntu-24.04) (push) Canceled after 0s

This commit is contained in:
ZacharyZhang-NY committed 2026-10-12 09:13:49 -04:00
1 parent f102ea0b6c
commit cf9cc1971c
8 files changed
+91 -19

No files matched your search

+1 -1
View File
@@ -104,7 +104,7 @@ impl CodeEditor {
to_utf16(text, range.start)..to_utf16(text, range.end)
}
fn byte_range(&self, range: &Range<usize>) -> Range<usize> {
pub(crate) fn byte_range(&self, range: &Range<usize>) -> Range<usize> {
let text = self.buffer.text();
from_utf16(text, range.start)..from_utf16(text, range.end)
}
+2
View File
@@ -19,6 +19,8 @@ pub(crate) enum Row {
Ghost(usize),
/// The inline chat's rows; the first draws it.
Chat(usize),
/// Typewriter room past an end.
Room,
}
/// Which lines folds hide.
+1
View File
@@ -158,6 +158,7 @@ impl CodeEditor {
.iter()
.rposition(|row| matches!(row, Row::Line(shown) if *shown <= line))
.unwrap_or(0)
+ self.pad
}
/// Scrolls the primary cursor into view: from below when moving down, from above when moving up.
+5
View File
@@ -23,6 +23,10 @@ impl CodeEditor {
.h(self.frame.line)
.flex();
let caret = self.buffer.line_of(self.primary().head);
let base = match self.frame.rows[ix] {
Row::Line(line) => base.debug_selector(move || format!("editor-line-{line}")),
_ => base,
};
match self.frame.rows[ix] {
Row::Line(line) if self.options.focus_line && line != caret => {
self.line_row(base.opacity(FADED), ix, line, window, cx)
@@ -32,6 +36,7 @@ impl CodeEditor {
Row::Removed(hunk, at) => self.removed_row(base, ix, hunk, at, cx),
Row::Ghost(at) => self.ghost_row(base, ix, at, cx),
Row::Chat(at) => self.chat_row(base, ix, at, cx),
Row::Room => base.into_any_element(),
}
}
+4 -4
View File
@@ -100,7 +100,7 @@ pub(crate) struct Metrics {
pub top: Pixels,
pub advance: Pixels,
pub line: Pixels,
/// The view's height, under any typewriter room.
/// The view's height.
pub height: Pixels,
}
@@ -124,8 +124,8 @@ pub struct CodeEditor {
pub(crate) metrics: Metrics,
/// The caret row typewriter scrolling last centered.
pub(crate) centered: Option<usize>,
/// Typewriter room past each end, as last drawn.
pub(crate) room: Pixels,
/// Typewriter room rows at each end.
pub(crate) pad: usize,
pub(crate) dragging: bool,
pub(crate) caret_on: bool,
/// Blink runs only while focused, or unseen cursors redraw forever.
@@ -212,7 +212,7 @@ impl CodeEditor {
composing: None,
metrics: Metrics::default(),
centered: None,
room: Pixels::ZERO,
pad: 0,
dragging: false,
caret_on: true,
focused: false,
+11 -13
View File
@@ -54,8 +54,7 @@ impl CodeEditor {
/// The first line the list shows, after scrolling.
pub(crate) fn top_line(&self) -> Option<usize> {
// Typewriter room above the first line is no line.
let scrolled = -self.scroll.0.borrow().base_handle.offset().y - self.room;
let scrolled = -self.scroll.0.borrow().base_handle.offset().y;
let first = (scrolled / self.frame.line).floor().max(0.0) as usize;
self.frame.rows[first.min(self.frame.rows.len().saturating_sub(1))..]
.iter()
@@ -252,8 +251,16 @@ impl Render for CodeEditor {
_ => Vec::new(),
};
let minimap = self.frame.minimap;
// Half a view of room rows: the ends center too.
self.pad = match self.options.typewriter && line > Pixels::ZERO {
true => (self.metrics.height / 2.0 / line).ceil() as usize,
false => 0,
};
let mut shown = vec![Row::Room; self.pad];
shown.extend(rows(&self.buffer, &hide, &self.marks));
shown.extend(std::iter::repeat_n(Row::Room, self.pad));
self.frame = Frame {
rows: rows(&self.buffer, &hide, &self.marks),
rows: shown,
folds: found,
brackets: found_brackets,
advance,
@@ -271,13 +278,6 @@ impl Render for CodeEditor {
.scroll_to_item_strict(row, ScrollStrategy::Center);
self.centered = Some(row);
}
// Half a view of room: a resize keeps the center.
let height = self.metrics.height;
self.room = match self.options.typewriter {
true => height / 2.0,
false => gpui::px(0.0),
};
let room = self.room;
let sticky = if self.options.sticky {
self.sticky(cx)
} else {
@@ -292,9 +292,7 @@ impl Render for CodeEditor {
}),
)
.track_scroll(&self.scroll)
.size_full()
.pt(room)
.pb(room);
.size_full();
let (top, focus, input) = (cx.entity(), self.focus.clone(), cx.entity());
let unlock = cx.entity();
let banner = self.options.read_only.then(|| {