From: Sondre Wold Date: Sun, 5 May 2024 17:03:14 +0000 (+0200) Subject: Status bar and status message line X-Git-Url: https://letsjmore.com/?a=commitdiff_plain;h=refs%2Fheads%2Fmain;p=octo.git Status bar and status message line --- diff --git a/octo/src/document.rs b/octo/src/document.rs index 71e5ea6..e4f616d 100644 --- a/octo/src/document.rs +++ b/octo/src/document.rs @@ -4,6 +4,7 @@ use std::fs; #[derive(Default)] pub struct Document { rows: Vec, + pub file_name: Option, } 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) diff --git a/octo/src/editor.rs b/octo/src/editor.rs index 458b0e2..c3459cd 100644 --- a/octo/src/editor.rs +++ b/octo/src/editor.rs @@ -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 = 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); + } + } } diff --git a/octo/src/terminal.rs b/octo/src/terminal.rs index cafbdef..4cb3c1a 100644 --- a/octo/src/terminal.rs +++ b/octo/src/terminal.rs @@ -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)); + } }