summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/edit.rs101
1 files changed, 82 insertions, 19 deletions
diff --git a/src/edit.rs b/src/edit.rs
index 97c1abf..a804def 100644
--- a/src/edit.rs
+++ b/src/edit.rs
@@ -1,7 +1,6 @@
use vtcol::{Palette, Rgb, Scheme};
-use std::fmt;
-use std::rc::Rc;
+use std::{fmt, path::PathBuf, rc::Rc};
use anyhow::{anyhow, Result};
@@ -324,7 +323,8 @@ slint::slint! {
}
#[derive(Debug)]
-enum KeyInput {
+enum KeyInput
+{
Printable(String),
Escape,
Return,
@@ -339,8 +339,10 @@ enum KeyInput {
Junk,
}
-impl fmt::Display for KeyInput {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+impl fmt::Display for KeyInput
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
+ {
let k = match self {
Self::Printable(s) => return write!(f, "‘{}’", s),
Self::Escape => "ESC",
@@ -360,12 +362,15 @@ impl fmt::Display for KeyInput {
}
/** Crude filter for rejecting strings containing control chars. */
-fn is_printable(s: &str) -> bool {
+fn is_printable(s: &str) -> bool
+{
s.chars().find(|c| c.is_control()).is_none()
}
-impl From<&KeyEvent> for KeyInput {
- fn from(ev: &KeyEvent) -> Self {
+impl From<&KeyEvent> for KeyInput
+{
+ fn from(ev: &KeyEvent) -> Self
+ {
match ev.text.as_str() {
"\u{0008}" => KeyInput::Backspace,
"\t" | "\u{000b}" => KeyInput::Tab,
@@ -382,17 +387,21 @@ impl From<&KeyEvent> for KeyInput {
}
}
-pub struct Edit {
- name: Option<String>,
+pub struct Edit
+{
+ name: Option<String>,
scheme: Scheme,
}
-impl Edit {
- pub fn new(name: Option<String>, scheme: Scheme) -> Self {
+impl Edit
+{
+ pub fn new(name: Option<String>, scheme: Scheme) -> Self
+ {
Self { name, scheme }
}
- pub fn run(self) -> Result<()> {
+ pub fn run(self) -> Result<()>
+ {
let Self { name, scheme } = self;
let pal = Palette::try_from(&scheme)?.iter().collect::<Vec<Rgb>>();
@@ -475,14 +484,28 @@ impl Edit {
text
},
KeyInput::Return => {
- todo!();
+ match Command::try_from(text.as_str()) {
+ Err(e) => {
+ eprintln!("bad command [{}]: {}", text, e);
+ String::new()
+ },
+ Ok(cmd) => {
+ if let Err(e) = cmd.exec() {
+ eprintln!(
+ "error executing command [{}]: {}",
+ text, e
+ );
+ }
+ String::new()
+ },
+ }
/* The empty string signals to leave command mode. */
- String::new()
- },
- KeyInput::Backspace => match text.char_indices().next_back() {
- Some((i, _)) => text[..i].into(),
- None => text.to_string(),
},
+ KeyInput::Backspace =>
+ match text.char_indices().next_back() {
+ Some((i, _)) => text[..i].into(),
+ None => text.to_string(),
+ },
other => {
eprintln!(
"»»» command mode input: “{}”",
@@ -507,3 +530,43 @@ impl Edit {
Ok(())
}
}
+
+#[derive(Debug)]
+enum Command
+{
+ Noop,
+ Save(Option<PathBuf>),
+}
+
+impl TryFrom<&str> for Command
+{
+ type Error = anyhow::Error;
+
+ fn try_from(text: &str) -> Result<Self>
+ {
+ let text = text.trim_start_matches(':').trim();
+ if text.len() == 0 {
+ return Ok(Self::Noop);
+ }
+ let (cmd, args) = if let Some(cmd) = text.get(..1) {
+ (cmd, &text[1..])
+ } else {
+ return Err(anyhow!("non-ascii command‽"));
+ };
+
+ match (cmd, args) {
+ ("w", "") => Ok(Self::Save(None)),
+ ("w", rest) => {
+ let rest = rest.trim();
+ let path = PathBuf::from(rest);
+ Ok(Self::Save(Some(path)))
+ },
+ _ => Err(anyhow!("only save (‘:w’) implemented for now")),
+ }
+ }
+}
+
+impl Command
+{
+ fn exec(self) -> Result<()> { todo!("got command: {:?}", self) }
+}