From 0c916c04bbff99adbb09ac47af6306e6ead023ff Mon Sep 17 00:00:00 2001 From: Evan Battaglia Date: Fri, 6 Sep 2024 02:16:30 -0230 Subject: [PATCH] add back in tests from old tabry (and fix indent on multi-line strings) --- TODO.md | 9 +++++- .../arguments_and_possible_options__arg_.json | 0 ...arguments_and_possible_options__arg_.tabry | 0 .../multi_line_descriptions.json | 0 .../multi_line_descriptions.tabry | 0 src/lang/compiler.rs | 8 ++++- src/lang/lexer.rs | 30 ++++++++++++++++++- 7 files changed, 44 insertions(+), 3 deletions(-) rename fixtures/{TODO_examples_from_language_reference => examples_from_language_reference}/arguments_and_possible_options__arg_.json (100%) rename fixtures/{TODO_examples_from_language_reference => examples_from_language_reference}/arguments_and_possible_options__arg_.tabry (100%) rename fixtures/{TODO_examples_from_language_reference => examples_from_language_reference}/multi_line_descriptions.json (100%) rename fixtures/{TODO_examples_from_language_reference => examples_from_language_reference}/multi_line_descriptions.tabry (100%) diff --git a/TODO.md b/TODO.md index 7366fc6..1719b26 100644 --- a/TODO.md +++ b/TODO.md @@ -2,16 +2,23 @@ TODO before "public announcement" * fish and nix support merged * zsh support/testing * go through TODOs -* get remaning example tests from ruby working * combining the three includes (sub, arg, flag) in the JSON format would be great --- * put on cargo +* more examples / language reference in this repo. * bump version number and add deb * better instructions for installing (build from source, cargo, nix, deb) -- very soon after * flags like -abc -> -a, -b, -c + -- soon after * tests to 80% coverage (goal 100% eventually) +* more TODOs from code +* documentation about using the tabry gem + "completion json" for speedy tab complteion, and in tabry * set up github automated tests * I think I need to use bytes instead of strings for reading argv + +-- much later +* actually use argument names, titles, and descriptions -- probably a'help' thing? although I'm not sure of the use without a CLI library +* CLI library? compile to clap (requires types)? not sure of the future diff --git a/fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.json b/fixtures/examples_from_language_reference/arguments_and_possible_options__arg_.json similarity index 100% rename from fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.json rename to fixtures/examples_from_language_reference/arguments_and_possible_options__arg_.json diff --git a/fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.tabry b/fixtures/examples_from_language_reference/arguments_and_possible_options__arg_.tabry similarity index 100% rename from fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.tabry rename to fixtures/examples_from_language_reference/arguments_and_possible_options__arg_.tabry diff --git a/fixtures/TODO_examples_from_language_reference/multi_line_descriptions.json b/fixtures/examples_from_language_reference/multi_line_descriptions.json similarity index 100% rename from fixtures/TODO_examples_from_language_reference/multi_line_descriptions.json rename to fixtures/examples_from_language_reference/multi_line_descriptions.json diff --git a/fixtures/TODO_examples_from_language_reference/multi_line_descriptions.tabry b/fixtures/examples_from_language_reference/multi_line_descriptions.tabry similarity index 100% rename from fixtures/TODO_examples_from_language_reference/multi_line_descriptions.tabry rename to fixtures/examples_from_language_reference/multi_line_descriptions.tabry diff --git a/src/lang/compiler.rs b/src/lang/compiler.rs index ad0950b..6989f5d 100644 --- a/src/lang/compiler.rs +++ b/src/lang/compiler.rs @@ -121,7 +121,13 @@ fn make_arg(stmt: &parser::ArgStatement, name: Option) -> types::TabryAr eprintln!("ignoring title: {:?}", title_stmt.title); } } - parser::Statement::Desc(_desc_stmt) => {} // TODO (not supported in types module yet) + parser::Statement::Desc(desc_stmt) => { + if arg.description.is_some() { + // TODO errors for real, dedup with cmd + panic!("multiple desc statements found"); + } + arg.description = Some(desc_stmt.desc); + } _ => unreachable!("unhandled statement in compile_arg: {:?}", stmt_in_block), } } diff --git a/src/lang/lexer.rs b/src/lang/lexer.rs index aeb2f85..f0b71db 100644 --- a/src/lang/lexer.rs +++ b/src/lang/lexer.rs @@ -58,9 +58,37 @@ fn string_internals(i: &mut &str) -> PResult { .parse_next(i) } +/// Multi-line strings in tabry can be indented for readability: +/// arg { +/// desc " +/// Hello +/// World +/// " +/// } +/// -> resulting string is "Hello\n World" +fn unindent(s: String) -> String { + if !(s.starts_with("\n ") || s.ends_with("\n\t")) { + return s; + } + + let base_indent_chars = s[1..].chars().take_while(|c| c.is_whitespace()).count(); + + let lines = s.trim().lines(); + let trimmed_lines = lines.map(|line| { + // min of base_indent_chars and actual indent on this line + let indent_here = line + .chars() + .take(base_indent_chars) + .take_while(|c| c.is_whitespace()) + .count(); + &line[indent_here..] + }); + trimmed_lines.collect::>().join("\n") +} + fn string<'a>(i: &mut &'a str) -> PResult> { let s = delimited("\"", string_internals, "\"").parse_next(i)?; - Ok(Token::String(s)) + Ok(Token::String(unindent(s))) } fn identifier_str<'a>(i: &mut &'a str) -> PResult<&'a str> {