Make Editor.rows a vector, cleanup some code and logic
This commit is contained in:
parent
4167088f81
commit
160b840151
@ -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
|
// Terminal
|
||||||
impl Editor {
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
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
|
// Input
|
||||||
impl Editor {
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
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
|
// Output
|
||||||
impl Editor {
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
/// 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())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Row Operations
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
fn append_row(&mut self, row: &str) {
|
||||||
|
self.rows.push(EditorRow::new(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
// File I/O
|
// File I/O
|
||||||
impl Editor {
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// 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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user