Phase 5: Editor und inkrementellen Compiler implementieren und archivieren

This commit is contained in:
2026-09-06 17:58:26 +02:00
parent df85a4b7b2
commit 9c85349a4d
36 changed files with 2993 additions and 247 deletions

View File

@@ -153,17 +153,74 @@ impl App {
content_style,
);
} else {
let lines: Vec<_> = doc
.code()
.split('\n')
.map(|line| expanded(line, self.options.tab_width))
.collect();
let expansion = self.editor.expansions.get(&view);
let code = expansion.map(String::as_str).unwrap_or(doc.code());
let lines: Vec<_> = code.split('\n').collect();
let count = lines.len();
let longest = lines.iter().map(|s| s.width()).max().unwrap_or(0);
let longest = lines
.iter()
.map(|s| expanded(s, self.options.tab_width).width())
.max()
.unwrap_or(0);
let selection = if expansion.is_none() {
v.selection()
} else {
None
};
let mut start = 0;
let text = lines
.into_iter()
.skip(v.scroll_line)
.map(|s| Line::raw(s.chars().skip(v.scroll_column).collect::<String>()))
.iter()
.enumerate()
.filter_map(|(row, line)| {
let base = start;
start += line.len() + 1;
if row < v.scroll_line {
return None;
}
let mut col = 0;
let mut spans = Vec::new();
for (i, c) in line.char_indices() {
if c == '\r' {
continue;
}
let width = if c == '\t' {
self.options.tab_width - col % self.options.tab_width
} else {
c.width().unwrap_or(0)
};
let end = col + width;
if end > v.scroll_column
&& col < v.scroll_column + inner.width as usize
{
let selected = selection
.as_ref()
.is_some_and(|r| r.contains(&(base + i)));
let text = if c == '\t'
|| col < v.scroll_column
|| end > v.scroll_column + inner.width as usize
{
" ".repeat(
end.min(v.scroll_column + inner.width as usize)
- col.max(v.scroll_column),
)
} else {
c.to_string()
};
spans.push(Span::styled(
text,
if selected {
content_style.add_modifier(Modifier::REVERSED)
} else {
content_style
},
));
} else if width == 0 && !spans.is_empty() {
spans.push(Span::raw(c.to_string()));
}
col = end;
}
Some(Line::from(spans))
})
.collect::<Vec<_>>();
f.render_widget(Paragraph::new(text).style(content_style), inner);
if count > inner.height as usize {
@@ -186,7 +243,11 @@ impl App {
.viewport_content_length(inner.width as usize),
);
}
if active && self.dialog.is_none() && self.menu.is_none() {
if active
&& expansion.is_none()
&& self.dialog.is_none()
&& self.menu.is_none()
{
let before = &doc.code()[..v.cursor.min(doc.code().len())];
let row = before.bytes().filter(|c| *c == b'\n').count();
let col = expanded(