]> git.sondrewold.no Git - octo.git/commitdiff
More navigation commands
authorSondre Wold <[email protected]>
Sun, 21 Apr 2024 09:34:51 +0000 (11:34 +0200)
committerSondre Wold <[email protected]>
Sun, 21 Apr 2024 09:34:51 +0000 (11:34 +0200)
octo/src/editor.rs
octo/src/main.rs
octo/src/terminal.rs

index bef7795af45260d31f4c10cb5c600ea62e45d1ec..dc87d899d8bf86cc8a212ec0280aa694766dc280 100644 (file)
@@ -1,14 +1,22 @@
 use crate::Terminal;
 use termion::event::Key;
 
+const VERSION: &str = env!("CARGO_PKG_VERSION");
+
 fn die(e: std::io::Error) {
     Terminal::clear_screen();
     panic!("{:?}", e);
 }
 
+pub struct Position {
+    pub x: usize,
+    pub y: usize,
+}
+
 pub struct Editor {
     should_quit: bool,
     terminal: Terminal,
+    current_position: Position,
 }
 
 impl Editor {
@@ -29,18 +37,21 @@ impl Editor {
         Self {
             should_quit: false,
             terminal: Terminal::default().expect("Failed to create terminal"),
+            current_position: Position { x: 0, y: 0 },
         }
     }
 
     fn refresh_screen(&self) -> Result<(), std::io::Error> {
-        Terminal::clear_screen();
-        Terminal::cursor_position(0, 0);
+        Terminal::cursor_hide();
+        Terminal::cursor_position(&Position { x: 0, y: 0 });
         if self.should_quit {
+            Terminal::clear_screen();
             println!("Goodbye.\r");
         } else {
             self.draw_rows();
-            Terminal::cursor_position(0, 0);
+            Terminal::cursor_position(&self.current_position);
         }
+        Terminal::cursor_show();
         Terminal::flush()
     }
 
@@ -48,13 +59,66 @@ impl Editor {
         let pressed_key = Terminal::read_key()?;
         match pressed_key {
             Key::Ctrl('q') => self.should_quit = true,
+            Key::Up
+            | Key::Down
+            | Key::Left
+            | Key::Right
+            | Key::PageUp
+            | Key::PageDown
+            | Key::Home
+            | Key::End => self.move_cursor(pressed_key),
             _ => (),
         };
         Ok(())
     }
+
+    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;
+        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.current_position = Position { x, y };
+    }
+
+    fn draw_welcome_message(&self) {
+        let mut welcome_message = format!("OCTO -- 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) {
-        for _ in 0..self.terminal.size().height {
-            println!("~\r");
+        let height = self.terminal.size().height;
+        for row in 0..height - 1 {
+            Terminal::clear_current_line();
+            if row == height / 3 {
+                self.draw_welcome_message();
+            } else {
+                println!("~\r");
+            }
         }
     }
 }
index 06376819a73a557d54c5a549c8c6ac30ef93d646..4bc5c579f2e12111cd6ce802108cb04d68f6a141 100644 (file)
@@ -3,6 +3,7 @@ mod editor;
 mod terminal;
 use editor::Editor;
 pub use terminal::Terminal;
+pub use editor::Position;
 
 fn main() {
     Editor::default().run();
index 599d873f3607af28945102763375e642676d2b83..cafbdef4a6f315918574ebf667efafe13034acd5 100644 (file)
@@ -1,3 +1,4 @@
+use crate::Position;
 use std::io::{self, stdout, Write};
 use termion::event::Key;
 use termion::input::TermRead;
@@ -32,9 +33,16 @@ impl Terminal {
         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 clear_current_line() {
+        print!("{}", termion::clear::CurrentLine);
+    }
+
+    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));
     }
 
@@ -42,6 +50,14 @@ impl Terminal {
         io::stdout().flush()
     }
 
+    pub fn cursor_hide() {
+        print!("{}", termion::cursor::Hide);
+    }
+
+    pub fn cursor_show() {
+        print!("{}", termion::cursor::Show);
+    }
+
     pub fn read_key() -> Result<Key, std::io::Error> {
         loop {
             if let Some(key) = io::stdin().lock().keys().next() {