Merge branch 'custom-validator' into 'main'

Add custom validator to fix multiline behaviour when working with strings

See merge request whom/relish!7
This commit is contained in:
Ava Apples Affine 2023-06-11 18:23:36 +00:00
commit e802eb480d

View file

@ -42,7 +42,7 @@ use {
Reedline, Signal, Prompt, PromptEditMode, PromptHistorySearch,
PromptHistorySearchStatus, Completer, Suggestion, Span,
KeyModifiers, KeyCode, ReedlineEvent, Keybindings,
ColumnarMenu, Emacs, ReedlineMenu,
ColumnarMenu, Emacs, ReedlineMenu, Validator, ValidationResult,
default_emacs_keybindings,
},
nu_ansi_term::{Color, Style},
@ -61,6 +61,8 @@ pub struct CustomPrompt(String, String, String);
#[derive(Clone)]
pub struct CustomCompleter(Vec<String>);
pub struct CustomValidator;
impl Prompt for CustomPrompt {
fn render_prompt_left(&self) -> Cow<str> {
{
@ -221,6 +223,51 @@ impl Completer for CustomCompleter {
}
}
impl Validator for CustomValidator {
fn validate(&self, line: &str) -> ValidationResult {
if incomplete_brackets(line) {
ValidationResult::Incomplete
} else {
ValidationResult::Complete
}
}
}
fn incomplete_brackets(line: &str) -> bool {
let mut balance: Vec<char> = Vec::new();
let mut within_string: Option<char> = None;
for c in line.chars() {
match c {
c if ['"', '`', '\''].contains(&c) => {
match within_string {
Some(w) if c == w => {
balance.pop();
within_string = None
}
Some(_) => {},
None => {
balance.push(c);
within_string = Some(c)
},
}
},
'(' if within_string.is_none() => balance.push(')'),
')' => if let Some(last) = balance.last() {
if last == &c {
balance.pop();
}
},
_ => {}
}
}
!balance.is_empty()
}
fn add_menu_keybindings(keybindings: &mut Keybindings) {
keybindings.add_binding(
KeyModifiers::NONE,
@ -313,7 +360,7 @@ fn main() {
rl = rl.with_hinter(Box::new(
DefaultHinter::default()
.with_style(Style::new().italic().fg(Color::LightGray)),
)).with_validator(Box::new(DefaultValidator));
)).with_validator(Box::new(CustomValidator));
let mut xdimension: u16 = 0;
let mut ydimension: u16 = 0;