Make Editor.rows a vector, cleanup some code and logic

This commit is contained in:
Timothy Warren 2019-08-27 15:13:32 -04:00
parent 4167088f81
commit 160b840151

View File

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