diff --git a/src/user/editor.rs b/src/user/editor.rs index 79eb0639..e2d1b8d8 100644 --- a/src/user/editor.rs +++ b/src/user/editor.rs @@ -1,4 +1,6 @@ use crate::{kernel, print, user}; +use crate::kernel::console::Style; +use alloc::format; use alloc::string::String; use alloc::vec::Vec; use core::cmp; @@ -56,26 +58,43 @@ impl Editor { if let Some(file) = &mut self.file { file.write(&contents.as_bytes()).unwrap(); + let status = format!("Wrote {}L to '{}'", n, self.pathname); + self.print_status(&status, "Yellow"); user::shell::ExitCode::CommandSuccessful } else { - print!("Could not write to '{}'\n", self.pathname); + let status = format!("Could not write to '{}'", self.pathname); + self.print_status(&status, "LightRed"); user::shell::ExitCode::CommandError } } + fn print_status(&mut self, status: &str, background: &str) { + let csi_color = Style::color("Black").with_background(background); + let csi_reset = Style::reset(); + let (x, y) = kernel::vga::cursor_position(); + kernel::vga::set_writer_position(0, self.height()); + print!("{}{:width$}{}", csi_color, status, csi_reset, width = self.width()); + kernel::vga::set_writer_position(x, y); + kernel::vga::set_cursor_position(x, y); + } + fn print_screen(&mut self) { let mut lines: Vec = Vec::new(); let from = self.offset; let to = cmp::min(self.lines.len(), self.offset + self.height()); for i in from..to { - let n = cmp::min(self.lines[i].len(), 80); - lines.push(self.lines[i][0..n].into()) // TODO: Use `offset_x .. offset_x + n` + let n = self.width(); + let line = format!("{:width$}", self.lines[i], width = n); + lines.push(line[0..n].into()); // TODO: Use `offset_x .. offset_x + n` } - kernel::vga::clear_screen(); + kernel::vga::set_writer_position(0, 0); print!("{}", lines.join("\n")); + let status = format!("Editing '{}'", self.pathname); + self.print_status(&status, "LightGray"); } pub fn run(&mut self) -> user::shell::ExitCode { + kernel::vga::clear_screen(); self.print_screen(); kernel::vga::set_cursor_position(0, 0); kernel::vga::set_writer_position(0, 0); @@ -87,10 +106,6 @@ impl Editor { '\0' => { continue; } - '\x03' => { // Ctrl C - kernel::vga::clear_screen(); - break; - } '\x11' => { // Ctrl Q // TODO: Warn if modifications have not been saved kernel::vga::clear_screen(); @@ -100,8 +115,9 @@ impl Editor { self.save(); }, '\x18' => { // Ctrl X + let res = self.save(); kernel::vga::clear_screen(); - return self.save(); + return res; }, '\n' => { // Newline let new_line = self.lines[self.offset + y].split_off(x); @@ -234,7 +250,7 @@ impl Editor { } fn height(&self) -> usize { - kernel::vga::screen_height() + kernel::vga::screen_height() - 1 // Leave out one line for status line } fn width(&self) -> usize { diff --git a/src/user/help.rs b/src/user/help.rs index ef1cae02..9e8e84f7 100644 --- a/src/user/help.rs +++ b/src/user/help.rs @@ -1,7 +1,27 @@ use crate::{print, user}; use crate::kernel::console::Style; -pub fn main(_args: &[&str]) -> user::shell::ExitCode { +pub fn main(args: &[&str]) -> user::shell::ExitCode { + if args.len() > 1 { + help_command(args[1]) + } else { + help_summary() + } +} + +fn help_command(cmd: &str) -> user::shell::ExitCode { + match cmd { + "edit" => help_edit(), + _ => help_unknown(cmd), + } +} + +fn help_unknown(cmd: &str) -> user::shell::ExitCode { + print!("Help not found for command '{}'\n", cmd); + user::shell::ExitCode::CommandError +} + +fn help_summary() -> user::shell::ExitCode { let csi_color = Style::color("Yellow"); let csi_reset = Style::reset(); print!("{}Commands:{}\n", csi_color, csi_reset); @@ -12,7 +32,7 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode { ("d", "elete ", "Delete file or empty directory\n"), ("e", "dit ", "Edit existing or new file\n"), ("g", "oto ", "Go to directory\n"), - ("h", "elp", "Display this text\n"), + ("h", "elp ", "Display help about a command\n"), ("l", "ist ", "List entries in directory\n"), ("m", "ove ", "Move file from source to destination\n"), ("p", "rint ", "Print string to screen\n"), @@ -33,3 +53,29 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode { print!("Made with <3 in 2019-2020 by Vincent Ollivier \n"); user::shell::ExitCode::CommandSuccessful } + +fn help_edit() -> user::shell::ExitCode { + let csi_color = Style::color("Yellow"); + let csi_reset = Style::reset(); + print!("MOROS text editor is somewhat inspired by nano, but with an even smaller range\n"); + print!("of features.\n"); + print!("\n"); + print!("{}Shortcuts:{}\n", csi_color, csi_reset); + print!("\n"); + + let shortcuts = [ + ("^Q", "Quit editor"), + ("^W", "Write to file"), + ("^X", "Write to file and quit"), + ("^T", "Go to top of file"), + ("^B", "Go to bottom of file"), + ("^A", "Go to beginning of line"), + ("^E", "Go to end of line"), + ]; + for (shortcut, usage) in &shortcuts { + let csi_color = Style::color("LightGreen"); + let csi_reset = Style::reset(); + print!(" {}{}{} {}\n", csi_color, shortcut, csi_reset, usage); + } + user::shell::ExitCode::CommandSuccessful +}