-use crate::Terminal;
+use crate::{Document, Row, Terminal};
+use std::env;
use termion::event::Key;
const VERSION: &str = env!("CARGO_PKG_VERSION");
fn die(e: std::io::Error) {
Terminal::clear_screen();
- panic!("{:?}", e);
+ panic!("{e:?}");
}
+#[derive(Default)]
pub struct Position {
pub x: usize,
pub y: usize,
should_quit: bool,
terminal: Terminal,
current_position: Position,
+ offset: Position,
+ document: Document,
}
impl Editor {
}
}
pub fn default() -> Self {
+ let args: Vec<String> = env::args().collect();
+ let document = if args.len() > 1 {
+ let file_name = &args[1];
+ Document::open(&file_name).unwrap_or_default()
+ } else {
+ Document::default()
+ };
Self {
should_quit: false,
terminal: Terminal::default().expect("Failed to create terminal"),
- current_position: Position { x: 0, y: 0 },
+ document,
+ current_position: Position::default(),
+ offset: Position::default(),
}
}
fn refresh_screen(&self) -> Result<(), std::io::Error> {
Terminal::cursor_hide();
- Terminal::cursor_position(&Position { x: 0, y: 0 });
+ Terminal::cursor_position(&Position::default());
if self.should_quit {
Terminal::clear_screen();
println!("Goodbye.\r");
| Key::End => self.move_cursor(pressed_key),
_ => (),
};
+ self.scroll();
Ok(())
}
+ fn scroll(&mut self) {
+ let Position { x, y } = self.current_position;
+ let width = self.terminal.size().width as usize;
+ let height = self.terminal.size().height as usize;
+ let mut offset = &mut self.offset;
+ if y < offset.y {
+ offset.y = y
+ } else if y >= offset.y.saturating_add(height) {
+ offset.y = y.saturating_sub(height).saturating_add(1);
+ }
+ if x < offset.x {
+ offset.x = x;
+ } else if x >= offset.x.saturating_add(width) {
+ offset.x = x.saturating_sub(width).saturating_add(1);
+ }
+ }
+
fn move_cursor(&mut self, key: Key) {
let Position { mut x, mut y } = self.current_position;
let size = self.terminal.size();
let width = size.width.saturating_sub(1) as usize;
- let height = size.height.saturating_sub(1) as usize;
+ let height = self.document.len();
match key {
Key::Up => y = y.saturating_sub(1),
Key::Down => {
println!("{}\r", welcome_message);
}
+ fn draw_row(&self, row: &Row) {
+ let width = self.terminal.size().width as usize;
+ let start = self.offset.x;
+ let end = self.offset.x + width;
+ let row = row.render(start, end);
+ println!("{}\r", row);
+ }
+
fn draw_rows(&self) {
let height = self.terminal.size().height;
- for row in 0..height - 1 {
+ for terminal_row in 0..height - 1 {
Terminal::clear_current_line();
- if row == height / 3 {
+ if let Some(row) = self.document.row(terminal_row as usize + self.offset.y) {
+ self.draw_row(row);
+ } else if self.document.is_empty() && terminal_row == height / 3 {
self.draw_welcome_message();
} else {
println!("~\r");