[Teton] Terminal now owns the command str.
This commit is contained in:
parent
f04e720811
commit
c155247f1d
|
@ -4,56 +4,33 @@ use crate::psf::Psf;
|
|||
pub struct Console {
|
||||
framebuffer: Framebuffer,
|
||||
psf: Psf,
|
||||
row: u32,
|
||||
col: u32,
|
||||
}
|
||||
|
||||
impl Console {
|
||||
pub fn new(framebuffer: Framebuffer, psf: Psf) -> Self {
|
||||
Self {
|
||||
framebuffer,
|
||||
psf,
|
||||
row: 0,
|
||||
col: 0,
|
||||
}
|
||||
Self { framebuffer, psf }
|
||||
}
|
||||
|
||||
fn incr_cursor(&mut self) {
|
||||
self.col += 1;
|
||||
if self.col >= self.cols() {
|
||||
self.col = 0;
|
||||
self.row += 1;
|
||||
pub fn write_char(&mut self, chr: char, row: u32, col: u32) {
|
||||
if row >= self.rows() {
|
||||
panic!("Write at row {}, max is {}", row, self.rows())
|
||||
}
|
||||
|
||||
if self.row >= self.rows() {
|
||||
panic!("Scroll unimplemented")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_char(&mut self, chr: char) {
|
||||
if chr == '\x08' {
|
||||
// Backspace.
|
||||
if self.col > 1 {
|
||||
self.col -= 1;
|
||||
self.write_char(' ');
|
||||
self.col -= 1;
|
||||
}
|
||||
return;
|
||||
if col >= self.cols() {
|
||||
panic!("Write at col {}, max is {}", col, self.cols())
|
||||
}
|
||||
let glyph = self.psf.glyph(chr as u32);
|
||||
self.framebuffer.draw_glyph(
|
||||
glyph,
|
||||
self.row * (self.psf.height() + 1),
|
||||
self.col * (self.psf.width() + 1),
|
||||
row * (self.psf.height() + 1),
|
||||
col * (self.psf.width() + 1),
|
||||
);
|
||||
self.incr_cursor()
|
||||
}
|
||||
|
||||
fn cols(&self) -> u32 {
|
||||
pub fn cols(&self) -> u32 {
|
||||
self.framebuffer.width() / (self.psf.width() + 1)
|
||||
}
|
||||
|
||||
fn rows(&self) -> u32 {
|
||||
pub fn rows(&self) -> u32 {
|
||||
self.framebuffer.height() / (self.psf.height() + 1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,9 +38,7 @@ extern "C" fn main() -> z_err_t {
|
|||
.expect("Failed to create framebuffer");
|
||||
|
||||
let psf = psf::Psf::new("/default8x16.psfu").expect("Failed to open font file.");
|
||||
let mut console = console::Console::new(framebuffer, psf);
|
||||
console.write_char('>');
|
||||
|
||||
let console = console::Console::new(framebuffer, psf);
|
||||
let terminal = Rc::new(RefCell::new(terminal::Terminal::new(console)));
|
||||
|
||||
let kb_listener = KeyboardListener::new(terminal).expect("Failed to create keyboard listener");
|
||||
|
|
|
@ -1,18 +1,94 @@
|
|||
use core::str::Split;
|
||||
|
||||
use crate::console::Console;
|
||||
use alloc::{
|
||||
format,
|
||||
string::{String, ToString},
|
||||
};
|
||||
use voyageurs::listener::KeyboardHandler;
|
||||
|
||||
pub struct Terminal {
|
||||
console: Console,
|
||||
curr_cmd: String,
|
||||
cwd: String,
|
||||
row: u32,
|
||||
}
|
||||
|
||||
impl KeyboardHandler for Terminal {
|
||||
fn handle_char(&mut self, c: char) {
|
||||
self.console.write_char(c)
|
||||
let mut should_execute = false;
|
||||
match c {
|
||||
'\x08' => {
|
||||
let mut chars = self.curr_cmd.chars();
|
||||
chars.next_back(); // Pop last char.
|
||||
self.curr_cmd = chars.collect();
|
||||
}
|
||||
'\n' => should_execute = true,
|
||||
_ => self.curr_cmd.push(c),
|
||||
}
|
||||
self.rewrite_command();
|
||||
if should_execute {
|
||||
self.execute_command();
|
||||
self.rewrite_command();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Terminal {
|
||||
pub fn new(console: Console) -> Self {
|
||||
Self { console }
|
||||
let mut term = Self {
|
||||
console,
|
||||
curr_cmd: String::new(),
|
||||
cwd: "/".to_string(),
|
||||
row: 0,
|
||||
};
|
||||
term.rewrite_command();
|
||||
term
|
||||
}
|
||||
|
||||
fn rewrite_command(&mut self) {
|
||||
self.console.write_char('>', self.row, 0);
|
||||
|
||||
let mut col = 1;
|
||||
for c in self.curr_cmd.chars() {
|
||||
self.console.write_char(c, self.row, col);
|
||||
col += 1;
|
||||
}
|
||||
|
||||
// Hacky way to properly backspace.
|
||||
// FIXME: This won't work once we have line wrapping.
|
||||
self.console.write_char(' ', self.row, col)
|
||||
}
|
||||
|
||||
fn write_line(&mut self, line: &str) {
|
||||
let mut col = 0;
|
||||
for c in line.chars() {
|
||||
self.console.write_char(c, self.row, col);
|
||||
col += 1;
|
||||
}
|
||||
|
||||
self.row += 1
|
||||
}
|
||||
|
||||
fn execute_command(&mut self) {
|
||||
self.row += 1;
|
||||
|
||||
let curr_cmd = self.curr_cmd.clone();
|
||||
let mut tokens = curr_cmd.split(' ');
|
||||
|
||||
match tokens.next() {
|
||||
None => {}
|
||||
Some(command) => self.execute_command_parsed(command, tokens),
|
||||
}
|
||||
|
||||
self.curr_cmd.clear()
|
||||
}
|
||||
|
||||
fn execute_command_parsed(&mut self, cmd: &str, _args: Split<'_, char>) {
|
||||
match cmd {
|
||||
"help" => self.write_line("Available commands are 'pwd', 'ls', 'cd', and 'exec'"),
|
||||
"pwd" => self.write_line(&self.cwd.clone()),
|
||||
_ => self.write_line(&format!("Unrecognized command: {}", cmd)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue