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