Skip to content

Commit

Permalink
Custom validator and prompt code examples (#500)
Browse files Browse the repository at this point in the history
* custom validator and prompt

* Split prompt and validator demo into two files

Also add info text when running

Co-authored-by: sholderbach <[email protected]>
  • Loading branch information
perlindgren and sholderbach authored Nov 7, 2022
1 parent 431d2ab commit cd2d263
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
75 changes: 75 additions & 0 deletions examples/custom_prompt.rs
Original file line number Diff line number Diff line change
@@ -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<u32>, &'static str);
pub static DEFAULT_MULTILINE_INDICATOR: &str = "::: ";
impl Prompt for CustomPrompt {
fn render_prompt_left(&self) -> Cow<str> {
{
Cow::Owned(self.1.to_string())
}
}

fn render_prompt_right(&self) -> Cow<str> {
{
let old = self.0.get();
self.0.set(old + 1);
Cow::Owned(format!("[{}]", old))
}
}

fn render_prompt_indicator(&self, _edit_mode: PromptEditMode) -> Cow<str> {
Cow::Owned(">".to_string())
}

fn render_prompt_multiline_indicator(&self) -> Cow<str> {
Cow::Borrowed(DEFAULT_MULTILINE_INDICATOR)
}

fn render_prompt_history_search_indicator(
&self,
history_search: PromptHistorySearch,
) -> Cow<str> {
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(());
}
}
}
}
41 changes: 41 additions & 0 deletions examples/validator.rs
Original file line number Diff line number Diff line change
@@ -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(());
}
}
}
}

0 comments on commit cd2d263

Please sign in to comment.