mirror of https://github.com/vinc/moros.git
Improve editor (#77)
* Show write status in editor * Add 'help edit' command * Show pathname in status bar * Update status bar colors * Avoid clearing before printing by overwriting whole lines
This commit is contained in:
parent
1f86f6ba7f
commit
b0266744c2
|
@ -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<String> = 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 {
|
||||
|
|
|
@ -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 <file>", "Delete file or empty directory\n"),
|
||||
("e", "dit <file>", "Edit existing or new file\n"),
|
||||
("g", "oto <dir>", "Go to directory\n"),
|
||||
("h", "elp", "Display this text\n"),
|
||||
("h", "elp <command>", "Display help about a command\n"),
|
||||
("l", "ist <dir>", "List entries in directory\n"),
|
||||
("m", "ove <file> <file>", "Move file from source to destination\n"),
|
||||
("p", "rint <string>", "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 <v@vinc.cc>\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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue