Skip to content

Commit d58bfb3

Browse files
author
Noam Lewis
committed
fixed bugs
1 parent 43838a3 commit d58bfb3

File tree

2 files changed

+49
-45
lines changed

2 files changed

+49
-45
lines changed

src/main.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,11 @@ impl State {
250250
}
251251

252252
fn iter_line_prev(&mut self) {
253-
self.cursor.y -= 1;
254-
self.lines.prev_line();
253+
self.cursor.y -= self.lines.prev_line();
255254
}
256255

257256
fn iter_line_next(&mut self) {
258-
self.cursor.y += 1;
259-
self.lines.next_line();
257+
self.cursor.y += self.lines.next_line();
260258
}
261259

262260
fn delete_prev_char(&mut self) {
@@ -278,7 +276,7 @@ impl State {
278276
if self.cursor.x < line.len() as u16 {
279277
line.remove(self.cursor.x as usize);
280278
} else {
281-
self.lines.next_line();
279+
self.iter_line_next();
282280
let next_line = self.lines.remove();
283281
let line = self.lines.get_mut();
284282
line.extend(next_line);
@@ -288,9 +286,9 @@ impl State {
288286
fn insert_line(&mut self) {
289287
let line = self.lines.get_mut();
290288
let new_line = line.split_off(self.cursor.x as usize);
289+
self.lines.insert_after(LoadedLine::new(new_line));
291290
self.iter_line_next();
292291
self.cursor.x = 0;
293-
self.lines.insert(LoadedLine::new(new_line));
294292
}
295293

296294
fn draw_frame(&mut self, frame: &mut Frame) {
@@ -303,20 +301,20 @@ impl State {
303301
let window_offset = self.window_offset;
304302

305303
let render_line = |pair: (usize, &LoadedLine)| -> Line<'_> {
306-
let content = pair
307-
.1
304+
let (line_index, loaded_line) = pair;
305+
306+
let content = loaded_line
308307
.chars_iter()
309308
.skip(window_offset.x as usize)
310309
.collect::<String>();
311-
let line_index = pair.0;
312310
Line::from(vec![
313311
Span::styled(
314312
format!(
315313
"{:>width$}",
316-
(line_index + 1),
314+
(line_index + window_offset.y as usize + 1),
317315
width = left_margin_width as usize
318316
),
319-
if cursor.y as usize == line_index {
317+
if (cursor.y - window_offset.y) as usize == line_index {
320318
Style::new().white()
321319
} else {
322320
Style::new().dark_gray()
@@ -327,21 +325,26 @@ impl State {
327325
])
328326
};
329327

330-
self.status_text = format!(
331-
"cursor: {:?}, window_offset {:?}",
332-
self.cursor, self.window_offset
333-
);
334-
335328
frame.render_widget(
336329
Text::from_iter(
337330
self.lines
338-
.iter_at(-(cursor.y as i64), lines_per_page as usize)
331+
.iter_at(
332+
self.window_offset.y as i64 - cursor.y as i64,
333+
lines_per_page as usize,
334+
)
339335
.enumerate()
340336
.map(render_line),
341337
),
342338
text_area,
343339
);
344340

341+
self.status_text = format!(
342+
"cursor: {:?}, window_offset {:?}, line_index: {:?}",
343+
self.cursor,
344+
self.window_offset,
345+
self.lines.get_index()
346+
);
347+
345348
frame.render_widget(self.status_text.clone(), status_area);
346349

347350
frame.set_cursor_position(Position::new(

src/virtual_file.rs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -109,25 +109,29 @@ impl VirtualFile {
109109
};
110110
}
111111

112-
pub fn prev_line(&mut self) -> Option<&mut LoadedLine> {
113-
if self.line_index == 0 {
114-
assert!(self.loaded_chunks.start > 0);
112+
pub fn prev_line(&mut self) -> u16 {
113+
if self.line_index == 0 && self.loaded_chunks.start > 0 {
115114
// seek to previous chunk
116115
self.seek(self.chunk_size * (self.loaded_chunks.start - 1));
117116
}
118-
self.line_index -= 1;
119-
return self.chunk_lines.get_mut(self.line_index);
117+
// after possible seek, line_index may still be zero if there was nothing to load
118+
if self.line_index > 0 {
119+
self.line_index -= 1;
120+
return 1;
121+
}
122+
return 0;
120123
}
121124

122-
pub fn next_line(&mut self) -> Option<&mut LoadedLine> {
123-
let lines_count = self.chunk_lines.len();
124-
self.line_index += 1;
125-
// "+1" because last line in the chunk may be incomplete
126-
if self.line_index + 1 >= lines_count {
127-
// seek to next chunk
125+
pub fn next_line(&mut self) -> u16 {
126+
if self.line_index + 2 >= self.chunk_lines.len() {
127+
// fetch more lines, after increasing index it will be the last line which may be incomplete
128128
self.seek(self.chunk_size * self.loaded_chunks.end);
129129
}
130-
return self.chunk_lines.get_mut(self.line_index);
130+
if self.line_index + 1 < self.chunk_lines.len() {
131+
self.line_index += 1;
132+
return 1;
133+
}
134+
return 0;
131135
}
132136

133137
pub fn remove(&mut self) -> LoadedLine {
@@ -145,8 +149,12 @@ impl VirtualFile {
145149
return removed_line;
146150
}
147151

148-
pub fn insert(&mut self, new_line: LoadedLine) {
149-
self.chunk_lines.insert(self.line_index, new_line);
152+
pub fn get_index(&self) -> usize {
153+
self.line_index
154+
}
155+
156+
pub fn insert_after(&mut self, new_line: LoadedLine) {
157+
self.chunk_lines.insert(self.line_index + 1, new_line);
150158
}
151159

152160
pub fn get(&self) -> &LoadedLine {
@@ -170,33 +178,26 @@ impl VirtualFile {
170178
count: usize,
171179
) -> impl Iterator<Item = &LoadedLine> {
172180
// TODO: This is inefficient and also clobbers the current line_index
173-
181+
let mut clobber: i32 = 0;
174182
if offset_from_line_index < 0 {
175183
// need to iterate lines backwards
176184
for _ in offset_from_line_index..0 {
177-
self.prev_line();
185+
clobber -= self.prev_line() as i32;
178186
}
179187
} else {
180188
// need to iterate lines forwards
181189
for _ in 0..offset_from_line_index {
182-
self.next_line();
190+
clobber += self.next_line() as i32;
183191
}
184192
}
185193
// line_index is now at the start of the range
194+
let start_index = self.line_index;
186195
// materialize 'count' lines
187196
for _ in 0..count {
188-
self.next_line();
197+
clobber += self.next_line() as i32;
189198
}
190-
191-
// correct the line_index: go back to beginning of the range
192-
for _ in 0..count {
193-
self.prev_line();
194-
}
195-
let start_index = self.line_index;
196199
// ... and now go back to where line_index was before
197-
for _ in 0..offset_from_line_index {
198-
self.prev_line();
199-
}
200+
self.line_index = (self.line_index as i32 - clobber).try_into().unwrap();
200201

201202
self.chunk_lines.iter().skip(start_index)
202203
}
@@ -265,7 +266,7 @@ mod tests {
265266
let file = create_test_file("line1\nline2\nline3\n");
266267
let mut vf = VirtualFile::new(10, file);
267268
vf.seek(0);
268-
vf.insert(LoadedLine::new("new_line".to_string()));
269+
vf.insert_after(LoadedLine::new("new_line".to_string()));
269270
assert_eq!(vf.get().str(), "new_line");
270271
}
271272

0 commit comments

Comments
 (0)