mirror of
https://github.com/zaphar/sheetsui.git
synced 2025-07-22 13:00:22 -04:00
parent
d7301246d8
commit
e91c149619
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1399,6 +1399,7 @@ dependencies = [
|
||||
"futures",
|
||||
"ironcalc",
|
||||
"ratatui",
|
||||
"slice-cursor",
|
||||
"thiserror",
|
||||
"tui-prompts",
|
||||
"tui-textarea",
|
||||
@ -1455,6 +1456,11 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slice-cursor"
|
||||
version = "0.1.0"
|
||||
source = "git+https://dev.zaphar.net/zaphar/slice-cursor-rs.git#562a78eb3f06ac2a9729af7aa211a070f8ed9c39"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
|
@ -16,3 +16,4 @@ ratatui = "0.29.0"
|
||||
thiserror = "1.0.65"
|
||||
tui-textarea = "0.7.0"
|
||||
tui-prompts = "0.5.0"
|
||||
slice-cursor = { git = "https://dev.zaphar.net/zaphar/slice-cursor-rs.git" }
|
||||
|
99
src/ui/cmd.rs
Normal file
99
src/ui/cmd.rs
Normal file
@ -0,0 +1,99 @@
|
||||
//! Command mode command parsers.
|
||||
use slice_cursor::{Cursor, Seekable, Span, SpanRange, StrCursor};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Cmd<'a> {
|
||||
Write(Option<&'a str>),
|
||||
InsertRow(usize),
|
||||
InsertColumns(usize),
|
||||
Edit(&'a str),
|
||||
Help(Option<&'a str>),
|
||||
}
|
||||
|
||||
pub fn parse<'cmd, 'i: 'cmd>(input: &'i str) -> Result<Option<Cmd<'cmd>>, &'static str> {
|
||||
let cursor = StrCursor::new(input);
|
||||
// try consume write command.
|
||||
if let Some(cmd) = try_consume_write(cursor.clone()) {
|
||||
return Ok(Some(cmd));
|
||||
}
|
||||
// try consume insert-row command.
|
||||
if let Some(cmd) = try_consume_insert_row(cursor.clone())? {
|
||||
return Ok(Some(cmd));
|
||||
}
|
||||
// try consume insert-col command.
|
||||
if let Some(cmd) = try_consume_insert_column(cursor.clone()) {
|
||||
return Ok(Some(cmd));
|
||||
}
|
||||
// try consume edit command.
|
||||
if let Some(cmd) = try_consume_edit(cursor.clone()) {
|
||||
return Ok(Some(cmd));
|
||||
}
|
||||
// try consume help command.
|
||||
if let Some(cmd) = try_consume_help(cursor.clone()) {
|
||||
return Ok(Some(cmd));
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
const WRITE: &'static str = "write";
|
||||
|
||||
pub fn try_consume_write<'cmd, 'i: 'cmd>(mut input: StrCursor<'i>) -> Option<Cmd<'cmd>> {
|
||||
let prefix_len = WRITE.len();
|
||||
let full_length = dbg!(input.span(..).len());
|
||||
let arg = if full_length >= prefix_len && input.span(..prefix_len) == WRITE {
|
||||
input.seek(prefix_len);
|
||||
// Should we check for whitespace?
|
||||
input.span(prefix_len..)
|
||||
} else if full_length >= 2 && input.span(..2) == "w " {
|
||||
input.span(2..)
|
||||
// Should we check for whitespace?
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
.trim();
|
||||
return Some(Cmd::Write(if arg.is_empty() { None } else { Some(arg) }));
|
||||
}
|
||||
|
||||
const IR: &'static str = "ir";
|
||||
const INSERT_ROW: &'static str = "insert-row";
|
||||
|
||||
pub fn try_consume_insert_row<'cmd, 'i: 'cmd>(
|
||||
mut input: StrCursor<'i>,
|
||||
) -> Result<Option<Cmd<'cmd>>, &'static str> {
|
||||
let prefix_len = INSERT_ROW.len();
|
||||
let second_prefix_len = IR.len();
|
||||
let full_length = input.span(..).len();
|
||||
let arg =
|
||||
if full_length >= prefix_len && input.span(..prefix_len) == INSERT_ROW {
|
||||
input.seek(prefix_len);
|
||||
// Should we check for whitespace?
|
||||
input.span(prefix_len..)
|
||||
} else if full_length >= second_prefix_len && input.span(..second_prefix_len) == IR {
|
||||
input.span(second_prefix_len..)
|
||||
// Should we check for whitespace?
|
||||
} else {
|
||||
return Ok(None);
|
||||
}
|
||||
.trim();
|
||||
return Ok(Some(Cmd::InsertRow(if arg.is_empty() {
|
||||
1
|
||||
} else {
|
||||
if let Ok(count) = arg.parse() {
|
||||
count
|
||||
} else {
|
||||
return Err("You must pass in a non negative number for the row count");
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
pub fn try_consume_insert_column<'cmd, 'i: 'cmd>(mut input: StrCursor<'i>) -> Option<Cmd<'cmd>> {
|
||||
todo!("insert-column not yet implemented")
|
||||
}
|
||||
|
||||
pub fn try_consume_edit<'cmd, 'i: 'cmd>(mut input: StrCursor<'i>) -> Option<Cmd<'cmd>> {
|
||||
todo!("edit not yet implemented")
|
||||
}
|
||||
|
||||
pub fn try_consume_help<'cmd, 'i: 'cmd>(mut input: StrCursor<'i>) -> Option<Cmd<'cmd>> {
|
||||
todo!("help not yet implemented")
|
||||
}
|
@ -12,6 +12,10 @@ use ratatui::{
|
||||
use tui_prompts::{State, Status, TextPrompt, TextState};
|
||||
use tui_textarea::{CursorMove, TextArea};
|
||||
|
||||
mod cmd;
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
#[derive(Default, Debug, PartialEq)]
|
||||
pub enum Modality {
|
||||
#[default]
|
||||
@ -197,6 +201,14 @@ impl<'ws> Workspace<'ws> {
|
||||
if cmd.is_empty() {
|
||||
return Ok(true);
|
||||
}
|
||||
match cmd.as_str() {
|
||||
"w" | "write" => {
|
||||
self.save_file()?;
|
||||
},
|
||||
_ => {
|
||||
// noop?
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
|
45
src/ui/test.rs
Normal file
45
src/ui/test.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use super::cmd::{parse, Cmd};
|
||||
|
||||
#[test]
|
||||
fn test_write_cmd() {
|
||||
let input = "write foo.xlsx";
|
||||
let result = parse(input);
|
||||
assert!(result.is_ok());
|
||||
let output = result.unwrap();
|
||||
assert!(output.is_some());
|
||||
let cmd = output.unwrap();
|
||||
assert_eq!(cmd, Cmd::Write(Some("foo.xlsx")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_short_write_cmd() {
|
||||
let input = "w foo.xlsx";
|
||||
let result = parse(input);
|
||||
assert!(result.is_ok());
|
||||
let output = result.unwrap();
|
||||
assert!(output.is_some());
|
||||
let cmd = output.unwrap();
|
||||
assert_eq!(cmd, Cmd::Write(Some("foo.xlsx")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_insert_row_cmd() {
|
||||
let input = "insert-row 1";
|
||||
let result = parse(input);
|
||||
assert!(result.is_ok());
|
||||
let output = result.unwrap();
|
||||
assert!(output.is_some());
|
||||
let cmd = output.unwrap();
|
||||
assert_eq!(cmd, Cmd::InsertRow(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_insert_row_cmd_short() {
|
||||
let input = "ir 1";
|
||||
let result = parse(input);
|
||||
assert!(result.is_ok());
|
||||
let output = result.unwrap();
|
||||
assert!(output.is_some());
|
||||
let cmd = output.unwrap();
|
||||
assert_eq!(cmd, Cmd::InsertRow(1));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user