Phase 5: Editor und inkrementellen Compiler implementieren und archivieren
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user