diff --git a/Cargo.lock b/Cargo.lock index 896b34b..6949ebb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -189,6 +189,7 @@ dependencies = [ "serde", "tokio", "toml", + "unicode-width", ] [[package]] @@ -262,6 +263,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-std-workspace-std" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba676a20abe46e5b0f1b0deae474aaaf31407e6c71147159890574599da04ef" + [[package]] name = "rustix" version = "0.38.37" @@ -436,6 +443,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +dependencies = [ + "rustc-std-workspace-std", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 298313a..1b9b28c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,4 @@ crossterm = "0.28.1" serde = { version = "1.0.210", features = ["derive", "serde_derive"] } tokio = { version = "1.40.0", features = ["full"] } toml = "0.8.19" +unicode-width = { version = "0.2.0", features = ["std"] } diff --git a/src/application.rs b/src/application.rs index 60150d0..c4c1b6c 100644 --- a/src/application.rs +++ b/src/application.rs @@ -6,11 +6,15 @@ use std::{ }; use crossterm::{ - cursor, event, queue, + cursor, + event::{self, KeyEvent, KeyModifiers}, + queue, style::{self, Color}, terminal::{self, disable_raw_mode, enable_raw_mode, ClearType}, }; +use unicode_width::UnicodeWidthStr; + use crate::{colortheme::ColorTheme, iterate_config, window::Window, Config}; pub struct Application { @@ -22,6 +26,7 @@ pub struct Application { command_mode: bool, command: String, cmdbar_show: String, + cmdbar_prompt: String, } impl Application { @@ -44,6 +49,7 @@ impl Application { command_mode: true, command: String::new(), cmdbar_show: String::new(), + cmdbar_prompt: String::from("New workspace"), }) } @@ -55,45 +61,66 @@ impl Application { match event::read()? { event::Event::FocusGained => queue!(self.stdout, cursor::Show)?, event::Event::FocusLost => queue!(self.stdout, cursor::Hide)?, - event::Event::Key(key_event) => match key_event.code { - event::KeyCode::Backspace => { - if self.command_mode { - self.command.pop(); - self.cmdbar_show.clone_from(&self.command); + event::Event::Key(key_event) => { + let KeyEvent { + code, modifiers, .. + } = key_event; + match code { + event::KeyCode::Backspace => { + if self.command_mode { + self.command.pop(); + self.cmdbar_show.clone_from(&self.command); + } } - } - event::KeyCode::Enter => (), - event::KeyCode::Left => (), - event::KeyCode::Right => (), - event::KeyCode::Up => (), - event::KeyCode::Down => (), - event::KeyCode::Home => (), - event::KeyCode::End => (), - event::KeyCode::PageUp => (), - event::KeyCode::PageDown => (), - event::KeyCode::Tab => (), - event::KeyCode::BackTab => (), - event::KeyCode::Delete => (), - event::KeyCode::Insert => (), - event::KeyCode::F(_) => (), - event::KeyCode::Char(c) => { - if self.command_mode { - self.command.push(c); - self.cmdbar_show.clone_from(&self.command); + event::KeyCode::Enter => { + if self.command_mode { + self.command.clear(); + self.cmdbar_show.clear(); + } + } + event::KeyCode::Left => (), + event::KeyCode::Right => (), + event::KeyCode::Up => (), + event::KeyCode::Down => (), + event::KeyCode::Home => (), + event::KeyCode::End => (), + event::KeyCode::PageUp => (), + event::KeyCode::PageDown => (), + event::KeyCode::Tab => (), + event::KeyCode::BackTab => (), + event::KeyCode::Delete => (), + event::KeyCode::Insert => (), + event::KeyCode::F(_) => (), + event::KeyCode::Char(c) => { + if self.command_mode { + let mut b = true; + if modifiers.contains(KeyModifiers::CONTROL) { + self.command += "C-"; + } else if modifiers.contains(KeyModifiers::ALT) { + self.command += "A-"; + } else { + b = false; + } + self.command.push(c); + if b { + self.command.push(' '); + } + self.cmdbar_show.clone_from(&self.command); + } } + event::KeyCode::Null => (), + event::KeyCode::Esc => (), + event::KeyCode::CapsLock => (), + event::KeyCode::ScrollLock => (), + event::KeyCode::NumLock => (), + event::KeyCode::PrintScreen => (), + event::KeyCode::Pause => (), + event::KeyCode::Menu => (), + event::KeyCode::KeypadBegin => (), + event::KeyCode::Media(media) => (), + event::KeyCode::Modifier(modifier) => (), } - event::KeyCode::Null => (), - event::KeyCode::Esc => (), - event::KeyCode::CapsLock => (), - event::KeyCode::ScrollLock => (), - event::KeyCode::NumLock => (), - event::KeyCode::PrintScreen => (), - event::KeyCode::Pause => (), - event::KeyCode::Menu => (), - event::KeyCode::KeypadBegin => (), - event::KeyCode::Media(media_key_code) => (), - event::KeyCode::Modifier(modifier_key_code) => (), - }, + } event::Event::Mouse(mouse_event) => (), event::Event::Paste(_) => (), event::Event::Resize(w, h) => self.size = (w, h), @@ -110,15 +137,7 @@ impl Application { if let Some((name, _)) = iterate_config(map, &f) { match name.as_str() { "quit" => break, - "print" => queue!( - self.stdout, - style::SetBackgroundColor(self.colortheme.background), - cursor::SavePosition, - cursor::MoveTo(0, 0), - style::Print("Hello"), - cursor::RestorePosition, - )?, - _ => (), + _ => self.cmdbar_prompt = String::from("Unknown command"), } self.command.clear(); } @@ -137,15 +156,25 @@ impl Application { let mut show = String::new(); for c in self.cmdbar_show.chars() { show.push(c); - if cursor::position().unwrap().0 >= self.size.0 - 1 { + if UnicodeWidthStr::width(show.as_str()) as u16 >= self.size.0 - 1 { break; } } + let x = cursor::position().unwrap().0; + let mut prompt = String::new(); + for c in self.cmdbar_prompt.chars() { + show.push(c); + if UnicodeWidthStr::width(prompt.as_str()) as u16 >= self.size.0 - 1 - x { + break; + } + } queue!( self.stdout, style::SetBackgroundColor(self.colortheme.command_bar), cursor::MoveTo(0, self.size.1 - 1), style::Print(show), + style::SetForegroudColor(self.colortheme.cmdbar_prompt), + style::Print(prompt), )?; let x = cursor::position().unwrap().0; queue!( diff --git a/src/colortheme.rs b/src/colortheme.rs index 8110510..649953d 100644 --- a/src/colortheme.rs +++ b/src/colortheme.rs @@ -1,7 +1,6 @@ use crossterm::style::Color; use toml::{Table, Value}; - pub struct ColorTheme { pub background: Color, pub command_bar: Color, diff --git a/src/window.rs b/src/window.rs index 41ad61f..a95ddd3 100644 --- a/src/window.rs +++ b/src/window.rs @@ -2,5 +2,3 @@ pub struct Window { pos: (u16, u16), size: (u16, u16), } - -