From cd2d263eb41a045f9c7084b98397a5dbda42dc35 Mon Sep 17 00:00:00 2001 From: perlindgren Date: Mon, 7 Nov 2022 20:33:54 +0100 Subject: [PATCH] Custom validator and prompt code examples (#500) * custom validator and prompt * Split prompt and validator demo into two files Also add info text when running Co-authored-by: sholderbach --- examples/custom_prompt.rs | 75 +++++++++++++++++++++++++++++++++++++++ examples/validator.rs | 41 +++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 examples/custom_prompt.rs create mode 100644 examples/validator.rs diff --git a/examples/custom_prompt.rs b/examples/custom_prompt.rs new file mode 100644 index 0000000..d7d6de9 --- /dev/null +++ b/examples/custom_prompt.rs @@ -0,0 +1,75 @@ +// Create a reedline object with a custom prompt. +// cargo run --example custom_prompt +// +// Pressing keys will increase the right prompt value + +use reedline::{ + Prompt, PromptEditMode, PromptHistorySearch, PromptHistorySearchStatus, Reedline, Signal, +}; +use std::{borrow::Cow, cell::Cell, io}; + +// For custom prompt, implement the Prompt trait +// +// This example displays the number of keystrokes +// or rather increments each time the prompt is rendered. +#[derive(Clone)] +pub struct CustomPrompt(Cell, &'static str); +pub static DEFAULT_MULTILINE_INDICATOR: &str = "::: "; +impl Prompt for CustomPrompt { + fn render_prompt_left(&self) -> Cow { + { + Cow::Owned(self.1.to_string()) + } + } + + fn render_prompt_right(&self) -> Cow { + { + let old = self.0.get(); + self.0.set(old + 1); + Cow::Owned(format!("[{}]", old)) + } + } + + fn render_prompt_indicator(&self, _edit_mode: PromptEditMode) -> Cow { + Cow::Owned(">".to_string()) + } + + fn render_prompt_multiline_indicator(&self) -> Cow { + Cow::Borrowed(DEFAULT_MULTILINE_INDICATOR) + } + + fn render_prompt_history_search_indicator( + &self, + history_search: PromptHistorySearch, + ) -> Cow { + let prefix = match history_search.status { + PromptHistorySearchStatus::Passing => "", + PromptHistorySearchStatus::Failing => "failing ", + }; + + Cow::Owned(format!( + "({}reverse-search: {}) ", + prefix, history_search.term + )) + } +} + +fn main() -> io::Result<()> { + println!("Custom prompt demo:\nAbort with Ctrl-C or Ctrl-D"); + let mut line_editor = Reedline::create(); + + let prompt = CustomPrompt(Cell::new(0), "Custom Prompt"); + + loop { + let sig = line_editor.read_line(&prompt)?; + match sig { + Signal::Success(buffer) => { + println!("We processed: {}", buffer); + } + Signal::CtrlD | Signal::CtrlC => { + println!("\nAborted!"); + break Ok(()); + } + } + } +} diff --git a/examples/validator.rs b/examples/validator.rs new file mode 100644 index 0000000..efe80be --- /dev/null +++ b/examples/validator.rs @@ -0,0 +1,41 @@ +// Create a reedline object with a custom validator to break the line on unfinished input. +// cargo run --example validator +// +// Input "complete" followed by [Enter], will accept the input line (Signal::Succeed will be called) +// Pressing [Enter] will in other cases give you a multi-line prompt. + +use reedline::{DefaultPrompt, Reedline, Signal, ValidationResult, Validator}; +use std::io; + +struct CustomValidator; + +// For custom validation, implement the Validator trait +impl Validator for CustomValidator { + fn validate(&self, line: &str) -> ValidationResult { + if line == "complete" { + ValidationResult::Complete + } else { + ValidationResult::Incomplete + } + } +} + +fn main() -> io::Result<()> { + println!("Input \"complete\" followed by [Enter], will accept the input line (Signal::Succeed will be called)\nPressing [Enter] will in other cases give you a multi-line prompt.\nAbort with Ctrl-C or Ctrl-D"); + let mut line_editor = Reedline::create().with_validator(Box::new(CustomValidator)); + + let prompt = DefaultPrompt::default(); + + loop { + let sig = line_editor.read_line(&prompt)?; + match sig { + Signal::Success(buffer) => { + println!("We processed: {}", buffer); + } + Signal::CtrlD | Signal::CtrlC => { + println!("\nAborted!"); + break Ok(()); + } + } + } +}