Skip to content

Commit

Permalink
feature: add document mod and welcome message
Browse files Browse the repository at this point in the history
  • Loading branch information
shepherdma committed Nov 29, 2023
1 parent e4e374c commit 493bf9c
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 11 deletions.
20 changes: 20 additions & 0 deletions hecto/src/document.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use crate::Row;

#[derive(Default)]
pub struct Document {
rows: Vec<Row>,
}

impl Document {
pub fn open() -> Self{
let mut rows = Vec::new();
rows.push(Row::from("Hello, World!"));
Self { rows }
}
pub fn row(&self, index: usize) -> Option<&Row> {
self.rows.get(index)
}
pub fn is_empty(&self) -> bool {
self.rows.is_empty()
}
}
58 changes: 53 additions & 5 deletions hecto/src/editor.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
use crate::Row;
use crate::Document;
use crate::Terminal;
use termion::event::Key;

const VERSION: &str = env!("CARGO_PKG_VERSION");
#[derive(Default)]
pub struct Position {
pub x: usize,
pub y: usize,
}
pub struct Editor {
should_quit: bool,
terminal: Terminal,
cursor_position: Position,
document: Document,
}
fn die(e: &std::io::Error) {
Terminal::clear_screen();
Expand All @@ -29,36 +39,74 @@ impl Editor {
Self{
should_quit: false,
terminal: Terminal::default().expect("Failed to initialize terminal"),
cursor_position: Position::default(),
document: Document::open(),
}
}
fn process_keypress(&mut self) -> Result<(), std::io::Error> {
let pressed_key = Terminal::read_key()?;
match pressed_key {
Key::Ctrl('q') => self.should_quit = true,
Key::Up | Key::Down | Key::Left | Key::Right => self.move_cursor(pressed_key),
_ => (),
}
Ok(())
}

fn move_cursor(&mut self, key: Key) {
let Position { mut y, mut x} = self.cursor_position;
match key {
Key::Up => y = y.saturating_sub(1),
Key::Down => y = y.saturating_add(1),
Key::Right => x = x.saturating_add(1),
Key::Left => x = x.saturating_sub(1),
_ => (),
}
self.cursor_position = Position { x, y }
}

fn refresh_screen(&self) -> Result<(), std::io::Error> {
// print!("\x1b[2J");
Terminal::cursor_hide();
Terminal::clear_screen();
Terminal::cursor_position(0, 0);
Terminal::cursor_position(&Position::default());
if self.should_quit {
println!("Goodbye.\r");
} else {
self.draw_rows();
Terminal::cursor_position(0, 0);
Terminal::cursor_position(&self.cursor_position);
}
Terminal::cursor_show();
Terminal::flush()
}
fn draw_rows(&self) {
for _ in 0..self.terminal.size().height - 1 {
println!("~\r");
let height = self.terminal.size().height;
for terminal_row in 0..height - 1 {
Terminal::clear_current_line();
if let Some(row) = self.document.row(terminal_row as usize) {
self.draw_row(row)
} else if self.document.is_empty() && terminal_row == height / 3 {
self.draw_welcome_message();
} else {
println!("~\r");
}
}
}

fn draw_welcome_message(&self) {
let mut welcome_message = format!("Hecto editor --version{}", VERSION);
let width = self.terminal.size().width as usize;
let len = welcome_message.len();
let padding = width.saturating_sub(len) / 2;
let spaces = " ".repeat(padding.saturating_sub(1));
welcome_message = format!("~{}{}", spaces, welcome_message);
welcome_message.truncate(width);
println!("{}\r", welcome_message);
}
pub fn draw_row(&self, row: &Row) {
let start = 0;
let end = self.terminal.size().width as usize;
let row = row.render(start, end);
println!("{}\r", row);
}

}
5 changes: 4 additions & 1 deletion hecto/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#![warn(clippy::all, clippy::pedantic)]
mod row;
mod editor;
mod document;
mod terminal;

use editor::Editor;
pub use terminal::Terminal;

pub use document::Document;
pub use row::Row;


fn main() {
Expand Down
20 changes: 20 additions & 0 deletions hecto/src/row.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::cmp;
pub struct Row {
string: String,
}

impl From<&str> for Row {
fn from(slice: &str) -> Self {
Self {
string: String::from(slice),
}
}
}

impl Row {
pub fn render(&self, start: usize, end: usize) -> String {
let end = cmp::min(end, self.string.len());
let start = cmp::min(start, end);
self.string.get(start..end).unwrap_or_default().to_string()
}
}
17 changes: 12 additions & 5 deletions hecto/src/terminal.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::editor::Position;
use std::io::{self, stdout, Write};
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::{IntoRawMode, RawTerminal}
use termion::raw::{IntoRawMode, RawTerminal};

pub struct Size {
pub width: u16,
Expand Down Expand Up @@ -30,9 +31,12 @@ impl Terminal {
pub fn clear_screen() {
print!("{}", termion::clear::All);
}
pub fn cursor_position(x: u16, y: u16) {
let x = x.saturating_add(1);
let y = y.saturating_add(1);
pub fn cursor_position(position: &Position) {
let Position{mut x, mut y} = position;
x = x.saturating_add(1);
y = y.saturating_add(1);
let x = x as u16;
let y = y as u16;
print!("{}", termion::cursor::Goto(x, y));
}
pub fn read_key() -> Result<Key, std::io::Error> {
Expand All @@ -43,13 +47,16 @@ impl Terminal {
}
}
pub fn flush() -> Result<(), std::io::Error> {
io::stdout::flush()
io::stdout().flush()
}
pub fn cursor_hide() {
print!("{}", termion::cursor::Hide);
}
pub fn cursor_show() {
print!("{}", termion::cursor::Show);
}
pub fn clear_current_line() {
print!("{}", termion::clear::CurrentLine);
}
}

0 comments on commit 493bf9c

Please sign in to comment.