mirror of
https://github.com/sigoden/aichat
synced 2024-11-18 09:28:27 +00:00
chore: optimize readline multiline
This commit is contained in:
parent
4aab872ee1
commit
0ed0ad1fd2
@ -1,11 +1,13 @@
|
||||
use super::{highlighter::ReplHighlighter, prompt::ReplPrompt, REPL_COMMANDS};
|
||||
use super::{
|
||||
highlighter::ReplHighlighter, prompt::ReplPrompt, validator::ReplValidator, REPL_COMMANDS,
|
||||
};
|
||||
|
||||
use crate::config::{Config, SharedConfig};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use reedline::{
|
||||
default_emacs_keybindings, ColumnarMenu, DefaultCompleter, DefaultValidator, Emacs,
|
||||
FileBackedHistory, KeyCode, KeyModifiers, Keybindings, Reedline, ReedlineEvent, ReedlineMenu,
|
||||
default_emacs_keybindings, ColumnarMenu, DefaultCompleter, Emacs, FileBackedHistory, KeyCode,
|
||||
KeyModifiers, Keybindings, Reedline, ReedlineEvent, ReedlineMenu,
|
||||
};
|
||||
|
||||
const MENU_NAME: &str = "completion_menu";
|
||||
@ -36,7 +38,7 @@ impl Repl {
|
||||
.with_edit_mode(edit_mode)
|
||||
.with_quick_completions(true)
|
||||
.with_partial_completions(true)
|
||||
.with_validator(Box::new(DefaultValidator))
|
||||
.with_validator(Box::new(ReplValidator))
|
||||
.with_ansi_colors(true);
|
||||
let prompt = ReplPrompt::new(config);
|
||||
Ok(Self { editor, prompt })
|
||||
|
@ -3,6 +3,7 @@ mod handler;
|
||||
mod highlighter;
|
||||
mod init;
|
||||
mod prompt;
|
||||
mod validator;
|
||||
|
||||
pub use self::abort::*;
|
||||
pub use self::handler::*;
|
||||
|
59
src/repl/validator.rs
Normal file
59
src/repl/validator.rs
Normal file
@ -0,0 +1,59 @@
|
||||
use reedline::{ValidationResult, Validator};
|
||||
|
||||
/// A default validator which checks for mismatched quotes and brackets
|
||||
pub struct ReplValidator;
|
||||
|
||||
impl Validator for ReplValidator {
|
||||
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 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…
Reference in New Issue
Block a user