From 154579425842a60f7d984cbf671353c6e47afc2b Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 12 Jul 2020 19:04:47 +0200 Subject: [PATCH 1/5] Show write status in editor --- src/user/editor.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/user/editor.rs b/src/user/editor.rs index 79eb06392..26d25e7c2 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; @@ -54,21 +56,34 @@ impl Editor { } } + let csi_reset = Style::reset(); if let Some(file) = &mut self.file { file.write(&contents.as_bytes()).unwrap(); + let csi_color = Style::color("Yellow"); + self.print_status(&format!("{}Wrote {}L to '{}'{}", csi_color, n, self.pathname, csi_reset)); user::shell::ExitCode::CommandSuccessful } else { - print!("Could not write to '{}'\n", self.pathname); + let csi_color = Style::color("LightRed"); + self.print_status(&format!("{}Could not write to '{}'{}", csi_color, self.pathname, csi_reset)); user::shell::ExitCode::CommandError } } + fn print_status(&mut self, status: &str) { + let (x, y) = kernel::vga::cursor_position(); + kernel::vga::set_writer_position(0, self.height()); + kernel::vga::set_cursor_position(0, self.height()); + print!("{}", status); + 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); + let n = cmp::min(self.lines[i].len(), self.width()); lines.push(self.lines[i][0..n].into()) // TODO: Use `offset_x .. offset_x + n` } 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 { From dd684b3df333adfd631328360a16e6f1faa63812 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 12 Jul 2020 21:34:24 +0200 Subject: [PATCH 2/5] Add 'help edit' command --- src/user/editor.rs | 5 +---- src/user/help.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/user/editor.rs b/src/user/editor.rs index 26d25e7c2..a4bc7814f 100644 --- a/src/user/editor.rs +++ b/src/user/editor.rs @@ -73,6 +73,7 @@ impl Editor { let (x, y) = kernel::vga::cursor_position(); kernel::vga::set_writer_position(0, self.height()); kernel::vga::set_cursor_position(0, self.height()); + kernel::vga::clear_row(); print!("{}", status); kernel::vga::set_writer_position(x, y); kernel::vga::set_cursor_position(x, y); @@ -102,10 +103,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(); diff --git a/src/user/help.rs b/src/user/help.rs index ef1cae024..9e8e84f7b 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 +} From 0219b36979f34451b5de94a2618d15dc08e43418 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 12 Jul 2020 21:57:12 +0200 Subject: [PATCH 3/5] Show pathname in status bar --- src/user/editor.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/user/editor.rs b/src/user/editor.rs index a4bc7814f..1fbc5b04e 100644 --- a/src/user/editor.rs +++ b/src/user/editor.rs @@ -89,6 +89,10 @@ impl Editor { } kernel::vga::clear_screen(); print!("{}", lines.join("\n")); + let csi_color = Style::color("Black").with_background("LightGray"); + let csi_reset = Style::reset(); + let status = format!("Editing '{}'", self.pathname); + self.print_status(&format!("{}{:80}{}", csi_color, status, csi_reset)); } pub fn run(&mut self) -> user::shell::ExitCode { From cda0ac247ff0939f6d6151eb1797c06909099ebf Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 12 Jul 2020 21:57:30 +0200 Subject: [PATCH 4/5] Update status bar colors --- src/user/editor.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/user/editor.rs b/src/user/editor.rs index 1fbc5b04e..6399ce872 100644 --- a/src/user/editor.rs +++ b/src/user/editor.rs @@ -59,12 +59,14 @@ impl Editor { let csi_reset = Style::reset(); if let Some(file) = &mut self.file { file.write(&contents.as_bytes()).unwrap(); - let csi_color = Style::color("Yellow"); - self.print_status(&format!("{}Wrote {}L to '{}'{}", csi_color, n, self.pathname, csi_reset)); + let csi_color = Style::color("Black").with_background("Yellow"); + let status = format!("Wrote {}L to '{}'", n, self.pathname); + self.print_status(&format!("{}{:80}{}", csi_color, status, csi_reset)); user::shell::ExitCode::CommandSuccessful } else { - let csi_color = Style::color("LightRed"); - self.print_status(&format!("{}Could not write to '{}'{}", csi_color, self.pathname, csi_reset)); + let csi_color = Style::color("Black").with_background("LightRed"); + let status = format!("Could not write to '{}'", self.pathname); + self.print_status(&format!("{}{:80}{}", csi_color, status, csi_reset)); user::shell::ExitCode::CommandError } } From 5c351edd7236b84a391b4ccd3a2fd9cfc46b4f3f Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 12 Jul 2020 23:45:10 +0200 Subject: [PATCH 5/5] Avoid clearing before printing by overwriting whole lines --- src/user/editor.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/user/editor.rs b/src/user/editor.rs index 6399ce872..e2d1b8d86 100644 --- a/src/user/editor.rs +++ b/src/user/editor.rs @@ -56,27 +56,24 @@ impl Editor { } } - let csi_reset = Style::reset(); if let Some(file) = &mut self.file { file.write(&contents.as_bytes()).unwrap(); - let csi_color = Style::color("Black").with_background("Yellow"); let status = format!("Wrote {}L to '{}'", n, self.pathname); - self.print_status(&format!("{}{:80}{}", csi_color, status, csi_reset)); + self.print_status(&status, "Yellow"); user::shell::ExitCode::CommandSuccessful } else { - let csi_color = Style::color("Black").with_background("LightRed"); let status = format!("Could not write to '{}'", self.pathname); - self.print_status(&format!("{}{:80}{}", csi_color, status, csi_reset)); + self.print_status(&status, "LightRed"); user::shell::ExitCode::CommandError } } - fn print_status(&mut self, status: &str) { + 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()); - kernel::vga::set_cursor_position(0, self.height()); - kernel::vga::clear_row(); - print!("{}", status); + print!("{}{:width$}{}", csi_color, status, csi_reset, width = self.width()); kernel::vga::set_writer_position(x, y); kernel::vga::set_cursor_position(x, y); } @@ -86,18 +83,18 @@ impl Editor { 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(), self.width()); - 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 csi_color = Style::color("Black").with_background("LightGray"); - let csi_reset = Style::reset(); let status = format!("Editing '{}'", self.pathname); - self.print_status(&format!("{}{:80}{}", csi_color, status, csi_reset)); + 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);