Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions examples/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use dialoguer::{theme::ColorfulTheme, Completion, Input};
fn main() {
println!("Use the Right arrow or Tab to complete your command");

let completion = MyCompletion::default();
let mut completion = MyCompletion::default();

Input::<String>::with_theme(&ColorfulTheme::default())
.with_prompt("dialoguer")
.completion_with(&completion)
.completion_with(&mut completion)
.interact_text()
.unwrap();
}
Expand All @@ -30,7 +30,7 @@ impl Default for MyCompletion {

impl Completion for MyCompletion {
/// Simple completion implementation based on substring
fn get(&self, input: &str) -> Option<String> {
fn next(&mut self, input: &str, _completion_modified: bool) -> Option<String> {
let matches = self
.options
.iter()
Expand Down
4 changes: 2 additions & 2 deletions src/completion.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/// Trait for completion handling.
pub trait Completion {
fn get(&self, input: &str) -> Option<String>;
pub trait Completion: Send {
fn next(&mut self, input: &str, completion_modified: bool) -> Option<String>;
}
30 changes: 25 additions & 5 deletions src/prompts/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ pub struct Input<'a, T> {
#[cfg(feature = "history")]
history: Option<Arc<Mutex<&'a mut dyn History<T>>>>,
#[cfg(feature = "completion")]
completion: Option<&'a dyn Completion>,
completion: Option<Arc<Mutex<&'a mut dyn Completion>>>,
#[cfg(feature = "completion")]
completion_modified: bool,
}

impl<T> Default for Input<'static, T> {
Expand Down Expand Up @@ -164,6 +166,8 @@ impl<'a, T> Input<'a, T> {
history: None,
#[cfg(feature = "completion")]
completion: None,
#[cfg(feature = "completion")]
completion_modified: false,
}
}

Expand Down Expand Up @@ -219,11 +223,11 @@ impl<'a, T> Input<'a, T> {

/// Enable completion
#[cfg(feature = "completion")]
pub fn completion_with<C>(mut self, completion: &'a C) -> Self
pub fn completion_with<C>(mut self, completion: &'a mut C) -> Self
where
C: Completion,
{
self.completion = Some(completion);
self.completion = Some(Arc::new(Mutex::new(completion)));
self
}
}
Expand Down Expand Up @@ -354,6 +358,11 @@ where
}

term.flush()?;

#[cfg(feature = "completion")]
if self.completion.is_some() {
self.completion_modified = true;
}
}
Key::Char(chr) if !chr.is_ascii_control() => {
chars.insert(position, chr);
Expand All @@ -363,6 +372,11 @@ where
term.write_str(&tail)?;
term.move_cursor_left(tail.chars().count() - 1)?;
term.flush()?;

#[cfg(feature = "completion")]
if self.completion.is_some() {
self.completion_modified = true;
}
}
Key::ArrowLeft if position > 0 => {
if (position + prompt_len) % term.size().1 as usize == 0 {
Expand Down Expand Up @@ -473,9 +487,13 @@ where
}
#[cfg(feature = "completion")]
Key::ArrowRight | Key::Tab => {
if let Some(completion) = &self.completion {
if let Some(completion) = &mut self.completion {
let input: String = chars.clone().into_iter().collect();
if let Some(x) = completion.get(&input) {
if let Some(x) = completion
.lock()
.unwrap()
.next(&input, self.completion_modified)
{
term.clear_chars(chars.len())?;
chars.clear();
position = 0;
Expand All @@ -486,6 +504,8 @@ where
term.write_str(&x)?;
term.flush()?;
}

self.completion_modified = false;
}
}
#[cfg(feature = "history")]
Expand Down
Loading