]> git.sondrewold.no Git - octo.git/commitdiff
Status bar and status message line main
authorSondre Wold <[email protected]>
Sun, 5 May 2024 17:03:14 +0000 (19:03 +0200)
committerSondre Wold <[email protected]>
Sun, 5 May 2024 17:03:14 +0000 (19:03 +0200)
octo/src/document.rs
octo/src/editor.rs
octo/src/terminal.rs

index 71e5ea65890dfcd4511d333434bc809b07eb2c1c..e4f616dbf2f1a11c7df35acda4dfba6becf04a28 100644 (file)
@@ -4,6 +4,7 @@ use std::fs;
 #[derive(Default)]
 pub struct Document {
     rows: Vec<Row>,
+    pub file_name: Option<String>,
 }
 
 impl Document {
@@ -13,7 +14,7 @@ impl Document {
         for value in contents.lines() {
             rows.push(Row::from(value));
         }
-        Ok(Self { rows })
+        Ok(Self { rows, file_name: Some(String::from(filename))})
     }
     pub fn row(&self, index: usize) -> Option<&Row> {
         self.rows.get(index)
index 458b0e2047a9e7eb5ce84988d519a56c2eedceb1..c3459cdd87e3fca45e02d76675e06023f8a4cd4c 100644 (file)
@@ -1,7 +1,12 @@
 use crate::{Document, Row, Terminal};
 use std::env;
+use std::time::Duration;
+use std::time::Instant;
+use termion::color;
 use termion::event::Key;
 
+const STATUS_FG_COLOR: color::Rgb = color::Rgb(63, 63, 63);
+const STATUS_BG_COLOR: color::Rgb = color::Rgb(239, 239, 239);
 const VERSION: &str = env!("CARGO_PKG_VERSION");
 
 fn die(e: std::io::Error) {
@@ -15,12 +20,27 @@ pub struct Position {
     pub y: usize,
 }
 
+struct StatusMessage {
+    text: String,
+    time: Instant,
+}
+
+impl StatusMessage {
+    fn from(message: String) -> Self {
+        Self {
+            text: message,
+            time: Instant::now(),
+        }
+    }
+}
+
 pub struct Editor {
     should_quit: bool,
     terminal: Terminal,
     current_position: Position,
     offset: Position,
     document: Document,
+    status_message:  StatusMessage,
 }
 
 impl Editor {
@@ -39,9 +59,16 @@ impl Editor {
     }
     pub fn default() -> Self {
         let args: Vec<String> = env::args().collect();
+        let mut initial_status = String::from("HELP: Ctrl-Q = quit");
         let document = if args.len() > 1 {
             let file_name = &args[1];
-            Document::open(&file_name).unwrap_or_default()
+            let doc = Document::open(&file_name);
+            if doc.is_ok() {
+                doc.unwrap()
+            } else {
+                initial_status = format!("Error: failed to open file: {}", file_name);
+                Document::default()
+            }
         } else {
             Document::default()
         };
@@ -51,6 +78,7 @@ impl Editor {
             document,
             current_position: Position::default(),
             offset: Position::default(),
+            status_message: StatusMessage::from(initial_status),
         }
     }
 
@@ -62,6 +90,8 @@ impl Editor {
             println!("Goodbye.\r");
         } else {
             self.draw_rows();
+            self.draw_status_bar();
+            self.draw_message_bar();
             Terminal::cursor_position(&Position {
                 x: self.current_position.x.saturating_sub(self.offset.x),
                 y: self.current_position.y.saturating_sub(self.offset.y),
@@ -193,7 +223,7 @@ impl Editor {
 
     fn draw_rows(&self) {
         let height = self.terminal.size().height;
-        for terminal_row in 0..height - 1 {
+        for terminal_row in 0..height {
             Terminal::clear_current_line();
             if let Some(row) = self.document.row(terminal_row as usize + self.offset.y) {
                 self.draw_row(row);
@@ -204,4 +234,40 @@ impl Editor {
             }
         }
     }
+
+    fn draw_status_bar(&self) {
+        let mut status;
+        let width = self.terminal.size().width as usize;
+        let mut file_name = "[No Name]".to_string();
+        if let Some(name) = &self.document.file_name {
+            file_name = name.clone();
+            file_name.truncate(20);
+        }
+        status = format!("{} - {} lines", file_name, self.document.len());
+        let line_indicator = format!(
+            "{}/{}",
+            self.current_position.y.saturating_add(1),
+            self.document.len()
+        );
+        let len = status.len() + line_indicator.len();
+        if width > len {
+            status.push_str(&" ".repeat(width - len));
+        }
+        status = format!("{}{}", status, line_indicator);
+        status.truncate(width);
+        Terminal::set_fg_color(STATUS_FG_COLOR);
+        println!("{}\r", status);
+        Terminal::reset_fg_color();
+        Terminal::reset_bg_color();
+    }
+
+    fn draw_message_bar(&self) {
+        Terminal::clear_current_line();
+        let message = &self.status_message;
+        if Instant::now() - message.time < Duration::new(5, 0) {
+            let mut text = message.text.clone();
+            text.truncate(self.terminal.size().width as usize);
+            print!("{}", text);
+        }
+    }
 }
index cafbdef4a6f315918574ebf667efafe13034acd5..4cb3c1aee21cd710c3ecd8b3c7c66e3f5c3acaac 100644 (file)
@@ -1,5 +1,6 @@
 use crate::Position;
 use std::io::{self, stdout, Write};
+use termion::color;
 use termion::event::Key;
 use termion::input::TermRead;
 use termion::raw::{IntoRawMode, RawTerminal};
@@ -20,7 +21,7 @@ impl Terminal {
         Ok(Self {
             size: Size {
                 width: size.0,
-                height: size.1,
+                height: size.1.saturating_sub(2),
             },
             _stdout: stdout().into_raw_mode()?,
         })
@@ -38,7 +39,7 @@ impl Terminal {
     }
 
     pub fn cursor_position(position: &Position) {
-        let Position{mut x, mut y} = position;
+        let Position { mut x, mut y } = position;
         x = x.saturating_add(1);
         y = y.saturating_add(1);
         let x = x as u16;
@@ -65,4 +66,19 @@ impl Terminal {
             }
         }
     }
+    pub fn set_bg_color(color: color::Rgb) {
+        print!("{}", color::Bg(color));
+    }
+
+    pub fn reset_bg_color() {
+        print!("{}", color::Bg(color::Reset));
+    }
+
+    pub fn set_fg_color(color: color::Rgb) {
+        print!("{}", color::Bg(color));
+    }
+
+    pub fn reset_fg_color() {
+        print!("{}", color::Bg(color::Reset));
+    }
 }