Complete chapter 3
This commit is contained in:
parent
3b6a36f3d7
commit
f79ff6ae02
@ -3,9 +3,15 @@ use termion::event::Key;
|
|||||||
|
|
||||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
pub struct Position {
|
||||||
|
pub x: usize,
|
||||||
|
pub y: usize,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Editor {
|
pub struct Editor {
|
||||||
should_quit: bool,
|
should_quit: bool,
|
||||||
terminal: Terminal,
|
terminal: Terminal,
|
||||||
|
cursor_position: Position,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Editor {
|
impl Editor {
|
||||||
@ -27,18 +33,19 @@ impl Editor {
|
|||||||
Self {
|
Self {
|
||||||
should_quit: false,
|
should_quit: false,
|
||||||
terminal: Terminal::default().expect("Failed to initialize terminal"),
|
terminal: Terminal::default().expect("Failed to initialize terminal"),
|
||||||
|
cursor_position: Position { x: 0, y: 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refresh_screen(&self) -> Result<(), std::io::Error> {
|
fn refresh_screen(&self) -> Result<(), std::io::Error> {
|
||||||
Terminal::cursor_hide();
|
Terminal::cursor_hide();
|
||||||
Terminal::cursor_position(0, 0);
|
Terminal::cursor_position(&Position { x: 0, y: 0});
|
||||||
if self.should_quit {
|
if self.should_quit {
|
||||||
Terminal::clear_screen();
|
Terminal::clear_screen();
|
||||||
println!("Goodbye.\r");
|
println!("Goodbye.\r");
|
||||||
} else {
|
} else {
|
||||||
self.draw_rows();
|
self.draw_rows();
|
||||||
Terminal::cursor_position(0, 0);
|
Terminal::cursor_position(&self.cursor_position);
|
||||||
}
|
}
|
||||||
Terminal::cursor_show();
|
Terminal::cursor_show();
|
||||||
Terminal::flush()
|
Terminal::flush()
|
||||||
@ -48,11 +55,52 @@ impl Editor {
|
|||||||
let pressed_key = Terminal::read_key()?;
|
let pressed_key = Terminal::read_key()?;
|
||||||
match pressed_key {
|
match pressed_key {
|
||||||
Key::Ctrl('q') => self.should_quit = true,
|
Key::Ctrl('q') => self.should_quit = true,
|
||||||
|
Key::Up | Key::Down | Key::Left | Key::Right | Key::PageUp | Key::PageDown | Key::End | Key::Home => self.move_cursor(pressed_key),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn move_cursor(&mut self, key: Key) {
|
||||||
|
let Position { mut y, mut x } = self.cursor_position;
|
||||||
|
let size = self.terminal.size();
|
||||||
|
let height = size.height.saturating_sub(1) as usize;
|
||||||
|
let width = size.width.saturating_sub(1) as usize;
|
||||||
|
|
||||||
|
match key {
|
||||||
|
Key::Up => y = y.saturating_sub(1),
|
||||||
|
Key::Down => {
|
||||||
|
if y < height {
|
||||||
|
y = y.saturating_add(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Key::Left => x = x.saturating_sub(1),
|
||||||
|
Key::Right => {
|
||||||
|
if x < width {
|
||||||
|
x = x.saturating_add(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Key::PageUp => y = 0,
|
||||||
|
Key::PageDown => y = height,
|
||||||
|
Key::Home => x = 0,
|
||||||
|
Key::End => x = width,
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.cursor_position = Position { x, y }
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_rows(&self) {
|
fn draw_rows(&self) {
|
||||||
let height = self.terminal.size().height;
|
let height = self.terminal.size().height;
|
||||||
|
|
||||||
@ -60,10 +108,7 @@ impl Editor {
|
|||||||
Terminal::clear_current_line();
|
Terminal::clear_current_line();
|
||||||
|
|
||||||
if row == height / 3 {
|
if row == height / 3 {
|
||||||
let welcome_message = format!("Hecto editor -- version {}", VERSION);
|
self.draw_welcome_message();
|
||||||
|
|
||||||
let width = std::cmp::min(self.terminal.size().width as usize, welcome_message.len());
|
|
||||||
println!("{}\r", &welcome_message[..width]);
|
|
||||||
} else {
|
} else {
|
||||||
println!("~\r");
|
println!("~\r");
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ mod terminal;
|
|||||||
|
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
pub use terminal::Terminal;
|
pub use terminal::Terminal;
|
||||||
|
pub use editor::Position;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
Editor::default().run();
|
Editor::default().run();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::Position;
|
||||||
use std::io::{self, stdout, Write};
|
use std::io::{self, stdout, Write};
|
||||||
use termion::event::Key;
|
use termion::event::Key;
|
||||||
use termion::input::TermRead;
|
use termion::input::TermRead;
|
||||||
@ -33,9 +34,14 @@ impl Terminal {
|
|||||||
print!("{}", termion::clear::All);
|
print!("{}", termion::clear::All);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor_position(x: u16, y: u16) {
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
let x = x.saturating_add(1);
|
pub fn cursor_position(position: &Position) {
|
||||||
let y = y.saturating_add(1);
|
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));
|
print!("{}", termion::cursor::Goto(x, y));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user