3 global line numbering across blocks, sync table states on reparse

This commit is contained in:
jess 2026-04-08 05:55:57 -07:00
parent a390a2cc4a
commit 5b4abcf3e5
1 changed files with 20 additions and 13 deletions

View File

@ -334,12 +334,6 @@ impl EditorState {
}
pub fn set_text(&mut self, text: &str) {
if text.is_empty() && !self.blocks.is_empty() {
// Swift sends empty text for untitled docs — keep initial content if present
if self.blocks.len() > 1 || !self.blocks[0].content.text().is_empty() {
return;
}
}
if self.blocks.is_empty() {
self.blocks = crate::blocks::parse_blocks(text);
} else {
@ -412,12 +406,12 @@ impl EditorState {
if self.focused_block >= self.blocks.len() {
self.focused_block = self.blocks.len().saturating_sub(1);
}
// If structure changed, try to restore cursor position
if self.blocks.len() != old_count {
if let Some(bi) = crate::blocks::block_at_line(&self.blocks, cursor.position.line) {
self.focused_block = bi;
}
}
self.sync_table_states();
}
#[allow(dead_code)]
@ -1025,6 +1019,7 @@ impl EditorState {
}
}
let mut global_line = 0usize;
for (bi, block) in self.blocks.iter().enumerate() {
match block.kind {
BlockKind::Text => {
@ -1072,6 +1067,7 @@ impl EditorState {
let gutter = Gutter {
line_count: block.content.line_count(),
source_line_count,
global_line_offset: 0,
font_size: self.font_size,
scroll_offset: self.scroll_offset,
cursor_line: block.content.cursor().position.line,
@ -1137,6 +1133,7 @@ impl EditorState {
let gutter = Gutter {
line_count: block.content.line_count(),
source_line_count,
global_line_offset: global_line,
font_size: self.font_size,
scroll_offset: self.scroll_offset,
cursor_line: block.content.cursor().position.line,
@ -1144,6 +1141,7 @@ impl EditorState {
result_mask,
line_decors: decors,
};
global_line += source_line_count;
let gw = gutter.gutter_width();
let gutter_canvas: Element<'_, Message, Theme, iced_wgpu::Renderer> =
@ -1171,9 +1169,11 @@ impl EditorState {
block_elements.push(
crate::heading_block::view(level, &block.heading_text, self.font_size)
);
global_line += 1;
}
BlockKind::HorizontalRule => {
block_elements.push(crate::hr_block::view());
global_line += 1;
}
BlockKind::Table => {
if let Some(ts) = self.table_states.get(&block.id) {
@ -1184,11 +1184,13 @@ impl EditorState {
)
);
}
global_line += block.line_count;
}
BlockKind::EvalResult => {
block_elements.push(
crate::eval_block::view::<Message>(&block.eval_text)
);
global_line += 1;
}
BlockKind::Tree => {
if let Some(ref data) = block.tree_data {
@ -1196,6 +1198,7 @@ impl EditorState {
crate::tree_block::view::<Message>(data)
);
}
global_line += 1;
}
}
}
@ -1208,10 +1211,12 @@ impl EditorState {
} else if single_text_block {
block_elements.remove(0)
} else {
iced_widget::column(block_elements)
.width(Length::Fill)
.height(Length::Fill)
.into()
iced_widget::scrollable(
iced_widget::column(block_elements)
.width(Length::Fill)
)
.height(Length::Fill)
.into()
}
}
@ -1450,6 +1455,7 @@ fn find_btn_style(
struct Gutter {
line_count: usize,
source_line_count: usize,
global_line_offset: usize,
font_size: f32,
scroll_offset: f32,
cursor_line: usize,
@ -1460,7 +1466,8 @@ struct Gutter {
impl Gutter {
fn gutter_width(&self) -> f32 {
let count = if self.source_line_count == 0 { 1 } else { self.source_line_count };
let total = self.global_line_offset + self.source_line_count;
let count = if total == 0 { 1 } else { total };
let digits = (count as f32).log10().floor() as usize + 1;
let char_width = self.font_size * 0.6;
(digits.max(2) as f32 * char_width + 16.0).ceil()
@ -1493,7 +1500,7 @@ impl canvas::Program<Message, Theme, iced_wgpu::Renderer> for Gutter {
let gw = self.gutter_width();
let mut source_num = 0usize;
let mut source_num = self.global_line_offset;
for idx in 0..first_visible {
if idx < self.result_mask.len() && !self.result_mask[idx] {
source_num += 1;