From 160b8401514a1972bd580f4d8acc6ba7b595825f Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Tue, 27 Aug 2019 15:13:32 -0400 Subject: [PATCH] Make Editor.rows a vector, cleanup some code and logic --- src/editor.rs | 99 ++++++++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/src/editor.rs b/src/editor.rs index 991e274..6f03b92 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -9,6 +9,7 @@ use std::io::BufReader; use self::EditorKey::*; +/// A representation of a line in the editor #[derive(Debug, Default)] pub struct EditorRow { chars: String, @@ -23,19 +24,19 @@ impl EditorRow { } /// Main structure for the editor -/// -/// impl blocks are split similarly to the original C implementation +/// `EditorConfig` struct in C version #[derive(Debug, Default)] pub struct Editor { cursor_x: usize, cursor_y: usize, - row: EditorRow, - num_rows: usize, + rows: Vec, + row_offset: usize, screen_cols: usize, screen_rows: usize, output_buffer: String, } +/// Keycode mapping enum #[derive(Copy, Clone, Debug, PartialEq)] enum EditorKey { Escape, @@ -48,6 +49,7 @@ enum EditorKey { EndKey, PageUp, PageDown, + /// Any other type of character OtherKey(T), } @@ -60,24 +62,29 @@ impl EditorKey { } } -// init impl Editor { + // ------------------------------------------------------------------------ + // Init + // ------------------------------------------------------------------------ + pub fn new() -> Self { let mut instance = Self::default(); let size = instance.get_window_size(); + instance.rows = vec![]; instance.cursor_x = 0; instance.cursor_y = 0; - instance.num_rows = 0; instance.screen_cols = size.cols as usize; instance.screen_rows = size.rows as usize; instance } -} -// Terminal -impl Editor { + // ------------------------------------------------------------------------ + // Terminal + // ------------------------------------------------------------------------ + fn read_key(&mut self) -> Option>> { + // TODO: see if return type can be simplified let stdin = io::stdin(); let stdin = stdin.lock(); let mut in_str = String::new(); @@ -149,10 +156,11 @@ impl Editor { None => unimplemented!("The easy way usually works"), } } -} -// Input -impl Editor { + // ------------------------------------------------------------------------ + // Input + // ------------------------------------------------------------------------ + fn move_cursor(&mut self, key: &EditorKey) { match key { ArrowLeft => { @@ -182,11 +190,8 @@ impl Editor { /// Route user input to the appropriate handler method pub fn process_keypress(&mut self) -> Option<()> { let chars = self.read_key(); - if chars.is_none() { - Some(()) // Continue input loop on empty input - } else { + if chars.is_some() { let chars = chars.unwrap(); - // print!("{:?}\r\n", &chars); let first = &chars[0]; match first { @@ -212,10 +217,10 @@ impl Editor { ArrowRight => self.move_cursor(&ArrowRight), _ => (), }; - - // Continue the main input loop - Some(()) } + + // Continue the main input loop + Some(()) } fn page_up_or_down(&mut self, key: EditorKey) { @@ -230,10 +235,11 @@ impl Editor { } } } -} -// Output -impl Editor { + // ------------------------------------------------------------------------ + // Output + // ------------------------------------------------------------------------ + /// Equivalent of the abAppend function /// in the original tutorial, just appends /// to the `output_buffer` String in the @@ -244,10 +250,12 @@ impl Editor { fn draw_rows(&mut self) { for y in 0..self.screen_rows { - if y >= self.num_rows { - if y == (self.screen_rows / 3) { - let mut welcome = - format!("Kilo editor -- version {}", env!("CARGO_PKG_VERSION")); + if y >= self.rows.len() { + if self.rows.is_empty() && y == (self.screen_rows / 3) { + let mut welcome = format!( + "Oxidized Kilo editor -- version {}", + env!("CARGO_PKG_VERSION") + ); if welcome.len() > self.screen_cols { welcome.truncate(self.screen_cols) } @@ -258,9 +266,8 @@ impl Editor { self.append_out("~"); padding -= 1; } - while padding > 0 { + for _ in 0..padding { self.append_out(" "); - padding -= 1; } self.append_out(&welcome); @@ -268,7 +275,7 @@ impl Editor { self.append_out("~"); } } else { - let mut output = self.row.chars.clone(); + let mut output = self.rows[y].chars.clone(); if output.len() > self.screen_cols { output.truncate(self.screen_cols); } @@ -286,8 +293,8 @@ impl Editor { self.output_buffer.clear(); // Hide cursor, reposition cursor - //self.append_out("\x1b[?25l"); - //self.append_out("\x1b[H"); + self.append_out("\x1b[?25l"); + self.append_out("\x1b[H"); self.draw_rows(); @@ -302,26 +309,30 @@ impl Editor { let mut handle = stdout.lock(); handle.write_all(&self.output_buffer.as_bytes()) } -} -// File I/O -impl Editor { + // ------------------------------------------------------------------------ + // Row Operations + // ------------------------------------------------------------------------ + + fn append_row(&mut self, row: &str) { + self.rows.push(EditorRow::new(row)); + } + + // ------------------------------------------------------------------------ + // File I/O + // ------------------------------------------------------------------------ + + /// Open a file for display pub fn open(&mut self, filename: &str) -> io::Result<()> { let file = File::open(filename)?; let buf_reader = BufReader::new(file); - let mut lines = buf_reader.lines().map(|l| l.unwrap()); + let lines = buf_reader.lines().map(|l| l.unwrap()); - let line = lines.next().unwrap(); - self.row = EditorRow::new(&line); - self.num_rows = 1; + for line in lines { + self.append_row(&line); + } - /*for line in lines { - let - }*/ - // let line_res = buf_reader.read_line() - // self.row = EditorRow::new("Hello, world!"); - // self.num_rows += 1; Ok(()) } }