feat: use backslash at end of line for multiline text (#147)

BREAKING CHANGE: use backslash at end of line for multiline text

```
〉.set dry_run true

〉abc \
def \
ijk

>>> The following message consumes 12 tokens.
abc 
def 
ijk
```

Deprecate old {}/() multi-line editing
pull/148/head
sigoden 11 months ago committed by GitHub
parent e09b39def9
commit b5e1460151
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -16,7 +16,6 @@ use crate::term;
use anyhow::{Context, Result};
use reedline::Signal;
use std::borrow::Cow;
use std::rc::Rc;
pub const REPL_COMMANDS: [(&str, &str); 13] = [
@ -86,7 +85,7 @@ impl Repl {
}
fn handle_line(&mut self, handler: &Rc<ReplCmdHandler>, line: &str) -> Result<bool> {
let line = clean_multiline_symbols(line);
let line = line.trim().replace("\\\n", "\n");
match parse_command(line.as_ref()) {
Some((cmd, args)) => match cmd {
".exit" => {
@ -165,21 +164,12 @@ fn dump_repl_help() {
print_now!(
r###"{head}
Type `{{` to enter the multi-line editing mode, type '}}' to exit the mode.
Press Ctrl+C to abort readline, Ctrl+D to exit the REPL
"###,
);
}
fn clean_multiline_symbols(line: &str) -> Cow<str> {
let trimed_line = line.trim();
match trimed_line.chars().next() {
Some('{' | '[' | '(') => trimed_line[1..trimed_line.len() - 1].into(),
_ => Cow::Borrowed(line),
}
}
fn parse_command(line: &str) -> Option<(&str, Option<&str>)> {
let mut trimed_line = line.trim_start();
if trimed_line.starts_with('.') {

@ -6,55 +6,10 @@ pub struct ReplValidator;
impl Validator for ReplValidator {
fn validate(&self, line: &str) -> ValidationResult {
if incomplete_brackets(line) {
if line.ends_with('\\') {
ValidationResult::Incomplete
} else {
ValidationResult::Complete
}
}
}
fn incomplete_brackets(line: &str) -> bool {
let mut balance: Vec<char> = Vec::new();
let mut symbol = None;
for c in line.chars() {
match symbol {
Some(s) => match (s, c) {
('{', '}') | ('(', ')') => {
balance.pop();
}
_ if s == c => {
balance.push(c);
}
_ => {}
},
None => match c {
'{' | '(' => {
balance.push(c);
symbol = Some(c);
}
_ => {}
},
}
}
!balance.is_empty()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_incomplete_brackets() {
assert!(incomplete_brackets("{"));
assert!(incomplete_brackets("("));
assert!(!incomplete_brackets("{}"));
assert!(!incomplete_brackets("()"));
assert!(!incomplete_brackets("{ab\nc}"));
assert!(!incomplete_brackets("(ab\nc)"));
assert!(!incomplete_brackets("{[}"));
assert!(!incomplete_brackets("{{{{{}}}}}"));
assert!(incomplete_brackets("{{}"));
}
}

Loading…
Cancel
Save